source: GTP/trunk/Lib/Vis/Preprocessing/src/HashPvs.h @ 2161

Revision 2161, 7.3 KB checked in by mattausch, 17 years ago (diff)
Line 
1#ifndef __HASHPVS_H
2#define __HASHPVS_H
3
4
5#include <hash_set>
6#include "common.h"
7#include <math.h>
8#include "PvsBase.h"
9#include "google/dense_hash_set"
10
11
12using namespace std;
13
14namespace GtpVisibilityPreprocessor {
15
16
17template<typename T>
18struct my_hash_compare
19{
20   enum
21   {
22      bucket_size = 1,
23      min_buckets = 16
24   };
25
26   size_t operator()(T a) const
27   {
28           return (size_t)(a->GetId());
29   }
30
31   bool operator()(T a, T b) const
32   {
33      return a < b;
34   }
35};
36
37
38#define HASH_SET google::dense_hash_set<T, my_hash_compare<T> >
39//#define HASH_SET stdext::hash_set<T, my_hash_compare<T> >
40#define HASH_ITERATOR HASH_SET::iterator
41#define CONST_HASH_ITERATOR HASH_SET::const_iterator
42
43/** Iterator over a hash pvs.
44*/
45template<typename T, typename S>
46class HashPvsIterator
47{
48public:
49       
50        HashPvsIterator<T, S>() {}
51
52        HashPvsIterator<T, S>(const typename CONST_HASH_ITERATOR &itCurrent,
53                                                  const typename CONST_HASH_ITERATOR &itEnd):
54        mItCurrent(itCurrent), mItEnd(itEnd)
55        {
56        }
57
58        bool HasMoreEntries() const
59        {
60                return (mItCurrent != mItEnd);
61        }
62
63        T Next(S &pdf)
64        {
65                T sample = *mItCurrent;
66                ++ mItCurrent;
67
68                return sample;
69        }
70
71        T Next()
72        {
73                T sample = *mItCurrent;
74                ++ mItCurrent;
75
76                return sample;
77        }
78       
79private:
80        typename CONST_HASH_ITERATOR mItCurrent;
81        typename CONST_HASH_ITERATOR mItEnd;
82};
83
84
85/** Template class representing the Potentially Visible Set (PVS)
86        mainly from a view cell, but also e.g., from objects.
87*/
88template<typename T, typename S>
89class HashPvs//: public PvsBase<T>
90{
91        template<typename T, typename S> friend class HashPvsIterator;
92
93public:
94
95        //HashPvs(): mEntries((Intersectable *)100) {};
96        HashPvs() {};
97        //virtual ~HashPvs() {};
98
99        int GetSize() const;
100        bool Empty() const;
101
102        /** Adds sample to PVS.
103                @returns contribution of sample (0 or 1)
104        */
105        float AddSample(T sample, const float pdf);
106
107        /** Adds sample to PVS without checking for presence of the sample
108                warning: pvs remains unsorted!
109        */
110        void AddSampleDirty(T sample, const float pdf);
111
112        /** Adds sample dirty (on the end of the vector) but
113                first checks if sample is already in clean part of the pvs.
114        */
115        bool AddSampleDirtyCheck(T sample, const float pdf);
116
117        /** Sort pvs entries - this should always be called after a
118                sequence of AddSampleDirty calls
119        */
120        void Sort();
121
122        /** Clears the pvs.
123        */
124        void Clear(const bool trim = true);
125
126        bool IsDirty() const;
127
128        bool RequiresResort() const;
129
130        /** Finds sample in PVS.
131                @param checkDirty if dirty part of the pvs should be checked for entry
132                (warning: linear runtime in dirty part)
133                @returns iterator on the sample if found, else the place where
134                it would be added in the sorted vector.
135        */
136        inline bool Find(T sample, typename HASH_ITERATOR &it);
137
138        typename HashPvsIterator<T, S> GetIterator() const;
139
140        /** Compute continuous PVS difference
141        */
142        float GetPvsHomogenity(HashPvs<T, S> &pvs);
143
144        static void Merge(HashPvs<T, S> &mergedPvs,
145                                          const HashPvs<T, S> &a,
146                                          const HashPvs<T, S> &b);
147
148        static int GetEntrySizeByte();
149        static float GetEntrySize();
150
151        bool GetSampleContribution(T sample,
152                                                   const float pdf,
153                                                           float &contribution);
154
155        int GetSamples() const
156        {
157                return mSamples;
158        }
159
160        void MergeInPlace(const HashPvs<T, S> &a)
161        {
162                cerr << "not implemented yet" << endl;
163        }
164
165        bool RequiresResortLog() const
166        {
167                return false;
168        }
169
170        void Reserve(const int n)
171        {
172                // not necessary
173        }
174
175        /** Sort pvs entries assume that the pvs contains unique entries
176        */
177        void SimpleSort()
178        {
179                // not necessary
180        }
181
182        int SubtractPvs(const HashPvs<T, S> &pvs)
183        {
184                cerr << "not yet implemented" << endl;
185                return 0;
186        }
187
188        /** Compute continuous PVS difference
189        */
190        void ComputeContinuousPvsDifference(HashPvs<T, S> &pvs,
191                                                                                float &pvsReduction,
192                                                                                float &pvsEnlargement)
193        {
194                cerr << "not yet implemented" << endl;
195        }
196protected:
197
198        /// hash table of PVS entries
199        HASH_SET mEntries;
200
201        /// Number of samples used to create the PVS
202        int mSamples;
203};
204
205
206template <typename T, typename S>
207bool HashPvs<T, S>::Find(T sample, typename HASH_ITERATOR &it)
208{
209        it = mEntries.find(sample);
210
211        // already in map
212        return (it != mEntries.end());
213        return false;
214}
215
216
217template <typename T, typename S>
218int HashPvs<T, S>::GetSize() const
219{
220        return (int)mEntries.size();
221}
222
223
224template <typename T, typename S>
225bool HashPvs<T, S>::Empty() const
226{
227        return mEntries.empty();
228}
229
230
231template <typename T, typename S>
232float HashPvs<T, S>::AddSample(T sample, const float pdf)
233{
234        static HASH_ITERATOR it;
235
236        if (Find(sample, it))
237                return 0.0f;
238       
239        mEntries.insert(sample);
240        return 1.0f;
241
242        /*pair<HASH_SET::iterator, bool> p = mEntries.insert(sample);
243
244        if (p.second)
245                return 0.0f;
246        else
247                return 1.0f;*/
248}
249       
250
251template <typename T, typename S>
252void HashPvs<T, S>::AddSampleDirty(T sample, const float pdf)
253{
254        static HASH_ITERATOR it;
255
256        // not yet in map
257        if (!Find(sample, it))
258        {
259                mEntries.insert(sample);       
260        }
261
262        //pair<HASH_SET::iterator, bool> p = mEntries.insert(sample);
263}
264
265
266template <typename T, typename S>
267bool HashPvs<T, S>::AddSampleDirtyCheck(T sample,
268                                                                                const float pdf)
269{
270        /*pair<HASH_ITERATOR, bool> p = mEntries.insert(sample);
271
272        // already in map
273        return p.second;
274*/
275        static HASH_ITERATOR it;
276
277        // already in map
278        if (Find(sample, it))
279                return false;
280       
281        mEntries.insert(sample);
282        return true;
283}
284
285
286template <typename T, typename S>
287void HashPvs<T, S>::Sort()
288{
289}
290
291
292template <typename T, typename S>
293void HashPvs<T, S>::Clear(const bool trim = true)
294{
295        mEntries.clear();
296}
297
298
299template <typename T, typename S>
300bool HashPvs<T, S>::IsDirty() const
301{
302        return false;
303}
304
305
306template <typename T, typename S>
307bool HashPvs<T, S>::RequiresResort() const
308{
309        return false;
310}
311
312
313template <typename T, typename S>
314typename HashPvsIterator<T, S> HashPvs<T, S>::GetIterator() const
315{
316        HashPvsIterator<T, S> pit(mEntries.begin(), mEntries.end());
317
318        return pit;
319}
320
321
322template <typename T, typename S>
323float HashPvs<T, S>::GetEntrySize()
324{
325        return (float)(sizeof(T)) / float(1024 * 1024);
326}
327
328
329template <typename T, typename S>
330int HashPvs<T, S>::GetEntrySizeByte()
331{
332        return sizeof(T);
333}
334
335
336template <typename T, typename S>
337float HashPvs<T, S>::GetPvsHomogenity(HashPvs<T, S> &pvs)
338{
339        float pvsReduction, pvsEnlargement;
340
341        ComputeContinuousPvsDifference(pvs,     pvsReduction, pvsEnlargement);
342
343        return pvsReduction + pvsEnlargement;
344}
345
346
347template <typename T, typename S>
348bool HashPvs<T, S>::GetSampleContribution(T sample,
349                                                                          const float pdf,
350                                                                          float &contribution)
351{
352        HASH_SET::iterator it;
353        const bool entryFound = Find(sample, it);
354
355        if (entryFound) 
356        {
357                contribution = 0.0f;
358                return false;
359        }
360        else
361        {
362                contribution = 1.0f;
363                return true;
364        }
365}
366
367
368template <typename T, typename S>
369void HashPvs<T, S>::Merge(HashPvs<T, S> &mergedPvs,
370                                                  const HashPvs<T, S> &a,
371                                                  const HashPvs<T, S> &b)
372{
373        CONST_HASH_ITERATOR ait, ait_end = a.mEntries.end();
374
375        for (ait = a.mEntries.begin(); ait != ait_end; ++ ait)
376        {
377                mergedPvs.AddSample(*ait, 1.0f);
378        }
379
380        CONST_HASH_ITERATOR bit, bit_end = b.mEntries.end();
381
382        for (bit = b.mEntries.begin(); bit != bit_end; ++ bit)
383        {
384                mergedPvs.AddSample(*bit, 1.0f);
385        }
386
387}
388
389}
390
391#endif
392
Note: See TracBrowser for help on using the repository browser.