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

Revision 1006, 16.9 KB checked in by mattausch, 18 years ago (diff)

started viewspace-objectspace subdivision
removed memory leaks

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