Merge branch 'Mesh_3-parallel-cjamin-old' into Mesh_3-parallel-cjamin

This commit is contained in:
Clement Jamin 2014-07-01 10:38:14 +02:00
commit e3abf7fc40
174 changed files with 50332 additions and 6077 deletions

3
.gitignore vendored
View File

@ -757,7 +757,6 @@ Ridges_3/examples/Ridges_3/Compute_Ridges_Umbilics
Ridges_3/examples/Ridges_3/Makefile
Ridges_3/test/Ridges_3/Makefile
Ridges_3/test/Ridges_3/ridge_test
STL_Extension/test/STL_Extension/CMakeLists.txt
STL_Extension/test/STL_Extension/cgal_test_with_cmake
STL_Extension/test/STL_Extension/test_Cache
STL_Extension/test/STL_Extension/test_Compact_container
@ -930,7 +929,6 @@ Triangulation_2/test/Triangulation_2/vrml_tds*
Triangulation_3/benchmark/Triangulation_3/CMakeLists.txt
Triangulation_3/benchmark/Triangulation_3/cgal_test_with_cmake
Triangulation_3/benchmark/Triangulation_3/simple
Triangulation_3/examples/Triangulation_3/CMakeLists.txt
Triangulation_3/examples/Triangulation_3/adding_handles_3
Triangulation_3/examples/Triangulation_3/cgal_test_with_cmake
Triangulation_3/examples/Triangulation_3/color
@ -946,7 +944,6 @@ Triangulation_3/examples/Triangulation_3/regular_3
Triangulation_3/examples/Triangulation_3/simple_triangulation_3
Triangulation_3/examples/Triangulation_3/simplex
Triangulation_3/examples/Triangulation_3/tds
Triangulation_3/test/Triangulation_3/CMakeLists.txt
Triangulation_3/test/Triangulation_3/Makefile
Triangulation_3/test/Triangulation_3/Test1_triangulation_IO_3_binary
Triangulation_3/test/Triangulation_3/Test2_triangulation_IO_3_binary

View File

@ -1811,7 +1811,7 @@ ABSTRACT = {We present the first complete, exact and efficient C++ implementatio
}
@inproceedings{cgal:tsa-ps3dd-09,
author = {Jane TOURNOIS and Rahul SRINIVASAN and Pierre ALLIEZ},
author = {Jane Tournois and Rahul Srinivasan and Pierre Alliez},
title = {{Perturbing slivers in 3D Delaunay meshes}},
year = {2009},
month = {october},

View File

@ -24,22 +24,24 @@
#ifndef CGAL_CHAINED_MAP_H
#define CGAL_CHAINED_MAP_H
#include <CGAL/memory.h>
namespace CGAL {
namespace internal {
template <typename T> class chained_map;
template <typename T, typename Allocator = CGAL_ALLOCATOR(T) > class chained_map;
template <typename T> class chained_map_elem;
template <typename T>
class chained_map_elem
{
friend class chained_map<T>;
template<typename T2, typename Alloc> friend class chained_map;
std::size_t k; T i;
chained_map_elem<T>* succ;
};
template <typename T>
template <typename T, typename Allocator>
class chained_map
{
const std::size_t NULLKEY;
@ -50,8 +52,8 @@ class chained_map
chained_map_elem<T>* table;
chained_map_elem<T>* table_end;
chained_map_elem<T>* free;
std::size_t table_size;
std::size_t table_size_1;
std::size_t table_size;
std::size_t table_size_1;
chained_map_elem<T>* old_table;
chained_map_elem<T>* old_table_end;
@ -61,6 +63,9 @@ class chained_map
std::size_t old_index;
typedef typename Allocator::template rebind<chained_map_elem<T> >::other allocator_type;
allocator_type alloc;
public:
T& xdef() { return STOP.i; }
const T& cxdef() const { return STOP.i; }
@ -84,14 +89,25 @@ public:
std::size_t index(chained_map_item it) const { return it->k; }
T& inf(chained_map_item it) const { return it->i; }
chained_map(std::size_t n = 1);
chained_map(const chained_map<T>& D);
chained_map& operator=(const chained_map<T>& D);
chained_map(std::size_t n = 1);
chained_map(const chained_map<T, Allocator>& D);
chained_map& operator=(const chained_map<T, Allocator>& D);
void clear_entries();
void clear();
~chained_map() { if (old_table) delete[] old_table; delete[] table; }
~chained_map()
{
if (old_table)
{
for (chained_map_item item = old_table ; item != old_table_end ; ++item)
alloc.destroy(item);
alloc.deallocate(old_table, old_table_end - old_table);
}
for (chained_map_item item = table ; item != table_end ; ++item)
alloc.destroy(item);
alloc.deallocate(table, table_end - table);
}
T& access(chained_map_item p, std::size_t x);
T& access(std::size_t x);
@ -101,8 +117,8 @@ public:
void statistics() const;
};
template <typename T>
inline T& chained_map<T>::access(std::size_t x)
template <typename T, typename Allocator>
inline T& chained_map<T, Allocator>::access(std::size_t x)
{ chained_map_item p = HASH(x);
if (old_table) del_old_table();
@ -121,12 +137,12 @@ inline T& chained_map<T>::access(std::size_t x)
}
}
template <typename T>
void chained_map<T>::init_table(std::size_t t)
template <typename T, typename Allocator>
void chained_map<T, Allocator>::init_table(std::size_t t)
{
table_size = t;
table_size_1 = t-1;
table = new chained_map_elem<T>[t + t/2];
table = alloc.allocate(t + t/2);
free = table + t;
table_end = table + t + t/2;
@ -138,8 +154,8 @@ void chained_map<T>::init_table(std::size_t t)
}
template <typename T>
inline void chained_map<T>::insert(std::size_t x, T y)
template <typename T, typename Allocator>
inline void chained_map<T, Allocator>::insert(std::size_t x, T y)
{ chained_map_item q = HASH(x);
if ( q->k == NULLKEY ) {
q->k = x;
@ -153,8 +169,8 @@ inline void chained_map<T>::insert(std::size_t x, T y)
}
template <typename T>
void chained_map<T>::rehash()
template <typename T, typename Allocator>
void chained_map<T, Allocator>::rehash()
{
old_table = table;
old_table_end = table_end;
@ -185,8 +201,8 @@ void chained_map<T>::rehash()
}
template <typename T>
void chained_map<T>::del_old_table()
template <typename T, typename Allocator>
void chained_map<T, Allocator>::del_old_table()
{
chained_map_item save_table = table;
chained_map_item save_table_end = table_end;
@ -204,7 +220,9 @@ void chained_map<T>::del_old_table()
T p = access(old_index);
delete[] table;
for (chained_map_item item = table ; item != table_end ; ++item)
alloc.destroy(item);
alloc.deallocate(table, table_end - table);
table = save_table;
table_end = save_table_end;
@ -214,8 +232,8 @@ void chained_map<T>::del_old_table()
access(old_index) = p;
}
template <typename T>
T& chained_map<T>::access(chained_map_item p, std::size_t x)
template <typename T, typename Allocator>
T& chained_map<T, Allocator>::access(chained_map_item p, std::size_t x)
{
STOP.k = x;
chained_map_item q = p->succ;
@ -247,8 +265,8 @@ T& chained_map<T>::access(chained_map_item p, std::size_t x)
}
template <typename T>
chained_map<T>::chained_map(std::size_t n) :
template <typename T, typename Allocator>
chained_map<T, Allocator>::chained_map(std::size_t n) :
NULLKEY(0), NONNULLKEY(1), old_table(0)
{
if (n < 512)
@ -261,8 +279,8 @@ chained_map<T>::chained_map(std::size_t n) :
}
template <typename T>
chained_map<T>::chained_map(const chained_map<T>& D) :
template <typename T, typename Allocator>
chained_map<T, Allocator>::chained_map(const chained_map<T, Allocator>& D) :
NULLKEY(0), NONNULLKEY(1), old_table(0)
{
init_table(D.table_size);
@ -276,11 +294,15 @@ chained_map<T>::chained_map(const chained_map<T>& D) :
}
}
template <typename T>
chained_map<T>& chained_map<T>::operator=(const chained_map<T>& D)
template <typename T, typename Allocator>
chained_map<T, Allocator>& chained_map<T, Allocator>::operator=(const chained_map<T, Allocator>& D)
{
clear_entries();
delete[] table;
for (chained_map_item item = table ; item != table_end ; ++item)
alloc.destroy(item);
alloc.deallocate(table, table_end - table);
init_table(D.table_size);
STOP.i = D.STOP.i; // xdef
@ -293,23 +315,28 @@ chained_map<T>& chained_map<T>::operator=(const chained_map<T>& D)
return *this;
}
template <typename T>
void chained_map<T>::clear_entries()
template <typename T, typename Allocator>
void chained_map<T, Allocator>::clear_entries()
{ for(chained_map_item p = table + 1; p < free; p++)
if (p->k != NULLKEY || p >= table + table_size)
p->i = T();
}
template <typename T>
void chained_map<T>::clear()
{ clear_entries();
delete[] table;
template <typename T, typename Allocator>
void chained_map<T, Allocator>::clear()
{
clear_entries();
for (chained_map_item item = table ; item != table_end ; ++item)
alloc.destroy(item);
alloc.deallocate(table, table_end - table);
init_table(512);
}
template <typename T>
typename chained_map<T>::chained_map_item
chained_map<T>::lookup(std::size_t x) const
template <typename T, typename Allocator>
typename chained_map<T, Allocator>::chained_map_item
chained_map<T, Allocator>::lookup(std::size_t x) const
{ chained_map_item p = HASH(x);
((std::size_t &)STOP.k) = x; // cast away const
while (p->k != x)
@ -318,21 +345,21 @@ chained_map<T>::lookup(std::size_t x) const
}
template <typename T>
typename chained_map<T>::chained_map_item
chained_map<T>::first_item() const
template <typename T, typename Allocator>
typename chained_map<T, Allocator>::chained_map_item
chained_map<T, Allocator>::first_item() const
{ return next_item(table); }
template <typename T>
typename chained_map<T>::chained_map_item
chained_map<T>::next_item(chained_map_item it) const
template <typename T, typename Allocator>
typename chained_map<T, Allocator>::chained_map_item
chained_map<T, Allocator>::next_item(chained_map_item it) const
{ if (it == 0) return 0;
do it++; while (it < table + table_size && it->k == NULLKEY);
return (it < free ? it : 0);
}
template <typename T>
void chained_map<T>::statistics() const
template <typename T, typename Allocator>
void chained_map<T, Allocator>::statistics() const
{ std::cout << "table_size: " << table_size <<"\n";
std::size_t n = 0;
for (chained_map_item p = table + 1; p < table + table_size; p++)

View File

@ -27,6 +27,7 @@
#define CGAL_UNIQUE_HASH_MAP_H
#include <CGAL/basic.h>
#include <CGAL/memory.h>
#include <CGAL/Handle_hash_function.h>
#include <CGAL/Tools/chained_map.h>
#include <cstddef>
@ -34,22 +35,24 @@
namespace CGAL {
template <class Key_, class Data_,
class UniqueHashFunction = Handle_hash_function>
class UniqueHashFunction = Handle_hash_function,
class Allocator_ = CGAL_ALLOCATOR(Data_) >
class Unique_hash_map {
public:
typedef Key_ Key;
typedef Data_ Data;
typedef UniqueHashFunction Hash_function;
typedef Allocator_ Allocator;
// STL compliance
typedef Key_ key_type;
typedef Data_ data_type;
typedef UniqueHashFunction hasher;
typedef Unique_hash_map<Key,Data,Hash_function> Self;
typedef Unique_hash_map<Key,Data,Hash_function,Allocator> Self;
private:
typedef internal::chained_map<Data> Map;
typedef internal::chained_map<Data, Allocator> Map;
typedef typename Map::item Item;
private:

View File

@ -164,14 +164,20 @@ and <code>src/</code> directories).
<li>The meshing functionality in the Qt demos
in <code>demo/Polyhedron/</code> and <code>demo/Mesh_3/</code> can now
use the handling of 1d-features, that exists in CGAL since version 3.8.
<li> Added a parallel version of the 3D mesh refinement and mesh optimization methods.
</li>
</ul>
<h3>STL_extension</h3>
<ul>
<li> Added Compact_container::operator[], allowing a direct access to the ith element of a compact container.
</li>
<li> Added Compact_container::operator[], allowing a direct access to the ith element of a compact container.</li>
<li> Added Concurrent_compact_container, a compact container which allows concurrent insertion and removal.</li>
</ul>
<h3>Triangulation_3</h3>
<ul>
<li> Added a parallel version of the Delaunay triangulation and the Regular triangulation algorithms,
which allows parallel insertion and removal of point ranges.</li>
</ul>
<h3>Triangulated Surface Mesh Simplification</h3>
<ul>
<li>Add some optimization in the code making the implementation faster

View File

@ -78,7 +78,7 @@ template <
/**< Previous level type, defaults to
\c Null_mesher_level. */
class Triangulation_traits /** Traits class that defines types for the
triangulation. */
triangulation. */
>
class Mesher_level
{
@ -121,7 +121,7 @@ public:
Derived,
Element,
Previous_level,
Triangulation_traits> Self;
Triangulation_traits> Self;
/** \name CONSTRUCTORS */
Mesher_level(Previous_level& previous)
@ -193,7 +193,7 @@ public:
/** Actions before testing conflicts for point \c p and element \c e */
template <typename Mesh_visitor>
void before_conflicts(const Element& e, const Point& p,
Mesh_visitor visitor)
Mesh_visitor visitor)
{
visitor.before_conflicts(e, p);
derived().before_conflicts_impl(e, p);
@ -207,7 +207,7 @@ public:
the tested element should be reconsidered latter.
*/
Mesher_level_conflict_status private_test_point_conflict(const Point& p,
Zone& zone)
Zone& zone)
{
return derived().private_test_point_conflict_impl(p, zone);
}
@ -222,7 +222,7 @@ public:
*/
Mesher_level_conflict_status
test_point_conflict_from_superior(const Point& p,
Zone& zone)
Zone& zone)
{
return derived().test_point_conflict_from_superior_impl(p, zone);
}
@ -254,7 +254,7 @@ public:
* if no point is inserted. */
template <class Mesh_visitor>
void after_no_insertion(const Element& e, const Point& p, Zone& zone,
Mesh_visitor visitor)
Mesh_visitor visitor)
{
derived().after_no_insertion_impl(e, p, zone);
visitor.after_no_insertion(e, p, zone);

View File

@ -80,7 +80,7 @@ int main(int argc, char** argv)
("show_patches", "Show surface patches in medit output");
po::options_description cmdline_options("Usage",1);
po::options_description cmdline_options("Usage");
cmdline_options.add(generic).add(mesh).add(desc);
po::variables_map vm;
@ -150,7 +150,7 @@ int main(int argc, char** argv)
// Output
std::ofstream medit_file_before("out_before.mesh");
c3t3.output_to_medit(medit_file_before,
!vm.count("no_label_rebind"), vm.count("show_patches"));
vm.count("no_label_rebind") == 0, vm.count("show_patches") > 0);
// Odt
if ( vm.count("odt") )
@ -198,7 +198,7 @@ int main(int argc, char** argv)
// Output
std::ofstream medit_file("out.mesh");
c3t3.output_to_medit(medit_file,!vm.count("no_label_rebind"), vm.count("show_patches"));
c3t3.output_to_medit(medit_file, vm.count("no_label_rebind") == 0, vm.count("show_patches") > 0);
return 0;
}

View File

@ -1,3 +1,4 @@
#define BOOST_FILESYSTEM_VERSION 2
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
@ -14,7 +15,7 @@
#include <sstream>
#include <stdlib.h>
#include <algorithm>
#include <tr1/memory>
#include <boost/tr1/memory.hpp>
#include "thread_queue.h"
@ -408,32 +409,32 @@ void save_histogram(const std::string& filename,
const Point_3& p3 = cit->vertex(3)->point();
double a = CGAL::to_double(CGAL::abs(CGAL::Mesh_3::dihedral_angle(p0,p1,p2,p3)));
histo[std::floor(a)] += 1;
histo[static_cast<int>(std::floor(a))] += 1;
min_value = (std::min)(min_value, a);
max_value = (std::max)(max_value, a);
a = CGAL::to_double(CGAL::abs(CGAL::Mesh_3::dihedral_angle(p0, p2, p1, p3)));
histo[std::floor(a)] += 1;
histo[static_cast<int>(std::floor(a))] += 1;
min_value = (std::min)(min_value, a);
max_value = (std::max)(max_value, a);
a = CGAL::to_double(CGAL::abs(CGAL::Mesh_3::dihedral_angle(p0, p3, p1, p2)));
histo[std::floor(a)] += 1;
histo[static_cast<int>(std::floor(a))] += 1;
min_value = (std::min)(min_value, a);
max_value = (std::max)(max_value, a);
a = CGAL::to_double(CGAL::abs(CGAL::Mesh_3::dihedral_angle(p1, p2, p0, p3)));
histo[std::floor(a)] += 1;
histo[static_cast<int>(std::floor(a))] += 1;
min_value = (std::min)(min_value, a);
max_value = (std::max)(max_value, a);
a = CGAL::to_double(CGAL::abs(CGAL::Mesh_3::dihedral_angle(p1, p3, p0, p2)));
histo[std::floor(a)] += 1;
histo[static_cast<int>(std::floor(a))] += 1;
min_value = (std::min)(min_value, a);
max_value = (std::max)(max_value, a);
a = CGAL::to_double(CGAL::abs(CGAL::Mesh_3::dihedral_angle(p2, p3, p0, p1)));
histo[std::floor(a)] += 1;
histo[static_cast<int>(std::floor(a))] += 1;
min_value = (std::min)(min_value, a);
max_value = (std::max)(max_value, a);

View File

@ -1,4 +1,4 @@
#include <mesher_tester.h>
#include "mesher_tester.h"
#include <CGAL/Labeled_image_mesh_domain_3.h>
#include <CGAL/Image_3.h>

View File

@ -1,4 +1,4 @@
#include <mesher_tester.h>
#include "mesher_tester.h"
#include <CGAL/Mesh_3/Robust_intersection_traits_3.h>
#include <CGAL/Polyhedral_mesh_domain_3.h>
#include <CGAL/IO/Polyhedron_iostream.h>

View File

@ -121,7 +121,7 @@ std::string format(std::string input, bool remove_template)
std::size_t pos = input.find('\074');
while ( remove_template && pos != std::string::npos )
{
unsigned int init = pos;
size_t init = pos;
int nb_open=1;
int nb_close=0;
@ -144,7 +144,7 @@ std::string format(std::string input, bool remove_template)
input.push_back('\n');
// Add " ! " at the begining of each line
unsigned int prev = 0;
size_t prev = 0;
pos = input.find("\n");
while ( pos != std::string::npos )
{

View File

@ -0,0 +1,110 @@
# Created by the script cgal_create_cmake_script
# This is the CMake script for compiling a CGAL application.
project( Mesh_3_benchmark )
cmake_minimum_required(VERSION 2.6.2)
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER 2.6)
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER 2.8.3)
cmake_policy(VERSION 2.8.4)
else()
cmake_policy(VERSION 2.6)
endif()
endif()
# Creates a new CMake option, turned ON by default
option(ACTIVATE_MSVC_PRECOMPILED_HEADERS
"Activate precompiled headers in MSVC"
ON)
# 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(../../include)
include_directories(../../../Triangulation_3/include)
include_directories(../../../STL_Extension/include)
include_directories(../../../AABB_tree/include)
add_definitions(-DCGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX
-DCGAL_MESH_3_NO_DEPRECATED_C3T3_ITERATORS)
if ( MESH_3_VERBOSE )
add_definitions(-DCGAL_MESH_3_VERBOSE)
endif()
find_package(CGAL COMPONENTS ImageIO)
if ( CGAL_FOUND )
include( ${CGAL_USE_FILE} )
# Activate concurrency ? (turned OFF by default)
option(ACTIVATE_CONCURRENT_MESH_3
"Activate parallelism in Mesh_3"
OFF)
# And add -DCGAL_CONCURRENT_MESH_3 if that option is ON
if( ACTIVATE_CONCURRENT_MESH_3 )
add_definitions( -DCGAL_CONCURRENT_MESH_3 )
find_package( TBB REQUIRED )
else()
option( LINK_WITH_TBB
"Link with TBB anyway so we can use TBB timers for profiling"
ON)
if( LINK_WITH_TBB )
find_package( TBB )
endif( LINK_WITH_TBB )
endif()
if( TBB_FOUND )
include(${TBB_USE_FILE})
list(APPEND CGAL_3RD_PARTY_LIBRARIES ${TBB_LIBRARIES})
endif()
# Link with Boost.ProgramOptions (optional)
find_package(Boost QUIET COMPONENTS program_options)
if(Boost_PROGRAM_OPTIONS_FOUND)
if( CGAL_AUTO_LINK_ENABLED )
message( STATUS "Boost.ProgramOptions library: found" )
else()
message( STATUS "Boost.ProgramOptions library: ${Boost_PROGRAM_OPTIONS_LIBRARY}" )
endif()
add_definitions( "-DCGAL_USE_BOOST_PROGRAM_OPTIONS" )
list(APPEND CGAL_3RD_PARTY_LIBRARIES ${Boost_LIBRARIES})
endif()
if ( Boost_FOUND AND Boost_VERSION GREATER 103400 )
include( CGAL_CreateSingleSourceCGALProgram )
# Compilable benchmark
set (BENCHMARK_SOURCE_FILES "concurrency.cpp")
ADD_MSVC_PRECOMPILED_HEADER("StdAfx.h" "StdAfx.cpp" BENCHMARK_SOURCE_FILES)
create_single_source_cgal_program( ${BENCHMARK_SOURCE_FILES} )
else()
message(STATUS "NOTICE: This program requires Boost >= 1.34.1, and will not be compiled.")
endif()
else()
message(STATUS "This program requires the CGAL library, and will not be compiled.")
endif()

View File

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

View File

@ -0,0 +1,288 @@
#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>
// 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.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 <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/eval_if.hpp>
#include <boost/mpl/has_key.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/if.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 <boost/optional.hpp>
//#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 <boost/shared_ptr.hpp>
#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_const.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/variant.hpp>
#include <boost/version.hpp>
// CGAL
//#include <CGAL/AABB_traits.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/gl.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/internal/Dummy_tds_3.h>
#include <CGAL/internal/Exact_type_selector.h>
#include <CGAL/internal/info_check.h>
//#include <CGAL/internal/Regular_triangulation_filtered_traits_3.h>
#include <CGAL/internal/Static_filters/Compare_weighted_squared_radius_3.h>
#include <CGAL/internal/Static_filters/Power_test_3.h>
//#include <CGAL/internal/Static_filters/Regular_triangulation_static_filters_traits_3.h>
#include <CGAL/internal/Static_filters/Static_filter_error.h>
#include <CGAL/internal/Static_filters/tools.h>
//#include <CGAL/internal/Triangulation_ds_circulators_3.h>
//#include <CGAL/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_image_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/Creator_weighted_point_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/Robust_weighted_circumcenter_filtered_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/Regular_triangulation_euclidean_traits_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_assertions.h>
//#include <CGAL/Triangulation_cell_base_3.h>
//#include <CGAL/Triangulation_cell_base_with_circumcenter_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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,6 @@
#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

@ -0,0 +1,266 @@
#########################################################
##### 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

@ -0,0 +1,27 @@
#==========================================
#======== Worksharing strategy ===========
#==========================================
locking_grid_num_cells_per_axis = 50
first_grid_lock_radius = 0
#==========================================
#============= Brute-force ================
#==========================================
#locking_grid_num_cells_per_axis = 30
#first_grid_lock_radius = 2
#==========================================
#=============== Other ====================
#==========================================
refinement_grainsize = 10 # for parallel_for techniques
refinement_batch_size = 10000 # for parallel_for technique
work_stats_grid_num_cells_per_axis = 5 # for "task" technique
num_work_items_per_batch = 50 # for "task" technique
min_num_vertices_of_coarse_mesh = 100
num_vertices_of_coarse_mesh_per_core = 3.5
num_pseudo_infinite_vertices_per_core = 5.0

View File

@ -1,3 +1,5 @@
#include "config.h"
#include <boost/config.hpp>
#if defined(BOOST_MSVC)
# pragma warning( disable : 4503)
@ -102,10 +104,14 @@ private:
void write_facets(const C3t3& c3t3, std::ofstream& out);
void write_facets(const C3t3& c3t3, const Plane& plane, std::ofstream& out);
void write_cells(const C3t3& c3t3, const Plane& plane, std::ofstream& out);
void write_surface_cells(const C3t3& c3t3, const Plane& plane, std::ofstream& out);
void write_cells_intersecting_a_plane(const C3t3& c3t3, const Plane& plane, std::ofstream& out);
void write_cells_on_the_positive_side_of_a_plane(const C3t3& c3t3, const Plane& plane, std::ofstream& out);
void write_triangle(const Point_3& p, const Point_3& q, const Point_3& r,
const QColor& color, const QColor& edge_color, std::ofstream& out);
void write_tetrahedron (const Point_3& p, const Point_3& q, const Point_3& r, const Point_3& s,
const QColor& color, const QColor& edge_color, std::ofstream& out);
void write_point(const Point_3& p, std::ofstream& out);
void write_point_sphere(const Point_3& p, std::ofstream& out);
@ -211,8 +217,9 @@ C3t3_rib_exporter_plugin::create_rib()
}
// Init data
if ( c3t3_item != prev_c3t3_ )
{
//if ( c3t3_item != prev_c3t3_ ) // Commented because it was causing problems
// when changing the color of the c3t3
{
init_maps(c3t3_item->c3t3(), c3t3_item->color());
init_point_radius(c3t3_item->c3t3());
init_parameters();
@ -383,12 +390,14 @@ save(const Scene_c3t3_item& c3t3_item, const QFileInfo& fileInfo)
write_facets(c3t3_item.c3t3(), c3t3_item.plane(), rib_file);
rib_file << "Surface \"plastic\" \"Ka\" 0.65 \"Kd\" 0.65 \"Ks\" 0.35 \"roughness\" 0.2" << std::endl;
write_cells(c3t3_item.c3t3(), c3t3_item.plane(), rib_file);
//write_cells_intersecting_a_plane(c3t3_item.c3t3(), c3t3_item.plane(), rib_file);
write_cells_on_the_positive_side_of_a_plane(c3t3_item.c3t3(), c3t3_item.plane(), rib_file);
break;
case MESH:
rib_file << "Surface \"plastic\" \"Ka\" 0.65 \"Kd\" 0.85 \"Ks\" 0.25 \"roughness\" 0.1" << std::endl;
write_facets(c3t3_item.c3t3(), rib_file);
//write_facets(c3t3_item.c3t3(), rib_file);
write_surface_cells(c3t3_item.c3t3(), c3t3_item.plane(), rib_file);
break;
case TRIANGULATION:
@ -436,7 +445,7 @@ C3t3_rib_exporter_plugin::init_maps(const C3t3& c3t3, const QColor& color)
}
// Fill value of maps
int nb_colors = static_cast<int>(subdomain_map_.size()); // + surface_map_.size();
size_t nb_colors = subdomain_map_.size(); // + surface_map_.size();
// Starting hue
double c = color.hueF();
@ -701,10 +710,137 @@ write_facets(const C3t3& c3t3, const Plane& plane, std::ofstream& out)
}
}
void
C3t3_rib_exporter_plugin::
write_surface_cells(const C3t3& c3t3, const Plane& plane, std::ofstream& out)
{
typedef Kernel::Oriented_side Side;
for ( C3t3::Cells_in_complex_iterator it_cell = c3t3.cells_in_complex_begin(),
end = c3t3.cells_in_complex_end() ; it_cell != end ; ++it_cell )
{
C3t3::Cell_handle c = it_cell;
// Compute the number of surface vertices in c
// Keep one of them in memory
int num_2D_vertices = 0;
int last_2D_vertex_index = -1;
for (int i = 0 ; i < 4 ; ++i)
{
if (c3t3.in_dimension(c->vertex(i)) == 2)
{
++num_2D_vertices;
last_2D_vertex_index = i;
}
}
//const int TRANSPARENCY_ALPHA_VALUE = 100;
CGAL::Bbox_3 bbox = c3t3.bbox();
float relPos = (c->weighted_circumcenter().x() - bbox.xmin())
/ (bbox.xmax() - bbox.xmin());
float TRANSPARENCY_ALPHA_VALUE =
1.f -
(relPos < 0.25f ?
0.0f :
(relPos > 0.75f ?
1.0f :
(relPos - 0.25f)*1.0f/0.5f
)
);
/*
// ONLY SURFACE FACETS ARE TRANSPARENT
if (num_2D_vertices >= 3)
{
QColor basecolor = subdomain_map_[c3t3.subdomain_index(c)];
QColor facecolor = basecolor.darker(150);
QColor edgecolor = facecolor.darker(150);
for (int i = 0 ; i < 4 ; ++i)
{
if (c3t3.in_dimension(c->vertex((i+1)%4)) == 2
&& c3t3.in_dimension(c->vertex((i+2)%4)) == 2
&& c3t3.in_dimension(c->vertex((i+3)%4)) == 2)
{
edgecolor.setAlpha(TRANSPARENCY_ALPHA_VALUE);
}
else
{
edgecolor.setAlpha(255);
}
write_triangle(c->vertex((i+1)%4)->point(),
c->vertex((i+2)%4)->point(),
c->vertex((i+3)%4)->point(),
facecolor, edgecolor, out );
}
}*/
// SURFACE CELLS ARE TRANSPARENT
if (num_2D_vertices >= 2)
{
QColor basecolor = subdomain_map_[c3t3.subdomain_index(c)];
QColor facecolor = basecolor.darker(150);
QColor edgecolor = facecolor.darker(150);
/*
// Transparency on the negative side of the plane
const Side s0 = plane.oriented_side(c->vertex(0)->point());
const Side s1 = plane.oriented_side(c->vertex(1)->point());
const Side s2 = plane.oriented_side(c->vertex(2)->point());
const Side s3 = plane.oriented_side(c->vertex(3)->point());
if( s0 == CGAL::ON_NEGATIVE_SIDE && s1 == CGAL::ON_NEGATIVE_SIDE
&& s2 == CGAL::ON_NEGATIVE_SIDE && s3 == CGAL::ON_NEGATIVE_SIDE )
{
edgecolor.setAlpha(TRANSPARENCY_ALPHA_VALUE);
}
else
{
edgecolor.setAlpha(255);
}*/
edgecolor.setAlphaF(TRANSPARENCY_ALPHA_VALUE);
for (int i = 0 ; i < 4 ; ++i)
{
write_triangle(c->vertex((i+1)%4)->point(),
c->vertex((i+2)%4)->point(),
c->vertex((i+3)%4)->point(),
facecolor, edgecolor, out );
}
}
else if (num_2D_vertices == 1)
{
QColor basecolor = subdomain_map_[c3t3.subdomain_index(c)];
QColor facecolor = basecolor.darker(150);
QColor edgecolor = facecolor.darker(150);
for (int i = 0 ; i < 4 ; ++i)
{
if (i == last_2D_vertex_index)
{
edgecolor.setAlpha(TRANSPARENCY_ALPHA_VALUE);
}
else
{
edgecolor.setAlphaF(TRANSPARENCY_ALPHA_VALUE);
}
write_triangle(c->vertex((i+1)%4)->point(),
c->vertex((i+2)%4)->point(),
c->vertex((i+3)%4)->point(),
facecolor, edgecolor, out );
}
}
}
}
void
C3t3_rib_exporter_plugin::
write_cells(const C3t3& c3t3, const Plane& plane, std::ofstream& out)
write_cells_intersecting_a_plane(const C3t3& c3t3, const Plane& plane, std::ofstream& out)
{
typedef Kernel::Oriented_side Side;
@ -728,6 +864,58 @@ write_cells(const C3t3& c3t3, const Plane& plane, std::ofstream& out)
QColor basecolor = subdomain_map_[c3t3.subdomain_index(it)];
QColor facecolor = basecolor.darker(150);
QColor edgecolor = facecolor.darker(150);
edgecolor.setAlpha(20);
// Don't write facet twice
if ( s1 != CGAL::ON_NEGATIVE_SIDE || s2 != CGAL::ON_NEGATIVE_SIDE || s3 != CGAL::ON_NEGATIVE_SIDE )
write_triangle(p1, p2, p3, facecolor, edgecolor, out );
if ( s1 != CGAL::ON_NEGATIVE_SIDE || s2 != CGAL::ON_NEGATIVE_SIDE || s4 != CGAL::ON_NEGATIVE_SIDE )
write_triangle(p1, p2, p4, facecolor, edgecolor, out );
if ( s1 != CGAL::ON_NEGATIVE_SIDE || s3 != CGAL::ON_NEGATIVE_SIDE || s4 != CGAL::ON_NEGATIVE_SIDE )
write_triangle(p1, p3, p4, facecolor, edgecolor, out );
if ( s2 != CGAL::ON_NEGATIVE_SIDE || s3 != CGAL::ON_NEGATIVE_SIDE || s4 != CGAL::ON_NEGATIVE_SIDE )
write_triangle(p2, p3, p4, facecolor, edgecolor, out );
}
}
}
void
C3t3_rib_exporter_plugin::
write_cells_on_the_positive_side_of_a_plane(const C3t3& c3t3, const Plane& plane, std::ofstream& out)
{
typedef Kernel::Oriented_side Side;
for ( C3t3::Cells_in_complex_iterator it = c3t3.cells_in_complex_begin(),
end = c3t3.cells_in_complex_end() ; it != end ; ++it )
{
const Point_3& p1 = it->vertex(0)->point();
const Point_3& p2 = it->vertex(1)->point();
const Point_3& p3 = it->vertex(2)->point();
const Point_3& p4 = it->vertex(3)->point();
const Side s1 = plane.oriented_side(p1);
const Side s2 = plane.oriented_side(p2);
const Side s3 = plane.oriented_side(p3);
const Side s4 = plane.oriented_side(p4);
if( ( s1 == CGAL::ON_POSITIVE_SIDE || s2 == CGAL::ON_POSITIVE_SIDE
|| s3 == CGAL::ON_POSITIVE_SIDE || s4 == CGAL::ON_POSITIVE_SIDE )
/*&&
( c3t3.surface_patch_index(it, 0) != C3t3::Surface_patch_index()
|| c3t3.surface_patch_index(it, 1) != C3t3::Surface_patch_index()
|| c3t3.surface_patch_index(it, 2) != C3t3::Surface_patch_index()
|| c3t3.surface_patch_index(it, 3) != C3t3::Surface_patch_index() )*/
)
{
QColor basecolor = subdomain_map_[c3t3.subdomain_index(it)];
QColor facecolor = basecolor.darker(150);
QColor edgecolor = facecolor.darker(150);
edgecolor.setAlpha(10);
// Don't write facet twice
if ( s1 != CGAL::ON_NEGATIVE_SIDE || s2 != CGAL::ON_NEGATIVE_SIDE || s3 != CGAL::ON_NEGATIVE_SIDE )
@ -772,6 +960,36 @@ write_triangle (const Point_3& p, const Point_3& q, const Point_3& r,
add_vertex(r,edge_color);
}
void
C3t3_rib_exporter_plugin::
write_tetrahedron (const Point_3& p, const Point_3& q, const Point_3& r, const Point_3& s,
const QColor& color, const QColor& edge_color, std::ofstream& out)
{
// Color
write_color(color, true, out);
// Triangle
out << "Polygon \"P\" [";
write_point(p,out);
write_point(q,out);
write_point(r,out);
write_point(s,out);
out << "]" << std::endl;
// Edges (will be drawn later on)
add_edge(p,q,edge_color);
add_edge(p,r,edge_color);
add_edge(q,r,edge_color);
add_edge(s,p,edge_color);
add_edge(s,q,edge_color);
add_edge(s,r,edge_color);
// Vertices (will be drawn later on)
add_vertex(p,edge_color);
add_vertex(q,edge_color);
add_vertex(r,edge_color);
add_vertex(s,edge_color);
}
void
C3t3_rib_exporter_plugin::
@ -852,7 +1070,7 @@ write_edges_flat(std::ofstream& out)
it != end ; ++it )
{
// Color
write_color(it->second, false, out);
write_color(it->second, true, out);
// Edge
out << "Curves \"linear\" [2] \"nonperiodic\" \"P\" [";
@ -874,7 +1092,7 @@ write_edges_volumic(std::ofstream& out)
it != end ; ++it )
{
// Color
write_color(it->second, false, out);
write_color(it->second, true, out);
// Edge
write_edge_cylinder(it->first.first, it->first.second, out);
}

View File

@ -12,6 +12,7 @@
#include <CGAL/Polyhedral_mesh_domain_3.h>
#include <CGAL/Polyhedral_mesh_domain_with_features_3.h>
#include <CGAL/Labeled_image_mesh_domain_3.h>
#include <CGAL/tags.h>
template <typename K>
struct Wrapper
@ -42,12 +43,18 @@ typedef CGAL::Polyhedral_mesh_domain_with_features_3<Kernel,
typedef CGAL::Labeled_image_mesh_domain_3<Image,Kernel> Image_mesh_domain;
typedef Wrapper<Kernel> Function_wrapper;
typedef CGAL::Labeled_mesh_domain_3<Function_wrapper, Kernel> Function_mesh_domain;
typedef CGAL::Labeled_mesh_domain_3<Function_wrapper, Kernel> Function_mesh_domain;
// Triangulation
typedef CGAL::Mesh_triangulation_3<Polyhedral_mesh_domain>::type Tr;
// 3D complex
#ifdef CGAL_CONCURRENT_MESH_3
typedef CGAL::Mesh_triangulation_3<Polyhedral_mesh_domain,
CGAL::Kernel_traits<Polyhedral_mesh_domain>::Kernel,
CGAL::Parallel_tag>::type Tr;
#else
typedef CGAL::Mesh_triangulation_3<Polyhedral_mesh_domain>::type Tr;
#endif
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
// 3D complex
#endif // CGAL_DEMO_MESH_3_C3T3_TYPE_H

View File

@ -9,6 +9,34 @@ else()
cmake_policy(VERSION 2.6)
endif()
# Creates a new CMake option, turned ON by default
option(ACTIVATE_MSVC_PRECOMPILED_HEADERS
"Activate precompiled headers in MSVC"
ON)
# 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()
# Let plugins be compiled in the same directory as the executable.
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
@ -22,9 +50,37 @@ include_directories( BEFORE ./ ./include ../../include )
add_definitions(-DCGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX
-DCGAL_MESH_3_NO_DEPRECATED_C3T3_ITERATORS)
# Add specific Find.cmake modules
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules )
set(CMAKE_MODULE_PATH
${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules
${CMAKE_CURRENT_SOURCE_DIR}/../../../Installation/cmake/modules/)
# Activate concurrency ? (turned OFF by default)
option(ACTIVATE_CONCURRENT_MESH_3
"Activate parallelism in Mesh_3"
OFF)
# And add -DCGAL_CONCURRENT_MESH_3 if that option is ON
if( ACTIVATE_CONCURRENT_MESH_3 )
add_definitions( -DCGAL_CONCURRENT_MESH_3 )
find_package( TBB REQUIRED )
else( ACTIVATE_CONCURRENT_MESH_3 )
option( LINK_WITH_TBB
"Link with TBB anyway so we can use TBB timers for profiling"
ON)
if( LINK_WITH_TBB )
find_package( TBB )
endif( LINK_WITH_TBB )
endif()
if( TBB_FOUND )
include(${TBB_USE_FILE})
endif()
# Creates a new CMake option, turned ON by default
option(ACTIVATE_MSVC_PRECOMPILED_HEADERS
"Activate precompiled headers in MSVC"
ON)
# Find CGAL and CGAL Qt4
find_package(CGAL COMPONENTS Qt4 ImageIO)
@ -133,7 +189,7 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND AND Boost_F
set(SCENE_SEGMENTED_IMAGE_ITEM_LIB "${MESH_3_LIB_PREFIX}scene_segmented_image_item")
add_library(${SCENE_SEGMENTED_IMAGE_ITEM_LIB} SHARED
Scene_segmented_image_item.cpp Scene_segmented_image_item.moc)
target_link_libraries(${SCENE_SEGMENTED_IMAGE_ITEM_LIB} ${SCENE_ITEM_LIB} ${CGAL_LIBRARIES})
target_link_libraries(${SCENE_SEGMENTED_IMAGE_ITEM_LIB} ${SCENE_ITEM_LIB} ${CGAL_LIBRARIES} ${TBB_LIBRARIES})
set_target_properties(${SCENE_SEGMENTED_IMAGE_ITEM_LIB} PROPERTIES DEFINE_SYMBOL scene_segmented_image_item_EXPORTS)
if(GLEW_FOUND)
@ -143,43 +199,49 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND AND Boost_F
set(SCENE_POLYHEDRON_ITEM_LIB "${MESH_3_LIB_PREFIX}scene_polyhedron_item")
add_library(${SCENE_POLYHEDRON_ITEM_LIB} SHARED
Scene_polyhedron_item.cpp Scene_polyhedron_item.moc)
target_link_libraries(${SCENE_POLYHEDRON_ITEM_LIB} ${SCENE_ITEM_LIB} ${CGAL_LIBRARIES})
target_link_libraries(${SCENE_POLYHEDRON_ITEM_LIB} ${SCENE_ITEM_LIB} ${CGAL_LIBRARIES} ${TBB_LIBRARIES})
set_target_properties(${SCENE_POLYHEDRON_ITEM_LIB} PROPERTIES DEFINE_SYMBOL scene_polyhedron_item_EXPORTS)
set(POLYGON_SOUP_LIB "${MESH_3_LIB_PREFIX}polygon_soup")
add_library(${POLYGON_SOUP_LIB} SHARED
Scene_polygon_soup.cpp Scene_polygon_soup.moc)
target_link_libraries(${POLYGON_SOUP_LIB} ${SCENE_ITEM_LIB} ${CGAL_LIBRARIES})
target_link_libraries(${POLYGON_SOUP_LIB} ${SCENE_ITEM_LIB} ${CGAL_LIBRARIES} ${TBB_LIBRARIES})
set_target_properties(${POLYGON_SOUP_LIB} PROPERTIES DEFINE_SYMBOL polygon_soup_EXPORTS)
set(SCENE_C3T3_ITEM_LIB "${MESH_3_LIB_PREFIX}scene_c3t3_item")
set (SCENE_C3T3_ITEM_LIB_SOURCE_FILES Scene_c3t3_item.cpp)
ADD_MSVC_PRECOMPILED_HEADER("StdAfx.h" "StdAfx.cpp" SCENE_C3T3_ITEM_LIB_SOURCE_FILES)
LIST(APPEND SCENE_C3T3_ITEM_LIB_SOURCE_FILES Scene_c3t3_item.moc)
add_library(${SCENE_C3T3_ITEM_LIB} SHARED
Scene_c3t3_item.cpp Scene_c3t3_item.moc)
target_link_libraries(${SCENE_C3T3_ITEM_LIB} ${SCENE_ITEM_LIB} ${QGLVIEWER_LIBRARIES} ${QT_LIBRARIES} ${CGAL_LIBRARIES} ${Boost_LIBRARIES})
${SCENE_C3T3_ITEM_LIB_SOURCE_FILES})
target_link_libraries(${SCENE_C3T3_ITEM_LIB} ${SCENE_ITEM_LIB} ${QGLVIEWER_LIBRARIES} ${QT_LIBRARIES} ${CGAL_LIBRARIES} ${Boost_LIBRARIES} ${TBB_LIBRARIES})
set_target_properties(${SCENE_C3T3_ITEM_LIB} PROPERTIES DEFINE_SYMBOL scene_c3t3_item_EXPORTS)
set(SCENE_IMPLICIT_FUNCTION_ITEM_LIB "${MESH_3_LIB_PREFIX}scene_implicit_function_item")
add_library(${SCENE_IMPLICIT_FUNCTION_ITEM_LIB} SHARED
Scene_implicit_function_item.cpp Scene_implicit_function_item.moc Color_ramp.cpp)
target_link_libraries(${SCENE_IMPLICIT_FUNCTION_ITEM_LIB} ${SCENE_ITEM_LIB} ${QGLVIEWER_LIBRARIES} ${QT_LIBRARIES})
target_link_libraries(${SCENE_IMPLICIT_FUNCTION_ITEM_LIB} ${SCENE_ITEM_LIB} ${QGLVIEWER_LIBRARIES} ${QT_LIBRARIES} ${TBB_LIBRARIES})
set_target_properties(${SCENE_IMPLICIT_FUNCTION_ITEM_LIB} PROPERTIES DEFINE_SYMBOL scene_implicit_function_item_EXPORTS)
add_definitions(-DUSE_FORWARD_DECL)
add_definitions(-DQT_STATICPLUGIN)
add_executable ( Mesh_3 MainWindow.cpp
set (MESH_3_SOURCE_FILES
MainWindow.cpp
Mesh_3.cpp
${DEMO_SRC_DIR}/Scene.cpp
MainWindow_moc.cpp
Scene_moc.cpp
${UI_FILES} ${RESOURCE_FILES} )
Scene_moc.cpp)
#ADD_MSVC_PRECOMPILED_HEADER("StdAfx.h" "StdAfx.cpp" MESH_3_SOURCE_FILES)
LIST(APPEND MESH_3_SOURCE_FILES ${UI_FILES} ${RESOURCE_FILES})
add_executable( Mesh_3 ${MESH_3_SOURCE_FILES} )
add_to_cached_list( CGAL_EXECUTABLE_TARGETS Mesh_3 )
# Link with Qt libraries
target_link_libraries( Mesh_3 ${QT_LIBRARIES} )
# Link with CGAL
target_link_libraries( Mesh_3 ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} )
target_link_libraries( Mesh_3 ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ${TBB_LIBRARIES})
# Link with libQGLViewer, OpenGL
target_link_libraries( Mesh_3 ${QGLVIEWER_LIBRARIES} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} )
@ -217,7 +279,7 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND AND Boost_F
# Link with scene_item
target_link_libraries( ${plugin_name} ${SCENE_ITEM_LIB})
# Link with CGAL
target_link_libraries( ${plugin_name} ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} )
target_link_libraries( ${plugin_name} ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ${TBB_LIBRARIES})
endmacro(polyhedron_demo_plugin)
set(IO_IMAGE_PLUGIN_LIB "${MESH_3_LIB_PREFIX}io_image_plugin")
@ -235,7 +297,7 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND AND Boost_F
if(GLEW_FOUND)
set(VOLUME_PLANES_PLUGIN_LIB "${MESH_3_LIB_PREFIX}volume_planes_plugin")
polyhedron_demo_plugin(${VOLUME_PLANES_PLUGIN_LIB} Volume_planes_plugin
${VOLUME_MOC_OUTFILES}
${VOLUME_MOC_OUTFILES}
Volume_plane_intersection.cpp)
target_link_libraries(${VOLUME_PLANES_PLUGIN_LIB} ${SCENE_SEGMENTED_IMAGE_ITEM_LIB} ${VIEWER_LIB})
else()
@ -257,13 +319,25 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND AND Boost_F
target_link_libraries(${IO_IMPLICIT_FUNCTION_PLUGIN_LIB} ${SCENE_IMPLICIT_FUNCTION_ITEM_LIB})
set(MESH_3_PLUGIN_LIB "${MESH_3_LIB_PREFIX}mesh_3_plugin")
polyhedron_demo_plugin(${MESH_3_PLUGIN_LIB} Mesh_3_plugin
Mesh_3_plugin_polyhedron_cgal_code.cpp
Mesh_3_plugin_image_cgal_code.cpp
Mesh_3_plugin_implicit_function_cgal_code.cpp
Meshing_thread.cpp
Scene_c3t3_item.moc
${meshingUI_FILES})
set(MESH_3_PLUGIN_SOURCE_FILES
Mesh_3_plugin.cpp
Mesh_3_plugin_polyhedron_cgal_code.cpp
Mesh_3_plugin_image_cgal_code.cpp
Mesh_3_plugin_implicit_function_cgal_code.cpp
Meshing_thread.cpp)
ADD_MSVC_PRECOMPILED_HEADER("StdAfx.h" "StdAfx.cpp" MESH_3_PLUGIN_SOURCE_FILES)
LIST(REMOVE_AT MESH_3_PLUGIN_SOURCE_FILES 0) # Remove Mesh_3_plugin.cpp since it's added by polyhedron_demo_plugin
LIST(APPEND MESH_3_PLUGIN_SOURCE_FILES "Scene_c3t3_item.moc" ${meshingUI_FILES})
polyhedron_demo_plugin(${MESH_3_PLUGIN_LIB} Mesh_3_plugin ${MESH_3_PLUGIN_SOURCE_FILES})
# set(MESH_3_PLUGIN_LIB "${MESH_3_LIB_PREFIX}mesh_3_plugin")
# polyhedron_demo_plugin(${MESH_3_PLUGIN_LIB} Mesh_3_plugin
# Mesh_3_plugin_polyhedron_cgal_code.cpp
# Mesh_3_plugin_image_cgal_code.cpp
# Mesh_3_plugin_implicit_function_cgal_code.cpp
# Meshing_thread.cpp
# Scene_c3t3_item.moc
# ${meshingUI_FILES})
target_link_libraries(${MESH_3_PLUGIN_LIB}
${SCENE_C3T3_ITEM_LIB}
@ -272,14 +346,18 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND AND Boost_F
${SCENE_IMPLICIT_FUNCTION_ITEM_LIB}
${QGLVIEWER_LIBRARIES}
${OPENGL_gl_LIBRARY}
${OPENGL_glu_LIBRARY})
${OPENGL_glu_LIBRARY}
${TBB_LIBRARIES})
set(MESH_3_OPTIMIZATION_PLUGIN_LIB "${MESH_3_LIB_PREFIX}mesh_3_optimization_plugin")
polyhedron_demo_plugin(${MESH_3_OPTIMIZATION_PLUGIN_LIB} Mesh_3_optimization_plugin
Mesh_3_optimization_plugin_cgal_code.cpp
Optimizer_thread.cpp
Scene_c3t3_item.moc
${optimUI_FILES})
set(MESH_3_OPTIMIZATION_PLUGIN_LIB "${MESH_3_LIB_PREFIX}mesh_3_optimization_plugin")
set(MESH_3_OPTIMIZATION_PLUGIN_SOURCE_FILES
Mesh_3_optimization_plugin.cpp
Mesh_3_optimization_plugin_cgal_code.cpp
Optimizer_thread.cpp)
ADD_MSVC_PRECOMPILED_HEADER("StdAfx.h" "StdAfx.cpp" MESH_3_OPTIMIZATION_PLUGIN_SOURCE_FILES)
LIST(REMOVE_AT MESH_3_OPTIMIZATION_PLUGIN_SOURCE_FILES 0) # Remove Mesh_3_optimization_plugin.cpp since it's added by polyhedron_demo_plugin
LIST(APPEND MESH_3_OPTIMIZATION_PLUGIN_SOURCE_FILES "Scene_c3t3_item.moc" ${optimUI_FILES})
polyhedron_demo_plugin(${MESH_3_OPTIMIZATION_PLUGIN_LIB} Mesh_3_optimization_plugin ${MESH_3_OPTIMIZATION_PLUGIN_SOURCE_FILES})
target_link_libraries(${MESH_3_OPTIMIZATION_PLUGIN_LIB}
${SCENE_C3T3_ITEM_LIB}
@ -288,7 +366,8 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND AND Boost_F
${SCENE_IMPLICIT_FUNCTION_ITEM_LIB}
${QGLVIEWER_LIBRARIES}
${OPENGL_gl_LIBRARY}
${OPENGL_glu_LIBRARY})
${OPENGL_glu_LIBRARY}
${TBB_LIBRARIES})
else (CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND AND Boost_FOUND)

View File

@ -1,3 +1,5 @@
#include "config.h"
#include "Color_ramp.h"
#include <iostream>

View File

@ -1,3 +1,5 @@
#include "config.h"
#include "Scene_c3t3_item.h"
#include <CGAL_demo/Io_plugin_interface.h>
@ -17,14 +19,15 @@ public:
virtual Scene_item* load(QFileInfo) { return NULL; }
virtual bool canSave(const Scene_item*);
virtual bool save(const Scene_item*, QFileInfo fileinfo);
virtual bool save(const Scene_item*, QFileInfo, QString);
};
QStringList
Io_c3t3_plugin::nameFilters() const
{
return QStringList() << "Mesh (*.mesh)";
return QStringList() << "Mesh (*.mesh)"
<< "Maya - surface only (*.ma)" << "Maya - cells (*.ma)";
}
@ -36,7 +39,7 @@ Io_c3t3_plugin::canSave(const Scene_item* item)
}
bool
Io_c3t3_plugin::save(const Scene_item* item, QFileInfo fileInfo)
Io_c3t3_plugin::save(const Scene_item* item, QFileInfo fileInfo, QString selectedFilter)
{
const Scene_c3t3_item* c3t3_item = qobject_cast<const Scene_c3t3_item*>(item);
if ( NULL == c3t3_item )
@ -45,8 +48,17 @@ Io_c3t3_plugin::save(const Scene_item* item, QFileInfo fileInfo)
}
QString path = fileInfo.absoluteFilePath();
std::ofstream medit_file (qPrintable(path));
c3t3_item->c3t3().output_to_medit(medit_file,true,true);
if (fileInfo.suffix() == "mesh")
{
std::ofstream medit_file (qPrintable(path));
c3t3_item->c3t3().output_to_medit(medit_file,true,true);
}
else if (fileInfo.suffix() == "ma")
{
std::ofstream maya_file (qPrintable(path));
c3t3_item->c3t3().output_to_maya(
maya_file, selectedFilter == "Maya - surface only (*.ma)");
}
return true;
}

View File

@ -1,3 +1,5 @@
#include "config.h"
#ifdef SCENE_SEGMENTED_IMAGE_GL_BUFFERS_AVAILABLE
# include <GL/glew.h>
#endif
@ -27,7 +29,7 @@ public:
Scene_item* load(QFileInfo fileinfo);
bool canSave(const Scene_item*);
bool save(const Scene_item*, QFileInfo) { return false; }
bool save(const Scene_item*, QFileInfo, QString) { return false; }
};
QStringList Io_image_plugin::nameFilters() const {

View File

@ -21,6 +21,7 @@
//******************************************************************************
// File Description :
//******************************************************************************
#include "config.h"
#include <CGAL_demo/Plugin_interface.h>
#include <CGAL_demo/Plugin_helper.h>

View File

@ -1,3 +1,5 @@
#include "config.h"
#include "Scene_polyhedron_item.h"
#include "Scene_polygon_soup.h"
#include "Polyhedron_type.h"
@ -18,7 +20,7 @@ public:
Scene_item* load(QFileInfo fileinfo);
bool canSave(const Scene_item*);
bool save(const Scene_item*, QFileInfo fileinfo);
bool save(const Scene_item*, QFileInfo, QString);
};
QStringList Io_off_plugin::nameFilters() const {
@ -69,7 +71,7 @@ bool Io_off_plugin::canSave(const Scene_item* item)
qobject_cast<const Scene_polygon_soup*>(item);
}
bool Io_off_plugin::save(const Scene_item* item, QFileInfo fileinfo)
bool Io_off_plugin::save(const Scene_item* item, QFileInfo fileinfo, QString selectedFilter)
{
// This plugin supports polyhedrons and polygon soups
const Scene_polyhedron_item* poly_item =

View File

@ -146,6 +146,26 @@ MainWindow::MainWindow(QWidget* parent)
readSettings(); // Among other things, the column widths are stored.
const char *windowTitle = "CGAL 3D mesh generator demo ["
#ifdef CGAL_CONCURRENT_MESH_3
"Parallel"
#else
"Sequential"
# ifdef CGAL_LINKED_WITH_TBB
" - With TBB"
# else
" - Without TBB"
# endif
#endif
#ifdef _DEBUG
" - Debug]";
#else
"]";
#endif
setWindowTitle(QApplication::translate(
"MainWindow", windowTitle, 0, QApplication::UnicodeUTF8));
this->dumpObjectTree();
}
@ -482,11 +502,13 @@ void MainWindow::on_actionSaveAs_triggered()
return;
}
QString selectedFilter;
QString filename =
QFileDialog::getSaveFileName(this,
tr("Save to File..."),
QString(),
filters.join(";;"));
filters.join(";;"),
&selectedFilter);
QFileInfo fileinfo(filename);
if(!fileinfo.isFile() ||
@ -499,7 +521,7 @@ void MainWindow::on_actionSaveAs_triggered()
{
Q_FOREACH(Io_plugin_interface* plugin, canSavePlugins) {
if(plugin->save(item, fileinfo))
if(plugin->save(item, fileinfo, selectedFilter))
break;
}
}

View File

@ -1,3 +1,5 @@
#include "config.h"
#include "MainWindow.h"
#include <QApplication>
#include <CGAL/Qt/resources.h>

View File

@ -34,29 +34,37 @@
// declare the CGAL function
#ifndef CGAL_MESH_3_DEMO_DISABLE_ODT
Optimizer_thread* cgal_code_odt_mesh_3(Scene_c3t3_item& c3t3_item,
const double time_limit,
const double convergence_ratio,
const double freeze_ratio,
const int max_iteration_number,
const bool create_new_item);
#endif
#ifndef CGAL_MESH_3_DEMO_DISABLE_LLOYD
Optimizer_thread* cgal_code_lloyd_mesh_3(Scene_c3t3_item& c3t3_item,
const double time_limit,
const double convergence_ratio,
const double freeze_ratio,
const int max_iteration_number,
const bool create_new_item);
#endif
#ifndef CGAL_MESH_3_DEMO_DISABLE_PERTURBER
Optimizer_thread* cgal_code_perturb_mesh_3(Scene_c3t3_item& c3t3_item,
const double time_limit,
const double sliver_bound,
const bool create_new_item);
#endif
#ifndef CGAL_MESH_3_DEMO_DISABLE_EXUDER
Optimizer_thread* cgal_code_exude_mesh_3(Scene_c3t3_item& c3t3_item,
const double time_limit,
const double sliver_bound,
const bool create_new_item);
#endif
QString translate(CGAL::Mesh_optimization_return_code rc);
@ -77,10 +85,18 @@ public:
inline virtual QList<QAction*> actions() const;
public slots:
#ifndef CGAL_MESH_3_DEMO_DISABLE_ODT
void odt();
#endif
#ifndef CGAL_MESH_3_DEMO_DISABLE_LLOYD
void lloyd();
#endif
#ifndef CGAL_MESH_3_DEMO_DISABLE_PERTURBER
void perturb();
#endif
#ifndef CGAL_MESH_3_DEMO_DISABLE_EXUDER
void exude();
#endif
void optimization_done(Optimizer_thread* t);
void status_report(QString s);
@ -127,29 +143,37 @@ init(QMainWindow* mainWindow,
this->mw = mainWindow;
// Create menu items
#ifndef CGAL_MESH_3_DEMO_DISABLE_ODT
actionOdt = this->getActionFromMainWindow(mw, "actionOdt");
if( NULL != actionOdt )
{
connect(actionOdt, SIGNAL(triggered()), this, SLOT(odt()));
}
#endif
#ifndef CGAL_MESH_3_DEMO_DISABLE_LLOYD
actionLloyd = this->getActionFromMainWindow(mw, "actionLloyd");
if( NULL != actionLloyd )
{
connect(actionLloyd, SIGNAL(triggered()), this, SLOT(lloyd()));
}
#endif
#ifndef CGAL_MESH_3_DEMO_DISABLE_PERTURBER
actionPerturb = this->getActionFromMainWindow(mw, "actionPerturb");
if( NULL != actionPerturb )
{
connect(actionPerturb, SIGNAL(triggered()), this, SLOT(perturb()));
}
#endif
#ifndef CGAL_MESH_3_DEMO_DISABLE_EXUDER
actionExude = this->getActionFromMainWindow(mw, "actionExude");
if( NULL != actionExude )
{
connect(actionExude, SIGNAL(triggered()), this, SLOT(exude()));
}
#endif
msg = msg_interface;
}
@ -164,6 +188,7 @@ Mesh_3_optimization_plugin::actions() const
}
#ifndef CGAL_MESH_3_DEMO_DISABLE_ODT
void
Mesh_3_optimization_plugin::odt()
{
@ -228,8 +253,10 @@ Mesh_3_optimization_plugin::odt()
launch_thread(opt_thread, "Odt iterations are running...");
QApplication::restoreOverrideCursor();
}
#endif
#ifndef CGAL_MESH_3_DEMO_DISABLE_LLOYD
void
Mesh_3_optimization_plugin::lloyd()
{
@ -294,8 +321,10 @@ Mesh_3_optimization_plugin::lloyd()
launch_thread(opt_thread, "Lloyd iterations are running...");
QApplication::restoreOverrideCursor();
}
#endif
#ifndef CGAL_MESH_3_DEMO_DISABLE_PERTURBER
void
Mesh_3_optimization_plugin::perturb()
{
@ -356,8 +385,10 @@ Mesh_3_optimization_plugin::perturb()
launch_thread(opt_thread, "Sliver perturbation is running...");
QApplication::restoreOverrideCursor();
}
#endif
#ifndef CGAL_MESH_3_DEMO_DISABLE_EXUDER
void
Mesh_3_optimization_plugin::exude()
{
@ -418,6 +449,7 @@ Mesh_3_optimization_plugin::exude()
launch_thread(opt_thread, "Sliver exudation is running...");
QApplication::restoreOverrideCursor();
}
#endif
Scene_c3t3_item*

View File

@ -1,3 +1,5 @@
#include "config.h"
#include "C3t3_type.h"
#include "Scene_c3t3_item.h"
#include "Scene_polyhedron_item.h"
@ -88,7 +90,8 @@ Optimizer_thread* cgal_code_optimization(Scene_c3t3_item& c3t3_item,
// Create domain using real type of c3t3_item.data_item()
// ------------------
#ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES
// Image
const Scene_segmented_image_item* image_item =
qobject_cast<const Scene_segmented_image_item*>(c3t3_item.data_item());
@ -110,7 +113,7 @@ Optimizer_thread* cgal_code_optimization(Scene_c3t3_item& c3t3_item,
return new Optimizer_thread(p_opt_function, p_result_item);
}
#endif
// Polyhedron
const Scene_polyhedron_item* poly_item =
@ -134,6 +137,7 @@ Optimizer_thread* cgal_code_optimization(Scene_c3t3_item& c3t3_item,
return new Optimizer_thread(p_opt_function, p_result_item);
}
#ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS
// Function
const Scene_implicit_function_item* function_item =
qobject_cast<const Scene_implicit_function_item*>(c3t3_item.data_item());
@ -160,6 +164,7 @@ Optimizer_thread* cgal_code_optimization(Scene_c3t3_item& c3t3_item,
return new Optimizer_thread(p_opt_function, p_result_item);
}
#endif
return NULL;
}
@ -252,6 +257,9 @@ protected:
// -----------------------------------
// Odt
// -----------------------------------
#ifndef CGAL_MESH_3_DEMO_DISABLE_ODT
struct Odt_parameters
{
double time_limit;
@ -356,12 +364,16 @@ cgal_code_odt_mesh_3(Scene_c3t3_item& c3t3_item,
return cgal_code_optimization(c3t3_item, p, create_new_item);
}
#endif
// -----------------------------------
// Lloyd
// -----------------------------------
#ifndef CGAL_MESH_3_DEMO_DISABLE_LLOYD
struct Lloyd_parameters
{
double time_limit;
@ -466,12 +478,16 @@ cgal_code_lloyd_mesh_3(Scene_c3t3_item& c3t3_item,
return cgal_code_optimization(c3t3_item, p, create_new_item);
}
#endif
// -----------------------------------
// Perturbation
// -----------------------------------
#ifndef CGAL_MESH_3_DEMO_DISABLE_PERTURBER
struct Perturb_parameters
{
double time_limit;
@ -606,11 +622,14 @@ cgal_code_perturb_mesh_3(Scene_c3t3_item& c3t3_item,
return cgal_code_optimization(c3t3_item, p, create_new_item);
}
#endif
// -----------------------------------
// Exudation
// -----------------------------------
#ifndef CGAL_MESH_3_DEMO_DISABLE_EXUDER
struct Exude_parameters
{
double time_limit;
@ -658,7 +677,8 @@ class Optimization_function < Domain, Exude_parameters >
typedef C3t3::Triangulation Tr;
typedef CGAL::Mesh_3::Min_dihedral_angle_criterion<Tr> Sc;
typedef Exude_visitor Visitor;
typedef CGAL::Mesh_3::Slivers_exuder<C3t3,Sc,Visitor> Exuder;
typedef CGAL::Mesh_3::Slivers_exuder<
C3t3,Domain,Sc,Visitor> Exuder;
typedef Optimization_function_base< Domain > Base;
@ -691,12 +711,12 @@ protected:
/// Launch sliver exudation
/// The content of this method is taken from CGAL::exude_mesh_3()
virtual CGAL::Mesh_optimization_return_code
operator()(C3t3& c3t3, const Domain&)
operator()(C3t3& c3t3, const Domain& domain)
{
if ( NULL != exude_ ) { return CGAL::MESH_OPTIMIZATION_UNKNOWN_ERROR; }
// Create exuder
exude_ = new Exuder(c3t3,criterion_);
exude_ = new Exuder(c3t3, domain, criterion_);
if ( NULL == exude_ ) { return CGAL::MESH_OPTIMIZATION_UNKNOWN_ERROR; }
// Set time_limit
@ -743,3 +763,4 @@ cgal_code_exude_mesh_3(Scene_c3t3_item& c3t3_item,
return new Optimizer_thread(p_opt_function, p_result_item);
}
#endif

View File

@ -46,19 +46,23 @@ Meshing_thread* cgal_code_mesh_3(const Polyhedron*,
const double tet_shape,
const bool protect_features);
#ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES
Meshing_thread* cgal_code_mesh_3(const Image*,
const double angle,
const double sizing,
const double approx,
const double tets_sizing,
const double tet_shape);
#endif
#ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS
Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface*,
const double angle,
const double sizing,
const double approx,
const double tets_sizing,
const double tet_shape);
#endif
double get_approximate(double d, int precision, int& decimals);
@ -244,7 +248,8 @@ void Mesh_3_plugin::mesh_3()
tet_sizing, radius_edge,
protect_features);
}
// Image
// Image
#ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES
else if( NULL != image_item )
{
const Image* pImage = image_item->image();
@ -258,7 +263,10 @@ void Mesh_3_plugin::mesh_3()
angle, facet_sizing, approx,
tet_sizing, radius_edge);
}
#endif
// Function
#ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS
else if( NULL != function_item )
{
const Implicit_function_interface* pFunction = function_item->function();
@ -273,6 +281,7 @@ void Mesh_3_plugin::mesh_3()
tet_sizing, radius_edge);
}
#endif
if ( NULL == thread )
{
@ -349,10 +358,19 @@ meshing_done(Meshing_thread* thread)
str.append(QString("( %1 )<br>").arg(param));
}
Scene_c3t3_item* result_item = thread->item();
const Scene_item::Bbox& bbox = result_item->bbox();
str.append(QString("BBox (x,y,z): [ %1, %2 ], [ %3, %4 ], [ %5, %6 ], <br>")
.arg(bbox.xmin)
.arg(bbox.xmax)
.arg(bbox.ymin)
.arg(bbox.ymax)
.arg(bbox.zmin)
.arg(bbox.zmax));
msg->information(qPrintable(str));
// Treat new c3t3 item
Scene_c3t3_item* result_item = thread->item();
treat_result(*source_item_, *result_item);
// close message box

View File

@ -1,3 +1,7 @@
#include "config.h"
#ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES
#include "C3t3_type.h"
#include "Scene_c3t3_item.h"
#include "Image_type.h"
@ -33,3 +37,5 @@ Meshing_thread* cgal_code_mesh_3(const Image* pImage,
Mesh_function* p_mesh_function = new Mesh_function(p_new_item->c3t3(), p_domain, param);
return new Meshing_thread(p_mesh_function, p_new_item);
}
#endif

View File

