mirror of https://github.com/CGAL/cgal
Add benchmark code (from branch Surface_mesh-GF, thanks to Philipp).
This commit is contained in:
parent
9a20e0e0c7
commit
aa31f66f50
|
|
@ -0,0 +1,11 @@
|
|||
project(LCC_performance)
|
||||
|
||||
cmake_minimum_required(VERSION 2.6.2)
|
||||
|
||||
find_package(CGAL REQUIRED)
|
||||
include(${CGAL_USE_FILE})
|
||||
|
||||
include_directories(BEFORE "../../include")
|
||||
|
||||
add_executable(lcc_performance performance.h lcc_performance.h lcc_performance.cpp)
|
||||
target_link_libraries(lcc_performance ${CGAL_LIBRARIES})
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
//=============================================================================
|
||||
|
||||
#ifndef STOPWATCH_HH
|
||||
#define STOPWATCH_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
#else // Unix
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
//== NAMESPACE ================================================================
|
||||
|
||||
namespace graphene {
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
/// Simple class for a stop watch
|
||||
class StopWatch
|
||||
{
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
StopWatch()
|
||||
{
|
||||
#ifdef _WIN32 // Windows
|
||||
QueryPerformanceFrequency(&freq_);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// Start time measurement
|
||||
void start()
|
||||
{
|
||||
#ifdef _WIN32 // Windows
|
||||
QueryPerformanceCounter(&starttime_);
|
||||
#else // Linux
|
||||
starttime_ = current_time();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/// Stop time measurement, return elapsed time in ms
|
||||
double stop()
|
||||
{
|
||||
#ifdef _WIN32 // Windows
|
||||
QueryPerformanceCounter(&endtime_);
|
||||
#else // Unix
|
||||
endtime_ = current_time();
|
||||
#endif
|
||||
return elapsed();
|
||||
}
|
||||
|
||||
/// Return elapsed time in ms (watch has to be stopped).
|
||||
double elapsed() const
|
||||
{
|
||||
#ifdef _WIN32 // Windows
|
||||
return ((double)(endtime_.QuadPart - starttime_.QuadPart)
|
||||
/ (double)freq_.QuadPart * 1000.0f);
|
||||
#else // Unix
|
||||
return ((endtime_.tv_sec - starttime_.tv_sec )*1000.0 +
|
||||
(endtime_.tv_usec - starttime_.tv_usec)*0.001);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
#ifdef _WIN32 // Windows
|
||||
|
||||
LARGE_INTEGER starttime_, endtime_;
|
||||
LARGE_INTEGER freq_;
|
||||
|
||||
#else // Unix
|
||||
|
||||
timeval current_time() const
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, 0);
|
||||
return tv;
|
||||
}
|
||||
|
||||
timeval starttime_, endtime_;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/// output a timer to a stream
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& _os, const StopWatch& _timer)
|
||||
{
|
||||
_os << _timer.elapsed() << " ms";
|
||||
return _os;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace graphene
|
||||
//=============================================================================
|
||||
#endif // STOPWATCH_HH defined
|
||||
//=============================================================================
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
//== INCLUDES =================================================================
|
||||
|
||||
|
||||
#include "lcc_performance.h"
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
std::cerr << "Usage:\n" << argv[0] << " <input-mesh>\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
LCC_performance().run(argv[1], "output_cgal.off");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
|
@ -0,0 +1,447 @@
|
|||
//== INCLUDES =================================================================
|
||||
|
||||
|
||||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Linear_cell_complex.h>
|
||||
#include <CGAL/Linear_cell_complex_constructors.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include "performance.h"
|
||||
|
||||
#define HAS_NORMALS 1
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
typedef CGAL::Simple_cartesian<double> MyKernelLCC;
|
||||
typedef MyKernelLCC::Point_3 Point_3;
|
||||
typedef MyKernelLCC::Vector_3 Vector_3;
|
||||
|
||||
class MyItemsLCC
|
||||
{
|
||||
public:
|
||||
|
||||
template <class LCC>
|
||||
struct Dart_wrapper
|
||||
{
|
||||
typedef CGAL::Dart<2, LCC> Dart; // Dim 2 == Polyhedron
|
||||
|
||||
#if HAS_NORMALS
|
||||
typedef CGAL::Cell_attribute_with_point<LCC, Vector_3, CGAL::Tag_true> Vertex;
|
||||
typedef CGAL::Cell_attribute<LCC, Vector_3, CGAL::Tag_true> Face;
|
||||
#else
|
||||
typedef CGAL::Cell_attribute_with_point<LCC, void, CGAL::Tag_true> Vertex;
|
||||
typedef CGAL::Cell_attribute<LCC, void, CGAL::Tag_true> Face;
|
||||
#endif
|
||||
typedef CGAL::cpp0x::tuple<Vertex,void,Face> Attributes;
|
||||
};
|
||||
};
|
||||
|
||||
typedef CGAL::Linear_cell_complex_traits<3, MyKernelLCC> MyTraitsLCC;
|
||||
typedef CGAL::Linear_cell_complex<2, 3, MyTraitsLCC, MyItemsLCC> LCC;
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
class LCC_performance : public Performance_test
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
LCC lcc;
|
||||
|
||||
private:
|
||||
|
||||
virtual bool read_mesh(const char* _filename)
|
||||
{
|
||||
std::ifstream ifs(_filename);
|
||||
CGAL::load_off(lcc, ifs);
|
||||
// lcc.display_characteristics(std::cout);
|
||||
|
||||
for ( LCC::Dart_range::iterator dit=lcc.darts().begin(),
|
||||
dend=lcc.darts().end(); dit!=dend; ++dit )
|
||||
{
|
||||
if ( dit->attribute<2>()==NULL )
|
||||
lcc.set_attribute<2>(dit, lcc.create_attribute<2>());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
virtual bool write_mesh(const char* _filename)
|
||||
{
|
||||
std::ofstream ofs(_filename);
|
||||
// CGAL::write_off(lcc, ofs);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
virtual int circulator_test()
|
||||
{
|
||||
LCC::Vertex_attribute_range::iterator vit, vend = lcc.vertex_attributes().end();
|
||||
LCC::Attribute_range<2>::type::iterator fit, fend = lcc.attributes<2>().end();
|
||||
|
||||
int counter = 0;
|
||||
|
||||
for (vit = lcc.vertex_attributes().begin(); vit != vend; ++vit)
|
||||
{
|
||||
for( LCC::Dart_of_cell_range<0>::iterator
|
||||
vhit = lcc.darts_of_cell<0>(vit->dart()).begin(),
|
||||
vhend = lcc.darts_of_cell<0>(vit->dart()).end();
|
||||
vhit!=vhend; ++vhit )
|
||||
{
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
|
||||
for (fit = lcc.attributes<2>().begin(); fit != fend; ++fit)
|
||||
{
|
||||
for( LCC::Dart_of_cell_range<2>::iterator
|
||||
fhit = lcc.darts_of_cell<2>(fit->dart()).begin(),
|
||||
fhend = lcc.darts_of_cell<2>(fit->dart()).end();
|
||||
fhit!=fhend; ++fhit )
|
||||
{
|
||||
--counter;
|
||||
}
|
||||
}
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
|
||||
virtual void barycenter_test()
|
||||
{
|
||||
LCC::Vertex_attribute_range::iterator vit, vend = lcc.vertex_attributes().end();
|
||||
Vector_3 v(CGAL::NULL_VECTOR);
|
||||
for (vit = lcc.vertex_attributes().begin(); vit != vend; ++vit)
|
||||
{
|
||||
v = v + (vit->point() - CGAL::ORIGIN);
|
||||
}
|
||||
v = v / lcc.number_of_vertex_attributes();
|
||||
for (vit = lcc.vertex_attributes().begin(); vit != vend; ++vit)
|
||||
{
|
||||
vit->point() = vit->point() - v;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virtual void normal_test()
|
||||
{
|
||||
#if HAS_NORMALS
|
||||
LCC::Vertex_attribute_range::iterator vit, vend = lcc.vertex_attributes().end();
|
||||
LCC::Attribute_range<2>::type::iterator fit, fend = lcc.attributes<2>().end();
|
||||
|
||||
for (fit = lcc.attributes<2>().begin(); fit != fend; ++fit)
|
||||
{
|
||||
LCC::Dart_handle dh = fit->dart();
|
||||
Point_3 p0 = LCC::point(dh);
|
||||
dh = dh->beta(1);
|
||||
Point_3 p1 = LCC::point(dh);
|
||||
dh = dh->beta(1);
|
||||
Point_3 p2 = LCC::point(dh);
|
||||
Vector_3 n = cross_product(p0-p1, p2-p1);
|
||||
n = n / sqrt(n.squared_length());
|
||||
fit->info() = n; // info is here the normal
|
||||
}
|
||||
|
||||
for (vit = lcc.vertex_attributes().begin(); vit != vend; ++vit)
|
||||
{
|
||||
Vector_3 n(0,0,0);
|
||||
for( LCC::Dart_of_cell_range<0>::iterator
|
||||
vhit = lcc.darts_of_cell<0>(vit->dart()).begin(),
|
||||
vhend = lcc.darts_of_cell<0>(vit->dart()).end();
|
||||
vhit!=vhend; ++vhit )
|
||||
{
|
||||
n = n + vhit->attribute<2>()->info();
|
||||
}
|
||||
n = n / sqrt(n.squared_length());
|
||||
vit->info() = n; // info is here the normal
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual void smoothing_test()
|
||||
{
|
||||
LCC::Vertex_attribute_range::iterator vit, vend = lcc.vertex_attributes().end();
|
||||
|
||||
for (vit = lcc.vertex_attributes().begin(); vit != vend; ++vit)
|
||||
{
|
||||
bool vertex_is_border = false;
|
||||
Vector_3 v(0,0,0);
|
||||
float c(0);
|
||||
for( LCC::Dart_of_cell_range<0>::iterator
|
||||
vhit = lcc.darts_of_cell<0>(vit->dart()).begin(),
|
||||
vhend = lcc.darts_of_cell<0>(vit->dart()).end();
|
||||
vhit!=vhend; ++vhit )
|
||||
{
|
||||
if (vhit->is_free(2))
|
||||
{
|
||||
vertex_is_border = true;
|
||||
break;
|
||||
}
|
||||
v = v + (LCC::point(vhit->other_extremity()) - CGAL::ORIGIN);
|
||||
++c;
|
||||
}
|
||||
if (!vertex_is_border)
|
||||
vit->point() = CGAL::ORIGIN + (v / c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void flip_edge(LCC::Dart_handle d)
|
||||
{
|
||||
LCC::Dart_handle d1 = d->beta(1);
|
||||
LCC::Dart_handle d2 = d->beta(2)->beta(0);
|
||||
|
||||
CGAL_assertion ( !d1->is_free(1) && !d2->is_free(0) );
|
||||
|
||||
LCC::Dart_handle d3 = d1->beta(1);
|
||||
LCC::Dart_handle d4 = d2->beta(0);
|
||||
|
||||
// We isolated the edge
|
||||
lcc.basic_link_beta_1(d->beta(0), d->beta(2)->beta(1));
|
||||
lcc.basic_link_beta_0(d->beta(1), d->beta(2)->beta(0));
|
||||
|
||||
// Then we push the two extremities.
|
||||
lcc.basic_link_beta_0(d3, d);
|
||||
lcc.basic_link_beta_0(d2, d->beta(2));
|
||||
lcc.link_beta_1(d4, d);
|
||||
lcc.link_beta_1(d1, d->beta(2));
|
||||
}
|
||||
|
||||
virtual void subdivision_test()
|
||||
{
|
||||
// for vector-storage we *must* reserve memory first!
|
||||
int nv = lcc.number_of_vertex_attributes();
|
||||
/*int nh = lcc.number_of_darts();
|
||||
int nf = lcc.number_of_attributes<2>();*/
|
||||
// lcc.reserve(nv+nf, nh+6*nf, 3*nf); /: TODO implement in CMap ?
|
||||
|
||||
// iterators
|
||||
LCC::Vertex_attribute_range::iterator vit, vend = lcc.vertex_attributes().end();
|
||||
LCC::Attribute_range<2>::type::iterator fit, fend = lcc.attributes<2>().end();
|
||||
LCC::Dart_range::iterator dit, dend =lcc.darts().end();
|
||||
|
||||
// compute new positions of old vertices
|
||||
int i;
|
||||
std::vector<Point_3> new_pos(nv);
|
||||
for (vit = lcc.vertex_attributes().begin(), i=0; vit != vend; ++vit, ++i)
|
||||
{
|
||||
bool is_border = false;
|
||||
Vector_3 v(0,0,0);
|
||||
float n = 0;
|
||||
|
||||
for( LCC::Dart_of_cell_range<0>::iterator
|
||||
vhit = lcc.darts_of_cell<0>(vit->dart()).begin(),
|
||||
vhend = lcc.darts_of_cell<0>(vit->dart()).end();
|
||||
vhit!=vhend; ++vhit )
|
||||
{
|
||||
if (vhit->is_free(2))
|
||||
{
|
||||
is_border = true;
|
||||
break;
|
||||
}
|
||||
|
||||
v = v + (LCC::point(vhit->other_extremity()) - CGAL::ORIGIN);
|
||||
++n;
|
||||
}
|
||||
|
||||
if ( !is_border )
|
||||
{
|
||||
float alpha = (4.0 - 2.0*cos(2.0*M_PI/n)) / 9.0;
|
||||
v = (1.0f-alpha)*(vit->point() - CGAL::ORIGIN) + alpha/n*v;
|
||||
new_pos[i] = CGAL::ORIGIN + v;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_pos[i] = vit->point();
|
||||
}
|
||||
}
|
||||
|
||||
// adjust end iterators
|
||||
--vend; --fend; --dend;
|
||||
|
||||
// split faces
|
||||
fit = lcc.attributes<2>().begin();
|
||||
do
|
||||
{
|
||||
Vector_3 v(CGAL::NULL_VECTOR);
|
||||
float c(0);
|
||||
|
||||
for( LCC::Dart_of_cell_range<2>::iterator
|
||||
vhit = lcc.darts_of_cell<2>(fit->dart()).begin(),
|
||||
vhend = lcc.darts_of_cell<2>(fit->dart()).end();
|
||||
vhit!=vhend; ++vhit )
|
||||
{
|
||||
v = v + (LCC::point(vhit) - CGAL::ORIGIN);
|
||||
++c;
|
||||
}
|
||||
v = v / c;
|
||||
|
||||
{ // Here we insert a point in cell_2: equivalent to
|
||||
// lcc.insert_point_in_cell<2>(fit->dart(), CGAL::ORIGIN + v);
|
||||
// but optimized, and we create faces.
|
||||
typename LCC::Dart_handle firstdart = fit->dart();
|
||||
typename LCC::Dart_handle currentdart = firstdart;
|
||||
typename LCC::Dart_handle nextdart = currentdart->beta(1);
|
||||
|
||||
typename LCC::Attribute_handle<2>::type newf;
|
||||
|
||||
typename LCC::Vertex_attribute_handle
|
||||
newv = lcc.create_vertex_attribute(CGAL::ORIGIN + v);
|
||||
typename LCC::Dart_handle newdart = lcc.create_dart(newv);
|
||||
typename LCC::Dart_handle newdart2 = lcc.create_dart(nextdart->attribute<0>());
|
||||
|
||||
lcc.basic_link_beta(newdart2, newdart, 2);
|
||||
lcc.basic_link_beta(newdart, nextdart, 1);
|
||||
lcc.basic_link_beta(currentdart, newdart2, 1);
|
||||
|
||||
for ( currentdart=nextdart, nextdart=nextdart->beta(1);
|
||||
currentdart!=firstdart;
|
||||
currentdart=nextdart, nextdart=nextdart->beta(1) )
|
||||
{
|
||||
newf = lcc.create_attribute<2>();
|
||||
|
||||
newdart = lcc.create_dart(newv);
|
||||
newdart2 = lcc.create_dart(nextdart->attribute<0>());
|
||||
|
||||
lcc.set_attribute_of_dart<2>(newdart2, newf);
|
||||
lcc.set_attribute_of_dart<2>(currentdart, newf);
|
||||
lcc.set_attribute_of_dart<2>(currentdart->beta(0), newf);
|
||||
|
||||
lcc.basic_link_beta(newdart2, newdart, 2);
|
||||
lcc.basic_link_beta(newdart, nextdart, 1);
|
||||
lcc.basic_link_beta(currentdart, newdart2, 1);
|
||||
lcc.basic_link_beta(newdart2, currentdart->beta(0), 1);
|
||||
}
|
||||
|
||||
lcc.basic_link_beta(firstdart->beta(1), firstdart->beta(0), 1);
|
||||
lcc.set_attribute_of_dart<2>(firstdart->beta(0),
|
||||
firstdart->attribute<2>());
|
||||
lcc.set_attribute_of_dart<2>(firstdart->beta(1),
|
||||
firstdart->attribute<2>());
|
||||
}
|
||||
|
||||
}
|
||||
while (fit++ != fend);
|
||||
|
||||
// adjust end iterators
|
||||
++vend; ++fend; ++dend;
|
||||
|
||||
// set new positions of old vertices
|
||||
for (vit = lcc.vertex_attributes().begin(), i=0; vit != vend; ++vit, ++i)
|
||||
vit->point() = new_pos[i];
|
||||
|
||||
// flip old edges
|
||||
for (dit = lcc.darts().begin(); dit != dend; ++dit)
|
||||
{
|
||||
if (!dit->is_free(2) && dit<dit->beta(2) )
|
||||
flip_edge(dit);
|
||||
}
|
||||
|
||||
// write_mesh("reslcc.off");
|
||||
}
|
||||
|
||||
virtual void collapse_test()
|
||||
{
|
||||
|
||||
// reserve memory
|
||||
/* int nv = P.size_of_vertices();
|
||||
int nh = P.size_of_halfedges();
|
||||
int nf = P.size_of_facets();
|
||||
P.reserve(nv+nf, nh+6*nf, 3*nf);
|
||||
|
||||
// iterators
|
||||
Polyhedron::Vertex_iterator vit, vend = P.vertices_end();
|
||||
Polyhedron::Face_iterator fit, fend = P.facets_end();
|
||||
|
||||
|
||||
// adjust end iterators
|
||||
--vend; --fend;
|
||||
|
||||
|
||||
// split faces (a for loop does not work for list-kernel!)
|
||||
Point_3 p(0,0,0);
|
||||
fit = P.facets_begin();
|
||||
do
|
||||
{
|
||||
Polyhedron::Halfedge_handle h = P.create_center_vertex(fit->halfedge());
|
||||
h->vertex()->point() = p;
|
||||
}
|
||||
while (++fit != fend);
|
||||
|
||||
|
||||
// adjust end iterators
|
||||
++vend; ++fend;
|
||||
|
||||
|
||||
// collapse new edges
|
||||
vit=vend; vend=P.vertices_end();
|
||||
for (; vit!=vend; ++vit)
|
||||
halfedge_collapse(vit->halfedge()->opposite());*/
|
||||
}
|
||||
|
||||
|
||||
void halfedge_collapse(LCC::Dart_handle pq)
|
||||
{
|
||||
// this code is copied from the CGAL surface simplification package
|
||||
/*
|
||||
Polyhedron::Halfedge_handle qp = pq->opposite();
|
||||
Polyhedron::Halfedge_handle pt = pq->prev()->opposite();
|
||||
Polyhedron::Halfedge_handle qb = qp->prev()->opposite();
|
||||
|
||||
bool lTopFaceExists = !pq->is_border() ;
|
||||
bool lBottomFaceExists = !qp->is_border() ;
|
||||
bool lTopLeftFaceExists = lTopFaceExists && !pt->is_border() ;
|
||||
bool lBottomRightFaceExists = lBottomFaceExists && !qb->is_border() ;
|
||||
|
||||
Polyhedron::Vertex_handle q = pq->vertex();
|
||||
Polyhedron::Vertex_handle p = pq->opposite()->vertex();
|
||||
|
||||
bool lP_Erased = false, lQ_Erased = false ;
|
||||
|
||||
if ( lTopFaceExists )
|
||||
{
|
||||
if ( lTopLeftFaceExists )
|
||||
{
|
||||
P.join_facet (pt);
|
||||
}
|
||||
else
|
||||
{
|
||||
P.erase_facet(pt->opposite());
|
||||
|
||||
if ( !lBottomFaceExists )
|
||||
{
|
||||
lP_Erased = true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( lBottomFaceExists )
|
||||
{
|
||||
if ( lBottomRightFaceExists )
|
||||
{
|
||||
P.join_facet (qb);
|
||||
}
|
||||
else
|
||||
{
|
||||
P.erase_facet(qb->opposite());
|
||||
|
||||
if ( !lTopFaceExists )
|
||||
{
|
||||
lQ_Erased = true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !lP_Erased && !lQ_Erased )
|
||||
{
|
||||
P.join_vertex(pq);
|
||||
lP_Erased = true ;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
//=============================================================================
|
||||
|
||||
#ifndef PERFORMANCE_TEST_H
|
||||
#define PERFORMANCE_TEST_H
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "Stop_watch.h"
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
class Performance_test
|
||||
{
|
||||
public:
|
||||
|
||||
Performance_test() {}
|
||||
|
||||
void run(const char* input, const char* output)
|
||||
{
|
||||
graphene::StopWatch timer;
|
||||
|
||||
timer.start();
|
||||
if (!read_mesh(input)) { std::cerr << "read error\n"; exit(1); }
|
||||
timer.stop();
|
||||
std::cout << "Read mesh : " << timer << std::endl;
|
||||
|
||||
timer.start();
|
||||
int c;
|
||||
for (int i=0; i<100; ++i)
|
||||
c = circulator_test();
|
||||
timer.stop();
|
||||
assert(c==0);
|
||||
std::cout << "Circulator : " << timer << std::endl;
|
||||
|
||||
timer.start();
|
||||
for (int i=0; i<1000; ++i)
|
||||
barycenter_test();
|
||||
timer.stop();
|
||||
std::cout << "Barycenter : " << timer << std::endl;
|
||||
|
||||
timer.start();
|
||||
for (int i=0; i<100; ++i)
|
||||
normal_test();
|
||||
timer.stop();
|
||||
std::cout << "Normals : " << timer << std::endl;
|
||||
|
||||
timer.start();
|
||||
for (int i=0; i<100; ++i)
|
||||
smoothing_test();
|
||||
timer.stop();
|
||||
std::cout << "Smoothing : " << timer << std::endl;
|
||||
|
||||
timer.start();
|
||||
subdivision_test();
|
||||
timer.stop();
|
||||
std::cout << "Subdivision : " << timer << std::endl;
|
||||
|
||||
timer.start();
|
||||
collapse_test();
|
||||
timer.stop();
|
||||
std::cout << "Collapse : " << timer << std::endl;
|
||||
|
||||
timer.start();
|
||||
if (!write_mesh(output)) { std::cerr << "write error\n"; exit(1); }
|
||||
timer.stop();
|
||||
std::cout << "Write mesh : " << timer << std::endl;
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool read_mesh(const char* _filename) = 0;
|
||||
virtual bool write_mesh(const char* _filename) = 0;
|
||||
virtual int circulator_test() { return 0; }
|
||||
virtual void barycenter_test() {}
|
||||
virtual void normal_test() {}
|
||||
virtual void smoothing_test() {}
|
||||
virtual void subdivision_test() {}
|
||||
virtual void collapse_test() {}
|
||||
};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
#endif
|
||||
//=============================================================================
|
||||
Loading…
Reference in New Issue