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

Revision 2116, 7.1 KB checked in by mattausch, 17 years ago (diff)

implemented hashpvs

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