Welcome to mirror list, hosted at ThFree Co, Russian Federation.

hashgrid.h « sdfgen « src « softbody « extern - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: a5eb9aaae8fb89be400891d4f6fc5226d1e46f37 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#ifndef HASHGRID_H
#define HASHGRID_H

#include "hashtable.h"
#include "vec.h"

//========================================================= first do 2D ============================

namespace sdfgen {

template<class DataType>
struct HashGrid2
{
   double dx, overdx; // side-length of a grid cell and its reciprocal
   HashTable<Vec2i,DataType> grid;

   explicit HashGrid2(double dx_=1, int expected_size=512)
      : dx(dx_), overdx(1/dx_), grid(expected_size)
   {}

   // only do this with an empty grid
   void set_grid_size(double dx_)
   { assert(size()==0); dx=dx_; overdx=1/dx; }

   void add_point(const Vec2d &x, const DataType &datum)
   { grid.add(round(x*overdx), datum); }

   void delete_point(const Vec2d &x, const DataType &datum)
   { grid.delete_entry(round(x*overdx), datum); }

   void add_box(const Vec2d &xmin, const Vec2d &xmax, const DataType &datum)
   {
      Vec2i imin=round(xmin*overdx), imax=round(xmax*overdx);
      for(int j=imin[1]; j<=imax[1]; ++j) for(int i=imin[0]; i<=imax[0]; ++i)
         grid.add(Vec2i(i,j), datum);
   }

   void delete_box(const Vec2d &xmin, const Vec2d &xmax, const DataType &datum)
   {
      Vec2i imin=round(xmin*overdx), imax=round(xmax*overdx);
      for(int j=imin[1]; j<=imax[1]; ++j) for(int i=imin[0]; i<=imax[0]; ++i)
         grid.delete_entry(Vec2i(i,j), datum);
   }

   unsigned int size(void) const
   { return grid.size(); }

   void clear(void)
   { grid.clear(); }

   void reserve(unsigned int expected_size)
   { grid.reserve(expected_size); }

   bool find_first_point(const Vec2d &x, DataType &datum) const
   { return grid.get_entry(round(x*overdx), datum); }

   bool find_point(const Vec2d &x, std::vector<DataType> &data_list) const
   {
      data_list.resize(0);
      grid.append_all_entries(round(x*overdx), data_list);
      return data_list.size()>0;
   }

   bool find_box(const Vec2d &xmin, const Vec2d &xmax, std::vector<DataType> &data_list) const
   {
      data_list.resize(0);
      Vec2i imin=round(xmin*overdx), imax=round(xmax*overdx);
      for(int j=imin[1]; j<=imax[1]; ++j) for(int i=imin[0]; i<=imax[0]; ++i)
         grid.append_all_entries(Vec2i(i,j), data_list);
      return data_list.size()>0;
   }
};

//==================================== and now in 3D =================================================

template<class DataType>
struct HashGrid3
{
   double dx, overdx; // side-length of a grid cell and its reciprocal
   HashTable<Vec3i,DataType> grid;

   explicit HashGrid3(double dx_=1, int expected_size=512)
      : dx(dx_), overdx(1/dx_), grid(expected_size)
   {}

   // only do this with an empty grid
   void set_grid_size(double dx_)
   { assert(size()==0); dx=dx_; overdx=1/dx; }

   void add_point(const Vec3d &x, const DataType &datum)
   { grid.add(round(x*overdx), datum); }

   void delete_point(const Vec3d &x, const DataType &datum)
   { grid.delete_entry(round(x*overdx), datum); }

   void add_box(const Vec3d &xmin, const Vec3d &xmax, const DataType &datum)
   {
      Vec3i imin=round(xmin*overdx), imax=round(xmax*overdx);
      for(int k=imin[2]; k<=imax[2]; ++k) for(int j=imin[1]; j<=imax[1]; ++j) for(int i=imin[0]; i<=imax[0]; ++i)
         grid.add(Vec3i(i,j,k), datum);
   }

   void delete_box(const Vec3d &xmin, const Vec3d &xmax, const DataType &datum)
   {
      Vec3i imin=round(xmin*overdx), imax=round(xmax*overdx);
      for(int k=imin[2]; k<=imax[2]; ++k) for(int j=imin[1]; j<=imax[1]; ++j) for(int i=imin[0]; i<=imax[0]; ++i)
         grid.delete_entry(Vec3i(i,j,k), datum);
   }
   
   unsigned int size(void) const
   { return grid.size(); }

   void clear(void)
   { grid.clear(); }

   void reserve(unsigned int expected_size)
   { grid.reserve(expected_size); }

   bool find_first_point(const Vec3d &x, DataType &index) const
   { return grid.get_entry(round(x*overdx), index); }

   bool find_point(const Vec3d &x, std::vector<DataType> &data_list) const
   {
      data_list.resize(0);
      grid.append_all_entries(round(x*overdx), data_list);
      return data_list.size()>0;
   }

   bool find_box(const Vec3d &xmin, const Vec3d &xmax, std::vector<DataType> &data_list) const
   {
      data_list.resize(0);
      Vec3i imin=round(xmin*overdx), imax=round(xmax*overdx);
      for(int k=imin[2]; k<=imax[2]; ++k) for(int j=imin[1]; j<=imax[1]; ++j) for(int i=imin[0]; i<=imax[0]; ++i)
         grid.append_all_entries(Vec3i(i, j, k), data_list);
      return data_list.size()>0;
   }
};

}

#endif