@ -1,3 +1,7 @@
#include "config.h"
#ifdef CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS
#include "C3t3_type.h"
#include "Scene_c3t3_item.h"
#include "implicit_functions/Implicit_function_interface.h"
@ -41,3 +45,5 @@ Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction,
Mesh_function* p_mesh_function = new Mesh_function(p_new_item->c3t3(), p_domain, param);
return new Meshing_thread(p_mesh_function, p_new_item);
}
#endif // CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS

View File

@ -1,3 +1,5 @@
#include "config.h"
#include "C3t3_type.h"
#include "Scene_c3t3_item.h"
#include "Polyhedron_type.h"

View File

@ -25,7 +25,9 @@
#ifndef CGAL_DEMO_MESH_3_MESH_FUNCTION_H
#define CGAL_DEMO_MESH_3_MESH_FUNCTION_H
#define CGAL_MESH_3_MESHER_STATUS_ACTIVATED 1
//#define CGAL_MESH_3_MESHER_STATUS_ACTIVATED 1
#include <CGAL/Mesh_3/Concurrent_mesher_config.h>
#include <QStringList>
#include <QString>
@ -38,7 +40,6 @@
#include "Meshing_thread.h"
#include <CGAL/make_mesh_3.h> // for C3t3_initializer
struct Mesh_parameters
{
double facet_angle;
@ -112,7 +113,9 @@ private:
Mesh_parameters p_;
bool continue_;
Mesher* mesher_;
#ifdef CGAL_MESH_3_MESHER_STATUS_ACTIVATED
mutable typename Mesher::Mesher_status last_report_;
#endif
};
@ -146,8 +149,13 @@ Mesh_function(C3t3& c3t3, Domain* domain, const Mesh_parameters& p)
, p_(p)
, continue_(true)
, mesher_(NULL)
#ifdef CGAL_MESH_3_MESHER_STATUS_ACTIVATED
, last_report_(0,0,0)
#endif
{
#ifdef CGAL_CONCURRENT_MESH_3
Concurrent_mesher_config::load_config_file(CONFIG_FILENAME, false);
#endif
}
@ -191,12 +199,22 @@ launch()
// Build mesher and launch refinement process
mesher_ = new Mesher(c3t3_, *domain_, criteria);
mesher_->initialize();
mesher_->refine_mesh();
/*mesher_->initialize();
#ifdef CGAL_MESH_3_PROFILING
WallClockTimer t;
#endif
while ( ! mesher_->is_algorithm_done() && continue_ )
{
mesher_->one_step();
}
#ifdef CGAL_MESH_3_PROFILING
std::cerr << "Full refinement time (without fix_c3t3): " << t.elapsed() << " seconds." << std::endl;
#endif
*/
// Ensure c3t3 is ok (usefull if process has been stop by the user)
mesher_->fix_c3t3();
@ -226,6 +244,9 @@ QString
Mesh_function<D_>::
status(double time_period) const
{
QString result;
#ifdef CGAL_MESH_3_MESHER_STATUS_ACTIVATED
// If mesher_ is not yet created, it means that either launch() has not
// been called or that initial points have not been founded
if ( NULL == mesher_ )
@ -236,7 +257,7 @@ status(double time_period) const
// Get status and return a string corresponding to it
typename Mesher::Mesher_status s = mesher_->status();
QString result = QString("Vertices: %1 \n"
result = QString("Vertices: %1 \n"
"Vertices inserted last %2s: %3 \n\n"
"Bad facets: %4 \n"
"Bad cells: %5")
@ -247,7 +268,7 @@ status(double time_period) const
.arg(s.cells_queue);
last_report_ = s;
#endif
return result;
}

View File

@ -22,6 +22,7 @@
// File Description :
//******************************************************************************
#include "config.h"
#include <QTime>
#include <QApplication>

View File

@ -22,6 +22,8 @@
// File Description :
//******************************************************************************
#include "config.h"
#include <QTime>
#include <QTimer>
#include "Optimizer_thread.h"

View File

@ -1,3 +1,5 @@
#include "config.h"
#include "Scene_c3t3_item.h"
#include <QVector>
@ -219,6 +221,108 @@ Scene_c3t3_item::direct_draw(int mode) const {
sb == ON_NEGATIVE_SIDE &&
sc == ON_NEGATIVE_SIDE)
{
#ifdef SHOW_REMAINING_BAD_ELEMENT_IN_RED
if(mode != DRAW_EDGES)
{
Tr::Facet mirror_facet = c3t3().triangulation().mirror_facet(*fit);
//int mirror_index = c3t3().triangulation().mirror_index(cell, index);
bool blueOrRed = false;
if(cell->mark == index || mirror_facet.first->mark == mirror_facet.second)
{
std::cerr << "================== BAD TRIANGLE =================" << std::endl;
blueOrRed = true;
if(cell->mark2 != -1)
{
const Kernel::Point_3& pa2 = cell->vertex((cell->mark2+1)&3)->point();
const Kernel::Point_3& pb2 = cell->vertex((cell->mark2+2)&3)->point();
const Kernel::Point_3& pc2 = cell->vertex((cell->mark2+3)&3)->point();
CGALglcolor(QColor("blue"));
std::cerr << "================== BLUE =================" << std::endl;
draw_triangle(pa2, pb2, pc2);
const Tr::Facet f_blue(cell, cell->mark2);
Tr::Facet mirror_f_blue = c3t3().triangulation().mirror_facet(f_blue);
const Kernel::Point_3& dual_edge_pa = c3t3().triangulation().dual(f_blue.first);
const Kernel::Point_3& dual_edge_pb = c3t3().triangulation().dual(mirror_f_blue.first);
const Kernel::Point_3& dual_edge_pc = dual_edge_pa + Kernel::Vector_3(0.001, 0., 0.);
CGALglcolor(QColor("yellow"));
draw_triangle(dual_edge_pa, dual_edge_pb, dual_edge_pc);
}
else if(mirror_facet.first->mark2 != -1)
{
const Kernel::Point_3& pa2 = mirror_facet.first->vertex((mirror_facet.first->mark2+1)&3)->point();
const Kernel::Point_3& pb2 = mirror_facet.first->vertex((mirror_facet.first->mark2+2)&3)->point();
const Kernel::Point_3& pc2 = mirror_facet.first->vertex((mirror_facet.first->mark2+3)&3)->point();
CGALglcolor(QColor("blue"));
std::cerr << "================== BLUE =================" << std::endl;
draw_triangle(pa2, pb2, pc2);
const Tr::Facet f_blue(mirror_facet.first, mirror_facet.first->mark2);
Tr::Facet mirror_f_blue = c3t3().triangulation().mirror_facet(f_blue);
const Kernel::Point_3& dual_edge_pa = c3t3().triangulation().dual(f_blue.first);
const Kernel::Point_3& dual_edge_pb = c3t3().triangulation().dual(mirror_f_blue.first);
const Kernel::Point_3& dual_edge_pc = dual_edge_pa + Kernel::Vector_3(0.001, 0., 0.);
CGALglcolor(QColor("yellow"));
draw_triangle(dual_edge_pa, dual_edge_pb, dual_edge_pc);
}
/*
//const Kernel::Point_3& dual_edge_pa = cell->circumcenter();
//const Kernel::Point_3& dual_edge_pb = mirror_facet.first->circumcenter();
const Kernel::Point_3& dual_edge_pa = c3t3().triangulation().dual(cell);
const Kernel::Point_3& dual_edge_pb = c3t3().triangulation().dual(mirror_facet.first);
const Kernel::Point_3& dual_edge_pc = dual_edge_pa + Kernel::Vector_3(0.001, 0., 0.);
CGALglcolor(QColor("yellow"));
draw_triangle(dual_edge_pa, dual_edge_pb, dual_edge_pc);
*/
}
else
{
if(cell->subdomain_index() == 0) {
CGALglcolor(d->colors[cell->neighbor(index)->subdomain_index()]);
}
else {
CGALglcolor(d->colors[cell->subdomain_index()]);
}
draw_triangle(pa, pb, pc);
}
}
/*if(mode != DRAW_EDGES) {
Tr::Facet mirror_facet = c3t3().triangulation().mirror_facet(*fit);
//int mirror_index = c3t3().triangulation().mirror_index(cell, index);
bool blueOrRed = false;
if(cell->mark == index || mirror_facet.first->mark == mirror_facet.second) {
//if (cell->mark != -1 || cell->neighbor(index)->mark != -1) {
CGALglcolor(QColor("red"));
std::cerr << "================== RED =================" << std::endl;
blueOrRed = true;
}
if(cell->mark2 == index || mirror_facet.first->mark2 == mirror_facet.second) {
//if(cell->mark2 != -1 || mirror_facet.first->mark2 != -1) {
CGALglcolor(QColor("blue"));
std::cerr << "================== BLUE =================" << std::endl;
blueOrRed = true;
}
if (!blueOrRed)
{
if(cell->subdomain_index() == 0) {
CGALglcolor(d->colors[cell->neighbor(index)->subdomain_index()]);
}
else {
CGALglcolor(d->colors[cell->subdomain_index()]);
}
}
}
draw_triangle(pa, pb, pc);*/
#else
if(mode != DRAW_EDGES) {
if(cell->subdomain_index() == 0) {
CGALglcolor(d->colors[cell->neighbor(index)->subdomain_index()]);
@ -228,6 +332,7 @@ Scene_c3t3_item::direct_draw(int mode) const {
}
}
draw_triangle(pa, pb, pc);
#endif
}
}
::glEnd();
@ -299,6 +404,20 @@ Scene_c3t3_item::graphicalToolTip() const
void
Scene_c3t3_item::build_histogram()
{
#ifdef CGAL_MESH_3_DEMO_BIGGER_HISTOGRAM_WITH_WHITE_BACKGROUNG
// Create an histogram_ and display it
const int height = 280;
const int top_margin = 5;
const int left_margin = 20;
const int drawing_height = height-top_margin*2;
const int width = 804;
const int cell_width = 4;
const int text_margin = 3;
const int text_height = 34;
histogram_ = QPixmap(width,height+text_height);
histogram_.fill(QColor(255,255,255));
#else
// Create an histogram_ and display it
const int height = 140;
const int top_margin = 5;
@ -311,7 +430,8 @@ Scene_c3t3_item::build_histogram()
histogram_ = QPixmap(width,height+text_height);
histogram_.fill(QColor(192,192,192));
#endif
QPainter painter(&histogram_);
painter.setPen(Qt::black);
painter.setBrush(QColor(128,128,128));
@ -389,6 +509,14 @@ create_histogram(const C3t3& c3t3, double& min_value, double& max_value)
if( !c3t3.is_in_complex(cit))
continue;
#ifdef CGAL_MESH_3_DEMO_DONT_COUNT_TETS_ADJACENT_TO_SHARP_FEATURES_FOR_HISTOGRAM
if (c3t3.in_dimension(cit->vertex(0)) <= 1
|| c3t3.in_dimension(cit->vertex(1)) <= 1
|| c3t3.in_dimension(cit->vertex(2)) <= 1
|| c3t3.in_dimension(cit->vertex(3)) <= 1)
continue;
#endif //CGAL_MESH_3_DEMO_DONT_COUNT_TETS_ADJACENT_TO_SHARP_FEATURES_FOR_HISTOGRAM
const Point_3& p0 = cit->vertex(0)->point();
const Point_3& p1 = cit->vertex(1)->point();
const Point_3& p2 = cit->vertex(2)->point();
@ -436,7 +564,7 @@ Scene_c3t3_item::get_histogram_color(const double v) const
if ( v < 5 ) { return Qt::red; }
else if ( v < 10 ) { return QColor(215,108,0); }
else if ( v < 15 ) { return QColor(138,139,0); }
else if ( v < 165 ) { return Qt::darkGreen; }
else if ( v < 165 ) { return QColor(60,136,64); }
else if ( v < 170 ) { return QColor(138,139,1); }
else if ( v < 175 ) { return QColor(215,108,0); }
else /* 175<v<=180 */ { return Qt::red; }

View File

@ -1,3 +1,5 @@
#include "config.h"
#include "Scene_implicit_function_item.h"
#include <QColor>
#include <map>

View File

@ -1,3 +1,5 @@
#include "config.h"
#include "Scene_polygon_soup.h"
#include <CGAL/IO/Polyhedron_iostream.h>

View File

@ -1,3 +1,5 @@
#include "config.h"
#include "Scene_polyhedron_item.h"
#include "Polyhedron_type.h"
#include <CGAL/IO/Polyhedron_iostream.h>

View File

@ -1,3 +1,5 @@
#include "config.h"
#ifdef SCENE_SEGMENTED_IMAGE_GL_BUFFERS_AVAILABLE
# include <GL/glew.h>
#endif

View File

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

346
Mesh_3/demo/Mesh_3/StdAfx.h Normal file
View File

@ -0,0 +1,346 @@
#ifndef STDAFX_H
#define STDAFX_H
#ifdef CGAL_CONCURRENT_MESH_3
// In case some code uses CGAL_PROFILE, it needs to be concurrent
#define CGAL_CONCURRENT_PROFILE
#endif
#include <cmath>
#include <cassert>
#include <crtdefs.h>
// STL
#include <algorithm>
#include <map>
#include <vector>
#include <stack>
#include <deque>
#include <fstream>
#include <typeindex>
// 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.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 <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/eval_if.hpp>
#include <boost/mpl/has_key.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/if.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 <boost/optional.hpp>
//#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 <boost/shared_ptr.hpp>
#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_const.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/variant.hpp>
#include <boost/version.hpp>
// Qt
#include <QAction>
#include <QApplication>
#include <QCheckBox>
#include <QColor>
#include <QDialog>
#include <QDialogButtonBox>
#include <QDockWidget>
#include <QDoubleSpinBox>
#include <QFileDialog>
#include <QFontMetrics>
#include <QGLWidget>
#include <QGridLayout>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QHeaderView>
#include <QInputDialog>
#include <QLabel>
#include <QList>
#include <QMainWindow>
#include <QMap>
#include <QMenu>
#include <QMessageBox>
#include <QObject>
#include <QSlider>
#include <QSpacerItem>
#include <QString>
#include <QStringList>
#include <QThread>
#include <QTime>
#include <QTimer>
#include <QVBoxLayout>
#include <QVariant>
#include <QVector>
#include <QtCore/qglobal.h>
#include <QtCore/qobject.h>
#include <QtCore/qpointer.h>
#include <QtPlugin>
#include <qglobal.h>
#include <QGLWidget>
#include <QVector>
#include <QColor>
#include <QThread>
// QGLViewer
#include <QGLViewer/qglviewer.h>
#include <QGLViewer/manipulatedFrame.h>
#include <qglviewer/frame.h>
#include <qglviewer/constraint.h>
#include <qglviewer/vec.h>
#include <qglviewer/config.h>
#include <qglviewer/mouseGrabber.h>
// CGAL
//#include <CGAL/AABB_traits.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/gl.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/internal/Dummy_tds_3.h>
#include <CGAL/internal/Exact_type_selector.h>
#include <CGAL/internal/info_check.h>
//#include <CGAL/internal/Regular_triangulation_filtered_traits_3.h>
#include <CGAL/internal/Static_filters/Compare_weighted_squared_radius_3.h>
#include <CGAL/internal/Static_filters/Power_test_3.h>
//#include <CGAL/internal/Static_filters/Regular_triangulation_static_filters_traits_3.h>
#include <CGAL/internal/Static_filters/Static_filter_error.h>
#include <CGAL/internal/Static_filters/tools.h>
//#include <CGAL/internal/Triangulation_ds_circulators_3.h>
//#include <CGAL/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_image_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/Creator_weighted_point_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/Robust_weighted_circumcenter_filtered_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/Regular_triangulation_euclidean_traits_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_assertions.h>
//#include <CGAL/Triangulation_cell_base_3.h>
//#include <CGAL/Triangulation_cell_base_with_circumcenter_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

@ -1,3 +1,5 @@
#include "config.h"
#include "Volume_plane_intersection.h"
#include "Volume_plane_interface.h"

View File

@ -1,3 +1,5 @@
#include "config.h"
#include <CGAL/Image_3.h>
#include "Volume_plane.h"

View File

@ -0,0 +1,27 @@
#==========================================
#======== Worksharing strategy ===========
#==========================================
locking_grid_num_cells_per_axis = 50
first_grid_lock_radius = 0
#==========================================
#============= Brute-force ================
#==========================================
#locking_grid_num_cells_per_axis = 30
#first_grid_lock_radius = 2
#==========================================
#=============== Other ====================
#==========================================
refinement_grainsize = 10 # for parallel_for techniques
refinement_batch_size = 10000 # for parallel_for technique
work_stats_grid_num_cells_per_axis = 5 # for "task" technique
num_work_items_per_batch = 50 # for "task" technique
min_num_vertices_of_coarse_mesh = 100
num_vertices_of_coarse_mesh_per_core = 3.5
num_pseudo_infinite_vertices_per_core = 5.0

View File

@ -1,9 +1,20 @@
#ifndef CGAL_DEMO_MESH_3_CONFIG_H
#define CGAL_DEMO_MESH_3_CONFIG_H
#define CGAL_PROFILE
// #define CGAL_POLYHEDRON_DEMO_NO_NEF
// #define CGAL_POLYHEDRON_DEMO_NO_SURFACE_MESHER
// #define CGAL_POLYHEDRON_DEMO_NO_PARAMETRIZATION
#ifndef CGAL_POLYHEDRON_DEMO_CONFIG_H
#define CGAL_POLYHEDRON_DEMO_CONFIG_H
//#define CGAL_MESH_3_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_MESH_3_IO_VERBOSE
//#define SHOW_REMAINING_BAD_ELEMENT_IN_RED
#ifndef CGAL_POLYHEDRON_DEMO_NO_PARAMETRIZATION
# define CGAL_POLYHEDRON_DEMO_USE_PARAMETRIZATION
@ -17,4 +28,94 @@
# define CGAL_POLYHEDRON_DEMO_USE_SURFACE_MESHER
#endif
#endif // CGAL_POLYHEDRON_DEMO_CONFIG_H
#define CGAL_MESH_3_DEMO_BIGGER_HISTOGRAM_WITH_WHITE_BACKGROUNG
// If you define this, implicit function and segmented images won't be available
//#define CGAL_MESH_3_DEMO_ACTIVATE_SHARP_FEATURES_IN_POLYHEDRAL_DOMAIN
#ifndef CGAL_MESH_3_DEMO_ACTIVATE_SHARP_FEATURES_IN_POLYHEDRAL_DOMAIN
# define CGAL_MESH_3_DEMO_ACTIVATE_IMPLICIT_FUNCTIONS
# define CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES
#endif
//#define CGAL_MESH_3_DEMO_DONT_COUNT_TETS_ADJACENT_TO_SHARP_FEATURES_FOR_HISTOGRAM
// Optimizers
//#define CGAL_MESH_3_DEMO_DISABLE_ODT
//#define CGAL_MESH_3_DEMO_DISABLE_LLOYD
//#define CGAL_MESH_3_DEMO_DISABLE_PERTURBER
//#define CGAL_MESH_3_DEMO_DISABLE_EXUDER
// ==========================================================================
// MESH_3 GENERAL PARAMETERS
// ==========================================================================
//#define CGAL_MESH_3_USE_OLD_SURFACE_RESTRICTED_DELAUNAY_UPDATE // WARNING: VERY SLOW
#define CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING
//#define CGAL_MESHES_DEBUG_REFINEMENT_POINTS
//#define CHECK_AND_DISPLAY_THE_NUMBER_OF_BAD_ELEMENTS_IN_THE_END
// ==========================================================================
// ==========================================================================
// CONCURRENT MESH_3?
// ==========================================================================
// ==========================================================================
#ifdef CGAL_CONCURRENT_MESH_3
# ifndef CGAL_LINKED_WITH_TBB
# pragma message(" : Warning: CGAL_LINKED_WITH_TBB not defined: EVERYTHING WILL BE SEQUENTIAL.")
# endif
# 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
# include <CGAL/Mesh_3/Concurrent_mesher_config.h>
// ==========================================================================
// Verbose
// ==========================================================================
# define CGAL_CONCURRENT_MESH_3_VERBOSE
//#define CGAL_CONCURRENT_MESH_3_VERY_VERBOSE
// ==========================================================================
// Concurrency config
// ==========================================================================
const char * const CONFIG_FILENAME = "concurrent_mesher_config.cfg";
// =====================
// Worksharing strategy
// =====================
//# define CGAL_MESH_3_LOAD_BASED_WORKSHARING // Not recommended
//# define CGAL_MESH_3_TASK_SCHEDULER_SORTED_BATCHES_WITH_MULTISET
//# define CGAL_MESH_3_TASK_SCHEDULER_SORTED_BATCHES_WITH_SORT // default
// ==========================================================================
// Profiling
// ==========================================================================
// For abortion profiling, etc.
# define CGAL_CONCURRENT_MESH_3_PROFILING
// Debugging
//# define CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT
// ==========================================================================
// ==========================================================================
// SEQUENTIAL MESH_3?
// ==========================================================================
// ==========================================================================
#else // !CGAL_CONCURRENT_MESH_3
//# define CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE
//# define CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE
# define CGAL_MESH_3_IF_UNSORTED_QUEUE_JUST_SORT_AFTER_SCAN
#endif // CGAL_CONCURRENT_MESH_3
#define CGAL_MESH_3_PROFILING
#endif // CGAL_DEMO_MESH_3_CONFIG_H

View File

@ -17,7 +17,7 @@ public:
virtual Scene_item* load(QFileInfo fileinfo) = 0;
virtual bool canSave(const Scene_item*) = 0;
virtual bool save(const Scene_item*, QFileInfo fileinfo) = 0;
virtual bool save(const Scene_item*, QFileInfo fileinfo, QString selectedFilter) = 0;
};
Q_DECLARE_INTERFACE(Io_plugin_interface,

View File

@ -14,7 +14,7 @@
<string>CGAL 3D mesh generator demo</string>
</property>
<property name="windowIcon">
<iconset>
<iconset resource="../Mesh_3.qrc">
<normaloff>:/cgal/icons/resources/cgal_logo.xpm</normaloff>:/cgal/icons/resources/cgal_logo.xpm</iconset>
</property>
<widget class="QWidget" name="centralwidget">
@ -128,7 +128,7 @@
<string>+</string>
</property>
<property name="icon">
<iconset>
<iconset resource="../Mesh_3.qrc">
<normaloff>:/cgal/icons/plus</normaloff>:/cgal/icons/plus</iconset>
</property>
</widget>
@ -139,7 +139,7 @@
<string>-</string>
</property>
<property name="icon">
<iconset>
<iconset resource="../Mesh_3.qrc">
<normaloff>:/cgal/icons/minus</normaloff>:/cgal/icons/minus</iconset>
</property>
</widget>
@ -150,7 +150,7 @@
<string>...</string>
</property>
<property name="icon">
<iconset>
<iconset resource="../Mesh_3.qrc">
<normaloff>:/cgal/icons/duplicate</normaloff>:/cgal/icons/duplicate</iconset>
</property>
</widget>
@ -315,7 +315,7 @@
</action>
<action name="actionLoad">
<property name="icon">
<iconset>
<iconset resource="../Mesh_3.qrc">
<normaloff>:/cgal/icons/plus</normaloff>:/cgal/icons/plus</iconset>
</property>
<property name="text">
@ -327,7 +327,7 @@
</action>
<action name="actionErase">
<property name="icon">
<iconset>
<iconset resource="../Mesh_3.qrc">
<normaloff>:/cgal/icons/minus</normaloff>:/cgal/icons/minus</iconset>
</property>
<property name="text">
@ -339,7 +339,7 @@
</action>
<action name="actionDuplicate">
<property name="icon">
<iconset>
<iconset resource="../Mesh_3.qrc">
<normaloff>:/cgal/icons/duplicate</normaloff>:/cgal/icons/duplicate</iconset>
</property>
<property name="text">
@ -465,6 +465,9 @@
<property name="text">
<string>Create a tetrahedral mesh</string>
</property>
<property name="shortcut">
<string>Ctrl+M</string>
</property>
</action>
<action name="actionMVC">
<property name="text">
@ -503,21 +506,33 @@
<property name="text">
<string>ODT-smoothing</string>
</property>
<property name="shortcut">
<string>Ctrl+O</string>
</property>
</action>
<action name="actionLloyd">
<property name="text">
<string>Lloyd-smoothing</string>
</property>
<property name="shortcut">
<string>Ctrl+Y</string>
</property>
</action>
<action name="actionPerturb">
<property name="text">
<string>Sliver perturbation</string>
</property>
<property name="shortcut">
<string>Ctrl+P</string>
</property>
</action>
<action name="actionExude">
<property name="text">
<string>Sliver exudation</string>
</property>
<property name="shortcut">
<string>Ctrl+E</string>
</property>
</action>
<action name="actionToto">
<property name="text">
@ -539,11 +554,11 @@
<customwidget>
<class>Viewer</class>
<extends>QWidget</extends>
<header>CGAL_demo/Viewer.h</header>
<header>CGAL_demo/Viewer.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="Mesh_3.qrc"/>
<include location="../Mesh_3.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -3,16 +3,17 @@ namespace CGAL {
/*!
\ingroup PkgMesh_3MeshClasses
The class `Mesh_triangulation_3` is a metafunctor which provides the triangulation type to be used
for the 3D triangulation embedding the mesh.
The class `Mesh_triangulation_3` is a metafunctor which provides the triangulation type to be used
for the 3D triangulation embedding the mesh.
\tparam MD stands for a model of `MeshDomain_3`.
\tparam Gt stands for a model of `RegularTriangulationTraits_3`
and defaults to `Kernel_traits<MD>::%Kernel`.
\tparam Concurrency_tag is a place-holder. It is not used yet
and defaults to `Default`.
\tparam Concurrency_tag enables sequential versus parallel meshing and optimization algorithms.
Possible values are `Sequential_tag` (the default) and
`Parallel_tag`.
\tparam Vertex_base stands for a model of `MeshVertexBase_3`
and defaults to `Mesh_vertex_base_3<Gt, MD>`.

View File

@ -4,7 +4,8 @@
The concept `MeshCellBase_3` describes the requirements
for the `Cell` type of the triangulation
used in the 3D mesh generation process. The type `MeshCellBase_3` refines the concept `RegularTriangulationCellBase_3`.
used in the 3D mesh generation process. The type `MeshCellBase_3` refines the concept `RegularTriangulationCellBase_3`
and must be copy constructible.
The concept `MeshCellBase_3`
includes a way to store and retrieve
if a given cell of the triangulation
@ -29,8 +30,17 @@ of a surface facet, the center of its biggest Delaunay surface ball.
The optimizers also need this concept to provide read-write access to two `Cell_handle`
called 'intrusive'.
For parallel algorithms, the functions related to facet
access/modification must be concurrency-safe when several calls are
made in parallel on different facets of the cell (e.g. calling
set_facet_visited(0, true), set_facet_visited(2, true)
and is_facet_visited(1) in parallel must be safe)
\cgalRefines `RegularTriangulationCellBase_3`
Moreover, the parallel algorithms require an erase counter in
each cell (see below).
\cgalRefines `RegularTriangulationCellBase_3`
\cgalRefines `CopyConstructible`
\cgalHasModel `CGAL::Compact_mesh_cell_base_3<Gt,MD,Tds>`
\cgalHasModel `CGAL::Mesh_cell_base_3<Gt,MD,Cb>`
@ -104,7 +114,7 @@ sets `Surface_patch_index` of facet `i` to `index`.
void set_surface_patch_index(int i, Surface_patch_index index);
/*!
Returns `true` iff `facet(i)` has been visited.
Returns `true` iff `facet(i)` has been visited.
*/
bool is_facet_visited (int i);
@ -124,7 +134,7 @@ Returns a const reference to the surface center of `facet(i)`.
const Point& get_facet_surface_center(int i);
/*!
Sets point `p` as the surface center of `facet(i)`.
Sets point `p` as the surface center of `facet(i)`.
*/
void set_facet_surface_center (int i, Point p);
@ -145,6 +155,20 @@ invalidate this cache value.
*/
void invalidate_circumcenter();
/// Get the erase counter.
/// Only required by the parallel algorithms.
/// See `CGAL::Compact_container` for more details.
unsigned int erase_counter() const;
/// Sets the erase counter.
/// Only required by the parallel algorithms.
/// See `CGAL::Compact_container` for more details.
void set_erase_counter(unsigned int c);
/// Increments the erase counter.
/// Only required by the parallel algorithms.
/// See `CGAL::Compact_container` for more details.
void increment_erase_counter();
/// @}
/*! \name Internal

View File

@ -17,6 +17,9 @@ and to an index characteristic of this face.
The concept `MeshVertexBase_3` provides storage and read-write access to a boolean, a `FT` value,
and two `Vertex_handle` called 'intrusive'.
The parallel algorithms require an erase counter in
each cell (see below).
\cgalRefines `TriangulationVertexBase_3`
\cgalRefines `SurfaceMeshVertexBase_3`
@ -117,7 +120,20 @@ Vertex_handle previous_intrusive() const;
*/
void set_previous_intrusive(Vertex_handle);
/// Get the erase counter.
/// Only required by the parallel algorithms.
/// See `CGAL::Compact_container` for more details.
unsigned int erase_counter() const;
/// Sets the erase counter.
/// Only required by the parallel algorithms.
/// See `CGAL::Compact_container` for more details.
void set_erase_counter(unsigned int c);
/// Increments the erase counter.
/// Only required by the parallel algorithms.
/// See `CGAL::Compact_container` for more details.
void increment_erase_counter();
/// @}
}; /* end MeshVertexBase_3 */

View File

@ -4,7 +4,7 @@ namespace CGAL {
\mainpage User Manual
\anchor Chapter_3D_Mesh_Generation
\anchor userchaptermesh3
\authors Pierre Alliez, Laurent Rineau, Stéphane Tayeb, Jane Tournois, Mariette Yvinec
\authors Pierre Alliez, Clément Jamin, Laurent Rineau, Stéphane Tayeb, Jane Tournois, Mariette Yvinec
\cgalAutoToc
\cgalFigureBegin{figuremultilabel_mesher,multilabel_mesher.jpg}
@ -15,7 +15,7 @@ Cut-view of a multi-domain 3D mesh generated from a segmented image.
This package is devoted to the generation of isotropic simplicial
meshes discretizing 3D domains.
The domain to be meshed is a region of 3D space that has to be bounded.
The domain to be meshed is a region of 3D space, required to be bounded.
The region may be connected or composed of multiple components
and/or subdivided in several subdomains.
@ -55,6 +55,9 @@ the boundary and subdivision surface patches may form \cgalCite{cgal:cdl-pdma-07
The Delaunay refinement is followed by a mesh optimization phase
to remove slivers and provide a good quality mesh.
Optionally, the meshing and optimization algorithms support multi-core shared-memory
architectures to take advantage of available parallelism.
\subsection Mesh_3InputDomain Input Domain
The domain to be meshed is assumed to be bounded
@ -543,6 +546,21 @@ Mesh_optimization_return_code exude_mesh_3(C3T3& c3t3);
Note that the global functions activating the optimization processes or launching
those processes have themselves parameters (see details in reference pages) to tune the optimization process.
\subsection Mesh_3ParallelAlgorithms Parallel Algorithms
Enabling parallel meshing and optimization algorithms is achieved through
setting the third template parameter of the `Mesh_triangulation_3` class
to `Parallel_tag`, when defining the triangulation type.
Note that when the user provides his/her own vertex and
cell base classes, the `MeshVertexBase_3` and
`MeshCellBase_3` concepts impose additionnal requirements.
Parallel algorithms require the executable to be linked against the
<a href="http://www.threadingbuildingblocks.org">Intel TBB library</a>.
To control the number of threads used, the user may use the tbb::task_scheduler_init class.
See the <a href="http://www.threadingbuildingblocks.org/documentation">TBB documentation</a>
for more details.
\section Mesh_3_section_examples Examples
\subsection Mesh_33DDomainsBoundedbyIsosurfaces 3D Domains Bounded by Isosurfaces
@ -684,18 +702,19 @@ We set a time bound of 10s and a sliver bound of 10 degrees for the exuder.
\cgalExample{Mesh_3/mesh_optimization_lloyd_example.cpp}
\section Mesh_3Performances Performances
\section Mesh_3Performances Performance
We provide here some benchmarks of the performances of the mesh generation engine. The machine
used is a PC running Linux64 with two Intel Xeon CPU X5450 clocked at 3.00 GHz
with 32GB of RAM. The program has been compiled with g++ v4.3.2 with the -O3 option.
Note that our implementation does not take advantage of multi-core
architectures.
Those benchmarks have been done using \cgal v3.8.
We provide here some benchmarks of the performance of the mesh generation algorithms.
\subsection Mesh_3DelaunayRefinement_1 Delaunay Refinement
The computer used for benchmarking is a PC running Linux64 with two Intel Xeon CPU X5450 clocked at 3.00 GHz
with 32GB of RAM. The program has been compiled with g++ v4.3.2 with the -O3 option.
These benchmarks have been done using \cgal v3.8.
Note that these benchmarks were obtained with the sequential version of the algorithm,
which does not take advantage of multi-core architectures. See the next
section for performance of parallel algorithms.
We study the refinement part of the mesh generation engine in this section. We
give the CPU time (measured by `Timer`) using the 3 provided oracles. In all experiments, we produce well
shaped elements: we set the facet angle bound and the radius edge bound to their
@ -975,6 +994,23 @@ vertices/second
</CENTER>
\subsection Mesh_3Parallel_performance_1 Parallel Performance
We provide below speed-up charts generated using the parallel version of the meshing algorithms of \cgal 4.5.
The machine used is a PC running Windows 7 64-bits with two 6-core Intel Xeon CPU X5660 clocked at 2.80 GHz
with 32GB of RAM. The program has been compiled with Microsoft Visual C++ 2012 in Release mode.
Figure \cgalFigureRef{figure_refinement_speedup} shows mesh refinement speed-up, and figure \cgalFigureRef{figure_lloyd_speedup}
shows Lloyd optimization speed-up. ODT optimization exhibits similar speed-up.
\cgalFigureBegin{figure_refinement_speedup,refinement_speedup.png}
Facet refinement speed-up (left) and cell refinement speed-up (right), compared to the sequential version of the algorithm.
\cgalFigureEnd
\cgalFigureBegin{figure_lloyd_speedup,lloyd_speedup.png}
Lloyd optimization speed-up, compared to the sequential version of the algorithm. Parallel ODT exhibits similar performance.
\cgalFigureEnd
\section Mesh_3DesignAndImpl Design and Implementation History
\subsection Mesh_3TheoreticalFoundations Theoretical Foundations
@ -1026,5 +1062,8 @@ Dobrina Boltcheva et al. \cgalCite{cgal:byb-mgmmi-09}, \cgalCite{cgal:-byb-fpdmg
of 1-dimensional features was worked out by Laurent Rineau, Stéphane Tayeb
and Mariette Yvinec. It appeared first in the release 3.8 of \cgal.
In 2013, Clément Jamin made the meshing and optimization algorithms parallel
on multi-core shared-memory architectures.
\todo Add reference to paper or research report when it is available.
*/
} /* namespace CGAL */

View File

@ -36,8 +36,8 @@
\cgalPkgDescriptionBegin{3D Mesh Generation,PkgMesh_3Summary}
\cgalPkgPicture{Mesh_3/fig/multilabel_mesher_small.jpg}
\cgalPkgSummaryBegin
\cgalPkgAuthors{Pierre Alliez, Laurent Rineau, Stéphane Tayeb, Jane Tournois, Mariette Yvinec}
\cgalPkgDesc{This package is devoted to the generation of isotropic simplicial meshes discretizing 3D domains. The domain to be meshed is a region of 3D space that has to be bounded. The region may be connected or composed of multiple components and/or subdivided in several subdomains. The domain is input as an oracle able to answer queries, of a few different types, on the domain. Boundary and subdivision surfaces are either smooth or piecewise smooth surfaces, formed with planar or curved surface patches. Surfaces may exhibit 1-dimensional features (e.g. crease edges) and 0-dimensional features (e.g. singular points as corners tips, cusps or darts), that have to be fairly approximated in the mesh. }
\cgalPkgAuthors{Pierre Alliez, Clément Jamin, Laurent Rineau, Stéphane Tayeb, Jane Tournois, Mariette Yvinec}
\cgalPkgDesc{This package is devoted to the generation of isotropic simplicial meshes discretizing 3D domains. The domain to be meshed is a region of 3D space that has to be bounded. The region may be connected or composed of multiple components and/or subdivided in several subdomains. The domain is input as an oracle able to answer queries, of a few different types, on the domain. Boundary and subdivision surfaces are either smooth or piecewise smooth surfaces, formed with planar or curved surface patches. Surfaces may exhibit 1-dimensional features (e.g. crease edges) and 0-dimensional features (e.g. singular points as corners tips, cusps or darts), that have to be fairly approximated in the mesh. Optionally, the algorithms support multi-core shared-memory architectures to take advantage of available parallelism.}
\cgalPkgManuals{Chapter_3D_Mesh_Generation,PkgMesh_3}
\cgalPkgSummaryEnd
\cgalPkgShortInfoBegin
@ -81,9 +81,9 @@ related to the template parameters of some models of the main concepts:
- `CGAL::Mesh_complex_3_in_triangulation_3<Tr,CornerIndex,CurveSegmentIndex>`
- `CGAL::Mesh_triangulation_3<MD,Gt,Concurrency_tag,Vertex_base,Cell_base>`
- `CGAL::Mesh_vertex_base_3<MD,Gt,Vb>`
- `CGAL::Mesh_vertex_base_3<Gt,MD,Vb>`
- `CGAL::Compact_mesh_cell_base_3<Gt,MD,Tds>`
- `CGAL::Mesh_cell_base_3<MD,Gt,Cb>`
- `CGAL::Mesh_cell_base_3<Gt,MD,Cb>`
- `CGAL::Mesh_criteria_3<Tr>`
- `CGAL::Mesh_cell_criteria_3<Tr>`
- `CGAL::Mesh_facet_criteria_3<Tr>`

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

View File

@ -13,3 +13,4 @@ demo/Mesh_3/C3t3_rib_exporter_plugin.cpp
examples/Mesh_3/mesh_polyhedral_edge_tolerance_region.cpp
examples/Mesh_3/mesh_polyhedral_implicit_function.cpp
examples/Mesh_3/mesh_polyhedral_surface_tolerance_region.cpp
benchmark

View File

@ -28,6 +28,30 @@ if ( CGAL_FOUND )
include( ${CGAL_USE_FILE} )
find_package(Boost)
# Activate concurrency ? (turned OFF by default)
option(ACTIVATE_CONCURRENT_MESH_3
"Activate parallelism in Mesh_3"
OFF)
# And add -DCGAL_CONCURRENT_MESH_3 if that option is ON
if( ACTIVATE_CONCURRENT_MESH_3 )
add_definitions( -DCGAL_CONCURRENT_MESH_3 )
find_package( TBB REQUIRED )
else( ACTIVATE_CONCURRENT_MESH_3 )
option( LINK_WITH_TBB
"Link with TBB anyway so we can use TBB timers for profiling"
ON)
if( LINK_WITH_TBB )
find_package( TBB )
endif( LINK_WITH_TBB )
endif()
if( TBB_FOUND )
include(${TBB_USE_FILE})
list(APPEND CGAL_3RD_PARTY_LIBRARIES ${TBB_LIBRARIES})
endif()
if ( Boost_FOUND AND Boost_VERSION GREATER 103400 )
include( CGAL_CreateSingleSourceCGALProgram )

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,15 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Labeled_image_mesh_domain_3<CGAL::Image_3,K> Mesh_domain;
// Triangulation
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#ifdef CGAL_CONCURRENT_MESH_3
typedef CGAL::Mesh_triangulation_3<
Mesh_domain,
CGAL::Kernel_traits<Mesh_domain>::Kernel, // Same as sequential
CGAL::Parallel_tag // Tag to activate parallelism
>::type Tr;
#else
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#endif
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
// Criteria

View File

@ -14,7 +14,15 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Labeled_image_mesh_domain_3<CGAL::Image_3,K> Mesh_domain;
// Triangulation
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#ifdef CGAL_CONCURRENT_MESH_3
typedef CGAL::Mesh_triangulation_3<
Mesh_domain,
CGAL::Kernel_traits<Mesh_domain>::Kernel, // Same as sequential
CGAL::Parallel_tag // Tag to activate parallelism
>::type Tr;
#else
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#endif
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
// Criteria

View File

@ -60,7 +60,7 @@ int main()
CGAL::perturb_mesh_3(c3t3, domain, time_limit=5, sliver_bound=12);
// Exudation
CGAL::exude_mesh_3(c3t3);
CGAL::exude_mesh_3(c3t3, domain);
// Output
medit_file.open("out_optimized.mesh");

View File

@ -15,7 +15,15 @@ typedef FT (Function)(const Point&);
typedef CGAL::Implicit_mesh_domain_3<Function,K> Mesh_domain;
// Triangulation
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#ifdef CGAL_CONCURRENT_MESH_3
typedef CGAL::Mesh_triangulation_3<
Mesh_domain,
CGAL::Kernel_traits<Mesh_domain>::Kernel, // Same as sequential
CGAL::Parallel_tag // Tag to activate parallelism
>::type Tr;
#else
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#endif
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
// Criteria

View File

@ -15,7 +15,15 @@ typedef FT (Function)(const Point&);
typedef CGAL::Implicit_mesh_domain_3<Function,K> Mesh_domain;
// Triangulation
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#ifdef CGAL_CONCURRENT_MESH_3
typedef CGAL::Mesh_triangulation_3<
Mesh_domain,
CGAL::Kernel_traits<Mesh_domain>::Kernel, // Same as sequential
CGAL::Parallel_tag // Tag to activate parallelism
>::type Tr;
#else
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#endif
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
// Criteria

View File

@ -13,7 +13,15 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Labeled_image_mesh_domain_3<CGAL::Image_3,K> Mesh_domain;
// Triangulation
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#ifdef CGAL_CONCURRENT_MESH_3
typedef CGAL::Mesh_triangulation_3<
Mesh_domain,
CGAL::Kernel_traits<Mesh_domain>::Kernel, // Same as sequential
CGAL::Parallel_tag // Tag to activate parallelism
>::type Tr;
#else
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#endif
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
// Mesh Criteria

View File

@ -13,7 +13,15 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Labeled_image_mesh_domain_3<CGAL::Image_3,K> Mesh_domain;
// Triangulation
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#ifdef CGAL_CONCURRENT_MESH_3
typedef CGAL::Mesh_triangulation_3<
Mesh_domain,
CGAL::Kernel_traits<Mesh_domain>::Kernel, // Same as sequential
CGAL::Parallel_tag // Tag to activate parallelism
>::type Tr;
#else
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#endif
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
// Mesh Criteria
@ -44,7 +52,7 @@ int main()
no_perturb(), no_exude());
CGAL::lloyd_optimize_mesh_3(c3t3_bis, domain, time_limit=30);
CGAL::exude_mesh_3(c3t3_bis, sliver_bound=10, time_limit=10);
CGAL::exude_mesh_3(c3t3_bis, domain, sliver_bound=10, time_limit=10);
// Output
std::ofstream medit_file("out.mesh");

View File

@ -17,7 +17,15 @@ typedef CGAL::Polyhedron_3<K> Polyhedron;
typedef CGAL::Polyhedral_mesh_domain_3<Polyhedron, K> Mesh_domain;
// Triangulation
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#ifdef CGAL_CONCURRENT_MESH_3
typedef CGAL::Mesh_triangulation_3<
Mesh_domain,
CGAL::Kernel_traits<Mesh_domain>::Kernel, // Same as sequential
CGAL::Parallel_tag // Tag to activate parallelism
>::type Tr;
#else
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#endif
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
// Criteria

View File

@ -12,7 +12,15 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Polyhedral_mesh_domain_with_features_3<K> Mesh_domain;
// Triangulation
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#ifdef CGAL_CONCURRENT_MESH_3
typedef CGAL::Mesh_triangulation_3<
Mesh_domain,
CGAL::Kernel_traits<Mesh_domain>::Kernel, // Same as sequential
CGAL::Parallel_tag // Tag to activate parallelism
>::type Tr;
#else
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#endif
typedef CGAL::Mesh_complex_3_in_triangulation_3<
Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_segment_index> C3t3;

View File

@ -23,7 +23,15 @@ typedef std::vector<Point> Polyline_3;
typedef std::list<Polyline_3> Polylines;
// Triangulation
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#ifdef CGAL_CONCURRENT_MESH_3
typedef CGAL::Mesh_triangulation_3<
Mesh_domain,
CGAL::Kernel_traits<Mesh_domain>::Kernel, // Same as sequential
CGAL::Parallel_tag // Tag to activate parallelism
>::type Tr;
#else
typedef CGAL::Mesh_triangulation_3<Mesh_domain>::type Tr;
#endif
typedef CGAL::Mesh_complex_3_in_triangulation_3<
Tr,Mesh_domain::Corner_index,Mesh_domain::Curve_segment_index> C3t3;

View File

@ -26,6 +26,7 @@
#include <CGAL/Mesh_3/config.h>
#include <CGAL/basic.h>
#include <CGAL/array.h>
#include <CGAL/triangulation_assertions.h>
#include <CGAL/internal/Dummy_tds_3.h>
@ -33,17 +34,147 @@
#include <CGAL/Mesh_3/io_signature.h>
namespace CGAL {
// Class Compact_mesh_cell_base_3_base
// Base for Compact_mesh_cell_base_3, with specializations
// for different values of Concurrency_tag
// Sequential
template <typename Concurrency_tag>
class Compact_mesh_cell_base_3_base
{
protected:
Compact_mesh_cell_base_3_base()
: bits_(0) {}
public:
#if defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \
|| defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE)
// Erase counter (cf. Compact_container)
unsigned int erase_counter() const
{
return this->m_erase_counter;
}
void set_erase_counter(unsigned int c)
{
this->m_erase_counter = c;
}
void increment_erase_counter()
{
++this->m_erase_counter;
}
#endif
/// Marks \c facet as visited
void set_facet_visited (const int facet)
{
CGAL_precondition(facet>=0 && facet <4);
bits_ |= (1 << facet);
}
/// Marks \c facet as not visited
void reset_visited (const int facet)
{
CGAL_precondition(facet>=0 && facet<4);
bits_ &= (15 & ~(1 << facet));
}
/// Returns \c true if \c facet is marked as visited
bool is_facet_visited (const int facet) const
{
CGAL_precondition(facet>=0 && facet<4);
return ( (bits_ & (1 << facet)) != 0 );
}
private:
char bits_;
#if defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \
|| defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE)
typedef unsigned int Erase_counter_type;
Erase_counter_type m_erase_counter;
#endif
};
#ifdef CGAL_LINKED_WITH_TBB
// Class Compact_mesh_cell_base_3_base
// Specialization for parallel
template <>
class Compact_mesh_cell_base_3_base<Parallel_tag>
{
protected:
Compact_mesh_cell_base_3_base()
{
bits_ = 0;
}
public:
// Erase counter (cf. Compact_container)
unsigned int erase_counter() const
{
return this->m_erase_counter;
}
void set_erase_counter(unsigned int c)
{
this->m_erase_counter = c;
}
void increment_erase_counter()
{
++this->m_erase_counter;
}
/// Marks \c facet as visited
void set_facet_visited (const int facet)
{
CGAL_precondition(facet>=0 && facet<4);
char current_bits = bits_;
while (bits_.compare_and_swap(current_bits | (1 << facet), current_bits) != current_bits)
{
current_bits = bits_;
}
}
/// Marks \c facet as not visited
void reset_visited (const int facet)
{
CGAL_precondition(facet>=0 && facet<4);
char current_bits = bits_;
while (bits_.compare_and_swap(current_bits & (15 & ~(1 << facet)), current_bits) != current_bits)
{
current_bits = bits_;
}
}
/// Returns \c true if \c facet is marked as visited
bool is_facet_visited (const int facet) const
{
CGAL_precondition(facet>=0 && facet<4);
return ( (bits_ & (1 << facet)) != 0 );
}
private:
typedef tbb::atomic<unsigned int> Erase_counter_type;
Erase_counter_type m_erase_counter;
/// Stores visited facets (4 first bits)
tbb::atomic<char> bits_;
};
#endif // CGAL_LINKED_WITH_TBB
// Class Compact_mesh_cell_base_3
// Cell base class used in 3D meshing process.
// Adds information to Cb about the cell of the input complex containing it
template< class GT,
class MD,
class TDS = void >
class TDS = void >
class Compact_mesh_cell_base_3
: public Compact_mesh_cell_base_3_base<typename TDS::Concurrency_tag>
{
typedef typename GT::FT FT;
public:
typedef TDS Triangulation_data_structure;
typedef typename TDS::Vertex_handle Vertex_handle;
@ -63,10 +194,10 @@ public:
typedef typename MD::Subdomain_index Subdomain_index;
typedef typename MD::Surface_patch_index Surface_patch_index;
typedef typename MD::Index Index;
typedef GT Geom_traits;
typedef typename GT::Point_3 Point;
typedef Point* Point_container;
typedef Point* Point_iterator;
typedef const Point* Point_const_iterator;
@ -92,21 +223,21 @@ public:
, surface_center_index_table_()
, sliver_value_(FT(0.))
, subdomain_index_()
, bits_(0)
, sliver_cache_validity_(false)
{
}
Compact_mesh_cell_base_3(const Compact_mesh_cell_base_3& rhs)
Compact_mesh_cell_base_3(const Compact_mesh_cell_base_3& rhs)
: circumcenter_(NULL)
, sliver_value_(rhs.sliver_value_)
, subdomain_index_(rhs.subdomain_index_)
, sliver_cache_validity_(false)
#ifdef CGAL_INTRUSIVE_LIST
, next_intrusive_(rhs.next_intrusive_)
, previous_intrusive_(rhs.previous_intrusive_)
#endif
, sliver_value_(rhs.sliver_value_)
, subdomain_index_(rhs.subdomain_index_)
, bits_(0)
, sliver_cache_validity_(false)
, V(rhs.V)
, N(rhs.N)
{
for(int i=0; i <4; i++){
surface_index_table_[i] = rhs.surface_index_table_[i];
@ -114,7 +245,7 @@ public:
surface_center_index_table_[i] = rhs.surface_center_index_table_[i];
}
}
Compact_mesh_cell_base_3 (Vertex_handle v0,
Vertex_handle v1,
Vertex_handle v2,
@ -128,11 +259,10 @@ public:
#endif
, surface_center_index_table_()
, sliver_value_(FT(0.))
, subdomain_index_()
, bits_(0)
, subdomain_index_()
, sliver_cache_validity_(false)
, V(CGAL::make_array(v0, v1, v2, v3))
{
set_vertices(v0, v1, v2, v3);
}
@ -154,11 +284,10 @@ public:
, surface_center_index_table_()
, sliver_value_(FT(0.))
, subdomain_index_()
, bits_(0)
, sliver_cache_validity_(false)
, V(CGAL::make_array(v0, v1, v2, v3))
, N(CGAL::make_array(n0, n1, n2, n3))
{
set_neighbors(n0, n1, n2, n3);
set_vertices(v0, v1, v2, v3);
}
~Compact_mesh_cell_base_3()
@ -327,11 +456,11 @@ public:
// Returns the index of the cell of the input complex that contains the cell
Subdomain_index subdomain_index() const { return subdomain_index_; }
// Sets the index of the cell of the input complex that contains the cell
void set_subdomain_index(const Subdomain_index& index)
{ subdomain_index_ = index; }
{ subdomain_index_ = index; }
void set_sliver_value(const FT& value)
{
sliver_cache_validity_ = true;
@ -361,27 +490,6 @@ public:
return surface_index_table_[facet];
}
/// Marks \c facet as visited
void set_facet_visited (const int facet)
{
CGAL_precondition(facet>=0 && facet <4);
bits_ |= (1 << facet);
}
/// Marks \c facet as not visited
void reset_visited (const int facet)
{
CGAL_precondition(facet>=0 && facet<4);
bits_ &= (15 & ~(1 << facet));
}
/// Returns \c true if \c facet is marked as visited
bool is_facet_visited (const int facet) const
{
CGAL_precondition(facet>=0 && facet<4);
return ( (bits_ & (1 << facet)) != 0 );
}
/// Sets surface center of \c facet to \c point
void set_facet_surface_center(const int facet, const Point& point)
{
@ -416,16 +524,16 @@ public:
CGAL_precondition(facet>=0 && facet<4);
return ( Surface_patch_index() != surface_index_table_[facet]);
}
// -----------------------------------
// Backward Compatibility
// -----------------------------------
#ifndef CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX
typedef Surface_patch_index Surface_index;
void set_surface_index(const int facet, const Surface_index& index)
{ set_surface_patch_index(facet,index); }
/// Returns surface index of facet \c facet
Surface_index surface_index(const int facet) const
{ return surface_patch_index(facet); }
@ -437,7 +545,7 @@ public:
static
std::string io_signature()
{
return
return
Get_io_signature<Subdomain_index>()() + "+" +
Get_io_signature<Regular_triangulation_cell_base_3<Geom_traits> >()()
+ "+(" + Get_io_signature<Surface_patch_index>()() + ")[4]";
@ -450,7 +558,7 @@ public:
{
next_intrusive_ = c;
}
Cell_handle previous_intrusive() const { return previous_intrusive_; }
void set_previous_intrusive(Cell_handle c)
{
@ -488,7 +596,6 @@ private:
Subdomain_index subdomain_index_;
TDS_data _tds_data;
char bits_;
mutable bool sliver_cache_validity_;

View File

@ -0,0 +1,323 @@
// Copyright (c) 2012 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL: $
// $Id: $
//
//
// Author(s) : Clement Jamin
#ifndef CGAL_IO_FILE_MAYA_H
#define CGAL_IO_FILE_MAYA_H
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <sstream>
#include <CGAL/utility.h>
namespace CGAL {
//-------------------------------------------------------
// IO functions
//-------------------------------------------------------
template <class C3T3>
void
output_to_maya(std::ostream& os,
const C3T3& c3t3,
bool surfaceOnly = true)
{
typedef typename C3T3::Triangulation Tr;
typedef typename C3T3::Facets_in_complex_iterator Facet_iterator;
typedef typename C3T3::Cells_in_complex_iterator Cell_iterator;
typedef typename Tr::Finite_vertices_iterator Finite_vertices_iterator;
typedef typename Tr::Vertex_handle Vertex_handle;
typedef typename Tr::Point Point_3;
#ifdef CGAL_MESH_3_IO_VERBOSE
std::cerr << "Output to maya:\n";
#endif
const Tr& tr = c3t3.triangulation();
//-------------------------------------------------------
// File output
//-------------------------------------------------------
//-------------------------------------------------------
// Header
//-------------------------------------------------------
os << std::setprecision(20);
os << "//Maya ASCII 2011 scene" << std::endl;
os << "//Name: testMaya3.ma" << std::endl;
os << "//Last modified: Wed, Jan 25, 2012 05:54:26 PM" << std::endl;
os << "//Codeset: 1252" << std::endl;
os << "requires maya \"2011\";" << std::endl;
os << "currentUnit -l centimeter -a degree -t film;" << std::endl;
os << "fileInfo \"application\" \"maya\";" << std::endl;
os << "fileInfo \"product\" \"Maya 2011\";" << std::endl;
os << "fileInfo \"version\" \"2011\";" << std::endl;
os << "fileInfo \"cutIdentifier\" \"201003190014-771504\";" << std::endl;
os << "fileInfo \"license\" \"education\";" << std::endl;
std::string name = "Mesh_3";
os << "createNode mesh -n \"" << name << "Shape\" -p \"" << name << "\";" << std::endl;
os << " setAttr -k off \".v\";" << std::endl;
os << " setAttr \".uvst[0].uvsn\" -type \"string\" \"map1\";" << std::endl;
os << " setAttr \".cuvs\" -type \"string\" \"map1\";" << std::endl;
os << " setAttr \".dcol\" yes;" << std::endl;
os << " setAttr \".dcc\" -type \"string\" \"Ambient+Diffuse\";" << std::endl;
os << " connectAttr \"" << name << "Shape.iog\" \":initialShadingGroup.dsm\" -na;\n\n";
//-------------------------------------------------------
// Colors
//------------------------------------------------------
/*os << " setAttr \".ccls\" -type \"string\" \"colorSet\";\n";
os << " setAttr \".clst[0].clsn\" -type \"string\" \"colorSet\";\n";
os << " setAttr \".clst[0].rprt\" 3;\n";
os << " setAttr -s " << 3 << " \".clst[0].clsp[0:" << 3-1 << "]\"" << std::endl;
os << " 10 50 250" << std::endl;
os << " 100 250 50" << std::endl;
os << " 0 200 200" << std::endl;
os << " ;\n";*/
//-------------------------------------------------------
// Vertices
//------------------------------------------------------
std::map<Vertex_handle, int> V;
std::stringstream vertices_sstr;
int num_vertices = 0;
for( Finite_vertices_iterator vit = tr.finite_vertices_begin();
vit != tr.finite_vertices_end();
++vit)
{
if ( (surfaceOnly && c3t3.in_dimension(vit) <= 2)
|| !surfaceOnly)
{
V[vit] = num_vertices++;
Point_3 p = vit->point();
vertices_sstr << " " << CGAL::to_double(p.x()) << " " << CGAL::to_double(p.y()) << " " << CGAL::to_double(p.z()) << std::endl;
}
}
os << " setAttr -s " << num_vertices << " \".vt[0:" << num_vertices-1 << "]\"" << std::endl;
os << vertices_sstr.str();
os << ";\n";
/*
// Triangles
os << "setAttr -s " << QString().setNum(number_of_triangles) << " \".fc[0:" << QString().setNum(number_of_triangles-1) << "]\" -type \"polyFaces\" \n";
for (int i=0;i<triangle.size();i=i+3){
int a=int(triangle[i+0]);
int b=int(triangle[i+1]);
int c=int(triangle[i+2]);
os << "f 3 " << QString().setNum(a) << " " << QString().setNum(b) << " " << QString().setNum(c) << " ";
if (mat.materialNode==VertexColor){
os << "mc 0 3 " << QString().setNum(index[i*2]) << " " << QString().setNum(index[i*2+2]) << " " << QString().setNum(index[i*2+4]) << " ";
}
}
os << ";\n\n";*/
//-------------------------------------------------------
// Get edges and facets
//-------------------------------------------------------
typename C3T3::size_type number_of_triangles = c3t3.number_of_facets_in_complex();
std::stringstream facets_sstr;
//std::stringstream normals_sstr;
//normals_sstr << " setAttr -s " << number_of_triangles*3 << " \".n[0:" << number_of_triangles*3-1 << "]\" -type \"float3\" \n";
// Save edges
typedef std::vector<std::pair<int, int> > EdgeList;
EdgeList edges;
// Surface only
if (surfaceOnly)
{
facets_sstr << " setAttr -s " << number_of_triangles
<< " \".fc[0:" << number_of_triangles-1 << "]\" -type \"polyFaces\" \n";
int c = 0;
for( Facet_iterator fit = c3t3.facets_in_complex_begin();
fit != c3t3.facets_in_complex_end();
++fit, ++c)
{
int indices[3];
//Point_3 points[3];
facets_sstr << " f 3 ";
for (int j = 0, i = (fit->second + 1) % 4 ; j < 3 ; i = (i+1)%4, ++j)
{
const Vertex_handle& vh = fit->first->vertex(i);
indices[j] = V[vh];
//points[j] = vh->point();
}
// Reverse triangle orientation?
bool reverse_triangle =
(fit->second % 2 == 0 && !c3t3.is_in_complex(fit->first))
|| (fit->second % 2 != 0 && c3t3.is_in_complex(fit->first));
if (reverse_triangle)
{
std::swap(indices[1], indices[2]);
//std::swap(points[1], points[2]);
}
//Kernel::Vector_3 n = cross_product(points[1] - points[0], points[2] - points[0]);
//n = n / CGAL::sqrt(n*n);
// Add the normal 3 times
//normals_sstr << " " << n.x() << " " << n.y() << " " << n.z() << std::endl;
//normals_sstr << " " << n.x() << " " << n.y() << " " << n.z() << std::endl;
//normals_sstr << " " << n.x() << " " << n.y() << " " << n.z() << std::endl;
// 3 edges
for (int i = 0 ; i < 3 ; ++i)
{
std::pair<int, int> edge = std::make_pair(
(std::min)(indices[i], indices[(i+1)%3]),
(std::max)(indices[i], indices[(i+1)%3]));
size_t pos = std::find(edges.begin(), edges.end(), edge) - edges.begin();
if (pos == edges.size()) // Not found?
{
edges.push_back(edge);
}
// ith edge of triangle
facets_sstr << pos << " ";
}
// 1 triangles
facets_sstr << std::endl;
// Colors
//facets_sstr << " mc 0 3 " << rand()%3 << " " << rand()%3 << " " << rand()%3 << std::endl;
}
}
// Tetrahedra = 4 facets for each
else
{
facets_sstr << " setAttr -s " << 4*c3t3.number_of_cells_in_complex()
<< " \".fc[0:" << 4*c3t3.number_of_cells_in_complex()-1 << "]\" -type \"polyFaces\" \n";
int c = 0;
for( Cell_iterator cit = c3t3.cells_in_complex_begin();
cit != c3t3.cells_in_complex_end();
++cit, ++c)
{
for (int facet_i = 0 ; facet_i < 4 ; ++facet_i)
{
int indices[3];
//Point_3 points[3];
facets_sstr << " f 3 ";
for (int j = 0, i = (facet_i + 1) % 4 ; j < 3 ; i = (i+1)%4, ++j)
{
const Vertex_handle& vh = cit->vertex(i);
indices[j] = V[vh];
//points[j] = vh->point();
}
// Reverse triangle orientation?
bool reverse_triangle = (facet_i % 2 != 0 && c3t3.is_in_complex(cit, facet_i));
if (reverse_triangle)
{
std::swap(indices[1], indices[2]);
//std::swap(points[1], points[2]);
}
//Kernel::Vector_3 n = cross_product(points[1] - points[0], points[2] - points[0]);
//n = n / CGAL::sqrt(n*n);
// Add the normal 3 times
//normals_sstr << " " << n.x() << " " << n.y() << " " << n.z() << std::endl;
//normals_sstr << " " << n.x() << " " << n.y() << " " << n.z() << std::endl;
//normals_sstr << " " << n.x() << " " << n.y() << " " << n.z() << std::endl;
// 3 edges
for (int i = 0 ; i < 3 ; ++i)
{
std::pair<int, int> edge = std::make_pair(
(std::min)(indices[i], indices[(i+1)%3]),
(std::max)(indices[i], indices[(i+1)%3]));
size_t pos = std::find(edges.begin(), edges.end(), edge) - edges.begin();
if (pos == edges.size()) // Not found?
{
edges.push_back(edge);
}
// ith edge of triangle
facets_sstr << pos << " ";
}
// 1 triangles
facets_sstr << std::endl;
// Colors
//facets_sstr << " mc 0 3 " << rand()%3 << " " << rand()%3 << " " << rand()%3 << std::endl;
}
}
}
facets_sstr << ";\n\n";
//normals_sstr << ";\n\n";
//-------------------------------------------------------
// Edges
//-------------------------------------------------------
os << " setAttr -s " << edges.size() << " \".ed[0:"
<< edges.size() - 1 << "]\"" << std::endl;
for (EdgeList::const_iterator it = edges.begin(), it_end = edges.end() ; it != it_end ; ++it)
os << " " << it->first << " " << it->second << " " << 0 << std::endl;
os << ";\n";
//-------------------------------------------------------
// Normals
//-------------------------------------------------------
//os << normals_sstr.str();
//-------------------------------------------------------
// Facets
//-------------------------------------------------------
os << facets_sstr.str();
//-------------------------------------------------------
// Tetrahedra
//-------------------------------------------------------
/*os << "Tetrahedra" << std::endl
<< c3t3.number_of_cells_in_complex() << std::endl;
for( Cell_iterator cit = c3t3.cells_in_complex_begin() ;
cit != c3t3.cells_in_complex_end() ;
++cit )
{
for (int i=0; i<4; i++)
os << V[cit->vertex(i)] << " ";
os << get(cell_pmap, cit) << std::endl;
}*/
//-------------------------------------------------------
// End
//-------------------------------------------------------
#ifdef CGAL_MESH_3_IO_VERBOSE
std::cerr << "done.\n";
#endif
} // end output_to_maya(...)
} // end namespace CGAL
#endif // CGAL_IO_FILE_MAYA_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,177 @@
// Copyright (c) 2012 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Clement Jamin
//
//******************************************************************************
// File Description :
//******************************************************************************
#ifndef CGAL_MESH_3_CONCURRENT_MESHER_CONFIG_H
#define CGAL_MESH_3_CONCURRENT_MESHER_CONFIG_H
#ifdef CGAL_USE_BOOST_PROGRAM_OPTIONS
# include <boost/program_options.hpp>
namespace po = boost::program_options;
#endif
#include <iostream>
#include <fstream>
// class Concurrent_mesher_config
/// Singleton containing config
class Concurrent_mesher_config
{
// Private constructor (singleton)
Concurrent_mesher_config()
: m_config_file_loaded(false),
locking_grid_num_cells_per_axis(50),
first_grid_lock_radius(0),
work_stats_grid_num_cells_per_axis(5),
num_work_items_per_batch(50),
refinement_grainsize(10),
refinement_batch_size(10000),
min_num_vertices_of_coarse_mesh(100),
num_vertices_of_coarse_mesh_per_core(3.5f),
num_pseudo_infinite_vertices_per_core(5.0f)
{}
public:
static Concurrent_mesher_config &get()
{
static Concurrent_mesher_config singleton;
return singleton;
}
static bool load_config_file(const char *filename,
bool reload_if_already_loaded = false)
{
return get().load_file(filename, reload_if_already_loaded);
}
//=============== PUBLIC PARAMETERS ==============
// From config file (or default)
int locking_grid_num_cells_per_axis;
int first_grid_lock_radius;
int work_stats_grid_num_cells_per_axis;
int num_work_items_per_batch;
int refinement_grainsize;
int refinement_batch_size;
int min_num_vertices_of_coarse_mesh;
float num_vertices_of_coarse_mesh_per_core;
float num_pseudo_infinite_vertices_per_core;
// Others
//================================================
protected:
bool load_file(
const char *filename,
bool reload_if_already_loaded = false)
{
#ifdef CGAL_USE_BOOST_PROGRAM_OPTIONS
if (m_config_file_loaded && reload_if_already_loaded == false)
return true;
try
{
std::ifstream in(filename);
if (in.fail())
{
std::string err = "could not open file '";
err += filename;
err += "'. Using default values.";
throw std::runtime_error(err);
}
// Declare the supported options.
po::options_description desc("Allowed options");
desc.add_options()
("locking_grid_num_cells_per_axis", po::value<int>(), "")
("first_grid_lock_radius", po::value<int>(), "")
("work_stats_grid_num_cells_per_axis", po::value<int>(), "")
("num_work_items_per_batch", po::value<int>(), "")
("refinement_grainsize", po::value<int>(), "")
("refinement_batch_size", po::value<int>(), "")
("min_num_vertices_of_coarse_mesh", po::value<int>(), "")
("num_vertices_of_coarse_mesh_per_core", po::value<float>(), "")
("num_pseudo_infinite_vertices_per_core", po::value<float>(), "");
po::store(po::parse_config_file<char>(in, desc), m_variables_map);
po::notify(m_variables_map);
}
catch (std::exception &e)
{
std::cerr << "Concurrency configuration file error: "
<< e.what() << std::endl;
return false;
}
locking_grid_num_cells_per_axis =
get_config_file_option_value<int>("locking_grid_num_cells_per_axis");
first_grid_lock_radius =
get_config_file_option_value<int>("first_grid_lock_radius");
work_stats_grid_num_cells_per_axis =
get_config_file_option_value<int>("work_stats_grid_num_cells_per_axis");
num_work_items_per_batch =
get_config_file_option_value<int>("num_work_items_per_batch");
refinement_grainsize =
get_config_file_option_value<int>("refinement_grainsize");
refinement_batch_size =
get_config_file_option_value<int>("refinement_batch_size");
min_num_vertices_of_coarse_mesh =
get_config_file_option_value<int>("min_num_vertices_of_coarse_mesh");
num_vertices_of_coarse_mesh_per_core =
get_config_file_option_value<float>("num_vertices_of_coarse_mesh_per_core");
num_pseudo_infinite_vertices_per_core =
get_config_file_option_value<float>("num_pseudo_infinite_vertices_per_core");
m_config_file_loaded = true;
#else // CGAL_USE_BOOST_PROGRAM_OPTIONS not defined
std::cerr << "Warning: could not load concurrency configuration file '"
<< filename << "'. Default values will be used."
<< std::endl;
#endif // CGAL_USE_BOOST_PROGRAM_OPTIONS
return true;
}
#ifdef CGAL_USE_BOOST_PROGRAM_OPTIONS
template <typename OptionType>
OptionType get_config_file_option_value(const char *option_name)
{
if (m_variables_map.count(option_name))
return m_variables_map[option_name].as<OptionType>();
else
return OptionType();
}
#endif
#ifdef CGAL_USE_BOOST_PROGRAM_OPTIONS
po::variables_map m_variables_map;
#endif
bool m_config_file_loaded;
};
#endif // CGAL_MESH_3_CONCURRENT_MESHER_CONFIG_H

View File

@ -86,7 +86,10 @@ public:
break;
case 1:
case 0:
case -1:
// Don't move edge or corner vertices
// N.B.: dimension = -1 is possible if we added points on a far sphere
// during initialization
return CGAL::NULL_VECTOR;
break;
default:
@ -99,7 +102,8 @@ public:
return CGAL::NULL_VECTOR;
}
#ifdef CGAL_MESH_3_OPTIMIZER_VERBOSE
#if defined(CGAL_MESH_3_OPTIMIZER_VERBOSE) \
|| defined (CGAL_MESH_3_EXPORT_PERFORMANCE_DATA)
static std::string name() { return std::string("Lloyd"); }
#endif

View File

@ -30,11 +30,16 @@
#include <CGAL/Mesh_3/utilities.h>
#include <CGAL/iterator.h>
#include <CGAL/IO/File_medit.h>
#include <CGAL/IO/File_maya.h>
#include <CGAL/Bbox_3.h>
#include <iostream>
#include <fstream>
#include <CGAL/Mesh_3/io_signature.h>
#ifdef CGAL_LINKED_WITH_TBB
#include <tbb/atomic.h>
#endif
namespace CGAL {
namespace Mesh_3 {
@ -43,10 +48,10 @@ namespace Mesh_3 {
* @brief A data-structure to represent and maintain a 3D complex embedded
* in a 3D triangulation.
*/
template<typename Tr>
template<typename Tr, typename Concurrency_tag>
class Mesh_complex_3_in_triangulation_3_base
{
typedef Mesh_complex_3_in_triangulation_3_base<Tr> Self;
typedef Mesh_complex_3_in_triangulation_3_base<Tr, Concurrency_tag> Self;
public:
// Triangulation types
@ -70,15 +75,21 @@ public:
* Builds an empty 3D complex.
*/
Mesh_complex_3_in_triangulation_3_base()
: number_of_facets_(0)
, tr_()
, number_of_cells_(0) {}
: tr_()
{
// We don't put it in the initialization list because
// tbb::atomic has no contructors
number_of_facets_ = 0;
number_of_cells_ = 0;
}
/// Copy constructor
Mesh_complex_3_in_triangulation_3_base(const Self& rhs)
: number_of_facets_(rhs.number_of_facets_)
, tr_(rhs.tr_)
, number_of_cells_(rhs.number_of_cells_) {}
: tr_(rhs.tr_)
{
number_of_facets_ = rhs.number_of_facets_;
number_of_cells_ = rhs.number_of_cells_;
}
/// Destructor
~Mesh_complex_3_in_triangulation_3_base() {}
@ -88,7 +99,7 @@ public:
number_of_facets_ = 0;
tr_.clear();
}
/// Assignment operator
Self& operator=(Self rhs)
{
@ -130,7 +141,7 @@ public:
/// Sets surface index of facet(\c cell, \c i) to \c index
void set_surface_patch_index(const Cell_handle& cell,
const int i,
const Surface_patch_index& index)
const Surface_patch_index& index) const
{
cell->set_surface_patch_index(i, index);
}
@ -188,19 +199,19 @@ public:
/// Sets subdomain index of cell \c cell to \c index
void set_subdomain_index(const Cell_handle& cell,
const Subdomain_index& index)
const Subdomain_index& index) const
{
cell->set_subdomain_index(index);
}
/// Sets index of vertex \c vertex to \c index
void set_index(const Vertex_handle& vertex, const Index& index)
void set_index(const Vertex_handle& vertex, const Index& index) const
{
vertex->set_index(index);
}
/// Sets dimension of vertex \c vertex to \c dimension
void set_dimension(const Vertex_handle& vertex, int dimension)
void set_dimension(const Vertex_handle& vertex, int dimension) const
{
vertex->set_dimension(dimension);
}
@ -229,7 +240,7 @@ public:
/// Returns the index of vertex \c v
Index index(const Vertex_handle& v) const { return v->index(); }
/// Outputs the mesh to medit
void output_to_medit(std::ofstream& os,
bool rebind = true,
@ -238,6 +249,14 @@ public:
// Call global function
CGAL::output_to_medit(os,*this,rebind,show_patches);
}
/// Outputs the mesh to medit
void output_to_maya(std::ofstream& os,
bool surfaceOnly = true) const
{
// Call global function
CGAL::output_to_maya(os,*this,surfaceOnly);
}
//-------------------------------------------------------
// Undocumented features
@ -283,7 +302,7 @@ public:
++first;
}
}
/// Swaps this & rhs
void swap(Self& rhs)
{
@ -291,16 +310,16 @@ public:
tr_.swap(rhs.tr_);
std::swap(rhs.number_of_cells_, number_of_cells_);
}
/// Returns bbox
Bbox_3 bbox() const;
//-------------------------------------------------------
// Traversal
//-------------------------------------------------------
private:
typedef Mesh_3::internal::Iterator_not_in_complex<Self> Iterator_not_in_complex;
class Facet_iterator_not_in_complex
{
const Self* c3t3_;
@ -311,15 +330,15 @@ private:
const Surface_patch_index& index = Surface_patch_index())
: c3t3_(&c3t3)
, index_(index) { }
template <typename Iterator>
bool operator()(Iterator it) const
{
{
if ( index_ == Surface_patch_index() ) { return ! c3t3_->is_in_complex(*it); }
else { return c3t3_->surface_patch_index(*it) != index_; }
}
};
/**
* @class Cell_not_in_complex
* @brief A class to filter cells which do not belong to the complex
@ -336,12 +355,12 @@ private:
, index_(index) { }
bool operator()(Cell_handle ch) const
{
{
if ( index_ == Subdomain_index() ) { return !r_self_->is_in_complex(ch); }
else { return r_self_->subdomain_index(ch) != index_; }
}
}; // end class Cell_not_in_complex
public:
/// Iterator type to visit the facets of the 2D complex.
typedef Filter_iterator<
@ -355,7 +374,7 @@ public:
Facet_iterator_not_in_complex(*this),
tr_.finite_facets_begin());
}
/// Returns a Facets_in_complex_iterator to the first facet of the 2D complex
Facets_in_complex_iterator
facets_in_complex_begin(const Surface_patch_index& index) const
@ -410,7 +429,7 @@ public:
Cell_not_in_complex(*this),
tr_.finite_cells_begin());
}
/// Returns a \c Cells_in_complex_iterator to the first cell of the 3D complex
Cells_in_complex_iterator
cells_in_complex_begin(const Subdomain_index& index) const
@ -426,7 +445,7 @@ public:
return CGAL::filter_iterator(tr_.finite_cells_end(),
Cell_not_in_complex(*this));
}
// -----------------------------------
// Backward Compatibility
// -----------------------------------
@ -435,30 +454,30 @@ public:
void set_surface_index(const Facet& f, const Surface_index& index)
{ set_surface_patch_index(f, index); }
void set_surface_index(const Cell_handle& c, const int i, const Surface_index& index)
{ set_surface_patch_index(c,i,index); }
Surface_index surface_index(const Facet& f) const
{ return surface_patch_index(f); }
Surface_index surface_index(const Cell_handle& c, const int i) const
{ return surface_patch_index(c,i); }
#endif // CGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX
#ifndef CGAL_MESH_3_NO_DEPRECATED_C3T3_ITERATORS
typedef Facets_in_complex_iterator Facet_iterator;
typedef Cells_in_complex_iterator Cell_iterator;
Facet_iterator facets_begin() const
{ return facets_in_complex_begin(); }
Facet_iterator facets_end() const
{ return facets_in_complex_end(); }
Cell_iterator cells_begin() const
{ return cells_in_complex_begin(); }
Cell_iterator cells_end() const
{ return cells_in_complex_end(); }
#endif // CGAL_MESH_3_NO_DEPRECATED_C3T3_ITERATORS
@ -473,11 +492,11 @@ public:
{ return number_of_cells_in_complex(); }
public:
template <typename Tr2>
template <typename Tr2, typename Ct2>
friend
std::istream &
operator>> (std::istream& is,
Mesh_complex_3_in_triangulation_3_base<Tr2> &c3t3);
std::istream &
operator>> (std::istream& is,
Mesh_complex_3_in_triangulation_3_base<Tr2,Ct2> &c3t3);
static
std::string io_signature()
@ -486,17 +505,34 @@ public:
Get_io_signature<Tr>()();
}
private:
// Private date members
size_type number_of_facets_;
Triangulation tr_;
size_type number_of_cells_;
// Sequential: non-atomic
// "dummy" is here to allow the specialization (see below)
// See http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/285ab1eec49e1cb6
template<typename Concurrency_tag2, typename dummy = void>
struct Number_of_elements
{
typedef size_type type;
};
#ifdef CGAL_LINKED_WITH_TBB
// Parallel: atomic
template<typename dummy>
struct Number_of_elements<Parallel_tag, dummy>
{
typedef tbb::atomic<size_type> type;
};
#endif // CGAL_LINKED_WITH_TBB
// Private date members
Triangulation tr_;
typename Number_of_elements<Concurrency_tag>::type number_of_facets_;
typename Number_of_elements<Concurrency_tag>::type number_of_cells_;
}; // end class Mesh_complex_3_in_triangulation_3_base
template <typename Tr>
template <typename Tr, typename Ct>
void
Mesh_complex_3_in_triangulation_3_base<Tr>::add_to_complex(
Mesh_complex_3_in_triangulation_3_base<Tr,Ct>::add_to_complex(
const Cell_handle& cell,
const int i,
const Surface_patch_index& index)
@ -513,9 +549,9 @@ Mesh_complex_3_in_triangulation_3_base<Tr>::add_to_complex(
}
template <typename Tr>
template <typename Tr, typename Ct>
void
Mesh_complex_3_in_triangulation_3_base<Tr>::remove_from_complex(const Facet& facet)
Mesh_complex_3_in_triangulation_3_base<Tr,Ct>::remove_from_complex(const Facet& facet)
{
if ( is_in_complex(facet) )
{
@ -525,46 +561,46 @@ Mesh_complex_3_in_triangulation_3_base<Tr>::remove_from_complex(const Facet& fac
--number_of_facets_;
}
}
// -----------------------------------
// Undocumented
// -----------------------------------
template <typename Tr>
template <typename Tr, typename Ct>
Bbox_3
Mesh_complex_3_in_triangulation_3_base<Tr>::
Mesh_complex_3_in_triangulation_3_base<Tr,Ct>::
bbox() const
{
if ( 0 == triangulation().number_of_vertices() )
{
return Bbox_3();
}
typename Tr::Finite_vertices_iterator vit = tr_.finite_vertices_begin();
Bbox_3 result = (vit++)->point().bbox();
for(typename Tr::Finite_vertices_iterator end = tr_.finite_vertices_end();
vit != end ; ++vit)
{
result = result + vit->point().bbox();
}
return result;
}
template < class Tr>
std::ostream &
operator<< (std::ostream& os,
const Mesh_complex_3_in_triangulation_3_base<Tr> &c3t3)
template <typename Tr, typename Ct>
std::ostream &
operator<< (std::ostream& os,
const Mesh_complex_3_in_triangulation_3_base<Tr,Ct> &c3t3)
{
return os << c3t3.triangulation();
}
template < class Tr>
std::istream &
operator>> (std::istream& is,
Mesh_complex_3_in_triangulation_3_base<Tr> &c3t3)
template <typename Tr, typename Ct>
std::istream &
operator>> (std::istream& is,
Mesh_complex_3_in_triangulation_3_base<Tr,Ct> &c3t3)
{
c3t3.clear();
is >> c3t3.triangulation();
@ -574,20 +610,20 @@ operator>> (std::istream& is,
return is;
}
for(typename Tr::Finite_facets_iterator
for(typename Tr::Finite_facets_iterator
fit = c3t3.triangulation().finite_facets_begin(),
end = c3t3.triangulation().finite_facets_end();
fit != end; ++fit)
fit != end; ++fit)
{
if ( c3t3.is_in_complex(*fit) ) {
++c3t3.number_of_facets_;
}
}
for(typename Tr::Finite_cells_iterator
for(typename Tr::Finite_cells_iterator
cit = c3t3.triangulation().finite_cells_begin(),
end = c3t3.triangulation().finite_cells_end();
cit != end; ++cit)
cit != end; ++cit)
{
if ( c3t3.is_in_complex(cit) ) {
++c3t3.number_of_cells_;

File diff suppressed because it is too large Load Diff

View File

@ -26,16 +26,70 @@
#ifndef CGAL_MESH_3_MESH_SIZING_FIELD_H
#define CGAL_MESH_3_MESH_SIZING_FIELD_H
#ifdef CGAL_LINKED_WITH_TBB
# include <tbb/enumerable_thread_specific.h>
#endif
namespace CGAL {
namespace Mesh_3
{
/**
* @class Mesh_sizing_field_base
*/
// Sequential
template <typename Cell_handle, typename Concurrency_tag>
class Mesh_sizing_field_base
{
protected:
Cell_handle get_last_cell() const
{
return last_cell_;
}
void set_last_cell(Cell_handle c) const
{
last_cell_ = c;
}
private:
/// A cell that is used to accelerate location queries
mutable Cell_handle last_cell_;
};
#ifdef CGAL_LINKED_WITH_TBB
/**
* @class Mesh_sizing_field_base specialization
*/
// Parallel
template <typename Cell_handle>
class Mesh_sizing_field_base<Cell_handle, Parallel_tag>
{
protected:
Cell_handle get_last_cell() const
{
return last_cell_.local();
}
void set_last_cell(Cell_handle c) const
{
last_cell_.local() = c;
}
private:
/// A cell that is used to accelerate location queries
mutable tbb::enumerable_thread_specific<Cell_handle> last_cell_;
};
#endif // CGAL_LINKED_WITH_TBB
/**
* @class Mesh_sizing_field
*/
template <typename Tr, bool Need_vertex_update = true>
class Mesh_sizing_field
: public Mesh_sizing_field_base<typename Tr::Cell_handle,
typename Tr::Concurrency_tag>
{
// Types
typedef typename Tr::Geom_traits Gt;
@ -44,91 +98,88 @@ class Mesh_sizing_field
typedef typename Tr::Vertex_handle Vertex_handle;
typedef typename Tr::Cell_handle Cell_handle;
public:
// update vertices of mesh triangulation ?
// update vertices of mesh triangulation ?
static const bool is_vertex_update_needed = Need_vertex_update;
public:
/**
* Constructor
*/
Mesh_sizing_field(Tr& tr);
/**
* Fill sizing field, using size associated to point in \c value_map
*/
void fill(const std::map<Point_3, FT>& value_map);
/**
* Returns size at point \c p.
*/
FT operator()(const Point_3& p) const
{ return this->operator()(p,last_cell_); }
{ return this->operator()(p, this->get_last_cell()); }
/**
* Returns size at point \c p, using \c v to accelerate \c p location
* in triangulation
*/
FT operator()(const Point_3& p, const Vertex_handle& v) const
{ return this->operator()(p,v->cell()); }
/**
* Returns size at point \c p.
*/
FT operator()(const Point_3& p, const Cell_handle& c) const;
/**
* Returns size at point \c p. Assumes that p is the centroid of c.
*/
FT operator()(const Point_3& p, const std::pair<Cell_handle,bool>& c) const;
private:
/**
* Returns size at point \c p, by interpolation into tetrahedron.
*/
FT interpolate_on_cell_vertices(const Point_3& p,
const Cell_handle& cell) const;
/**
* Returns size at point \c p, by interpolation into facet (\c cell is assumed
* to be an infinite cell).
*/
FT interpolate_on_facet_vertices(const Point_3& p,
const Cell_handle& cell) const;
private:
/// The triangulation
Tr& tr_;
/// A cell that is used to accelerate location queries
mutable Cell_handle last_cell_;
};
template <typename Tr, bool B>
Mesh_sizing_field<Tr,B>::
Mesh_sizing_field(Tr& tr)
: tr_(tr)
, last_cell_()
{
}
}
template <typename Tr, bool B>
void
Mesh_sizing_field<Tr,B>::
fill(const std::map<Point_3, FT>& value_map)
{
typedef typename Tr::Finite_vertices_iterator Fvi;
for ( Fvi vit = tr_.finite_vertices_begin() ;
vit != tr_.finite_vertices_end() ;
++ vit )
{
typename std::map<Point_3, FT>::const_iterator find_result =
typename std::map<Point_3, FT>::const_iterator find_result =
value_map.find(vit->point());
if ( find_result != value_map.end() )
{
vit->set_meshing_info(find_result->second);
@ -139,14 +190,14 @@ fill(const std::map<Point_3, FT>& value_map)
vit->set_meshing_info(FT(0));
}
}
}
}
template <typename Tr, bool B>
typename Mesh_sizing_field<Tr,B>::FT
Mesh_sizing_field<Tr,B>::
operator()(const Point_3& p, const Cell_handle& c) const
{
#ifdef CGAL_MESH_3_SIZING_FIELD_INEXACT_LOCATE
operator()(const Point_3& p, const Cell_handle& c) const
{
#ifdef CGAL_MESH_3_SIZING_FIELD_INEXACT_LOCATE
//use the inexact locate (much faster than locate) to get a hint
//and then use locate to check whether p is really inside hint
// if not, an exact locate will be performed
@ -155,8 +206,8 @@ operator()(const Point_3& p, const Cell_handle& c) const
#else
const Cell_handle cell = tr_.locate(p,c);
#endif
last_cell_ = cell;
this->set_last_cell(cell);
if ( !tr_.is_infinite(cell) )
return interpolate_on_cell_vertices(p,cell);
else
@ -171,17 +222,17 @@ operator()(const Point_3&, const std::pair<Cell_handle,bool>& c) const
{
// Assumes that p is the centroid of c
const Cell_handle& cell = c.first;
// Interpolate value using tet vertices values
const FT& va = cell->vertex(0)->meshing_info();
const FT& vb = cell->vertex(1)->meshing_info();
const FT& vc = cell->vertex(2)->meshing_info();
const FT& vd = cell->vertex(3)->meshing_info();
return ( (va+vb+vc+vd)/4 );
}
template <typename Tr, bool B>
typename Mesh_sizing_field<Tr,B>::FT
Mesh_sizing_field<Tr,B>::
@ -189,32 +240,32 @@ interpolate_on_cell_vertices(const Point_3& p, const Cell_handle& cell) const
{
typename Gt::Compute_volume_3 volume =
Gt().compute_volume_3_object();
// Interpolate value using tet vertices values
const FT& va = cell->vertex(0)->meshing_info();
const FT& vb = cell->vertex(1)->meshing_info();
const FT& vc = cell->vertex(2)->meshing_info();
const FT& vd = cell->vertex(3)->meshing_info();
const Point_3& a = cell->vertex(0)->point();
const Point_3& b = cell->vertex(1)->point();
const Point_3& c = cell->vertex(2)->point();
const Point_3& d = cell->vertex(3)->point();
const FT abcp = CGAL::abs(volume(a,b,c,p));
const FT abdp = CGAL::abs(volume(a,d,b,p));
const FT acdp = CGAL::abs(volume(a,c,d,p));
const FT bcdp = CGAL::abs(volume(b,d,c,p));
// If volume is 0, then compute the average value
if ( is_zero(abcp+abdp+acdp+bcdp) )
return (va+vb+vc+vd)/4.;
return ( (abcp*vd + abdp*vc + acdp*vb + bcdp*va) / (abcp+abdp+acdp+bcdp) );
}
template <typename Tr, bool B>
typename Mesh_sizing_field<Tr,B>::FT
Mesh_sizing_field<Tr,B>::
@ -222,44 +273,44 @@ interpolate_on_facet_vertices(const Point_3& p, const Cell_handle& cell) const
{
typename Gt::Compute_area_3 area =
Gt().compute_area_3_object();
// Find infinite vertex and put it in k0
int k0 = 0;
int k1 = 1;
int k2 = 2;
int k3 = 3;
if ( tr_.is_infinite(cell->vertex(1)) )
std::swap(k0,k1);
if ( tr_.is_infinite(cell->vertex(2)) )
std::swap(k0,k2);
if ( tr_.is_infinite(cell->vertex(3)) )
std::swap(k0,k3);
// Interpolate value using tet vertices values
const FT& va = cell->vertex(k1)->meshing_info();
const FT& vb = cell->vertex(k2)->meshing_info();
const FT& vc = cell->vertex(k3)->meshing_info();
const Point_3& a = cell->vertex(k1)->point();
const Point_3& b = cell->vertex(k2)->point();
const Point_3& c = cell->vertex(k3)->point();
const FT abp = area(a,b,p);
const FT acp = area(a,c,p);
const FT bcp = area(b,c,p);
CGAL_assertion(abp >= 0);
CGAL_assertion(acp >= 0);
CGAL_assertion(bcp >= 0);
// If area is 0, then compute the average value
if ( is_zero(abp+acp+bcp) )
return (va+vb+vc)/3.;
return ( (abp*vc + acp*vb + bcp*va ) / (abp+acp+bcp) );
}
} // end namespace Mesh_3

View File

@ -31,6 +31,10 @@
#include <CGAL/Regular_triangulation_cell_base_3.h>
#include <CGAL/Mesh_3/io_signature.h>
#ifdef CGAL_LINKED_WITH_TBB
# include <tbb/atomic.h>
#endif
#ifdef _MSC_VER
// Kill warning "C4351: new behavior: elements of array
// 'CGAL::Mesh_3::Mesh_surface_cell_base_3<GT,MT,Cb>::surface_index_table_'
@ -42,78 +46,20 @@ namespace CGAL {
namespace Mesh_3 {
/************************************************
// Class Mesh_surface_cell_base_3_base
// Two versions: sequential / parallel
************************************************/
/**
* @class Mesh_surface_cell_base_3
*/
template <class GT,
class MT,
class Cb = CGAL::Regular_triangulation_cell_base_3<GT> >
class Mesh_surface_cell_base_3
: public Cb
// Sequential
template <typename Concurrency_tag>
class Mesh_surface_cell_base_3_base
{
public:
// Indices
typedef typename MT::Surface_patch_index Surface_patch_index;
typedef typename MT::Index Index;
// Triangulation types
typedef typename Cb::Triangulation_data_structure Tds;
typedef typename Tds::Vertex_handle Vertex_handle;
typedef typename Tds::Cell_handle Cell_handle;
typedef typename GT::Point_3 Point;
// To get correct cell type in TDS
template < class TDS3 >
struct Rebind_TDS
{
typedef typename Cb::template Rebind_TDS<TDS3>::Other Cb3;
typedef Mesh_surface_cell_base_3 <GT, MT, Cb3> Other;
};
/// Constructors
Mesh_surface_cell_base_3()
: Cb()
, surface_index_table_()
, surface_center_table_()
, bits_(0) { }
Mesh_surface_cell_base_3(Vertex_handle v0, Vertex_handle v1,
Vertex_handle v2, Vertex_handle v3)
: Cb (v0, v1, v2, v3)
, surface_index_table_()
, surface_center_table_()
, bits_(0) { }
Mesh_surface_cell_base_3(Vertex_handle v0, Vertex_handle v1,
Vertex_handle v2, Vertex_handle v3,
Cell_handle n0, Cell_handle n1,
Cell_handle n2, Cell_handle n3)
: Cb (v0, v1, v2, v3, n0, n1, n2, n3)
, surface_index_table_()
, surface_center_table_()
, bits_(0) { }
/// Destructor
~Mesh_surface_cell_base_3() { }
// Default copy constructor and assignment operator are ok
/// Set surface index of \c facet to \c index
void set_surface_patch_index(const int facet, const Surface_patch_index& index)
{
CGAL_precondition(facet>=0 && facet<4);
surface_index_table_[facet] = index;
}
/// Returns surface index of facet \c facet
Surface_patch_index surface_patch_index(const int facet) const
{
CGAL_precondition(facet>=0 && facet<4);
return surface_index_table_[facet];
}
Mesh_surface_cell_base_3_base()
: bits_(0) {}
/// Marks \c facet as visited
void set_facet_visited (const int facet)
{
@ -135,6 +81,131 @@ public:
return ( (bits_ & (1 << facet)) != 0 );
}
protected:
/// Stores visited facets (4 first bits)
char bits_;
};
#ifdef CGAL_LINKED_WITH_TBB
// Parallel
template<>
class Mesh_surface_cell_base_3_base<Parallel_tag>
{
public:
Mesh_surface_cell_base_3_base()
{
bits_ = 0;
}
/// Marks \c facet as visited
void set_facet_visited (const int facet)
{
CGAL_precondition(facet>=0 && facet<4);
char current_bits = bits_;
while (bits_.compare_and_swap(current_bits | (1 << facet), current_bits) != current_bits)
{
current_bits = bits_;
}
}
/// Marks \c facet as not visited
void reset_visited (const int facet)
{
CGAL_precondition(facet>=0 && facet<4);
char current_bits = bits_;
while (bits_.compare_and_swap(current_bits & (15 & ~(1 << facet)), current_bits) != current_bits)
{
current_bits = bits_;
}
}
/// Returns \c true if \c facet is marked as visited
bool is_facet_visited (const int facet) const
{
CGAL_precondition(facet>=0 && facet<4);
return ( (bits_ & (1 << facet)) != 0 );
}
protected:
/// Stores visited facets (4 first bits)
tbb::atomic<char> bits_;
};
#endif // CGAL_LINKED_WITH_TBB
/**
* @class Mesh_surface_cell_base_3
*/
template <class GT,
class MT,
class Cb>
class Mesh_surface_cell_base_3
: public Mesh_surface_cell_base_3_base<
typename Cb::Triangulation_data_structure::Concurrency_tag>
, public Cb
{
public:
// Indices
typedef typename MT::Surface_patch_index Surface_patch_index;
typedef typename MT::Index Index;
// Triangulation types
typedef typename Cb::Triangulation_data_structure Tds;
typedef typename Tds::Vertex_handle Vertex_handle;
typedef typename Tds::Cell_handle Cell_handle;
typedef typename GT::Point_3 Point;
// To get correct cell type in TDS
template < class TDS3 >
struct Rebind_TDS
{
typedef typename Cb::template Rebind_TDS<TDS3>::Other Cb3;
typedef Mesh_surface_cell_base_3 <GT, MT, Cb3> Other;
};
/// Constructors
Mesh_surface_cell_base_3()
: Cb()
, surface_index_table_()
, surface_center_table_()
{ }
Mesh_surface_cell_base_3(Vertex_handle v0, Vertex_handle v1,
Vertex_handle v2, Vertex_handle v3)
: Cb (v0, v1, v2, v3)
, surface_index_table_()
, surface_center_table_()
{ }
Mesh_surface_cell_base_3(Vertex_handle v0, Vertex_handle v1,
Vertex_handle v2, Vertex_handle v3,
Cell_handle n0, Cell_handle n1,
Cell_handle n2, Cell_handle n3)
: Cb (v0, v1, v2, v3, n0, n1, n2, n3)
, surface_index_table_()
, surface_center_table_()
{ }
/// Destructor
~Mesh_surface_cell_base_3() { }
// Default copy constructor and assignment operator are ok
/// Set surface index of \c facet to \c index
void set_surface_patch_index(const int facet, const Surface_patch_index& index)
{
CGAL_precondition(facet>=0 && facet<4);
surface_index_table_[facet] = index;
}
/// Returns surface index of facet \c facet
Surface_patch_index surface_patch_index(const int facet) const
{
CGAL_precondition(facet>=0 && facet<4);
return surface_index_table_[facet];
}
/// Sets surface center of \c facet to \c point
void set_facet_surface_center(const int facet, const Point& point)
{
@ -201,8 +272,6 @@ private:
Point surface_center_table_[4];
/// Stores surface center index of each facet of the cell
Index surface_center_index_table_[4];
/// Stores visited facets (4 first bits)
char bits_;
}; // end class Mesh_surface_cell_base_3

View File

@ -35,51 +35,150 @@
#include<CGAL/Mesh_3/Refine_cells_3.h>
#include <CGAL/Mesh_3/Refine_tets_visitor.h>
#include <CGAL/Mesher_level_visitors.h>
#include <CGAL/Kernel_traits.h>
#ifdef CGAL_MESH_3_USE_OLD_SURFACE_RESTRICTED_DELAUNAY_UPDATE
#include <CGAL/Surface_mesher/Surface_mesher_visitor.h>
#endif
#include <CGAL/Mesh_3/Concurrent_mesher_config.h>
#include <CGAL/Timer.h>
#ifdef CGAL_MESH_3_PROFILING
#include <CGAL/Mesh_3/Profiling_tools.h>
#endif
#ifdef CGAL_LINKED_WITH_TBB
# if TBB_IMPLEMENT_CPP0X
# include <tbb/compat/thread>
# else
# include <thread>
# endif
#endif
#include <boost/format.hpp>
#include <boost/thread.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <string>
namespace CGAL {
namespace Mesh_3 {
// Class Mesher_3
//
/************************************************
// Class Mesher_3_base
// Two versions: sequential / parallel
************************************************/
// Sequential
template <typename Tr, typename Concurrency_tag>
class Mesher_3_base
{
protected:
typedef typename Tr::Lock_data_structure Lock_data_structure;
Mesher_3_base(const Bbox_3 &, int) {}
Lock_data_structure *get_lock_data_structure() { return 0; }
WorksharingDataStructureType *get_worksharing_data_structure() { return 0; }
void set_bbox(const Bbox_3 &) {}
};
#ifdef CGAL_LINKED_WITH_TBB
// Parallel
template <typename Tr>
class Mesher_3_base<Tr, Parallel_tag>
{
protected:
typedef typename Tr::Lock_data_structure Lock_data_structure;
Mesher_3_base(const Bbox_3 &bbox, int num_grid_cells_per_axis)
: m_lock_ds(bbox, num_grid_cells_per_axis),
m_worksharing_ds(bbox)
{}
Lock_data_structure *get_lock_data_structure()
{
return &m_lock_ds;
}
WorksharingDataStructureType *get_worksharing_data_structure()
{
return &m_worksharing_ds;
}
void set_bbox(const Bbox_3 &bbox)
{
m_lock_ds.set_bbox(bbox);
m_worksharing_ds.set_bbox(bbox);
}
/// Lock data structure
Lock_data_structure m_lock_ds;
/// Worksharing data structure
WorksharingDataStructureType m_worksharing_ds;
};
#endif // CGAL_LINKED_WITH_TBB
/************************************************
*
* Mesher_3 class
*
************************************************/
template<class C3T3, class MeshCriteria, class MeshDomain>
class Mesher_3
: public Mesher_3_base<
typename C3T3::Triangulation,
#ifdef CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT
Sequential_tag
#else
typename C3T3::Concurrency_tag
#endif
>
{
public:
#ifdef CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT
typedef Sequential_tag Concurrency_tag;
#else
typedef typename C3T3::Concurrency_tag Concurrency_tag;
#endif
typedef typename C3T3::Triangulation Triangulation;
typedef typename Triangulation::Point Point;
typedef typename Kernel_traits<Point>::Kernel Kernel;
typedef typename Kernel::Vector_3 Vector;
typedef typename MeshDomain::Index Index;
// Self
typedef Mesher_3<C3T3, MeshCriteria, MeshDomain> Self;
typedef typename C3T3::Triangulation Triangulation;
typedef Mesher_3<C3T3, MeshCriteria, MeshDomain> Self;
#ifdef CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT
typedef Mesher_3_base<Triangulation, Sequential_tag> Base;
#else
typedef Mesher_3_base<Triangulation, typename C3T3::Concurrency_tag> Base;
#endif
using Base::get_lock_data_structure;
//-------------------------------------------------------
// Mesher_levels
//-------------------------------------------------------
/// Facets mesher level
typedef Mesh_3::Refine_facets_3<
typedef Refine_facets_3<
Triangulation,
typename MeshCriteria::Facet_criteria,
MeshDomain,
C3T3,
Null_mesher_level> Facets_level;
Null_mesher_level,
Concurrency_tag> Facets_level;
/// Cells mesher level
typedef Mesh_3::Refine_cells_3<
typedef Refine_cells_3<
Triangulation,
typename MeshCriteria::Cell_criteria,
MeshDomain,
C3T3,
Facets_level> Cells_level;
Facets_level,
Concurrency_tag> Cells_level;
//-------------------------------------------------------
// Visitors
//-------------------------------------------------------
@ -88,7 +187,7 @@ public:
Triangulation,
Cells_level,
Null_mesh_visitor> Facets_visitor;
#ifndef CGAL_MESH_3_USE_OLD_SURFACE_RESTRICTED_DELAUNAY_UPDATE
/// Cells visitor : it just need to know previous level
typedef Null_mesh_visitor_level<Facets_visitor> Cells_visitor;
@ -105,67 +204,74 @@ public:
Mesher_3(C3T3& c3t3,
const MeshDomain& domain,
const MeshCriteria& criteria);
/// Destructor
~Mesher_3() { }
/// Launch mesh refinement
double refine_mesh(std::string dump_after_refine_surface_prefix = "");
/// Debug
std::string debug_info() const;
std::string debug_info_header() const;
// Step-by-step methods
void initialize();
void fix_c3t3();
void display_number_of_bad_elements();
void one_step();
bool is_algorithm_done();
#ifdef CGAL_MESH_3_MESHER_STATUS_ACTIVATED
struct Mesher_status
{
{
std::size_t vertices, facet_queue, cells_queue;
Mesher_status(std::size_t v, std::size_t f, std::size_t c)
: vertices(v), facet_queue(f), cells_queue(c) {}
};
Mesher_status status() const;
#endif
private:
void remove_cells_from_c3t3();
private:
/// The oracle
const MeshDomain& r_oracle_;
/// Meshers
Null_mesher_level null_mesher_;
Facets_level facets_mesher_;
Cells_level cells_mesher_;
/// Visitors
Null_mesh_visitor null_visitor_;
Facets_visitor facets_visitor_;
Cells_visitor cells_visitor_;
/// The container of the resulting mesh
C3T3& r_c3t3_;
private:
// Disabled copy constructor
Mesher_3(const Self& src);
// Disabled assignment operator
Self& operator=(const Self& src);
}; // end class Mesher_3
template<class C3T3, class MC, class MD>
Mesher_3<C3T3,MC,MD>::Mesher_3(C3T3& c3t3,
const MD& domain,
const MC& criteria)
: null_mesher_()
: Base(c3t3.bbox(),
Concurrent_mesher_config::get().locking_grid_num_cells_per_axis)
, r_oracle_(domain)
, null_mesher_()
, facets_mesher_(c3t3.triangulation(),
criteria.facet_criteria_object(),
domain,
@ -185,6 +291,10 @@ Mesher_3<C3T3,MC,MD>::Mesher_3(C3T3& c3t3,
#endif
, r_c3t3_(c3t3)
{
facets_mesher_.set_lock_ds(this->get_lock_data_structure());
facets_mesher_.set_worksharing_ds(this->get_worksharing_data_structure());
cells_mesher_.set_lock_ds(this->get_lock_data_structure());
cells_mesher_.set_worksharing_ds(this->get_worksharing_data_structure());
}
@ -196,15 +306,42 @@ Mesher_3<C3T3,MC,MD>::refine_mesh(std::string dump_after_refine_surface_prefix)
CGAL::Timer timer;
timer.start();
double elapsed_time = 0.;
// First surface mesh could modify c3t3 without notifying cells_mesher
// So we have to ensure that no old cell will be left in c3t3
remove_cells_from_c3t3();
#ifndef CGAL_MESH_3_VERBOSE
// Scan surface and refine it
facets_mesher_.scan_triangulation();
initialize();
#ifdef CGAL_MESH_3_PROFILING
std::cerr << "Refining facets..." << std::endl;
WallClockTimer t;
#endif
facets_mesher_.refine(facets_visitor_);
#ifdef CGAL_MESH_3_PROFILING
double facet_ref_time = t.elapsed();
std::cerr << "==== Facet refinement: " << facet_ref_time << " seconds ===="
<< 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_time", facet_ref_time);
# endif
# endif
#endif
#if defined(CHECK_AND_DISPLAY_THE_NUMBER_OF_BAD_ELEMENTS_IN_THE_END)
std::cerr << std::endl
<< "===============================================================" << std::endl
<< "=== CHECK_AND_DISPLAY_THE_NUMBER_OF_BAD_ELEMENTS_IN_THE_END ===" << std::endl;
display_number_of_bad_elements();
std::cerr
<< "==============================================================="
<< std::endl << std::endl;
#endif
// Then activate facet to surface visitor (surface could be
// refined again if it is encroached)
@ -214,26 +351,50 @@ Mesher_3<C3T3,MC,MD>::refine_mesh(std::string dump_after_refine_surface_prefix)
// Then scan volume and refine it
cells_mesher_.scan_triangulation();
#ifdef CGAL_MESH_3_PROFILING
std::cerr << "Refining cells..." << std::endl;
t.reset();
#endif
cells_mesher_.refine(cells_visitor_);
#else // if defined(CGAL_MESH_3_VERBOSE)
#ifdef CGAL_MESH_3_PROFILING
double cell_ref_time = t.elapsed();
std::cerr << "==== Cell refinement: " << cell_ref_time << " seconds ===="
<< 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("Cells_refin_time", cell_ref_time);
# endif
# endif
#endif
#if defined(CGAL_MESH_3_VERBOSE) || defined(CGAL_MESH_3_PROFILING)
std::cerr
<< "Vertices: " << r_c3t3_.triangulation().number_of_vertices() << std::endl
<< "Facets : " << r_c3t3_.number_of_facets_in_complex() << std::endl
<< "Tets : " << r_c3t3_.number_of_cells_in_complex() << std::endl;
#endif
#else // ifdef CGAL_MESH_3_VERBOSE
std::cerr << "Start surface scan...";
facets_mesher_.scan_triangulation();
initialize();
std::cerr << "end scan. [Bad facets:" << facets_mesher_.size() << "]";
std::cerr << std::endl << std::endl;
elapsed_time += timer.time();
timer.stop(); timer.reset(); timer.start();
const Triangulation& r_tr = r_c3t3_.triangulation();
int nbsteps = 0;
std::cerr << "Refining Surface...\n";
std::cerr << "Legende of the following line: "
std::cerr << "Legend of the following line: "
<< "(#vertices,#steps," << cells_mesher_.debug_info_header()
<< ")\n";
std::cerr << "(" << r_tr.number_of_vertices() << ","
<< nbsteps << "," << cells_mesher_.debug_info() << ")";
while ( ! facets_mesher_.is_algorithm_done() )
{
facets_mesher_.one_step(facets_visitor_);
@ -252,7 +413,7 @@ Mesher_3<C3T3,MC,MD>::refine_mesh(std::string dump_after_refine_surface_prefix)
elapsed_time += timer.time();
timer.stop(); timer.reset(); timer.start();
nbsteps = 0;
facets_visitor_.activate();
dump_c3t3(r_c3t3_, dump_after_refine_surface_prefix);
std::cerr << "Start volume scan...";
@ -261,9 +422,9 @@ Mesher_3<C3T3,MC,MD>::refine_mesh(std::string dump_after_refine_surface_prefix)
std::cerr << std::endl << std::endl;
elapsed_time += timer.time();
timer.stop(); timer.reset(); timer.start();
std::cerr << "Refining...\n";
std::cerr << "Legende of the following line: "
std::cerr << "Legend of the following line: "
<< "(#vertices,#steps," << cells_mesher_.debug_info_header()
<< ")\n";
std::cerr << "(" << r_tr.number_of_vertices() << ","
@ -286,9 +447,21 @@ Mesher_3<C3T3,MC,MD>::refine_mesh(std::string dump_after_refine_surface_prefix)
std::cerr << "Total refining time: " << timer.time()+elapsed_time << "s" << std::endl;
std::cerr << std::endl;
#endif
timer.stop();
elapsed_time += timer.time();
#if defined(CHECK_AND_DISPLAY_THE_NUMBER_OF_BAD_ELEMENTS_IN_THE_END) \
|| defined(SHOW_REMAINING_BAD_ELEMENT_IN_RED)
std::cerr << std::endl
<< "===============================================================" << std::endl
<< "=== CHECK_AND_DISPLAY_THE_NUMBER_OF_BAD_ELEMENTS_IN_THE_END ===" << std::endl;
display_number_of_bad_elements();
std::cerr
<< "==============================================================="
<< std::endl << std::endl;
#endif
return elapsed_time;
}
@ -298,7 +471,138 @@ void
Mesher_3<C3T3,MC,MD>::
initialize()
{
facets_mesher_.scan_triangulation();
#ifdef CGAL_MESH_3_PROFILING
std::cerr << "Initializing... ";
WallClockTimer t;
#endif
//=====================================
// Bounding box estimation
//=====================================
typedef std::vector<std::pair<Point, Index> > Points_vector;
Points_vector random_points_on_surface;
r_oracle_.construct_initial_points_object()(
std::back_inserter(random_points_on_surface), 1000);
typename Points_vector::const_iterator
it = random_points_on_surface.begin(),
it_end = random_points_on_surface.end();
Bbox_3 estimated_bbox = it->first.bbox();
++it;
for( ; it != it_end ; ++it)
estimated_bbox = estimated_bbox + it->first.bbox();
Base::set_bbox(estimated_bbox);
//========================================
// Initialization: parallel or sequential
//========================================
#ifdef CGAL_LINKED_WITH_TBB
// Parallel
if (boost::is_convertible<Concurrency_tag, Parallel_tag>::value)
{
// we're not multi-thread, yet
r_c3t3_.triangulation().set_lock_data_structure(0);
# ifndef CGAL_PARALLEL_MESH_3_DO_NOT_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE
if (r_c3t3_.number_of_facets() == 0)
{
const Bbox_3 &bbox = estimated_bbox;
// Compute radius for far sphere
const double& xdelta = bbox.xmax()-bbox.xmin();
const double& ydelta = bbox.ymax()-bbox.ymin();
const double& zdelta = bbox.zmax()-bbox.zmin();
const double radius = 1.3 * 0.5 * std::sqrt(xdelta*xdelta +
ydelta*ydelta +
zdelta*zdelta);
const Vector center(
bbox.xmin() + 0.5*xdelta,
bbox.ymin() + 0.5*ydelta,
bbox.zmin() + 0.5*zdelta);
# ifdef CGAL_CONCURRENT_MESH_3_VERBOSE
std::cerr << "Adding points on a far sphere (radius = " << radius <<")...";
# endif
Random_points_on_sphere_3<Point> random_point(radius);
const int NUM_PSEUDO_INFINITE_VERTICES = static_cast<int>(
boost::thread::hardware_concurrency()
* Concurrent_mesher_config::get().num_pseudo_infinite_vertices_per_core);
for (int i = 0 ; i < NUM_PSEUDO_INFINITE_VERTICES ; ++i, ++random_point)
r_c3t3_.triangulation().insert(*random_point + center);
# ifdef CGAL_CONCURRENT_MESH_3_VERBOSE
std::cerr << "done." << std::endl;
# endif
}
# endif // CGAL_PARALLEL_MESH_3_DO_NOT_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE
#ifdef CGAL_MESH_3_PROFILING
double init_time = t.elapsed();
std::cerr << "done in " << init_time << " seconds." << std::endl;
#endif
// Scan triangulation
facets_mesher_.scan_triangulation();
// From now on, we're multi-thread
r_c3t3_.triangulation().set_lock_data_structure(get_lock_data_structure());
}
// Sequential
else
#endif // CGAL_LINKED_WITH_TBB
{
#ifdef CGAL_SEQUENTIAL_MESH_3_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE
if (r_c3t3_.number_of_facets() == 0)
{
/*std::cerr << "A little bit of refinement... ";
// Start by a little bit of refinement to get a coarse mesh
// => Good approx of bounding box
const int NUM_VERTICES_OF_COARSE_MESH = 40;
facets_mesher_.refine_sequentially_up_to_N_vertices(
facets_visitor_, NUM_VERTICES_OF_COARSE_MESH);
std::cerr << "done." << std::endl;
std::cerr
<< "Vertices: " << r_c3t3_.triangulation().number_of_vertices() << std::endl
<< "Facets : " << r_c3t3_.number_of_facets_in_complex() << std::endl
<< "Tets : " << r_c3t3_.number_of_cells_in_complex() << std::endl;*/
// Compute radius for far sphere
//const Bbox_3 &bbox = r_c3t3_.bbox();
const Bbox_3 &bbox = estimated_bbox;
const double& xdelta = bbox.xmax()-bbox.xmin();
const double& ydelta = bbox.ymax()-bbox.ymin();
const double& zdelta = bbox.zmax()-bbox.zmin();
const double radius = 1.3 * 0.5 * std::sqrt(xdelta*xdelta +
ydelta*ydelta +
zdelta*zdelta);
const Vector center(
bbox.xmin() + 0.5*xdelta,
bbox.ymin() + 0.5*ydelta,
bbox.zmin() + 0.5*zdelta);
# ifdef CGAL_MESH_3_VERBOSE
std::cerr << "Adding points on a far sphere (radius = " << radius << ")...";
# endif
Random_points_on_sphere_3<Point> random_point(radius);
const int NUM_PSEUDO_INFINITE_VERTICES = 12*2;
for (int i = 0 ; i < NUM_PSEUDO_INFINITE_VERTICES ; ++i, ++random_point)
r_c3t3_.triangulation().insert(*random_point + center);
# ifdef CGAL_MESH_3_VERBOSE
std::cerr << "done." << std::endl;
# endif
}
#endif // CGAL_SEQUENTIAL_MESH_3_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE
#ifdef CGAL_MESH_3_PROFILING
double init_time = t.elapsed();
std::cerr << "done in " << init_time << " seconds." << std::endl;
#endif
// Scan triangulation
facets_mesher_.scan_triangulation();
}
}
@ -309,11 +613,21 @@ fix_c3t3()
{
if ( ! facets_visitor_.is_active() )
{
cells_mesher_.scan_triangulation();
cells_mesher_.scan_triangulation();
}
}
template<class C3T3, class MC, class MD>
void
Mesher_3<C3T3,MC,MD>::
display_number_of_bad_elements()
{
int nf = facets_mesher_.number_of_bad_elements();
int nc = cells_mesher_.number_of_bad_elements();
std::cerr << "Bad facets: " << nf << " - Bad cells: " << nc << std::endl;
}
template<class C3T3, class MC, class MD>
void
Mesher_3<C3T3,MC,MD>::
@ -322,7 +636,7 @@ one_step()
if ( ! facets_visitor_.is_active() )
{
facets_mesher_.one_step(facets_visitor_);
if ( facets_mesher_.is_algorithm_done() )
{
facets_visitor_.activate();
@ -331,10 +645,10 @@ one_step()
}
else
{
cells_mesher_.one_step(cells_visitor_);
cells_mesher_.one_step(cells_visitor_);
}
}
template<class C3T3, class MC, class MD>
bool
Mesher_3<C3T3,MC,MD>::
@ -353,7 +667,7 @@ status() const
return Mesher_status(r_c3t3_.triangulation().number_of_vertices(),
facets_mesher_.queue_size(),
cells_mesher_.queue_size());
}
}
#endif
@ -362,7 +676,7 @@ void
Mesher_3<C3T3,MC,MD>::
remove_cells_from_c3t3()
{
for ( typename C3T3::Triangulation::Finite_cells_iterator
for ( typename C3T3::Triangulation::Finite_cells_iterator
cit = r_c3t3_.triangulation().finite_cells_begin(),
end = r_c3t3_.triangulation().finite_cells_end() ; cit != end ; ++cit )
{
@ -372,22 +686,22 @@ remove_cells_from_c3t3()
template<class C3T3, class MC, class MD>
inline
std::string
std::string
Mesher_3<C3T3,MC,MD>::debug_info() const
{
return cells_mesher_.debug_info();
}
template<class C3T3, class MC, class MD>
inline
std::string
std::string
Mesher_3<C3T3,MC,MD>::debug_info_header() const
{
return cells_mesher_.debug_info_header();
}
} // end namespace Mesh_3
} // end namespace CGAL

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,148 @@
// Copyright (c) 2005 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Laurent RINEAU, Clement JAMIN
#ifndef CGAL_MESH_3_MESHER_LEVEL_DEFAULT_IMPLEMENTATIONS_H
#define CGAL_MESH_3_MESHER_LEVEL_DEFAULT_IMPLEMENTATIONS_H
#include <CGAL/Mesh_3/Mesher_level.h>
namespace CGAL { namespace Mesh_3 {
/** This class implements the two get_triangulation_ref() functions.
\param Tr The triangulation type */
template <class Tr>
class Triangulation_ref_impl
{
Tr& tr;
public:
Triangulation_ref_impl(Tr& t) : tr(t)
{
}
Tr& triangulation_ref_impl()
{
return tr;
}
const Tr& triangulation_ref_impl() const
{
return tr;
}
}; // end class Triangulation_ref_impl<Tr>
/** This struct implements an empty private_test_point_conflict_impl()
function. */
struct No_private_test_point_conflict
{
template <typename Point, typename Zone>
Mesher_level_conflict_status
private_test_point_conflict_impl(const Point&, const Zone&) const
{
return NO_CONFLICT;
}
}; // end No_private_test_point_conflict
/** This struct implements an empty test_point_conflict_from_superior_impl()
function. */
struct No_test_point_conflict_from_superior
{
// For sequential
template <typename Point, typename Zone>
Mesher_level_conflict_status
test_point_conflict_from_superior_impl(const Point&, const Zone&) const
{
return NO_CONFLICT;
}
// For parallel
template <typename Point, typename Zone, typename Mesh_visitor>
Mesher_level_conflict_status
test_point_conflict_from_superior_impl(const Point&, const Zone&,
Mesh_visitor &) const
{
return NO_CONFLICT;
}
}; // end No_test_point_conflict_from_superior
/** This struct implements empty functions:
- private_test_point_conflict_impl() and
- test_point_conflict_from_superior_impl().
*/
struct No_test_point_conflict :
public No_private_test_point_conflict,
public No_test_point_conflict_from_superior
{
};
/** This struct implements an empty before_insertion_impl()
function. */
struct No_before_insertion
{
template <typename Cell_handle, typename Point, typename Zone>
void before_insertion_impl(const Cell_handle&, const Point&,
Zone& )
{
}
}; // end No_before_insertion
/** This struct implements an empty after_insertion_impl()
function. */
struct No_after_insertion
{
template <typename Vertex_handle>
void after_insertion_impl(const Vertex_handle&)
{
}
}; // end No_after_insertion
/** This struct implements an empty after_insertion_impl()
function. */
struct No_after_no_insertion
{
template <typename Cell_handle, typename Point, typename Zone>
void after_no_insertion_impl(const Cell_handle&, const Point&,
const Zone& )
{
}
}; // end No_after_no_insertion
/** This struct implements empty functions:
- before_insertion_impl(),
- after_insertion_impl(),
- after_no_insertion_impl()
*/
struct No_before_after_insertion :
public No_after_insertion,
public No_before_insertion,
public No_after_no_insertion
{
};
/** This struct implements an empty before_conflicts_impl() function. */
struct No_before_conflicts {
template <typename Face_handle, typename Point>
void before_conflicts_impl(const Face_handle&, const Point&)
{
}
};
} } // end namespace CGAL::Mesh_3
#endif // CGAL_MESH_3_MESHER_LEVEL_DEFAULT_IMPLEMENTATIONS_H

View File

@ -113,8 +113,8 @@ public:
return CGAL::NULL_VECTOR;
}
#ifdef CGAL_MESH_3_OPTIMIZER_VERBOSE
#if defined(CGAL_MESH_3_OPTIMIZER_VERBOSE) \
|| defined (CGAL_MESH_3_EXPORT_PERFORMANCE_DATA)
static std::string name() { return std::string("Odt"); }
#endif

View File

@ -0,0 +1,69 @@
// Copyright (c) 2012 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
//
//
// Author(s) : Clement Jamin
//
//******************************************************************************
// File Description :
//******************************************************************************
#ifndef CGAL_MESH_3_PROFILING_TOOLS_H
#define CGAL_MESH_3_PROFILING_TOOLS_H
// TBB timers
#ifdef CGAL_LINKED_WITH_TBB
#include <tbb/tick_count.h>
struct WallClockTimer
{
tbb::tick_count t;
WallClockTimer()
{
t = tbb::tick_count::now();
}
void reset()
{
t = tbb::tick_count::now();
}
double elapsed() const
{
return (tbb::tick_count::now() - t).seconds();
}
};
#else
#include <CGAL/Real_timer.h>
struct WallClockTimer
{
CGAL::Real_timer t;
WallClockTimer()
{
t.start();
}
void reset()
{
t.reset();
}
double elapsed() const
{
return t.time();
}
};
#endif
#endif // CGAL_MESH_3_PROFILING_TOOLS_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -165,7 +165,8 @@ public:
Bare_point operator() ( const Weighted_point_3 & p,
const Weighted_point_3 & q,
const Weighted_point_3 & r,
const Weighted_point_3 & s ) const
const Weighted_point_3 & s,
bool force_exact = false) const
{
CGAL_precondition(Rt().orientation_3_object()(p,q,r,s) == CGAL::POSITIVE);
@ -181,7 +182,7 @@ public:
s.x(), s.y(), s.z(), s.weight(),
num_x, num_y, num_z, den);
if ( ! CGAL_NTS is_zero(den) )
if ( ! force_exact && ! CGAL_NTS is_zero(den) )
{
FT inv = FT(1)/(FT(2) * den);
Bare_point res(p.x() + num_x*inv, p.y() - num_y*inv, p.z() + num_z*inv);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,7 @@
// Author(s) : Stephane Tayeb
//
//******************************************************************************
// File Description :
// File Description :
//******************************************************************************
#ifndef CGAL_MESH_3_TRIANGULATION_HELPERS_H
@ -31,8 +31,8 @@
namespace CGAL {
namespace Mesh_3 {
template<typename Tr>
class Triangulation_helpers
{
@ -41,7 +41,7 @@ class Triangulation_helpers
typedef typename Tr::Vertex_handle Vertex_handle;
typedef typename Tr::Cell_handle Cell_handle;
typedef std::vector<Cell_handle> Cell_vector;
/**
* A functor to reset visited flag of each facet of a cell
*/
@ -53,19 +53,41 @@ class Triangulation_helpers
c->reset_visited(i);
}
};
/**
* A functor to get the point of a vertex vh, but replacing
* it by m_p when vh == m_vh
*/
struct Point_getter
{
/// When the requested will be about vh, the returned point will be p
/// instead of vh->point()
Point_getter(const Vertex_handle &vh, const Point_3&p)
: m_vh(vh), m_p(p)
{}
const Point_3& operator()(const Vertex_handle &vh) const
{
return (vh == m_vh ? m_p : vh->point());
}
private:
const Vertex_handle m_vh;
const Point_3 &m_p;
};
public:
/// Constructor / Destructor
Triangulation_helpers() {}
~Triangulation_helpers() {}
/**
* Moves point from \c v to \c p.
*/
void move_point(Tr& tr,
const Vertex_handle& v,
const Point_3& p) const;
/**
* Returns true if moving \c v to \c p makes no topological
* change in \c tr
@ -74,11 +96,20 @@ public:
const Vertex_handle& v,
const Point_3& p,
Cell_vector& cells_tos) const;
bool no_topological_change__without_set_point(
const Tr& tr,
const Vertex_handle& v,
const Point_3& p,
Cell_vector& cells_tos) const;
bool no_topological_change(const Tr& tr,
const Vertex_handle& v,
const Point_3& p) const;
bool no_topological_change__without_set_point(
const Tr& tr,
const Vertex_handle& v,
const Point_3& p) const;
bool inside_protecting_balls(const Tr& tr,
const Vertex_handle& v,
@ -88,11 +119,16 @@ private:
/**
* Returns true if \c v is well_oriented on each cell of \c cell_tos
*/
// For sequential version
bool well_oriented(const Tr& tr,
const Cell_vector& cell_tos) const;
// For parallel version
bool well_oriented(const Tr& tr,
const Cell_vector& cell_tos,
const Point_getter& pg) const;
};
template<typename Tr>
void
Triangulation_helpers<Tr>::
@ -108,7 +144,7 @@ move_point(Tr& tr,
tr.remove(v);
}
}
template<typename Tr>
bool
Triangulation_helpers<Tr>::
@ -120,66 +156,149 @@ no_topological_change(const Tr& tr,
bool np = true;
Point_3 fp = v0->point();
v0->set_point(p);
/// @TODO: One can do the same checks without the set_point.
/// In the following orientation or side_of_power_sphere tests, just
/// replace v0->point() by p.
if(!well_oriented(tr, cells_tos))
if(!well_oriented(tr, cells_tos))
{
// Reset (restore) v0
v0->set_point(fp);
return false;
}
// Reset visited tags of facets
std::for_each(cells_tos.begin(), cells_tos.end(), Reset_facet_visited());
for ( typename Cell_vector::iterator cit = cells_tos.begin() ;
cit != cells_tos.end() ;
++cit )
{
Cell_handle c = *cit;
for(int j=0; j<4; j++)
for(int j=0; j<4; j++)
{
// Treat each facet only once
if(c->is_facet_visited(j))
continue;
// Set facet and it's mirror's one visited
Cell_handle cj = c->neighbor(j);
int mj = tr.mirror_index(c, j);
c->set_facet_visited(j);
cj->set_facet_visited(mj);
cj->set_facet_visited(mj);
Vertex_handle v1 = c->vertex(j);
if(tr.is_infinite(v1))
if(tr.is_infinite(v1))
{
if(tr.side_of_power_sphere(c, cj->vertex(mj)->point(), false)
!= CGAL::ON_UNBOUNDED_SIDE)
if(tr.side_of_power_sphere(c, cj->vertex(mj)->point(), false)
!= CGAL::ON_UNBOUNDED_SIDE)
{
np = false;
np = false;
break;
}
}
else
{
if(tr.side_of_power_sphere(cj, v1->point(), false)
!= CGAL::ON_UNBOUNDED_SIDE)
if(tr.side_of_power_sphere(cj, v1->point(), false)
!= CGAL::ON_UNBOUNDED_SIDE)
{
np = false;
np = false;
break;
}
}
}
}
// Reset (restore) v0
v0->set_point(fp);
return np;
}
template<typename Tr>
bool
Triangulation_helpers<Tr>::
no_topological_change__without_set_point(
const Tr& tr,
const Vertex_handle& v0,
const Point_3& p,
Cell_vector& cells_tos) const
{
bool np = true;
Point_getter pg(v0, p);
if(!well_oriented(tr, cells_tos, pg))
{
return false;
}
// Reset visited tags of facets
std::for_each(cells_tos.begin(), cells_tos.end(), Reset_facet_visited());
for ( typename Cell_vector::iterator cit = cells_tos.begin() ;
cit != cells_tos.end() ;
++cit )
{
Cell_handle c = *cit;
for(int j=0; j<4; j++)
{
// Treat each facet only once
if(c->is_facet_visited(j))
continue;
// Set facet and it's mirror's one visited
Cell_handle cj = c->neighbor(j);
int mj = tr.mirror_index(c, j);
c->set_facet_visited(j);
cj->set_facet_visited(mj);
Vertex_handle v1 = c->vertex(j);
if(tr.is_infinite(v1))
{
// Build a copy of c, and replace V0 by a temporary vertex (position "p")
typename Cell_handle::value_type c_copy (*c);
int i_v0;
typename Vertex_handle::value_type v;
if (c_copy.has_vertex(v0, i_v0))
{
v.set_point(p);
c_copy.set_vertex(i_v0,
Tr::Triangulation_data_structure::Vertex_range::s_iterator_to(v));
}
if(tr.side_of_power_sphere(&c_copy, pg(cj->vertex(mj)), false)
!= CGAL::ON_UNBOUNDED_SIDE)
{
np = false;
break;
}
}
else
{
// Build a copy of cj, and replace V0 by a temporary vertex (position "p")
typename Cell_handle::value_type cj_copy (*cj);
int i_v0;
typename Vertex_handle::value_type v;
if (cj_copy.has_vertex(v0, i_v0))
{
v.set_point(p);
cj_copy.set_vertex(i_v0,
Tr::Triangulation_data_structure::Vertex_range::s_iterator_to(v));
}
Cell_handle cj_copy_h =
Tr::Triangulation_data_structure::Cell_range::s_iterator_to(cj_copy);
if(tr.side_of_power_sphere(cj_copy_h, pg(v1), false)
!= CGAL::ON_UNBOUNDED_SIDE)
{
np = false;
break;
}
}
}
}
return np;
}
template<typename Tr>
bool
@ -194,6 +313,21 @@ no_topological_change(const Tr& tr,
return no_topological_change(tr, v0, p, cells_tos);
}
template<typename Tr>
bool
Triangulation_helpers<Tr>::
no_topological_change__without_set_point(
const Tr& tr,
const Vertex_handle& v0,
const Point_3& p) const
{
Cell_vector cells_tos;
cells_tos.reserve(64);
tr.incident_cells(v0, std::back_inserter(cells_tos));
return no_topological_change__without_set_point(tr, v0, p, cells_tos);
}
template<typename Tr>
bool
Triangulation_helpers<Tr>::
@ -211,7 +345,6 @@ inside_protecting_balls(const Tr& tr,
/// This function well_oriented is called by no_topological_change after a
/// v->set_point(p)
/// @TODO: One can do the same checks without the set_point.
template<typename Tr>
bool
Triangulation_helpers<Tr>::
@ -222,7 +355,7 @@ well_oriented(const Tr& tr,
for( ; it != cells_tos.end() ; ++it)
{
Cell_handle c = *it;
if( tr.is_infinite(c) )
if( tr.is_infinite(c) )
{
int iv = c->index(tr.infinite_vertex());
Cell_handle cj = c->neighbor(iv);
@ -240,12 +373,46 @@ well_oriented(const Tr& tr,
return false;
}
return true;
}
}
/// Another version for the parallel version
/// Here, the set_point is not done before, but we use a Point_getter instance
/// to get the point of a vertex.
template<typename Tr>
bool
Triangulation_helpers<Tr>::
well_oriented(const Tr& tr,
const Cell_vector& cells_tos,
const Point_getter& pg) const
{
typename Cell_vector::const_iterator it = cells_tos.begin();
for( ; it != cells_tos.end() ; ++it)
{
Cell_handle c = *it;
if( tr.is_infinite(c) )
{
int iv = c->index(tr.infinite_vertex());
Cell_handle cj = c->neighbor(iv);
int mj = tr.mirror_index(c, iv);
if(CGAL::orientation(pg(cj->vertex(mj)),
pg(c->vertex((iv+1)&3)),
pg(c->vertex((iv+2)&3)),
pg(c->vertex((iv+3)&3))) != CGAL::NEGATIVE)
return false;
}
else if(CGAL::orientation(pg(c->vertex(0)),
pg(c->vertex(1)),
pg(c->vertex(2)),
pg(c->vertex(3))) != CGAL::POSITIVE)
return false;
}
return true;
}
} // end namespace Mesh_3
} // end namespace Mesh_3
} //namespace CGAL
#endif // CGAL_MESH_3_TRIANGULATION_HELPERS_H

View File

@ -0,0 +1,882 @@
// Copyright (c) 2012 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL: $
// $Id: $
//
// Author(s) : Clement Jamin
#ifndef CGAL_MESH_3_WORKSHARING_DATA_STRUCTURES_H
#define CGAL_MESH_3_WORKSHARING_DATA_STRUCTURES_H
#ifdef CGAL_LINKED_WITH_TBB
#include <CGAL/Mesh_3/Concurrent_mesher_config.h>
#include <CGAL/Bbox_3.h>
#include <tbb/concurrent_queue.h>
#include <tbb/task.h>
#include <tbb/enumerable_thread_specific.h>
#include <tbb/concurrent_vector.h>
#include <tbb/scalable_allocator.h>
#include <vector>
#ifdef CGAL_MESH_3_TASK_SCHEDULER_SORTED_BATCHES_WITH_MULTISET
# include <set>
#endif
namespace CGAL { namespace Mesh_3 {
// Forward declarations
class Load_based_worksharing_ds;
class Auto_worksharing_ds;
// Typedef
// Load-based
#ifdef CGAL_MESH_3_LOAD_BASED_WORKSHARING
typedef Load_based_worksharing_ds WorksharingDataStructureType;
// Task-scheduler with TLS work buffers
// => 1 work-buffer / thread
#else
typedef Auto_worksharing_ds WorksharingDataStructureType;
#endif
class Work_statistics
{
public:
// Constructors
Work_statistics(const Bbox_3 &bbox,
int num_grid_cells_per_axis)
: m_num_grid_cells_per_axis(num_grid_cells_per_axis)
{
m_laziest_cell_index = 0;
m_laziest_cell_occupation = 1000;
m_num_cells =
num_grid_cells_per_axis*num_grid_cells_per_axis*num_grid_cells_per_axis;
m_occupation_grid = new tbb::atomic<int>[m_num_cells];
m_num_batches_grid = new tbb::atomic<int>[m_num_cells];
// Initialize grid
for (int i = 0 ; i < m_num_cells ; ++i)
{
m_occupation_grid[i] = 0;
m_num_batches_grid[i] = 0;
}
set_bbox(bbox);
}
/// Destructor
virtual ~Work_statistics()
{
delete [] m_occupation_grid;
delete [] m_num_batches_grid;
}
void set_bbox(const Bbox_3 &bbox)
{
// Keep mins and resolutions
m_xmin = bbox.xmin();
m_ymin = bbox.ymin();
m_zmin = bbox.zmin();
double n = static_cast<double>(m_num_grid_cells_per_axis);
m_resolution_x = n / (bbox.xmax() - m_xmin);
m_resolution_y = n / (bbox.ymax() - m_ymin);
m_resolution_z = n / (bbox.zmax() - m_zmin);
#ifdef CGAL_CONCURRENT_MESH_3_VERBOSE
std::cerr << "Worksharing data structure Bounding Box = ["
<< bbox.xmin() << ", " << bbox.xmax() << "], "
<< bbox.ymin() << ", " << bbox.ymax() << "], "
<< bbox.zmin() << ", " << bbox.zmax() << "]"
<< std::endl;
#endif
}
void add_batch(int cell_index, int to_add)
{
m_num_batches_grid[cell_index].fetch_and_add(to_add);
}
void add_occupation(int cell_index, int to_add, int num_items_in_work_queue)
{
m_occupation_grid[cell_index].fetch_and_add(to_add);
/*int new_occupation =
(m_occupation_grid[cell_index].fetch_and_add(to_add))
+ to_add;
//m_num_batches_grid[cell_index] = num_items_in_work_queue;
// If this cell is the current most lazy, update the value
if (cell_index == m_laziest_cell_index)
{
if (num_items_in_work_queue == 0)
// So that it won't stay long the laziest
m_laziest_cell_occupation = 999999;
else
m_laziest_cell_occupation = new_occupation;
}
else if (num_items_in_work_queue > 0
&& new_occupation <= m_laziest_cell_occupation)
{
m_laziest_cell_index = cell_index;
m_laziest_cell_occupation = new_occupation;
}*/
}
void add_occupation(int index_x, int index_y, int index_z,
int to_add, int num_items_in_work_queue)
{
int index =
index_z*m_num_grid_cells_per_axis*m_num_grid_cells_per_axis
+ index_y*m_num_grid_cells_per_axis
+ index_x;
return add_occupation(index, to_add, num_items_in_work_queue);
}
/// P3 must provide .x(), .y(), .z()
template <typename P3>
int compute_index(const P3 &point) const
{
// Compute indices on grid
int index_x = static_cast<int>( (to_double(point.x()) - m_xmin) * m_resolution_x);
index_x = std::max( 0, std::min(index_x, m_num_grid_cells_per_axis - 1) );
int index_y = static_cast<int>( (to_double(point.y()) - m_ymin) * m_resolution_y);
index_y = std::max( 0, std::min(index_y, m_num_grid_cells_per_axis - 1) );
int index_z = static_cast<int>( (to_double(point.z()) - m_zmin) * m_resolution_z);
index_z = std::max( 0, std::min(index_z, m_num_grid_cells_per_axis - 1) );
int index =
index_z*m_num_grid_cells_per_axis*m_num_grid_cells_per_axis
+ index_y*m_num_grid_cells_per_axis
+ index_x;
return index;
}
/// P3 must provide .x(), .y(), .z()
// Returns index in grid
template <typename P3>
int add_occupation(const P3 &point, int to_add, int num_items_in_work_queue)
{
int index = compute_index(point);
add_occupation(index, to_add, num_items_in_work_queue);
return index;
}
int get_laziest_cell_index() const
{
//return m_laziest_cell_index;
/*
// Look for best occupation/work ratio
int laziest_index = 0;
float laziest_ratio = 200000.f;
for (int i = 0 ; i < m_num_cells ; ++i)
{
if (m_num_batches_grid[i] > 0)
{
float ratio =
static_cast<float>(m_occupation_grid[i])
/ m_num_batches_grid[i];
if (ratio < laziest_ratio)
{
laziest_index = i;
laziest_ratio = ratio;
}
}
}
return laziest_index;*/
// Look for the least occupied
/*int laziest_index = 0;
int smallest_occupation = 99999;
for (int i = 0 ; i < m_num_cells ; ++i)
{
if (m_num_batches_grid[i] > 1)
{
if (m_occupation_grid[i] < smallest_occupation)
{
laziest_index = i;
smallest_occupation = m_occupation_grid[i];
}
}
}
//std::cerr << "Occ=" << m_occupation_grid[laziest_index]
// << " / Bat=" << m_num_batches_grid[laziest_index]
// << std::endl;
return laziest_index;*/
// Rotate
static tbb::atomic<int> last_cell_index;
//std::cerr << "last=" << last_cell_index << std::endl;
int i = (last_cell_index + 1) % m_num_cells;
for ( ; i != last_cell_index ; i = (i + 1) % m_num_cells)
{
//std::cerr << "#" << i << "=" << m_num_batches_grid[i] << std::endl;
if (m_num_batches_grid[i] > 0)
{
break;
}
}
last_cell_index = i;
return i;
}
protected:
double m_xmin;
double m_ymin;
double m_zmin;
double m_resolution_x;
double m_resolution_y;
double m_resolution_z;
int m_num_grid_cells_per_axis;
int m_num_cells;
tbb::atomic<int> * m_occupation_grid;
tbb::atomic<int> * m_num_batches_grid;
tbb::atomic<int> m_laziest_cell_index;
tbb::atomic<int> m_laziest_cell_occupation;
};
/*
* ==============
* class WorkItem
* Abstract base class for a piece of work.
* ==============
*/
class WorkItem
{
public:
WorkItem() {}
// Derived class defines the actual work.
virtual void run() = 0;
virtual bool less_than(const WorkItem &) const = 0;
};
struct CompareTwoWorkItems
{
bool operator()(const WorkItem *p1, const WorkItem *p2) const
{
return p1->less_than(*p2);
}
};
/*
* ==============
* class MeshRefinementWorkItem
* Concrete class for a piece of work in the refinement process.
* ==============
*/
template<typename Func, typename Quality>
class MeshRefinementWorkItem
: public WorkItem
{
public:
MeshRefinementWorkItem(const Func& func, const Quality &quality)
: m_func(func), m_quality(quality)
{}
void run()
{
m_func();
tbb::scalable_allocator<MeshRefinementWorkItem<Func, Quality> >().deallocate(this, 1);
}
bool less_than (const WorkItem &other) const
{
/*try
{
const MeshRefinementWorkItem& other_cwi = dynamic_cast<const MeshRefinementWorkItem<Func,Quality>&>(other);
return m_quality < other_cwi.m_quality;
}
catch (const std::bad_cast&)
{
return false;
}*/
const MeshRefinementWorkItem& other_cwi = static_cast<const MeshRefinementWorkItem<Func,Quality>&>(other);
return m_quality < other_cwi.m_quality;
}
private:
Func m_func;
Quality m_quality;
};
/*
* ==============
* class SimpleFunctorWorkItem
* Concrete class for a work item embedding a simple functor
* ==============
*/
template<typename Func>
class SimpleFunctorWorkItem
: public WorkItem
{
public:
SimpleFunctorWorkItem(const Func& func)
: m_func(func)
{}
void run()
{
m_func();
tbb::scalable_allocator<SimpleFunctorWorkItem<Func> >().deallocate(this, 1);
}
// Irrelevant here
bool less_than (const WorkItem &other) const
{
// Just compare addresses
return this < &other;
}
private:
Func m_func;
};
/*
* ===============
* class WorkBatch
* ===============
*/
class WorkBatch
{
public:
#ifdef CGAL_MESH_3_TASK_SCHEDULER_SORTED_BATCHES_WITH_MULTISET
typedef std::multiset<WorkItem *, CompareTwoWorkItems> Batch;
#else
typedef std::vector<WorkItem *> Batch;
#endif
typedef Batch::const_iterator BatchConstIterator;
typedef Batch::iterator BatchIterator;
WorkBatch() {}
void add_work_item(WorkItem *p_item)
{
#ifdef CGAL_MESH_3_TASK_SCHEDULER_SORTED_BATCHES_WITH_MULTISET
m_batch.insert(p_item);
#else
m_batch.push_back(p_item);
#endif
}
void move_first_elements(WorkBatch &dest, int num_elements)
{
BatchIterator it = m_batch.begin();
BatchIterator it_end = m_batch.end();
for (int i = 0 ; i < num_elements && it != it_end ; ++it)
{
dest.add_work_item(*it);
}
m_batch.erase(m_batch.begin(), it);
}
void run()
{
#ifdef CGAL_MESH_3_TASK_SCHEDULER_SORTED_BATCHES_WITH_SORT
std::sort(m_batch.begin(), m_batch.end(), CompareTwoWorkItems());
#endif
BatchIterator it = m_batch.begin();
BatchIterator it_end = m_batch.end();
for ( ; it != it_end ; ++it)
(*it)->run();
}
size_t size() const
{
return m_batch.size();
}
void clear()
{
m_batch.clear();
}
protected:
Batch m_batch;
};
/*
* ===================
* class WorkItemTask
* ===================
*/
class WorkItemTask
: public tbb::task
{
public:
WorkItemTask(WorkItem *pwi)
: m_pwi(pwi)
{
}
private:
/*override*/inline tbb::task* execute();
WorkItem *m_pwi;
};
/*
* =======================================
* class Simple_worksharing_ds
* =======================================
*/
class Simple_worksharing_ds
{
public:
// Constructors
Simple_worksharing_ds()
{
}
/// Destructor
virtual ~Simple_worksharing_ds()
{
}
template <typename Func>
void enqueue_work(Func f, tbb::task &parent_task) const
{
//WorkItem *p_item = new SimpleFunctorWorkItem<Func>(f);
WorkItem *p_item =
tbb::scalable_allocator<SimpleFunctorWorkItem<Func> >().allocate(1);
new (p_item) SimpleFunctorWorkItem<Func>(f);
enqueue_task(create_task(p_item, parent_task));
}
protected:
WorkItemTask *create_task(WorkItem *pwi, tbb::task &parent_task) const
{
return new(tbb::task::allocate_additional_child_of(parent_task)) WorkItemTask(pwi);
}
void enqueue_task(WorkItemTask *t) const
{
tbb::task::spawn(*t);
}
};
/*
* ==================
* class TokenTask
* ==================
*/
class TokenTask
: public tbb::task
{
public:
TokenTask(Load_based_worksharing_ds *p_wsds)
: m_worksharing_ds(p_wsds) {}
private:
/*override*/inline tbb::task* execute();
Load_based_worksharing_ds *m_worksharing_ds;
};
/*
* =======================================
* class Load_based_worksharing_ds
* =======================================
*/
class Load_based_worksharing_ds
{
public:
// Constructors
Load_based_worksharing_ds(const Bbox_3 &bbox)
: m_num_cells_per_axis(
Concurrent_mesher_config::get().work_stats_grid_num_cells_per_axis),
m_stats(bbox, m_num_cells_per_axis),
m_num_cells(m_num_cells_per_axis*m_num_cells_per_axis*m_num_cells_per_axis),
NUM_WORK_ITEMS_PER_BATCH(
Concurrent_mesher_config::get().num_work_items_per_batch)
{
m_tls_work_buffers = new TLS_WorkBuffer[m_num_cells];
m_work_batches = new tbb::concurrent_queue<WorkBatch>[m_num_cells];
m_num_batches = new tbb::atomic<int>[m_num_cells];
for (int i = 0 ; i < m_num_cells ; ++i)
m_num_batches[i] = 0;
set_bbox(bbox);
}
/// Destructor
virtual ~Load_based_worksharing_ds()
{
delete [] m_tls_work_buffers;
delete [] m_work_batches;
delete [] m_num_batches;
}
void set_bbox(const Bbox_3 &bbox)
{
m_stats.set_bbox(bbox);
}
template <typename P3, typename Func, typename Quality>
void enqueue_work(Func f, const Quality &quality, tbb::task &parent_task, const P3 &point)
{
WorkItem *p_item = new MeshRefinementWorkItem<Func, Quality>(f, quality);
int index = m_stats.compute_index(point);
WorkBatch &wb = m_tls_work_buffers[index].local();
wb.add_work_item(p_item);
if (wb.size() >= NUM_WORK_ITEMS_PER_BATCH)
{
add_batch_and_enqueue_task(wb, index, parent_task);
wb.clear();
}
}
// Returns true if some items were flushed
bool flush_work_buffers(tbb::task &parent_task)
{
int num_flushed_items = 0;
for (int i = 0 ; i < m_num_cells ; ++i)
{
for (TLS_WorkBuffer::iterator it_buffer = m_tls_work_buffers[i].begin() ;
it_buffer != m_tls_work_buffers[i].end() ;
++it_buffer )
{
if (it_buffer->size() > 0)
{
add_batch(*it_buffer, i);
it_buffer->clear();
++num_flushed_items;
}
}
}
for (int i = 0 ; i < num_flushed_items ; ++i)
enqueue_task(parent_task);
return (num_flushed_items > 0);
}
void run_next_work_item()
{
WorkBuffer wb;
int index = m_stats.get_laziest_cell_index();
bool popped = m_work_batches[index].try_pop(wb);
if (!popped)
{
// Look for an non-empty queue
for (index = 0 ; !popped ; ++index)
{
CGAL_assertion(index < m_num_cells);
popped = m_work_batches[index].try_pop(wb);
}
--index;
}
CGAL_assertion(index < m_num_cells);
--m_num_batches[index];
m_stats.add_batch(index, -1);
add_occupation(index, 1);
#ifdef CGAL_CONCURRENT_MESH_3_VERY_VERBOSE
std::cerr << "Running a batch of " << wb.size() <<
" elements on cell #" << index << std::endl;
#endif
wb.run();
add_occupation(index, -1);
}
protected:
// TLS
typedef WorkBatch WorkBuffer;
typedef tbb::enumerable_thread_specific<WorkBuffer> TLS_WorkBuffer;
void add_batch(const WorkBuffer &wb, int index)
{
m_work_batches[index].push(wb);
++m_num_batches[index];
m_stats.add_batch(index, 1);
}
void enqueue_task(tbb::task &parent_task)
{
parent_task.increment_ref_count();
// Warning: when using "enqueue", the system will use up to two threads
// even if you told task_scheduler_init to use only one
// (see http://software.intel.com/en-us/forums/showthread.php?t=101669)
tbb::task::spawn(*new(parent_task.allocate_child()) TokenTask(this));
}
void add_batch_and_enqueue_task(const WorkBuffer &wb, int index, tbb::task &parent_task)
{
add_batch(wb, index);
enqueue_task(parent_task);
}
void add_occupation(int cell_index, int to_add, int occupation_radius = 1)
{
int index_z = cell_index/(m_num_cells_per_axis*
m_num_cells_per_axis);
cell_index -= index_z*
m_num_cells_per_axis*
m_num_cells_per_axis;
int index_y = cell_index/m_num_cells_per_axis;
cell_index -= index_y*m_num_cells_per_axis;
int index_x = cell_index;
// For each cell inside the square
for (int i = std::max(0, index_x-occupation_radius) ;
i <= std::min(m_num_cells_per_axis - 1, index_x+occupation_radius) ;
++i)
{
for (int j = std::max(0, index_y-occupation_radius) ;
j <= std::min(m_num_cells_per_axis - 1, index_y+occupation_radius) ;
++j)
{
for (int k = std::max(0, index_z-occupation_radius) ;
k <= std::min(m_num_cells_per_axis - 1, index_z+occupation_radius) ;
++k)
{
int index =
k*m_num_cells_per_axis*m_num_cells_per_axis
+ j*m_num_cells_per_axis
+ i;
int weight =
(occupation_radius + 1 - std::abs(i - index_x))
*(occupation_radius + 1 - std::abs(j - index_y))
*(occupation_radius + 1 - std::abs(k - index_z));
m_stats.add_occupation(index, to_add*weight, m_num_batches[index]);
}
}
}
}
const int NUM_WORK_ITEMS_PER_BATCH;
int m_num_cells_per_axis;
int m_num_cells;
Work_statistics m_stats;
TLS_WorkBuffer *m_tls_work_buffers;
tbb::concurrent_queue<WorkBatch> *m_work_batches;
tbb::atomic<int> *m_num_batches;
};
/*
* ===================
* class WorkBatchTask
* ===================
*/
class WorkBatchTask
: public tbb::task
{
public:
WorkBatchTask(const WorkBatch &wb)
: m_wb(wb)
{
//set_affinity(tbb::task::self().affinity());
}
private:
/*override*/inline tbb::task* execute();
WorkBatch m_wb;
};
/*
* =======================================
* class Auto_worksharing_ds
* =======================================
*/
class Auto_worksharing_ds
{
public:
// Constructors
Auto_worksharing_ds(const Bbox_3 &bbox)
: NUM_WORK_ITEMS_PER_BATCH(
Concurrent_mesher_config::get().num_work_items_per_batch)
{
set_bbox(bbox);
}
/// Destructor
virtual ~Auto_worksharing_ds()
{
}
void set_bbox(const Bbox_3 &/*bbox*/)
{
// We don't need it.
}
template <typename Func>
void enqueue_work(Func f, tbb::task &parent_task)
{
//WorkItem *p_item = new SimpleFunctorWorkItem<Func>(f);
WorkItem *p_item =
tbb::scalable_allocator<SimpleFunctorWorkItem<Func> >().allocate(1);
new (p_item) SimpleFunctorWorkItem<Func>(f);
WorkBatch &workbuffer = m_tls_work_buffers.local();
workbuffer.add_work_item(p_item);
if (workbuffer.size() >= NUM_WORK_ITEMS_PER_BATCH)
{
/*WorkBatch wb;
workbuffer.move_first_elements(wb, NUM_WORK_ITEMS_PER_BATCH);
add_batch_and_enqueue_task(wb, parent_task);*/
add_batch_and_enqueue_task(workbuffer, parent_task);
workbuffer.clear();
}
}
template <typename Func, typename Quality>
void enqueue_work(Func f, const Quality &quality, tbb::task &parent_task)
{
//WorkItem *p_item = new MeshRefinementWorkItem<Func, Quality>(f, quality);
WorkItem *p_item =
tbb::scalable_allocator<MeshRefinementWorkItem<Func, Quality> >()
.allocate(1);
new (p_item) MeshRefinementWorkItem<Func, Quality>(f, quality);
WorkBatch &workbuffer = m_tls_work_buffers.local();
workbuffer.add_work_item(p_item);
if (workbuffer.size() >= NUM_WORK_ITEMS_PER_BATCH)
{
/*WorkBatch wb;
workbuffer.move_first_elements(wb, NUM_WORK_ITEMS_PER_BATCH);
add_batch_and_enqueue_task(wb, parent_task);*/
add_batch_and_enqueue_task(workbuffer, parent_task);
workbuffer.clear();
}
}
// Returns true if some items were flushed
bool flush_work_buffers(tbb::task &parent_task)
{
int num_flushed_items = 0;
std::vector<WorkBatchTask*> tasks;
for (TLS_WorkBuffer::iterator it_buffer = m_tls_work_buffers.begin() ;
it_buffer != m_tls_work_buffers.end() ;
++it_buffer )
{
if (it_buffer->size() > 0)
{
tasks.push_back(create_task(*it_buffer, parent_task));
it_buffer->clear();
++num_flushed_items;
}
}
for (std::vector<WorkBatchTask*>::const_iterator it = tasks.begin() ;
it != tasks.end() ; ++it)
{
enqueue_task(*it, parent_task);
}
return (num_flushed_items > 0);
}
protected:
// TLS
typedef WorkBatch WorkBuffer;
typedef tbb::enumerable_thread_specific<WorkBuffer> TLS_WorkBuffer;
WorkBatchTask *create_task(const WorkBuffer &wb, tbb::task &parent_task) const
{
return new(tbb::task::allocate_additional_child_of(parent_task)) WorkBatchTask(wb);
}
void enqueue_task(WorkBatchTask *task,
tbb::task &parent_task) const
{
tbb::task::spawn(*task);
}
void add_batch_and_enqueue_task(const WorkBuffer &wb,
tbb::task &parent_task) const
{
enqueue_task(create_task(wb, parent_task), parent_task);
}
const int NUM_WORK_ITEMS_PER_BATCH;
TLS_WorkBuffer m_tls_work_buffers;
};
inline tbb::task* TokenTask::execute()
{
m_worksharing_ds->run_next_work_item();
return NULL;
}
inline tbb::task* WorkItemTask::execute()
{
m_pwi->run();
return NULL;
}
inline tbb::task* WorkBatchTask::execute()
{
m_wb.run();
return NULL;
}
} } //namespace CGAL::Mesh_3
#else // !CGAL_LINKED_WITH_TBB
namespace CGAL { namespace Mesh_3 {
typedef void WorksharingDataStructureType;
} } //namespace CGAL::Mesh_3
#endif // CGAL_LINKED_WITH_TBB
#endif // CGAL_MESH_3_WORKSHARING_DATA_STRUCTURES_H

View File

@ -35,6 +35,8 @@
//experimental
# define CGAL_FASTER_BUILD_QUEUE 1
//# define CGAL_SEQUENTIAL_MESH_3_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE
//# define CGAL_PARALLEL_MESH_3_DO_NOT_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE // slower / not recommended
//should not be used
//#define CGAL_MESH_3_OLD_MINIMUM_DIHEDRAL_ANGLE 1

View File

@ -31,6 +31,10 @@
#include <CGAL/Mesh_3/C3T3_helpers.h>
#include <CGAL/Mesh_3/Triangulation_helpers.h>
#ifdef CGAL_MESH_3_PERTURBER_VERBOSE
#include <CGAL/Timer.h>
#endif
#include <boost/optional.hpp>
#include <boost/random/lagged_fibonacci.hpp>
#include <boost/random/uniform_real.hpp>
@ -224,18 +228,19 @@ public:
const MeshDomain& domain,
const SliverCriterion& criterion,
const FT& sliver_bound,
std::vector<Vertex_handle>& modified_vertices) const
std::vector<Vertex_handle>& modified_vertices,
bool *could_lock_zone = NULL) const
{
#ifndef CGAL_MESH_3_PERTURBER_VERBOSE
return do_perturb(v, slivers, c3t3, domain, criterion,
sliver_bound, modified_vertices);
sliver_bound, modified_vertices, could_lock_zone);
#else
timer_.start();
// Virtual call
std::pair<bool,Vertex_handle> perturb =
do_perturb(v, slivers, c3t3, domain, criterion,
sliver_bound, modified_vertices);
sliver_bound, modified_vertices, could_lock_zone);
if ( perturb.first )
++counter_;
@ -300,7 +305,8 @@ protected:
const MeshDomain& domain,
const SliverCriterion& criterion,
const FT& sliver_bound,
std::vector<Vertex_handle>& modified_vertices) const = 0;
std::vector<Vertex_handle>& modified_vertices,
bool *could_lock_zone = NULL) const = 0;
/**
@ -390,7 +396,8 @@ protected:
const MeshDomain& domain,
const SliverCriterion& criterion,
const FT& sliver_bound,
std::vector<Vertex_handle>& modified_vertices) const = 0;
std::vector<Vertex_handle>& modified_vertices,
bool *could_lock_zone = NULL) const = 0;
protected:
// -----------------------------------
@ -407,7 +414,8 @@ protected:
C3T3& c3t3,
const MeshDomain& domain,
const SliverCriterion& criterion,
std::vector<Vertex_handle>& modified_vertices) const
std::vector<Vertex_handle>& modified_vertices,
bool *could_lock_zone = NULL) const
{
typedef typename C3T3::Triangulation::Geom_traits Gt;
typedef typename Gt::FT FT;
@ -434,27 +442,46 @@ protected:
// as long as no topological change takes place
unsigned int i = 0;
while( Th().no_topological_change(c3t3.triangulation(), v, final_loc)
&& (++i <= max_step_nb_) )
// Concurrent-safe version
if (could_lock_zone)
{
new_loc = new_loc + step_length * gradient_vector;
while(Th().no_topological_change__without_set_point(c3t3.triangulation(),
v, final_loc)
&& (++i <= max_step_nb_) )
{
new_loc = new_loc + step_length * gradient_vector;
if ( c3t3.in_dimension(v) == 3 )
final_loc = new_loc;
else
final_loc = helper.project_on_surface(new_loc, v);
if ( c3t3.in_dimension(v) == 3 )
final_loc = new_loc;
else
final_loc = helper.project_on_surface(new_loc, v);
}
}
else
{
while( Th().no_topological_change(c3t3.triangulation(), v, final_loc)
&& (++i <= max_step_nb_) )
{
new_loc = new_loc + step_length * gradient_vector;
if ( c3t3.in_dimension(v) == 3 )
final_loc = new_loc;
else
final_loc = helper.project_on_surface(new_loc, v);
}
}
// Topology could not change moving this vertex
if ( i > max_step_nb_
|| Th().inside_protecting_balls(c3t3.triangulation(), v, final_loc))
return std::make_pair(false,v);
// we know that there will be a combinatorial change
return helper.update_mesh_topo_change(final_loc,
v,
criterion,
std::back_inserter(modified_vertices));
std::back_inserter(modified_vertices),
could_lock_zone);
}
@ -515,7 +542,8 @@ protected:
const MeshDomain& domain,
const SliverCriterion& criterion,
const FT&,
std::vector<Vertex_handle>& modified_vertices) const
std::vector<Vertex_handle>& modified_vertices,
bool *could_lock_zone = NULL) const
{
CGAL_precondition(!slivers.empty());
@ -530,7 +558,8 @@ protected:
c3t3,
domain,
criterion,
modified_vertices);
modified_vertices,
could_lock_zone);
}
private:
@ -671,7 +700,8 @@ protected:
const MeshDomain& domain,
const SliverCriterion& criterion,
const FT&,
std::vector<Vertex_handle>& modified_vertices) const
std::vector<Vertex_handle>& modified_vertices,
bool *could_lock_zone = NULL) const
{
CGAL_precondition(!slivers.empty());
@ -686,7 +716,8 @@ protected:
c3t3,
domain,
criterion,
modified_vertices);
modified_vertices,
could_lock_zone);
}
private:
@ -810,7 +841,8 @@ protected:
const MeshDomain& domain,
const SliverCriterion& criterion,
const FT&,
std::vector<Vertex_handle>& modified_vertices) const
std::vector<Vertex_handle>& modified_vertices,
bool *could_lock_zone = NULL) const
{
CGAL_precondition(!slivers.empty());
@ -825,7 +857,8 @@ protected:
c3t3,
domain,
criterion,
modified_vertices);
modified_vertices,
could_lock_zone);
}
private:
@ -1009,7 +1042,8 @@ protected:
const MeshDomain& domain,
const SliverCriterion& criterion,
const FT& sliver_bound,
std::vector<Vertex_handle>& modified_vertices) const = 0;
std::vector<Vertex_handle>& modified_vertices,
bool *could_lock_zone = NULL) const = 0;
protected:
// -----------------------------------
@ -1140,12 +1174,14 @@ protected:
const MeshDomain& domain,
const SliverCriterion& criterion,
const FT& sliver_bound,
std::vector<Vertex_handle>& modified_vertices) const
std::vector<Vertex_handle>& modified_vertices,
bool *could_lock_zone = NULL) const
{
CGAL_precondition(!slivers.empty());
return apply_perturbation(v, slivers, c3t3, domain, criterion,
sliver_bound, modified_vertices);
sliver_bound, modified_vertices,
could_lock_zone);
}
private:
@ -1163,7 +1199,8 @@ private:
const MeshDomain& domain,
const SliverCriterion& criterion,
const FT& sliver_bound,
std::vector<Vertex_handle>& modified_vertices) const
std::vector<Vertex_handle>& modified_vertices,
bool *could_lock_zone = NULL) const
{
typedef Triangulation_helpers<typename C3T3::Triangulation> Th;
@ -1206,8 +1243,12 @@ private:
helper.update_mesh(new_location,
moving_vertex,
criterion,
std::back_inserter(tmp_mod_vertices));
std::back_inserter(tmp_mod_vertices),
could_lock_zone);
if (could_lock_zone && *could_lock_zone == false)
return std::make_pair(false, Vertex_handle());
// get new vertex
moving_vertex = update.second;

View File

@ -34,8 +34,68 @@
#include <CGAL/Mesh_3/Mesh_surface_cell_base_3.h>
#include <CGAL/Mesh_3/io_signature.h>
#include <boost/type_traits/is_convertible.hpp>
#ifdef CGAL_LINKED_WITH_TBB
# include <tbb/atomic.h>
#endif
namespace CGAL {
// Sequential
template <typename Concurrency_tag>
class Mesh_cell_base_3_base
{
public:
#if defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \
|| defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE)
// Erase counter (cf. Compact_container)
unsigned int erase_counter() const
{
return this->m_erase_counter;
}
void set_erase_counter(unsigned int c)
{
this->m_erase_counter = c;
}
void increment_erase_counter()
{
++this->m_erase_counter;
}
private:
typedef unsigned int Erase_counter_type;
Erase_counter_type m_erase_counter;
#endif
};
#ifdef CGAL_LINKED_WITH_TBB
// Specialized version (parallel)
template <>
class Mesh_cell_base_3_base<Parallel_tag>
{
public:
// Erase counter (cf. Compact_container)
unsigned int erase_counter() const
{
return this->m_erase_counter;
}
void set_erase_counter(unsigned int c)
{
this->m_erase_counter = c;
}
void increment_erase_counter()
{
++this->m_erase_counter;
}
protected:
typedef tbb::atomic<unsigned int> Erase_counter_type;
Erase_counter_type m_erase_counter;
};
#endif // CGAL_LINKED_WITH_TBB
// Class Mesh_cell_base_3
// Cell base class used in 3D meshing process.
// Adds information to Cb about the cell of the input complex containing it
@ -44,7 +104,9 @@ template< class GT,
class Cb= CGAL::Regular_triangulation_cell_base_with_weighted_circumcenter_3<
GT, CGAL::Regular_triangulation_cell_base_3<GT> > >
class Mesh_cell_base_3
: public Mesh_3::Mesh_surface_cell_base_3<GT, MD, Cb>
: public Mesh_3::Mesh_surface_cell_base_3<GT, MD, Cb>,
public Mesh_cell_base_3_base<
typename Mesh_3::Mesh_surface_cell_base_3<GT, MD, Cb>::Tds::Concurrency_tag>
{
typedef typename GT::FT FT;

View File

@ -20,23 +20,24 @@
// Author(s) : Stephane Tayeb
//
//******************************************************************************
// File Description :
// File Description :
//******************************************************************************
#ifndef CGAL_MESH_COMPLEX_3_IN_TRIANGULATION_3_H
#define CGAL_MESH_COMPLEX_3_IN_TRIANGULATION_3_H
#include <map>
#include <boost/bimap/bimap.hpp>
#include <boost/bimap/multiset_of.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <CGAL/iterator.h>
#include <CGAL/Mesh_3/utilities.h>
#include <CGAL/Mesh_3/Mesh_complex_3_in_triangulation_3_base.h>
#include <map>
#include <boost/bimap/bimap.hpp>
#include <boost/bimap/multiset_of.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/mpl/if.hpp>
namespace CGAL {
@ -45,57 +46,63 @@ template <typename Tr,
typename CornerIndex = int,
typename CurveSegmentIndex = int>
class Mesh_complex_3_in_triangulation_3 :
public Mesh_3::Mesh_complex_3_in_triangulation_3_base<Tr>
public Mesh_3::Mesh_complex_3_in_triangulation_3_base<
Tr, typename Tr::Concurrency_tag>
{
public:
typedef typename Tr::Concurrency_tag Concurrency_tag;
private:
typedef Mesh_complex_3_in_triangulation_3<
Tr,CornerIndex,CurveSegmentIndex> Self;
typedef Mesh_3::Mesh_complex_3_in_triangulation_3_base<Tr> Base;
typedef Mesh_3::Mesh_complex_3_in_triangulation_3_base<
Tr,Concurrency_tag> Base;
public:
typedef typename Base::size_type size_type;
typedef typename Base::Edge Edge;
typedef typename Base::Vertex_handle Vertex_handle;
typedef CornerIndex Corner_index;
typedef CurveSegmentIndex Curve_segment_index;
typedef typename Base::Triangulation Triangulation;
private:
// Type to store the edges:
// - a set of std::pair<Vertex_handle,Vertex_handle> (ordered at insertion)
// - which allows fast lookup from one Vertex_handle
// - each element of the set has an associated info (Curve_segment_index) value
typedef boost::bimaps::bimap<
typedef boost::bimaps::bimap<
boost::bimaps::multiset_of<Vertex_handle>,
boost::bimaps::multiset_of<Vertex_handle>,
boost::bimaps::set_of_relation<>,
boost::bimaps::with_info<Curve_segment_index> > Edge_map;
typedef typename Edge_map::value_type Internal_edge;
// Type to store the corners
typedef std::map<Vertex_handle,Corner_index> Corner_map;
public:
/**
* Constructor
*/
Mesh_complex_3_in_triangulation_3()
Mesh_complex_3_in_triangulation_3()
: Base()
, edges_()
, corners_() {}
/**
* Copy constructor
*/
Mesh_complex_3_in_triangulation_3(const Self& rhs);
/**
* Destructor
*/
virtual ~Mesh_complex_3_in_triangulation_3() {}
/**
* Assignement operator
*/
@ -104,7 +111,7 @@ public:
swap(rhs);
return *this;
}
/**
* Swaps this & rhs
*/
@ -114,7 +121,7 @@ public:
edges_.swap(rhs.edges_);
corners_.swap(rhs.corners_);
}
/**
* Clears data of c3t3
*/
@ -124,16 +131,16 @@ public:
edges_.clear();
corners_.clear();
}
/// Import Base functions
using Base::is_in_complex;
using Base::add_to_complex;
using Base::remove_from_complex;
/**
* Add edge e to complex, with Curve_segment_index index
*/
*/
void add_to_complex(const Edge& e,
const Curve_segment_index& index)
{
@ -141,7 +148,7 @@ public:
e.first->vertex(e.third),
index);
}
/**
* Add edge (v1,v2) to complex, with Curve_segment_index index
*/
@ -151,7 +158,7 @@ public:
{
add_to_complex(make_internal_edge(v1,v2), index);
}
/**
* Mark vertex \c v as a corner of the complex
*/
@ -163,12 +170,12 @@ public:
/**
* Remove edge \c e from complex
*/
*/
void remove_from_complex(const Edge& e)
{
remove_from_complex(e.first->vertex(e.second), e.first->vertex(e.third));
}
/**
* Remove edge (v1,v2) from complex
*/
@ -176,7 +183,7 @@ public:
{
remove_from_complex(make_internal_edge(v1,v2));
}
/**
* Remove vertex \c v from complex
*/
@ -185,7 +192,7 @@ public:
corners_.erase(v);
v->set_dimension(-1);
}
/**
* Returns the number of edges of c3t3
*/
@ -205,7 +212,7 @@ public:
{
return corners_.size();
}
/**
* Returns true if edge \c e is in complex
*/
@ -213,7 +220,7 @@ public:
{
return is_in_complex(e.first->vertex(e.second), e.first->vertex(e.third));
}
/**
* Returns true if edge (v1,v2) is in C3T3
*/
@ -229,7 +236,7 @@ public:
{
return (corners_.find(v) != corners_.end());
}
/**
* Returns Curve_segment_index of edge \c e
*/
@ -238,7 +245,7 @@ public:
return curve_segment_index(e.first->vertex(e.second),
e.first->vertex(e.third));
}
/**
* Returns Curve_segment_index of edge \c (v1,v2)
*/
@ -247,7 +254,7 @@ public:
{
return curve_index(make_internal_edge(v1,v2));
}
/**
* Returns Corner_index of vertex \c v
*/
@ -257,25 +264,25 @@ public:
if ( corners_.end() != it ) { return it->second; }
return Corner_index();
}
/**
* Fills \c out with incident edges (1-dimensional features of \c v.
* OutputIterator value type is std::pair<Vertex_handle,Curve_segment_index>
* \pre v->in_dimension() < 2
* \pre v->in_dimension() < 2
*/
template <typename OutputIterator>
OutputIterator
adjacent_vertices_in_complex(const Vertex_handle& v, OutputIterator out) const;
// -----------------------------------
// Undocumented
// -----------------------------------
/**
* Returns true if c3t3 is valid
*/
bool is_valid(bool verbose = false) const;
// -----------------------------------
// Complex traversal
// -----------------------------------
@ -289,15 +296,15 @@ private:
const Curve_segment_index& index = Curve_segment_index())
: c3t3_(c3t3)
, index_(index) { }
template <typename Iterator>
bool operator()(Iterator it) const
{
{
if ( index_ == Curve_segment_index() ) { return ! c3t3_.is_in_complex(*it); }
else { return c3t3_.curve_segment_index(*it) != index_; }
}
};
class Vertex_iterator_not_in_complex
{
const Self& c3t3_;
@ -307,15 +314,15 @@ private:
const Corner_index& index = Corner_index())
: c3t3_(c3t3)
, index_(index) { }
template <typename ItMap>
bool operator()(const ItMap it) const
{
{
if ( index_ == Corner_index() ) { return false; }
else { return it->second != index_; }
}
};
// Filtered iterator
typedef Filter_iterator<
typename Corner_map::const_iterator,
@ -325,7 +332,7 @@ private:
typedef boost::transform_iterator <
Mesh_3::internal::First_of<typename Vertex_map_filter_iterator::value_type>,
Vertex_map_filter_iterator > Vertex_map_iterator_first;
// Iterator type to remove a level of referencing
class Vertex_map_iterator_first_dereference
: public boost::iterator_adaptor <
@ -345,26 +352,26 @@ private:
public:
typedef typename Vertex_map_iterator_first::reference pointer;
typedef typename iterator_adaptor_::reference reference;
Vertex_map_iterator_first_dereference() : Self::iterator_adaptor_() { }
template < typename Iterator >
Vertex_map_iterator_first_dereference(Iterator i)
: Self::iterator_adaptor_(typename Self::iterator_adaptor_::base_type(i))
{ }
pointer operator->() const { return *(this->base()); }
reference operator*() const { return **(this->base()); }
operator Vertex_handle() { return Vertex_handle(*(this->base())); }
};
public:
/// Iterator type to visit the edges of the 1D complex.
typedef Filter_iterator<
typename Triangulation::Finite_edges_iterator,
Edge_iterator_not_in_complex > Edges_in_complex_iterator;
/// Returns a Facets_in_complex_iterator to the first facet of the 1D complex
Edges_in_complex_iterator edges_in_complex_begin() const
{
@ -372,7 +379,7 @@ public:
Edge_iterator_not_in_complex(*this),
this->triangulation().finite_edges_begin());
}
/// Returns a Facets_in_complex_iterator to the first facet of the 1D complex
Edges_in_complex_iterator
edges_in_complex_begin(const Curve_segment_index& index) const
@ -381,17 +388,17 @@ public:
Edge_iterator_not_in_complex(*this,index),
this->triangulation().finite_edges_begin());
}
/// Returns past-the-end iterator on facet of the 1D complex
Edges_in_complex_iterator edges_in_complex_end(const Curve_segment_index& = Curve_segment_index()) const
{
return CGAL::filter_iterator(this->triangulation().finite_edges_end(),
Edge_iterator_not_in_complex(*this));
}
/// Iterator type to visit the edges of the 0D complex.
typedef Vertex_map_iterator_first_dereference Vertices_in_complex_iterator;
/// Returns a Vertices_in_complex_iterator to the first vertex of the 0D complex
Vertices_in_complex_iterator vertices_in_complex_begin() const
{
@ -407,20 +414,20 @@ public:
return CGAL::filter_iterator(corners_.end(),
Vertex_iterator_not_in_complex(*this,index),
corners_.begin());
}
}
/// Returns past-the-end iterator on facet of the 0D complex
Vertices_in_complex_iterator vertices_in_complex_end() const
{
return CGAL::filter_iterator(corners_.end(),
Vertex_iterator_not_in_complex(*this));
}
}
private:
/**
* Creates an Internal_edge object (i.e a pair of ordered Vertex_handle)
*/
*/
Internal_edge make_internal_edge(const Vertex_handle& v1,
const Vertex_handle& v2) const
{
@ -435,7 +442,7 @@ private:
{
return (curve_index(edge) != Curve_segment_index() );
}
/**
* Add edge \c edge to complex, with Curve_segment_index index
*/
@ -450,7 +457,7 @@ private:
std::pair<typename Edge_map::iterator, bool> it = edges_.insert(edge);
it.first->info = index;
}
/**
* Remove edge \c edge from complex
*/
@ -468,7 +475,7 @@ private:
if ( edges_.end() != it ) { return it->info; }
return Curve_segment_index();
}
private:
Edge_map edges_;
Corner_map corners_;
@ -483,23 +490,23 @@ Mesh_complex_3_in_triangulation_3(const Self& rhs)
, corners_()
{
// Copy edges
for ( typename Edge_map::const_iterator it = rhs.edges_.begin(),
for ( typename Edge_map::const_iterator it = rhs.edges_.begin(),
end = rhs.edges_.end() ; it != end ; ++it )
{
const Vertex_handle& va = it->right;
const Vertex_handle& vb = it->left;
Vertex_handle new_va;
this->triangulation().is_vertex(va->point(), new_va);
Vertex_handle new_vb;
this->triangulation().is_vertex(vb->point(), new_vb);
this->add_to_complex(make_internal_edge(new_va,new_vb), it->info);
}
// Copy corners
for ( typename Corner_map::const_iterator it = rhs.corners_.begin(),
for ( typename Corner_map::const_iterator it = rhs.corners_.begin(),
end = rhs.corners_.end() ; it != end ; ++it )
{
Vertex_handle new_v;
@ -516,7 +523,7 @@ Mesh_complex_3_in_triangulation_3<Tr,CI_,CSI_>::
adjacent_vertices_in_complex(const Vertex_handle& v, OutputIterator out) const
{
CGAL_precondition(v->in_dimension() < 2);
typedef typename Edge_map::right_const_iterator Rcit;
typedef typename Edge_map::left_const_iterator Lcit;
@ -526,14 +533,14 @@ adjacent_vertices_in_complex(const Vertex_handle& v, OutputIterator out) const
{
*out++ = std::make_pair(rit->second, rit->info);
}
// Add edges containing v on the right
std::pair<Lcit,Lcit> range_left = edges_.left.equal_range(v);
for ( Lcit lit = range_left.first ; lit != range_left.second ; ++lit )
{
*out++ = std::make_pair(lit->second, lit->info);
}
return out;
}
@ -548,7 +555,7 @@ is_valid(bool verbose) const
typedef Weight FT;
std::map<Vertex_handle, int> vertex_map;
// Fill map counting neighbor number for each vertex of an edge
for ( typename Edge_map::const_iterator it = edges_.begin(),
end = edges_.end() ; it != end ; ++it )
@ -556,12 +563,12 @@ is_valid(bool verbose) const
const Vertex_handle& v1 = it->right;
if ( vertex_map.find(v1) == vertex_map.end() ) { vertex_map[v1] = 1; }
else { vertex_map[v1] += 1; }
const Vertex_handle& v2 = it->left;
if ( vertex_map.find(v2) == vertex_map.end() ) { vertex_map[v2] = 1; }
else { vertex_map[v2] += 1; }
}
// Verify that each vertex has 2 neighbors if it's not a corner
for ( typename std::map<Vertex_handle, int>::iterator vit = vertex_map.begin(),
vend = vertex_map.end() ; vit != vend ; ++vit )
@ -576,53 +583,57 @@ is_valid(bool verbose) const
return false;
}
}
// Verify that balls of each edge intersect
for ( typename Edge_map::const_iterator it = edges_.begin(),
end = edges_.end() ; it != end ; ++it )
{
const Bare_point& p = it->right->point().point();
const Bare_point& q = it->left->point().point();
typename Tr::Geom_traits::Construct_sphere_3 sphere =
typename Tr::Geom_traits::Construct_sphere_3 sphere =
this->triangulation().geom_traits().construct_sphere_3_object();
typename Tr::Geom_traits::Do_intersect_3 do_intersect =
typename Tr::Geom_traits::Do_intersect_3 do_intersect =
this->triangulation().geom_traits().do_intersect_3_object();
const FT& sq_rp = it->right->point().weight();
const FT& sq_rq = it->left->point().weight();
if ( ! do_intersect(sphere(p, sq_rp), sphere(q, sq_rq)) )
{
std::cerr << "Point p[" << p << "], dim=" << it->right->in_dimension()
<< " and q[" << q << "], dim=" << it->left->in_dimension()
std::cerr << "Point p[" << p << "], dim=" << it->right->in_dimension()
<< " and q[" << q << "], dim=" << it->left->in_dimension()
<< " form an edge but do not intersect !\n";
return false;
}
}
return true;
}
template < class Tr, class CI_, class CSI_>
std::ostream &
operator<< (std::ostream& os,
template <typename Tr, typename CI_, typename CSI_>
std::ostream &
operator<< (std::ostream& os,
const Mesh_complex_3_in_triangulation_3<Tr,CI_,CSI_> &c3t3)
{
// TODO: implement edge saving
return os << static_cast<const Mesh_3::Mesh_complex_3_in_triangulation_3_base<Tr>&>(c3t3);
typedef typename Mesh_complex_3_in_triangulation_3<Tr,CI_,CSI_>::Concurrency_tag Concurrency_tag;
return os << static_cast<
const Mesh_3::Mesh_complex_3_in_triangulation_3_base<Tr, Concurrency_tag>&>(c3t3);
}
template < class Tr, class CI_, class CSI_>
std::istream &
operator>> (std::istream& is,
template <typename Tr, typename CI_, typename CSI_>
std::istream &
operator>> (std::istream& is,
Mesh_complex_3_in_triangulation_3<Tr,CI_,CSI_> &c3t3)
{
// TODO: implement edge loading
is >> static_cast<Mesh_3::Mesh_complex_3_in_triangulation_3_base<Tr>&>(c3t3);
typedef typename Mesh_complex_3_in_triangulation_3<Tr,CI_,CSI_>::Concurrency_tag Concurrency_tag;
is >> static_cast<
Mesh_3::Mesh_complex_3_in_triangulation_3_base<Tr, Concurrency_tag>&>(c3t3);
return is;
}

View File

@ -35,41 +35,46 @@
#include <CGAL/Compact_mesh_cell_base_3.h>
namespace CGAL {
namespace details {
template<typename K>
struct Mesh_geom_traits_generator
{
private:
typedef Robust_weighted_circumcenter_filtered_traits_3<K>
Geom_traits;
public:
typedef Geom_traits type;
typedef type Type;
}; // end struct Mesh_geom_traits_generator
} // end namespace details
// Struct Mesh_triangulation_3
//
template<class MD,
class K=typename Kernel_traits<MD>::Kernel,
class Concurrency_tag = Default,
class Concurrency_tag = Sequential_tag,
class Vertex_base_ = Default,
class Cell_base_ = Default>
struct Mesh_triangulation_3;
// Sequential version (default)
template<class MD, class K, class Concurrency_tag,
class Vertex_base_, class Cell_base_>
struct Mesh_triangulation_3
{
{
private:
typedef typename details::Mesh_geom_traits_generator<K>::type Geom_traits;
typedef typename Default::Get<
Vertex_base_,
Vertex_base_,
Mesh_vertex_base_3<Geom_traits, MD> >::type Vertex_base;
typedef typename Default::Get<
Cell_base_,
Cell_base_,
Compact_mesh_cell_base_3<Geom_traits, MD> >::type Cell_base;
typedef Triangulation_data_structure_3<Vertex_base,Cell_base> Tds;
@ -80,6 +85,33 @@ public:
typedef type Type;
}; // end struct Mesh_triangulation_3
#ifdef CGAL_LINKED_WITH_TBB
// Parallel version (specialization)
//
template<class MD, class K,
class Vertex_base_, class Cell_base_>
struct Mesh_triangulation_3<MD, K, Parallel_tag, Vertex_base_, Cell_base_>
{
private:
typedef typename details::Mesh_geom_traits_generator<K>::type Geom_traits;
typedef typename Default::Get<
Vertex_base_,
Mesh_vertex_base_3<Geom_traits, MD> >::type Vertex_base;
typedef typename Default::Get<
Cell_base_,
Compact_mesh_cell_base_3<Geom_traits, MD> >::type Cell_base;
typedef Triangulation_data_structure_3<
Vertex_base, Cell_base, Parallel_tag> Tds;
typedef Regular_triangulation_3<Geom_traits, Tds> Triangulation;
public:
typedef Triangulation type;
typedef type Type;
}; // end struct Mesh_triangulation_3
#endif // CGAL_LINKED_WITH_TBB
} // end namespace CGAL
#endif // CGAL_MESH_TRIANGULATION_3_H

View File

@ -35,6 +35,62 @@
#include <CGAL/Mesh_3/io_signature.h>
namespace CGAL {
// Without erase counter
template <typename Concurrency_tag>
class Mesh_vertex_base_3_base
{
#if defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) \
|| defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE)
public:
// Erase counter (cf. Compact_container)
unsigned int erase_counter() const
{
return this->m_erase_counter;
}
void set_erase_counter(unsigned int c)
{
this->m_erase_counter = c;
}
void increment_erase_counter()
{
++this->m_erase_counter;
}
protected:
typedef unsigned int Erase_counter_type;
Erase_counter_type m_erase_counter;
#endif
};
#ifdef CGAL_LINKED_WITH_TBB
// Specialized version (parallel)
template <>
class Mesh_vertex_base_3_base<Parallel_tag>
{
public:
// Erase counter (cf. Compact_container)
unsigned int erase_counter() const
{
return this->m_erase_counter;
}
void set_erase_counter(unsigned int c)
{
this->m_erase_counter = c;
}
void increment_erase_counter()
{
++this->m_erase_counter;
}
protected:
typedef tbb::atomic<unsigned int> Erase_counter_type;
Erase_counter_type m_erase_counter;
};
#endif // CGAL_LINKED_WITH_TBB
// Class Mesh_vertex_base_3
// Vertex base class used in 3D meshing process.
@ -44,7 +100,9 @@ template<class GT,
class MD,
class Vb = Triangulation_vertex_base_3<GT> >
class Mesh_vertex_base_3
: public Vb
: public Vb,
public Mesh_vertex_base_3_base<
typename Vb::Triangulation_data_structure::Concurrency_tag>
{
public:
typedef Vb Cmvb3_base;

View File

@ -0,0 +1,318 @@
// Copyright (c) 2012 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL: $
// $Id: $
//
//
// Author(s) : Clement JAMIN
#ifndef CGAL_MESHES_FILTERED_DEQUE_CONTAINER_H
#define CGAL_MESHES_FILTERED_DEQUE_CONTAINER_H
#include <algorithm>
#include <utility>
#include <deque>
#ifdef CGAL_LINKED_WITH_TBB
#include <tbb/enumerable_thread_specific.h>
#endif
namespace CGAL {
namespace Meshes {
/************************************************
// Class Filtered_deque_container_base
// Two versions: sequential / parallel
************************************************/
// Sequential
template <typename Element, typename Quality,
typename Concurrency_tag>
class Filtered_deque_container_base
{
public:
typedef std::deque<std::pair<Quality, Element> > Container;
typedef typename Container::size_type size_type;
typedef typename Container::value_type value_type;
void add_to_TLS_lists_impl(bool add) {}
Element get_next_local_element_impl()
{ return Element(); }
value_type get_next_local_raw_element_impl()
{ return value_type(); }
void pop_next_local_element_impl() {}
protected:
Filtered_deque_container_base() {}
Filtered_deque_container_base(bool) {}
template<typename Container>
void splice_local_lists_impl(Container &)
{}
template <typename Predicate>
bool no_longer_local_element_to_refine_impl(const Predicate &)
{
return true;
}
template<typename Container>
void insert_raw_element(const value_type &re, Container &container)
{
container.push_back(re);
}
};
#ifdef CGAL_LINKED_WITH_TBB
// Parallel
template <typename Element, typename Quality>
class Filtered_deque_container_base<Element, Quality, Parallel_tag>
{
public:
typedef std::deque<std::pair<Quality, Element> > Container;
typedef typename Container::size_type size_type;
typedef typename Container::value_type value_type;
void add_to_TLS_lists_impl(bool add)
{
m_add_to_TLS_lists = add;
}
// Warning: no_longer_local_element_to_refine_impl must have been called
// just before calling get_next_local_element_impl
// (successive calls to "get_next_local_element_impl" are not allowed)
Element get_next_local_element_impl()
{
CGAL_assertion(!m_local_lists.local().empty());
// Add this? It shouldn't be necessary as user
// is supposed to call "no_longer_element_to_refine_impl" first
/*while( !test(container.front()) )
{
container.pop_front();
}*/
return m_local_lists.local().front().second;
}
// Warning: no_longer_local_element_to_refine_impl must have been called
// just before calling get_next_local_raw_element_impl
// (successive calls to "get_next_local_raw_element_impl" are not allowed)
value_type get_next_local_raw_element_impl()
{
CGAL_assertion(!m_local_lists.local().empty());
return m_local_lists.local().front();
}
void pop_next_local_element_impl()
{
// Erase last element
m_local_lists.local().pop_front();
}
protected:
Filtered_deque_container_base(bool add_to_TLS_lists = false)
: m_add_to_TLS_lists(add_to_TLS_lists) {}
template<typename Container>
void splice_local_lists_impl(Container &container)
{
for(typename LocalList::iterator it_list = m_local_lists.begin() ;
it_list != m_local_lists.end() ;
++it_list )
{
#ifdef _DEBUG
size_t deque_size = container.size();
size_t local_list_size = it_list->size();
#endif
container.insert(container.end(), it_list->begin(), it_list->end());
it_list->clear();
}
}
template <typename Predicate>
bool no_longer_local_element_to_refine_impl(const Predicate &test)
{
bool is_empty = m_local_lists.local().empty();
while( !is_empty && !test(m_local_lists.local().front().second) )
{
pop_next_local_element_impl();
is_empty = m_local_lists.local().empty();
}
return is_empty;
}
template<typename Container>
void insert_raw_element(const value_type &re, Container &container)
{
if (m_add_to_TLS_lists)
m_local_lists.local().push_back(re);
else
container.push_back(re);
}
// === Member variables ===
typedef tbb::enumerable_thread_specific<
std::deque<std::pair<Quality, Element> > > LocalList;
LocalList m_local_lists;
bool m_add_to_TLS_lists;
};
#endif // CGAL_LINKED_WITH_TBB
/************************************************
// Class Filtered_deque_container
//
// This container is a filtered deque:
// front() and empty() use an object predicate
// to test if the element is ok.
************************************************/
template <typename Element_, typename Quality_,
typename Predicate, typename Concurrency_tag>
class Filtered_deque_container
: public Filtered_deque_container_base<Element_, Quality_, Concurrency_tag>
{
public:
typedef Filtered_deque_container_base<Element_, Quality_, Concurrency_tag> Base;
typedef typename Base::Container Container;
typedef typename Base::value_type value_type;
typedef typename Base::size_type size_type;
typedef Quality_ Quality;
typedef Element_ Element;
protected:
// --- protected datas ---
Container container;
Predicate test;
static bool CompareTwoElements(std::pair<Quality, Element> e1,
std::pair<Quality, Element> e2)
{
return (e1.first < e2.first);
}
public:
// Constructors - For sequential
Filtered_deque_container() {}
explicit Filtered_deque_container(const Predicate &p)
: test(p) {}
// Constructors - For parallel
explicit Filtered_deque_container(bool add_to_TLS_lists)
: Base(add_to_TLS_lists) {}
explicit Filtered_deque_container(const Predicate &p, bool add_to_TLS_lists)
: test(p), Base(add_to_TLS_lists) {}
void splice_local_lists_impl()
{
Base::splice_local_lists_impl(container);
}
bool no_longer_local_element_to_refine_impl()
{
return Base::no_longer_local_element_to_refine_impl(test);
}
void insert_raw_element(const value_type &re)
{
Base::insert_raw_element(re, container);
}
bool no_longer_element_to_refine_impl()
{
#ifdef _DEBUG
size_t deque_size = container.size();
#endif
bool is_empty = container.empty();
while( !is_empty && !test(container.front().second) )
{
pop_next_element_impl();
is_empty = container.empty();
}
return is_empty;
}
// Warning: no_longer_element_to_refine_impl must have been called
// just before calling get_next_element_impl
// (successive calls to "get_next_element_impl" are not allowed)
Element get_next_element_impl() const
{
CGAL_assertion(!container.empty());
// Add this? It shouldn't be necessary as user
// is supposed to call "no_longer_element_to_refine_impl" first
/*while( !test(container.front()) )
{
container.pop_front();
}*/
return container.front().second;
}
void add_bad_element(const Element& e, const Quality& q)
{
insert_raw_element(std::make_pair(q, e));
}
void pop_next_element_impl()
{
// Erase last element
container.pop_front();
}
// Sort
// Worst (smallest) quality first
void sort ()
{
std::sort(container.begin(), container.end(), CompareTwoElements);
}
// Clear
void clear ()
{
container.clear();
}
// Random shuffle
void random_shuffle ()
{
std::random_shuffle(container.begin(), container.end());
}
size_type size() const
{
return container.size();
}
// Warning: no_longer_element_to_refine_impl must have been called
// just before calling get_next_raw_element_impl
// (successive calls to "get_next_raw_element_impl" are not allowed)
value_type get_next_raw_element_impl()
{
CGAL_assertion(!container.empty());
return container.front();
}
bool is_zombie(const Element &e) const
{
return !test(e);
}
}; // end Filtered_deque_container
} // end namespace Mesh_3
} // end namespace CGAL
#endif // CGAL_MESHES_FILTERED_DEQUE_CONTAINER_H

View File

@ -0,0 +1,309 @@
// Copyright (c) 2012 INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// You can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL: $
// $Id: $
//
//
// Author(s) : Clement JAMIN
#ifndef CGAL_MESHES_FILTERED_MULTIMAP_CONTAINER_H
#define CGAL_MESHES_FILTERED_MULTIMAP_CONTAINER_H
#include <map>
#include <deque>
#ifdef CGAL_LINKED_WITH_TBB
#include <tbb/enumerable_thread_specific.h>
#endif
namespace CGAL {
namespace Meshes {
/************************************************
// Class Filtered_multimap_container_base
// Two versions: sequential / parallel
************************************************/
// Sequential
template <typename Element, typename Quality,
typename Concurrency_tag>
class Filtered_multimap_container_base
{
public:
typedef std::multimap<Quality, Element> Map;
typedef typename Map::size_type size_type;
typedef typename Map::value_type value_type;
void add_to_TLS_lists_impl(bool add) {}
Element get_next_local_element_impl()
{ return Element(); }
value_type get_next_local_raw_element_impl()
{ return value_type(); }
void pop_next_local_element_impl() {}
protected:
Filtered_multimap_container_base() {}
Filtered_multimap_container_base(bool) {}
template<typename Container>
void splice_local_lists_impl(Container &)
{}
template <typename Predicate>
bool no_longer_local_element_to_refine_impl(const Predicate &)
{
return true;
}
template<typename Container>
void insert_raw_element(const value_type &re, Container &container)
{
container.insert(re);
}
};
#ifdef CGAL_LINKED_WITH_TBB
// Parallel
template <typename Element, typename Quality>
class Filtered_multimap_container_base<Element, Quality, Parallel_tag>
{
public:
typedef std::multimap<Quality, Element> Map;
typedef typename Map::size_type size_type;
typedef typename Map::value_type value_type;
void add_to_TLS_lists_impl(bool add)
{
m_add_to_TLS_lists = add;
}
// Warning: no_longer_local_element_to_refine_impl must have been called
// just before calling get_next_local_element_impl
// (successive calls to "get_next_local_element_impl" are not allowed)
Element get_next_local_element_impl()
{
CGAL_assertion(!m_local_lists.local().empty());
// Add this? It shouldn't be necessary as user
// is supposed to call "no_longer_element_to_refine_impl" first
/*while( !test(container.front()) )
{
container.pop_front();
}*/
return m_local_lists.local().front().second;
}
// Warning: no_longer_local_element_to_refine_impl must have been called
// just before calling get_next_local_raw_element_impl
// (successive calls to "get_next_local_raw_element_impl" are not allowed)
value_type get_next_local_raw_element_impl()
{
CGAL_assertion(!m_local_lists.local().empty());
return m_local_lists.local().front();
}
void pop_next_local_element_impl()
{
// Erase last element
m_local_lists.local().pop_front();
}
protected:
Filtered_multimap_container_base(bool add_to_TLS_lists = false)
: m_add_to_TLS_lists(add_to_TLS_lists) {}
template<typename Container>
void splice_local_lists_impl(Container &container)
{
for(typename LocalList::iterator it_list = m_local_lists.begin() ;
it_list != m_local_lists.end() ;
++it_list )
{
#ifdef _DEBUG
size_t multimap_size = container.size();
size_t local_list_size = it_list->size();
#endif
container.insert(it_list->begin(), it_list->end());
it_list->clear();
}
}
template <typename Predicate>
bool no_longer_local_element_to_refine_impl(const Predicate &test)
{
bool is_empty = m_local_lists.local().empty();
while( !is_empty && !test(m_local_lists.local().front().second) )
{
pop_next_local_element_impl();
is_empty = m_local_lists.local().empty();
}
return is_empty;
}
template<typename Container>
void insert_raw_element(const value_type &re, Container &container)
{
if (m_add_to_TLS_lists)
m_local_lists.local().push_back(re);
else
container.insert(re);
}
// === Member variables ===
typedef tbb::enumerable_thread_specific<
std::deque<std::pair<Quality, Element> > > LocalList;
LocalList m_local_lists;
bool m_add_to_TLS_lists;
};
#endif // CGAL_LINKED_WITH_TBB
/************************************************
// Class Filtered_multimap_container
//
// This container is a filtered multimap:
// front() and empty() use an object predicate
// to test if the element is ok.
************************************************/
template <typename Element_, typename Quality_,
typename Predicate, typename Concurrency_tag>
class Filtered_multimap_container
: public Filtered_multimap_container_base<Element_, Quality_, Concurrency_tag>
{
public:
typedef Quality_ Quality;
typedef Element_ Element;
typedef Filtered_multimap_container_base<Element_, Quality_, Concurrency_tag> Base;
typedef typename Base::Map Map;
typedef typename Base::value_type value_type;
typedef typename Base::size_type size_type;
protected:
// --- protected datas ---
Map container;
Predicate test;
public:
// Constructors - For sequential
Filtered_multimap_container() {}
explicit Filtered_multimap_container(const Predicate &p)
: test(p) {}
// Constructors - For parallel
explicit Filtered_multimap_container(bool add_to_TLS_lists)
: Base(add_to_TLS_lists) {}
explicit Filtered_multimap_container(const Predicate &p, bool add_to_TLS_lists)
: test(p), Base(add_to_TLS_lists) {}
void splice_local_lists_impl()
{
#ifdef _DEBUG
size_t s = size();
#endif
Base::splice_local_lists_impl(container);
}
bool no_longer_local_element_to_refine_impl()
{
return Base::no_longer_local_element_to_refine_impl(test);
}
void insert_raw_element(const value_type &re)
{
Base::insert_raw_element(re, container);
}
bool no_longer_element_to_refine_impl()
{
#ifdef _DEBUG
size_t multimap_size = container.size();
#endif
bool is_empty = container.empty();
while( !is_empty && !test(container.begin()->second) )
{
pop_next_element_impl();
is_empty = container.empty();
}
return is_empty;
}
// Warning: no_longer_element_to_refine_impl must have been called
// just before calling get_next_element_impl
// (successive calls to "get_next_element_impl" are not allowed)
Element get_next_element_impl() const
{
CGAL_assertion(!container.empty());
// Add this? It shouldn't be necessary as user
// is supposed to call "no_longer_element_to_refine_impl" first
/*while( !test(container.front()) )
{
container.pop_front();
}*/
return container.begin()->second;
}
void add_bad_element(const Element& e, const Quality& q)
{
insert_raw_element(std::make_pair(q, e));
}
void pop_next_element_impl()
{
// Erase last element
container.erase( container.begin() );
}
/*void remove_element(const Element& e)
{
container.erase(container.find(e));
}
const Quality& quality(const Element& e)
{
return container[e];
}*/
size_type size() const
{
return container.size();
}
// Clear
void clear ()
{
container.clear();
}
// Warning: no_longer_element_to_refine_impl must have been called
// just before calling get_next_raw_element_impl
// (successive calls to "get_next_raw_element_impl" are not allowed)
value_type get_next_raw_element_impl()
{
CGAL_assertion(!container.empty());
return *container.begin();
}
bool is_zombie(const Element &e) const
{
return !test(e);
}
}; // end Filtered_multimap_container
} // end namespace Mesh_3
} // end namespace CGAL
#endif // CGAL_MESHES_FILTERED_MULTIMAP_CONTAINER_H

View File

@ -50,6 +50,10 @@
#include <boost/variant.hpp>
#include <boost/math/special_functions/round.hpp>
#ifdef CGAL_LINKED_WITH_TBB
# include <tbb/enumerable_thread_specific.h>
#endif
namespace CGAL {
namespace Mesh_3 {
@ -202,8 +206,8 @@ public:
/// Default constructor
Polyhedral_mesh_domain_3()
: tree_()
, bounding_tree_(&tree_)
, has_cache(false) {}
, bounding_tree_(&tree_)
{}
/**
* @brief Constructor. Contruction from a polyhedral surface
@ -211,9 +215,8 @@ public:
*/
Polyhedral_mesh_domain_3(const Polyhedron& p)
: tree_(TriangleAccessor().triangles_begin(p),
TriangleAccessor().triangles_end(p)),
bounding_tree_(&tree_) // the bounding tree is tree_
, has_cache(false)
TriangleAccessor().triangles_end(p))
, bounding_tree_(&tree_) // the bounding tree is tree_
{
if(!p.is_pure_triangle()) {
std::cerr << "Your input polyhedron must be triangulated!\n";
@ -227,7 +230,6 @@ public:
TriangleAccessor().triangles_end(p))
, bounding_tree_(new AABB_tree_(TriangleAccessor().triangles_begin(bounding_polyhedron),
TriangleAccessor().triangles_end(bounding_polyhedron)))
, has_cache(false)
{
tree_.insert(TriangleAccessor().triangles_begin(bounding_polyhedron),
TriangleAccessor().triangles_end(bounding_polyhedron));
@ -250,7 +252,6 @@ public:
Polyhedral_mesh_domain_3(InputPolyhedraPtrIterator begin,
InputPolyhedraPtrIterator end,
const Polyhedron& bounding_polyhedron)
: has_cache(false)
{
if(begin != end) {
for(; begin != end; ++begin) {
@ -285,7 +286,6 @@ public:
template <typename InputPolyhedraPtrIterator>
Polyhedral_mesh_domain_3(InputPolyhedraPtrIterator begin,
InputPolyhedraPtrIterator end)
: has_cache(false)
{
if(begin != end) {
for(; begin != end; ++begin) {
@ -423,14 +423,14 @@ public:
#ifndef CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3
if(r_domain_.query_is_cached(q))
{
const AABB_primitive_id primitive_id = r_domain_.cached_primitive_id;
const AABB_primitive_id primitive_id = r_domain_.cached_primitive_id();
typename cpp11::result_of<
typename IGT::Intersect_3(typename Primitive::Datum, Query)>::type o
= IGT().intersect_3_object()(Primitive(primitive_id).datum(),q);
intersection = o ?
Intersection_and_primitive_id(*o, primitive_id) :
AABB_intersection();
} else
} else
#endif // not CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3
{
#ifndef CGAL_MESH_3_NO_LONGER_CALLS_DO_INTERSECT_3
@ -589,11 +589,20 @@ private:
AABB_tree_* bounding_tree_;
// cache queries and intersected primitive
// cache queries and intersected primitive
typedef typename boost::make_variant_over<Allowed_query_types>::type Cached_query;
mutable bool has_cache;
mutable Cached_query cached_query;
mutable AABB_primitive_id cached_primitive_id;
struct Query_cache
{
Query_cache() : has_cache(false) {}
bool has_cache;
Cached_query cached_query;
AABB_primitive_id cached_primitive_id;
};
#ifdef CGAL_LINKED_WITH_TBB
mutable tbb::enumerable_thread_specific<Query_cache> query_cache;
#else
mutable Query_cache query_cache;
#endif
public:
@ -601,14 +610,35 @@ public:
void cache_primitive(const Query& q,
const AABB_primitive_id id) const
{
cached_query = Cached_query(q);
has_cache = true;
cached_primitive_id = id;
#ifdef CGAL_LINKED_WITH_TBB
Query_cache &qc = query_cache.local();
qc.cached_query = Cached_query(q);
qc.has_cache = true;
qc.cached_primitive_id = id;
#else
query_cache.cached_query = Cached_query(q);
query_cache.has_cache = true;
query_cache.cached_primitive_id = id;
#endif
}
template <typename Query>
bool query_is_cached(const Query& q) const {
return has_cache && (cached_query == Cached_query(q));
#ifdef CGAL_LINKED_WITH_TBB
Query_cache &qc = query_cache.local();
return qc.has_cache && (qc.cached_query == Cached_query(q));
#else
return query_cache.has_cache
&& (query_cache.cached_query == Cached_query(q));
#endif
}
AABB_primitive_id cached_primitive_id() const {
#ifdef CGAL_LINKED_WITH_TBB
return query_cache.local().cached_primitive_id;
#else
return query_cache.cached_primitive_id;
#endif
}
private:
@ -641,9 +671,9 @@ Construct_initial_points::operator()(OutputIterator pts,
Random_points_on_sphere_3<Point_3> random_point(1.);
int i = n;
#ifdef CGAL_MESH_3_VERBOSE
# ifdef CGAL_MESH_3_VERBOSE
std::cerr << "construct initial points:" << std::endl;
#endif
# endif
// Point construction by ray shooting from the center of the enclosing bbox
while ( i > 0 )
{
@ -666,11 +696,11 @@ Construct_initial_points::operator()(OutputIterator pts,
"%1%/%2% initial point(s) found...")
% (n - i)
% n;
#endif
# endif
}
++random_point;
}
#ifdef CGAL_MESH_3_VERBOSE
std::cerr << std::endl;
#endif

Some files were not shown because too many files have changed in this diff Show More