mirror of https://github.com/CGAL/cgal
Use an unordered map to find neighbor cells
This commit is contained in:
parent
f5dffb0aab
commit
6462016ce3
|
|
@ -0,0 +1,156 @@
|
||||||
|
// Copyright (c) 2019 GeometryFactory (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$
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0+
|
||||||
|
//
|
||||||
|
// Author(s) : Andreas Fabri
|
||||||
|
|
||||||
|
#ifndef CGAL_SMALL_UNORDERED_MAP_H
|
||||||
|
#define CGAL_SMALL_UNORDERED_MAP_H
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
//#define CGAL_SMALL_UNORDERED_MAP_STATS
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
template <typename K, typename T, typename H, unsigned int N>
|
||||||
|
class Small_unordered_map{
|
||||||
|
#ifdef CGAL_SMALL_UNORDERED_MAP_STATS
|
||||||
|
std::array<int,10> collisions = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
|
#endif
|
||||||
|
static const unsigned int M = N<<3;
|
||||||
|
int head = -2;
|
||||||
|
std::array<int, M> occupied;
|
||||||
|
std::array<std::pair<K,T>, M> data;
|
||||||
|
const H hash = {};
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
Small_unordered_map()
|
||||||
|
{
|
||||||
|
occupied.fill(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CGAL_SMALL_UNORDERED_MAP_STATS
|
||||||
|
~Small_unordered_map()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 10; i++){
|
||||||
|
std::cout << i << " " << collisions[i] << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Set only once for a key and not more than N
|
||||||
|
void set(const K& k, const T& t)
|
||||||
|
{
|
||||||
|
unsigned int h = hash(k)%M;
|
||||||
|
unsigned i = h;
|
||||||
|
#ifdef CGAL_SMALL_UNORDERED_MAP_STATS
|
||||||
|
int collision = 0;
|
||||||
|
#endif
|
||||||
|
do {
|
||||||
|
if(occupied[i]== -1){
|
||||||
|
data[i].first = k;
|
||||||
|
data[i].second = t;
|
||||||
|
occupied[i] = head;
|
||||||
|
head = i;
|
||||||
|
#ifdef CGAL_SMALL_UNORDERED_MAP_STATS
|
||||||
|
if(collision>9){
|
||||||
|
std::cerr << collision << " collisions" << std::endl;
|
||||||
|
}
|
||||||
|
++collisions[collision];
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
i = (i+1)%M;
|
||||||
|
#ifdef CGAL_SMALL_UNORDERED_MAP_STATS
|
||||||
|
++collision;
|
||||||
|
#endif
|
||||||
|
}while(i != h);
|
||||||
|
std::cerr << "In set: continue? " << std::flush;
|
||||||
|
char c; std::cin >> c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const T& get(const K& k) const
|
||||||
|
{
|
||||||
|
unsigned int h = hash(k)%M;
|
||||||
|
int i = h;
|
||||||
|
do{
|
||||||
|
if(data[i].first == k){
|
||||||
|
return data[i].second;
|
||||||
|
}
|
||||||
|
i = (i+1)%M;
|
||||||
|
}while(i != h);
|
||||||
|
std::cerr << "In get: continue? " << std::flush;
|
||||||
|
char c; std::cin >> c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
head = -2;
|
||||||
|
occupied.fill(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct iterator {
|
||||||
|
const Small_unordered_map& map;
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
iterator(const Small_unordered_map& map)
|
||||||
|
: map(map),pos(-2)
|
||||||
|
{}
|
||||||
|
|
||||||
|
iterator(const Small_unordered_map& map, int pos)
|
||||||
|
: map(map), pos(pos)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool operator==(const iterator& other) const
|
||||||
|
{
|
||||||
|
return pos == other.pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const iterator& other) const
|
||||||
|
{
|
||||||
|
return pos != other.pos;
|
||||||
|
}
|
||||||
|
iterator operator++()
|
||||||
|
{
|
||||||
|
pos = map.occupied[pos];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::pair<K,T>& operator*()const
|
||||||
|
{
|
||||||
|
return map.data[pos];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
iterator begin() const
|
||||||
|
{
|
||||||
|
return iterator(*this,head);
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator end() const
|
||||||
|
{
|
||||||
|
return iterator(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend struct iterator;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
#endif // CGAL_SMALL_UNORDERED_MAP_H
|
||||||
|
|
@ -37,9 +37,13 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
|
// #include <parallel_hashmap/phmap.h>
|
||||||
|
// #include <absl/container/flat_hash_map.h>
|
||||||
|
|
||||||
#include <CGAL/Unique_hash_map.h>
|
#include <CGAL/Unique_hash_map.h>
|
||||||
#include <CGAL/triangulation_assertions.h>
|
#include <CGAL/triangulation_assertions.h>
|
||||||
#include <CGAL/Triangulation_utils_3.h>
|
#include <CGAL/Triangulation_utils_3.h>
|
||||||
|
|
@ -56,6 +60,7 @@
|
||||||
#include <CGAL/Iterator_project.h>
|
#include <CGAL/Iterator_project.h>
|
||||||
#include <CGAL/Default.h>
|
#include <CGAL/Default.h>
|
||||||
#include <CGAL/internal/boost/function_property_map.hpp>
|
#include <CGAL/internal/boost/function_property_map.hpp>
|
||||||
|
#include <CGAL/Small_unordered_map.h>
|
||||||
|
|
||||||
#include <CGAL/Bbox_3.h>
|
#include <CGAL/Bbox_3.h>
|
||||||
#include <CGAL/Spatial_lock_grid_3.h>
|
#include <CGAL/Spatial_lock_grid_3.h>
|
||||||
|
|
@ -3586,6 +3591,9 @@ insert(const Point& p, Locate_type lt, Cell_handle c, int li, int lj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define AF_NEW
|
||||||
|
|
||||||
|
|
||||||
template < class GT, class Tds, class Lds >
|
template < class GT, class Tds, class Lds >
|
||||||
template < class Conflict_tester, class Hidden_points_visitor >
|
template < class Conflict_tester, class Hidden_points_visitor >
|
||||||
typename Triangulation_3<GT,Tds,Lds>::Vertex_handle
|
typename Triangulation_3<GT,Tds,Lds>::Vertex_handle
|
||||||
|
|
@ -3596,6 +3604,7 @@ insert_in_conflict(const Point& p,
|
||||||
Hidden_points_visitor& hider,
|
Hidden_points_visitor& hider,
|
||||||
bool *could_lock_zone)
|
bool *could_lock_zone)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(could_lock_zone)
|
if(could_lock_zone)
|
||||||
*could_lock_zone = true;
|
*could_lock_zone = true;
|
||||||
|
|
||||||
|
|
@ -3621,11 +3630,12 @@ insert_in_conflict(const Point& p,
|
||||||
cells.reserve(32);
|
cells.reserve(32);
|
||||||
Facet facet;
|
Facet facet;
|
||||||
|
|
||||||
|
std::vector<Facet> facets;
|
||||||
|
facets.reserve(32);
|
||||||
|
|
||||||
// Parallel
|
// Parallel
|
||||||
if(could_lock_zone)
|
if(could_lock_zone)
|
||||||
{
|
{
|
||||||
std::vector<Facet> facets;
|
|
||||||
facets.reserve(32);
|
|
||||||
|
|
||||||
find_conflicts(c,
|
find_conflicts(c,
|
||||||
tester,
|
tester,
|
||||||
|
|
@ -3647,8 +3657,6 @@ insert_in_conflict(const Point& p,
|
||||||
}
|
}
|
||||||
return Vertex_handle();
|
return Vertex_handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
facet = facets.back();
|
|
||||||
}
|
}
|
||||||
// Sequential
|
// Sequential
|
||||||
else
|
else
|
||||||
|
|
@ -3657,22 +3665,76 @@ insert_in_conflict(const Point& p,
|
||||||
find_conflicts(c,
|
find_conflicts(c,
|
||||||
tester,
|
tester,
|
||||||
make_triple(
|
make_triple(
|
||||||
Oneset_iterator<Facet>(facet),
|
std::back_inserter(facets),
|
||||||
std::back_inserter(cells),
|
std::back_inserter(cells),
|
||||||
Emptyset_iterator()));
|
Emptyset_iterator()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
facet = facets.back();
|
||||||
|
|
||||||
// Remember the points that are hidden by the conflicting cells,
|
// Remember the points that are hidden by the conflicting cells,
|
||||||
// as they will be deleted during the insertion.
|
// as they will be deleted during the insertion.
|
||||||
hider.process_cells_in_conflict(cells.begin(), cells.end());
|
hider.process_cells_in_conflict(cells.begin(), cells.end());
|
||||||
|
Vertex_handle nv;
|
||||||
|
// AF: the new code
|
||||||
|
|
||||||
Vertex_handle v = _insert_in_hole(p,
|
if( facets.size() < 128){
|
||||||
|
// LESS64++;
|
||||||
|
typedef std::pair<Vertex_handle,Vertex_handle> Halfedge;
|
||||||
|
typedef Small_unordered_map<Halfedge, Facet, boost::hash<Halfedge>, 128 > Halfedge_facet_map;
|
||||||
|
// typedef absl::flat_hash_map<std::pair<Vertex_handle,Vertex_handle>, Facet// , boost::hash<std::pair<Vertex_handle,Vertex_handle> >> E2F;
|
||||||
|
static Halfedge_facet_map h2f;
|
||||||
|
nv = tds().create_vertex();
|
||||||
|
nv->set_point(p);
|
||||||
|
for(Facet f : facets){
|
||||||
|
|
||||||
|
f = mirror_facet(f);
|
||||||
|
f.first->tds_data().clear(); // was on boundary
|
||||||
|
Vertex_handle u = f.first->vertex(vertex_triple_index(f.second, 0));
|
||||||
|
Vertex_handle v = f.first->vertex(vertex_triple_index(f.second, 1));
|
||||||
|
Vertex_handle w = f.first->vertex(vertex_triple_index(f.second, 2));
|
||||||
|
u->set_cell(f.first);
|
||||||
|
v->set_cell(f.first);
|
||||||
|
w->set_cell(f.first);
|
||||||
|
Cell_handle nc = tds().create_cell(v, u, w, nv);
|
||||||
|
nv->set_cell(nc);
|
||||||
|
nc->set_neighbor(3, f.first);
|
||||||
|
f.first->set_neighbor(f.second, nc);
|
||||||
|
|
||||||
|
h2f.set(std::make_pair(u,v), Facet(nc,nc->index(w)));
|
||||||
|
h2f.set(std::make_pair(v,w), Facet(nc,nc->index(u)));
|
||||||
|
h2f.set(std::make_pair(w,u), Facet(nc,nc->index(v)));
|
||||||
|
}
|
||||||
|
|
||||||
|
int E = 3* facets.size();
|
||||||
|
int ei = 0;
|
||||||
|
for(auto it = h2f.begin(); it != h2f.end(); ++it){
|
||||||
|
if(ei>E){
|
||||||
|
std::cout << "Stop"<< std::flush;
|
||||||
|
char c; std::cin >> c;
|
||||||
|
}
|
||||||
|
++ei;
|
||||||
|
const std::pair<Halfedge,Facet>& ef = *it;
|
||||||
|
if(ef.first.first < ef.first.second){
|
||||||
|
Facet f = ef.second;
|
||||||
|
Facet n = h2f.get(std::make_pair(ef.first.second, ef.first.first));
|
||||||
|
f.first->set_neighbor(f.second, n.first);
|
||||||
|
n.first->set_neighbor(n.second, f.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(Cell_handle c : cells){
|
||||||
|
c->tds_data().clear(); // was in conflict
|
||||||
|
}
|
||||||
|
tds().delete_cells(cells.begin(), cells.end());
|
||||||
|
h2f.clear();
|
||||||
|
}else{
|
||||||
|
Vertex_handle nv = _insert_in_hole(p,
|
||||||
cells.begin(), cells.end(),
|
cells.begin(), cells.end(),
|
||||||
facet.first, facet.second);
|
facet.first, facet.second);
|
||||||
|
}
|
||||||
// Store the hidden points in their new cells.
|
// Store the hidden points in their new cells.
|
||||||
hider.reinsert_vertices(v);
|
hider.reinsert_vertices(nv);
|
||||||
return v;
|
return nv;
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue