source: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h @ 997

Revision 997, 15.9 KB checked in by mattausch, 18 years ago (diff)

fixed bug for histogram
improved samplerenderer
todo: difference detectempty true / false

Line 
1#ifndef _ViewCell_H__
2#define _ViewCell_H__
3
4#include "Mesh.h"
5#include "Containers.h"
6#include "Ray.h"
7#include "Statistics.h"
8#include "Material.h"
9#include "gzstream.h"
10
11
12namespace GtpVisibilityPreprocessor {
13
14struct Triangle3;
15
16class BspInterior;
17class BspPvs;
18class BspLeaf;
19class VspKdTree;
20class VspKdLeaf;
21class KdLeaf;
22class ViewCellInterior;
23class MergeCandidate;
24class ViewCellsManager;
25class ViewCellLeaf;
26class Environment;
27
28
29/** Statistics for a view cell partition.
30*/
31
32class ViewCellsStatistics: public StatisticsBase
33{
34public:
35
36        /// number of view cells
37        int viewCells;
38
39        /// size of the PVS
40        int pvsSize;
41
42        /// largest PVS of all view cells
43        int maxPvs;
44
45        /// smallest PVS of all view cells
46        int minPvs;
47
48        /// view cells with empty PVS
49        int emptyPvs;
50
51        /// number of leaves covering the view space
52        int leaves;
53
54        /// largest number of leaves covered by one view cell
55        int maxLeaves;
56
57        int invalid;
58
59    // Constructor
60        ViewCellsStatistics()
61        {
62                Reset();
63        }
64
65        double AvgLeaves() const {return (double)leaves / (double)viewCells;};
66        double AvgPvs() const {return (double)pvsSize / (double)viewCells;};
67
68        void Reset()
69        {
70                viewCells = 0;
71                pvsSize = 0;
72                maxPvs = 0;
73
74                minPvs = 999999;
75                emptyPvs = 0;
76                leaves = 0;
77                maxLeaves = 0;
78                invalid = 0;
79        }
80
81        void Print(ostream &app) const;
82
83        friend ostream &operator<<(ostream &s, const ViewCellsStatistics &stat)
84        {
85                stat.Print(s);
86                return s;
87        }
88};
89
90
91/**
92        View cell with an optional mesh representation
93*/
94
95
96class ViewCell: public MeshInstance
97{
98        friend class ViewCellsTree;
99        friend class ViewCellsManager;
100        friend class VspBspViewCellsManager;
101        friend class BspViewCellsManager;
102        friend class VspBspTree;
103        friend class FromPointVisibilityTree;
104        friend class BspTree;
105
106
107public:
108        ViewCell();
109
110        /** Constructor taking a mesh representing the shape of the viewcell.
111        */
112        ViewCell(Mesh *mesh);
113
114        /** Default destructor.
115        */
116        virtual ~ViewCell() {}
117
118        /** Returns Pvs.
119        */
120        const ObjectPvs &GetPvs() const;
121
122        ObjectPvs &GetPvs();
123
124        void SetPvs(const ObjectPvs &pvs);
125
126        /** Type of view cells.
127        */
128        int Type() const;
129
130        void SetParent(ViewCellInterior *parent);
131
132        /** Adds a passing ray to the passing ray container.
133        */
134        void AddPassingRay(const Ray &ray, const int contributions);
135
136        /** Returns volume of the view cell.
137        */
138        float GetVolume() const;
139
140        /** Returns area of the view cell.
141        */
142        float GetArea() const;
143
144        /** Sets the volume of the view cell.
145        */
146        void SetVolume(float volume);
147       
148        /** Sets the area of the view cell.
149        */
150        void SetArea(float area);
151
152
153        /** if this view cell is the root of a view cell hierarchy
154        */
155        bool IsRoot() const;
156
157        /** Returns parent view cell.
158        */
159        ViewCellInterior *GetParent() const;
160
161       
162        /** Sets the mesh for this view cell.
163        */
164        void SetMesh(Mesh *mesh);
165
166        void SetValid(const bool valid);
167        bool GetValid() const;
168
169        /** Returns estimated render cost of this view cell.
170        */
171        float GetRenderCost() const;
172
173        /** set color for visiualizations.
174        */
175        void SetColor(const RgbColor &color);
176
177        /** get color for visualuzations.
178        */
179    RgbColor GetColor() const;
180
181 
182        /// parent view cell in the view cell hierarchy
183        ViewCellInterior *mParent;
184
185        /// Rays piercing this view cell.
186        RayContainer mPiercingRays;
187
188
189        /** if this is a view cell correspending to a leaf in a hierarchy.
190        */
191        virtual bool IsLeaf() const = 0;
192
193        static bool SmallerPvs(const ViewCell *a, const ViewCell *b)
194        {
195                // HACK: take scalar value because pvs may not have been stored properly
196#if 1
197                return a->mPvsSize < b->mPvsSize;
198#else
199                return a->GetPvs().GetSize() < b->GetPvs().GetSize();
200#endif
201        }
202
203        static bool SmallerRenderCost(const ViewCell *a, const ViewCell *b)
204        {
205                return a->GetRenderCost() < b->GetRenderCost();
206        }
207
208        static bool LargerRenderCost(const ViewCell *a, const ViewCell *b)
209        {
210                return a->GetRenderCost() > b->GetRenderCost();
211        }
212
213        void SetMergeCost(const float mergeCost);
214
215        float GetMergeCost() const;
216
217        static void NewMail(const int reserve = 1)
218        {
219                sMailId += sReservedMailboxes;
220                sReservedMailboxes = reserve;
221        }
222
223        void Mail() { mMailbox = sMailId; }
224        bool Mailed() const { return mMailbox == sMailId; }
225
226        void Mail(const int mailbox) { mMailbox = sMailId + mailbox; }
227        bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; }
228
229        int IncMail() { return ++mMailbox - sMailId; }
230
231
232
233        // last mail id -> warning not thread safe!
234        // both mailId and mailbox should be unique for each thread!!!
235        static int sMailId;
236        static int sReservedMailboxes;
237
238       
239protected:
240
241        /// the potentially visible objects
242        ObjectPvs mPvs;
243
244        float mVolume;
245        float mArea;
246
247        float mMergeCost;
248
249        bool mValid;
250
251        /// color used for consistent visualization
252        RgbColor mColor;
253
254       
255        /// pvs size, used for lazy pvs computation
256        int mPvsSize;
257        /// if the given pvs size is the real pvs size
258        bool mPvsSizeValid;
259
260};
261
262
263class ViewCellInterior: public ViewCell
264{
265        friend class ViewCellsManager;
266public:
267        ViewCellInterior();
268        ~ViewCellInterior();
269
270        ViewCellInterior(Mesh *mesh);
271       
272
273        /** Sets pointer from parent to child and vice versa.
274        */
275        void SetupChildLink(ViewCell *l);
276        void RemoveChildLink(ViewCell *l);
277        bool IsLeaf() const;
278
279        ViewCellContainer mChildren;
280
281  void SetCost(const float c) {
282        mCost = c;
283  }
284  float GetCost() const {
285        return mCost;
286  }
287 
288protected:
289  /** overall cost resulting from the merge */
290  float mCost;
291};
292
293
294/**
295        Leaf of the view cell.
296*/
297class ViewCellLeaf: public ViewCell
298{
299public:
300        ViewCellLeaf()  {  mActiveViewCell = this; }
301        ViewCellLeaf(Mesh *mesh):
302        ViewCell(mesh) { mActiveViewCell = this; }
303
304        bool IsLeaf() const
305        {
306                return true;
307        }
308
309        /** Returns if this view cell is active.
310        */
311        ViewCell *GetActiveViewCell() const
312        { return mActiveViewCell; }
313
314        /** Sets this view cell to be an active view cell.
315        */
316        void SetActiveViewCell(ViewCell *vc)
317        { mActiveViewCell = vc;}
318
319       
320        /** points to the currently active view cell. This is the
321                view cell representing the current brach.
322        */
323        ViewCell *mActiveViewCell;
324};
325
326/**
327        Leaf of the view cell hierarchy corresponding to a leaf in a spatial hierarchy.
328*/
329template<typename T>
330class HierarchyLeafViewCell: public ViewCellLeaf
331{
332public:
333
334        HierarchyLeafViewCell<T>(): ViewCellLeaf() {  }
335        HierarchyLeafViewCell<T>(Mesh *mesh):
336        ViewCellLeaf(mesh) {  }
337               
338
339        bool IsLeaf() const
340        {
341                return true;
342        }
343
344
345        /// Leaf of some hierarchy which is part of this view cell.
346        T mLeaf;
347};
348
349
350typedef HierarchyLeafViewCell<BspLeaf *> BspViewCell;
351typedef HierarchyLeafViewCell<KdLeaf *> KdViewCell;
352typedef HierarchyLeafViewCell<VspKdLeaf *> VspKdViewCell;
353
354
355
356class ViewCellsTree
357{
358        friend class ViewCellsManager;
359
360
361public:
362        /** View cells tree constructor taking a view cell mnanager and
363                an environment as parameters.
364        */
365        ViewCellsTree(ViewCellsManager *vcm, Environment *env);
366        ~ViewCellsTree();
367
368        /** Returns number of leaves this view cell consists of.
369        */
370        int GetNumInitialViewCells(ViewCell *vc) const;
371
372        /** Collects leaves corresponding to a view cell.
373        */
374        void CollectLeaves(ViewCell *vc, ViewCellContainer &leaves) const;
375
376        /** Merges view cells according to some cost heuristics.
377        */
378        int ConstructMergeTree(const VssRayContainer &rays, const ObjectContainer &objects);
379       
380        /** Refines view cells using shuffling, i.e., border leaves
381                of two view cells are exchanged if the resulting view cells
382                are tested to be "better" than the old ones.
383                @returns number of refined view cells
384        */
385        int RefineViewCells(const VssRayContainer &rays, const ObjectContainer &objects);
386       
387        /** Assign colors to the viewcells so that they can be renderered interactively without
388            color flickering. 
389        */
390        void AssignRandomColors();
391
392        /** Updates view cell stats for this particular view cell.
393        */
394        void UpdateViewCellsStats(ViewCell *vc, ViewCellsStatistics &vcStat);
395
396
397        /** Get costs resulting from each merge step.
398        */
399        void GetCostFunction(vector<float> &costFunction);
400
401 
402        /** Returns optimal set of view cells for a given number of view cells.
403        */
404        void CollectBestViewCellSet(ViewCellContainer &viewCells, const int numViewCells);
405
406        /** Root of view cells tree.
407        */
408        ViewCell *GetRoot() const;
409
410        /** Returns pvs of view cell.
411                @note pvs is returned per reference if tree is not compressed,
412                per copy else.
413        */
414        void GetPvs(ViewCell *vc, ObjectPvs &pvs) const;
415
416        /** Returns pvs size of view cell.
417        */
418        int GetPvsSize(ViewCell *vc) const;
419
420        /** Returns actual number of object in this pvs and the children.
421        */
422        int GetNumPvsEntries(ViewCell *vc) const;
423
424        /** Returns memory cost of this view cell.
425        */
426        float GetMemoryCost(ViewCell *vc) const;
427
428        /** Sets method of storage for view cells.
429        */
430        void SetViewCellsStorage(int type);
431
432        /** pvs storage methods
433        */
434        enum {PVS_IN_INTERIORS, COMPRESSED, PVS_IN_LEAVES};
435
436       
437        /** If view cells in this tree have compressed pvs.
438        */
439        int ViewCellsStorage() const;
440
441        /** Returns active view cell that is in the path of this view cell.
442        */
443        ViewCell *GetActiveViewCell(ViewCellLeaf *vc) const;
444
445        /** Sets the leaves to be the currently active view cells.
446        */
447    void SetActiveSetToLeaves();
448
449        /** Propagates pvs up the tree to the root and downwards the tree.
450        */
451        void PropagatePvs(ViewCell *vc);
452
453        /** Exports view cells to file.
454        */
455#if ZIPPED_VIEWCELLS
456        bool Export(ogzstream &stream, const bool exportPvs = false);
457#else
458        bool Export(ofstream &stream, const bool exportPvs = false);
459#endif
460
461        /** Export statistics of this view cell tree.
462        */
463        void ExportStats(const string &mergeStats);
464
465        /** Sets root of hierarchy.
466        */
467        void SetRoot(ViewCell *root);
468
469        //float ComputeVolume(ViewCell *vc);
470
471        /** Assignes unique ids to view cells.
472        */
473        void CreateUniqueViewCellsIds();
474
475        /** Resets pvs of whole tree.
476        */
477        void ResetPvs();
478
479protected:
480
481
482        /////////////////////////////////////////////////////////////////
483        //                    merge related stuff                      //
484        /////////////////////////////////////////////////////////////////
485
486        /** Computes render cost of the merged pvs.
487        */
488        float ComputeMergedPvsCost(const ObjectPvs &pvs1, const ObjectPvs &pvs2) const;
489
490        /** Returns cost of this leaf according to current heuristics.
491        */
492        float GetCostHeuristics(ViewCell *vc) const;
493
494        /** Returns cost of leaf.
495        */
496        float GetRenderCost(ViewCell *vc) const;
497
498        /** Evaluates the merge cost of this merge candidate pair.
499        */
500        void EvalMergeCost(MergeCandidate &mc) const;
501
502        /** Variance of leaf.
503        */
504        float GetVariance(ViewCell *vc) const;
505
506        /** Standard deviation of leaf.
507        */
508        float GetDeviation(ViewCell *vc) const;
509
510        /** Tries to set this merge candidate to valid.
511                @returns false if both view cells are the same
512        */
513        bool ValidateMergeCandidate(MergeCandidate &mc) const;
514
515        /** Merge view cells of leaves l1 and l2.
516                @returns difference in pvs size
517        */
518        ViewCellInterior *MergeViewCells(ViewCell *l, ViewCell *r, int &pvsDiff); //const;
519
520        /** Shuffles, i.e. takes border leaf from view cell 1 and adds it
521                to view cell 2.
522        */
523        void ShuffleLeaf(ViewCell *leaf, ViewCellInterior *vc1, ViewCellInterior *vc2) const;   
524               
525        /** Shuffles the leaves, i.e., tests if exchanging
526                the leaves helps in improving the view cells.
527        */
528        bool ShuffleLeaves(MergeCandidate &mc) const;
529
530        /** Calculates cost for merge of view cell 1 and 2.
531        */
532        float EvalShuffleCost(ViewCell *leaf,
533                                                  ViewCellInterior *vc1,
534                                                  ViewCellInterior *vc2) const;
535
536        /** Exports a snapshot of the merged view cells to disc.
537        */
538        void ExportMergedViewCells(ViewCellContainer &viewCells,
539                                                           const ObjectContainer &objects,
540                                                           const int numNewViewCells);
541
542        /** Merge queue must be reset after some time because expected value
543                may not be valid.
544        */
545        void ResetMergeQueue();
546
547        /** Updates the current top level of view cells.
548                @returns number of newly merged view cells
549        */
550        int UpdateActiveViewCells(ViewCellContainer &viewCells);
551
552        /** Helper function pullling pvs as high up in the tree as possible.
553        */
554        void PullUpVisibility(ViewCellInterior *interior);
555
556        /** Compress pvs of view cell and children.
557        */
558        void CompressViewCellsPvs(ViewCell *root);
559
560        /** Returns memory usage of view cells.
561        */
562        float GetMemUsage() const;
563
564        /**     Exports single view cell.
565                NOTE: should be in exporter!!
566        */
567#if ZIPPED_VIEWCELLS
568        void ExportViewCell(ViewCell *viewCell, ogzstream &stream, const bool exportPvs);
569#else
570        void ExportViewCell(ViewCell *viewCell, ofstream &stream, const bool exportPvs);       
571#endif
572
573        /** Exports pvs of a view cell.
574        */
575#if ZIPPED_VIEWCELLS
576        void ExportPvs(ViewCell *viewCell, ogzstream &stream);
577#else
578        void ExportPvs(ViewCell *viewCell, ofstream &stream);
579#endif
580
581
582        /// if the view cell tree hold compressed pvs
583        int mViewCellsStorage;
584
585        ViewCellsManager *mViewCellsManager;
586        ViewCell *mRoot;
587
588        /// if merge visualization should be shown
589        bool mExportMergedViewCells;
590
591       
592        /// intermediate container of merged view cells.
593        ViewCellContainer mMergedViewCells;
594       
595
596        /// if merged view cells are refined.
597        bool mRefineViewCells;
598
599        /// weights between variance and render cost increase (must be between zero and one)
600        float mRenderCostWeight;
601
602        /// overall cost used to normalize cost ratio
603        float mOverallCost;
604        float mExpectedCost;
605    float mDeviation;
606        float mAvgRenderCost;
607        /// the area is used for pvs heuristics
608        int mUseAreaForPvs;
609
610        int mNumActiveViewCells;
611
612        /// minimal number of view cells
613        int mMergeMinViewCells;
614        /// maximal cost ratio for the merge
615        float mMergeMaxCostRatio;
616
617        typedef priority_queue<MergeCandidate> MergeQueue;
618
619        MergeQueue mMergeQueue;
620
621        float mMaxMemory;
622
623        int mMaxMergesPerPass;
624        float mAvgCostMaxDeviation;
625};
626
627
628/**
629        Candidate for leaf merging based on priority.
630*/
631class MergeCandidate
632
633        friend class ViewCellsTree;
634
635public:
636
637        MergeCandidate(ViewCell *l, ViewCell *r);
638
639        /** If this merge pair is still valid.
640        */
641        bool IsValid() const;
642
643       
644        friend bool operator<(const MergeCandidate &leafa, const MergeCandidate &leafb)
645        {
646                return leafb.GetMergeCost() < leafa.GetMergeCost();
647        }
648
649        void SetLeftViewCell(ViewCell *l);
650        void SetRightViewCell(ViewCell *l);
651
652        ViewCell *GetLeftViewCell() const;
653        ViewCell *GetRightViewCell() const;
654
655        /** Returns leaf view cell initially associated with this merge candidate.
656        */
657        ViewCell *GetInitialLeftViewCell() const;
658        ViewCell *GetInitialRightViewCell() const;
659
660        /** Returns the increase of the standard deviation of this merge candidate.
661        */
662        float GetDeviationIncr() const;
663
664        /** Merge cost of this candidate pair.
665        */
666        float GetMergeCost() const;
667
668        /** Render cost of this candidate.
669        */
670        float GetRenderCost() const;
671       
672        static float sRenderCostWeight;
673
674protected:
675
676        /// render cost increase by this merge
677        float mRenderCost;
678        /// increase / decrease of standard deviation
679        float mDeviationIncr;
680
681        ViewCell *mLeftViewCell;
682        ViewCell *mRightViewCell;
683
684        ViewCell *mInitialLeftViewCell;
685        ViewCell *mInitialRightViewCell;
686};
687
688
689class MergeStatistics: public StatisticsBase
690{
691public:
692       
693        int merged;
694        int siblings;
695        int candidates;
696        int nodes;
697
698        int accTreeDist;
699        int maxTreeDist;
700       
701        Real collectTime;
702        Real mergeTime;
703
704        Real overallCost;
705
706        Real expectedRenderCost;
707        Real deviation;
708        Real heuristics;
709
710        // Constructor
711        MergeStatistics()
712        {
713                Reset();
714        }
715       
716        double AvgTreeDist() const {return (double)accTreeDist / (double)merged;};
717
718        void Reset()
719        {
720                nodes = 0;
721                merged = 0;
722                siblings = 0;
723                candidates = 0;
724       
725                accTreeDist = 0;
726                maxTreeDist = 0;
727
728                collectTime = 0;
729                mergeTime = 0;
730                overallCost = 0;
731
732                expectedRenderCost = 0;
733                deviation = 0;
734                heuristics = 0;
735
736        }
737
738        void Print(ostream &app) const;
739
740        friend ostream &operator<<(ostream &s, const MergeStatistics &stat)
741        {
742                stat.Print(s);
743                return s;
744        }
745};
746
747}
748
749#endif
Note: See TracBrowser for help on using the repository browser.