Skip to content

Prototype for callback: add a callback in Triangulation_3::file_input #1036

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 51 additions & 7 deletions Polyhedron/demo/Polyhedron/Plugins/Mesh_3/C3t3_io_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <CGAL/Three/Polyhedron_demo_io_plugin_interface.h>
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
#include <CGAL/IO/File_avizo.h>
#include <CGAL/Real_timer.h>
#include <iostream>
#include <fstream>

Expand Down Expand Up @@ -71,11 +72,9 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) {
item->setName(fileinfo.baseName());
item->setScene(scene);


if(item->load_binary(in)) {
return item;
}

item->c3t3().clear();
in.seekg(0);
if(try_load_other_binary_format(in, item->c3t3())) {
Expand All @@ -84,7 +83,6 @@ Polyhedron_demo_c3t3_binary_io_plugin::load(QFileInfo fileinfo) {
item->resetCutPlane();
return item;
}

item->c3t3().clear();
in.seekg(0);
if(try_load_a_cdt_3(in, item->c3t3())) {
Expand Down Expand Up @@ -476,10 +474,56 @@ try_load_other_binary_format(std::istream& is, C3t3& c3t3)
if(binary) CGAL::set_binary_mode(is);
else CGAL::set_ascii_mode(is);
std::istream& f_is = CGAL::file_input<
Fake_c3t3::Triangulation,
C3t3::Triangulation,
Update_vertex<Fake_c3t3::Triangulation, C3t3::Triangulation>,
Update_cell>(is, c3t3.triangulation());
Fake_c3t3::Triangulation,
C3t3::Triangulation,
Update_vertex<Fake_c3t3::Triangulation, C3t3::Triangulation>,
Update_cell>(is, c3t3.triangulation(),
Update_vertex<Fake_c3t3::Triangulation, C3t3::Triangulation>(),
Update_cell()
,
/* call_back: a C++11 lambda */
[](std::istream& is,
const C3t3::Triangulation::Triangulation_data_structure& tds,
const char* text = 0)
{
static CGAL::Real_timer timer;
static double last_time = 0;

if(!timer.is_running()) {
std::cerr << "Start loading...\n";
timer.start();
}
if(text != 0) { std::cerr << text; return; }
const double current_time = timer.time();
if(current_time > last_time + 1.) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my experience with progress trackers, it is a good idea to only refresh every second, but calling time() in itself can be a bit costly if it is done too often (for example if it's called inside a loop with a large number of very short iterations). I am not sure if this is the case here, but one simple option is to add a simple iterative counter and to only check time every 100 or 1000 iterations for example

static int i = 0;
if (i ++ != 100)
  return;
const double current_time = time.time();

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, in general, because time() can make a syscall. But in my case the loop itself is just a lot of syscalls, that read the file. I do not think that can slow down. ...

-> to bench.

std::cerr << current_time << ": ";
std::cerr << "Loaded " << tds.number_of_vertices()
<< " vertices, " << tds.number_of_cells()
<< " cells";
typedef std::istream::pos_type pos_type;
static pos_type last_pos = 0;
const pos_type curr = is.tellg();
is.seekg(0, std::ios_base::end);
const pos_type end = is.tellg();
is.seekg(curr);
const std::streamoff divider =
end > 500000000 ? 1000000 : 1000;
const char unit =
end > 500000000 ? 'M' : 'k';
if(curr != pos_type(-1) && end != pos_type(-1)) {
std::cerr << " (" << (curr/divider) << " "
<< unit << "B/"
<< (end/divider) << " "
<< unit << "B, "
<< ((curr-last_pos) / divider)
<< unit << "B/s)\n";
} else std::cerr << "\n";
last_time = current_time;
last_pos = curr;
}
}
);
std::cerr << "DONE.\n";

c3t3.rescan_after_load_of_triangulation();
return f_is.good();
Expand Down
18 changes: 14 additions & 4 deletions Polyhedron/demo/Polyhedron/include/CGAL/Triangulation_file_input.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
#ifndef CGAL_TRIANGULATION_FILE_INPUT_3_H
#define CGAL_TRIANGULATION_FILE_INPUT_3_H

#include <CGAL/basic.h>
#include <iostream>
#include <CGAL/function.h>
#include <CGAL/callback.h>

namespace CGAL {

Expand All @@ -34,8 +36,11 @@ template <typename Tr1,
typename Update_cell>
std::istream& file_input(std::istream& is, Tr2 &tr,
Update_vertex update_vertex = Update_vertex(),
Update_cell update_cell = Update_cell())
// reads
Update_cell update_cell = Update_cell(),
CGAL_CALLBACK_PARAM(cpp11::function<void(std::istream&,
const typename Tr2::Triangulation_data_structure&,
const char*)> call_back = nullptr))
// reads
// the dimension
// the number of finite vertices
// the non combinatorial information on vertices (point, etc)
Expand Down Expand Up @@ -78,12 +83,14 @@ std::istream& file_input(std::istream& is, Tr2 &tr,
is.setstate(std::ios_base::failbit);
return is;
}
CGAL_CALLBACK(call_back, is, tr.tds(), 0);
}

std::vector< Cell_handle > C;

std::size_t m;
tr.tds().read_cells(is, V, m, C);
tr.tds().read_cells(is, V, m, C,
CGAL_CALLBACK_VAR(call_back));

for (std::size_t j=0 ; j < m; j++) {
Cell1 c;
Expand All @@ -92,9 +99,12 @@ std::istream& file_input(std::istream& is, Tr2 &tr,
is.setstate(std::ios_base::failbit);
return is;
}
CGAL_CALLBACK(call_back, is, tr.tds(), 0);
}

CGAL_CALLBACK(call_back, is, tr.tds(), "tr.is_valid()...");
CGAL_triangulation_assertion( tr.is_valid(false) );
CGAL_CALLBACK(call_back, is, tr.tds(), " DONE\n");
return is;
}

Expand Down
30 changes: 30 additions & 0 deletions STL_Extension/include/CGAL/callback.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (c) 2016 GeometryFactory Sarl (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 Lesser 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
//

#ifndef CGAL_CALLBACK_H
#define CGAL_CALLBACK_H

#include <CGAL/config.h>
# include <functional>
# define CGAL_CALLBACK_PARAM(x) x
# define CGAL_CALLBACK(f, ...) if(f) f(__VA_ARGS__);
# define CGAL_CALLBACK_VAR(x) x

#endif // CGAL_CALLBACK_H
17 changes: 15 additions & 2 deletions TDS_3/include/CGAL/Triangulation_data_structure_3.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
#include <boost/unordered_set.hpp>
#include <CGAL/utility.h>
#include <CGAL/iterator.h>
#include <CGAL/callback.h>
#include <CGAL/function.h>

#include <CGAL/Unique_hash_map.h>
#include <CGAL/triangulation_assertions.h>
Expand Down Expand Up @@ -339,7 +341,10 @@ class Triangulation_data_structure_3

// not documented
void read_cells(std::istream& is, const std::vector< Vertex_handle > &V,
std::size_t & m, std::vector< Cell_handle > &C);
std::size_t & m, std::vector< Cell_handle > &C,
cpp11::function<void(std::istream&,
const Tds&,
const char*)> call_back = nullptr);
// not documented
void print_cells(std::ostream& os,
const Unique_hash_map<Vertex_handle, std::size_t> &V ) const;
Expand Down Expand Up @@ -2272,7 +2277,10 @@ template <class Vb, class Cb, class Ct>
void
Triangulation_data_structure_3<Vb,Cb,Ct>::
read_cells(std::istream& is, const std::vector< Vertex_handle > &V,
std::size_t & m, std::vector< Cell_handle > &C)
std::size_t & m, std::vector< Cell_handle > &C,
cpp11::function<void(std::istream&,
const Tds&,
const char*)> call_back)
{
// creation of the cells and neighbors
switch (dimension()) {
Expand All @@ -2299,6 +2307,7 @@ read_cells(std::istream& is, const std::vector< Vertex_handle > &V,
V[ik]->set_cell(c);
}
C[i] = c;
CGAL_CALLBACK(call_back, is, *this, 0);
}
for(std::size_t j = 0; j < m; j++) {
Cell_handle c = C[j];
Expand All @@ -2310,6 +2319,7 @@ read_cells(std::istream& is, const std::vector< Vertex_handle > &V,
read(is, ik);
c->set_neighbor(k, C[ik]);
}
CGAL_CALLBACK(call_back, is, *this, 0);
}
break;
}
Expand All @@ -2322,10 +2332,12 @@ read_cells(std::istream& is, const std::vector< Vertex_handle > &V,
Cell_handle c = create_face(V[i], Vertex_handle(), Vertex_handle());
C[i] = c;
V[i]->set_cell(c);
CGAL_CALLBACK(call_back, is, *this, 0);
}
for (int j=0; j < 2; j++) {
Cell_handle c = C[j];
c->set_neighbor(0, C[1-j]);
CGAL_CALLBACK(call_back, is, *this, 0);
}
break;
}
Expand All @@ -2337,6 +2349,7 @@ read_cells(std::istream& is, const std::vector< Vertex_handle > &V,
Cell_handle c = create_face(V[0], Vertex_handle(), Vertex_handle());
C[0] = c;
V[0]->set_cell(c);
CGAL_CALLBACK(call_back, is, *this, 0);
break;
}
}
Expand Down