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

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