source: GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h @ 1919

Revision 1919, 17.9 KB checked in by mattausch, 18 years ago (diff)

added mechanism for histogram on certain MB in hierarchymanager
no more bug in undersampling estimation
added sampling strategy to spatial box based (also for eval)
added testing scripts

Line 
1#ifndef _HierarchyManager_H__
2#define _HierarchyManager_H__
3
4#include <stack>
5
6#include "Mesh.h"
7#include "Containers.h"
8#include "Statistics.h"
9#include "VssRay.h"
10#include "RayInfo.h"
11#include "gzstream.h"
12#include "SubdivisionCandidate.h"
13
14
15
16namespace GtpVisibilityPreprocessor {
17
18class ViewCellLeaf;
19class OspTree;
20class VspTree;
21class Plane3;
22class AxisAlignedBox3;
23class Ray;
24class ViewCellsStatistics;
25class ViewCellsManager;
26class MergeCandidate;
27class Beam;
28class ViewCellsTree;
29class Environment;
30class VspInterior;
31class VspLeaf;
32class VspNode;
33class KdNode;
34class KdInterior;
35class KdLeaf;
36class OspTree;
37class KdIntersectable;
38class KdTree;
39class VspTree;
40class KdTreeStatistics;
41class BvHierarchy;
42class Exporter;
43class ViewCellsParseHandlers;
44
45
46#define COUNT_ORIGIN_OBJECTS 1
47#define USE_AVGRAYCONTRI 1
48
49
50/** View space / object space hierarchy statistics.
51*/
52class HierarchyStatistics: public StatisticsBase
53{
54public:
55        /// total number of entries in the pvs
56        int mPvsEntries;
57        /// storage cost in MB
58        float mMemory;
59        /// total number of nodes
60        int mNodes;
61        /// maximal reached depth
62        int mMaxDepth;
63        /// accumulated depth
64        int mAccumDepth;
65        /// time spent for queue repair
66        float mRepairTime;
67
68        // global cost ratio violations
69        int mGlobalCostMisses;
70        /// total cost of subdivision
71        float mTotalCost;
72        /// render cost decrease of subdivision
73        float mRenderCostDecrease;
74
75        // Constructor
76        HierarchyStatistics()
77        {
78                Reset();
79        }
80
81        int Nodes() const {return mNodes;}
82        int Interior() const { return mNodes / 2 - 1; }
83        int Leaves() const { return (mNodes / 2) + 1; }
84       
85        // TODO: computation wrong
86        double AvgDepth() const { return mAccumDepth / (double)Leaves();}
87
88        void Reset()
89        {
90                mGlobalCostMisses = 0;
91                mTotalCost = 0;
92                mRenderCostDecrease = 0;
93
94                mNodes = 0;
95                mMaxDepth = 0;
96                mAccumDepth = 0;
97                mRepairTime = 0;
98                mMemory = 0;
99                mPvsEntries = 0;
100        }
101
102        void Print(ostream &app) const;
103
104        friend ostream &operator<<(ostream &s, const HierarchyStatistics &stat)
105        {
106                stat.Print(s);
107                return s;
108        }
109};
110
111
112class HierarchySubdivisionStats
113{
114public:
115           
116        int mNumSplits;
117               
118        float mRenderCostDecrease;
119
120    float mTotalRenderCost;
121   
122        int mEntriesInPvs;
123   
124        float mMemoryCost;
125       
126        float mFullMemory;
127
128        int mViewSpaceSplits;
129
130        int mObjectSpaceSplits;
131
132        float mPriority;
133
134        float VspOspRatio() const { return (float)mViewSpaceSplits / (float)mObjectSpaceSplits; }
135
136        float FpsPerMb() const { return 1.0f / (mTotalRenderCost * mMemoryCost); }
137
138        HierarchySubdivisionStats() { Reset(); }
139
140        void Reset()
141        {
142                mNumSplits = 0;
143                mRenderCostDecrease = 0;
144                mTotalRenderCost = 0;
145                mEntriesInPvs = 0;
146                mMemoryCost = 0;
147                mFullMemory = 0;
148                mViewSpaceSplits = 0;
149                mObjectSpaceSplits = 0;
150                mPriority = 0;
151        }
152
153
154        void Print(ostream &app) const;
155
156        friend ostream &operator<<(ostream &s, const HierarchySubdivisionStats &stat)
157        {
158                stat.Print(s);
159                return s;
160        }
161};
162
163
164/** This class implements a structure holding two different hierarchies,
165        one for object space partitioning and one for view space partitioning.
166
167        The object space and the view space are subdivided using a cost heuristics.
168        If an object space split or a view space split is chosen is also evaluated
169        based on the heuristics.
170       
171        The view space heuristics is evaluated by weighting and adding the pvss of the back and
172        front node of each specific split. unlike for the standalone method vspbsp tree,
173        the pvs of an object would not be the pvs of single object but that of all objects
174        which are contained in the same leaf of the object subdivision. This could be done
175        by storing the pointer to the object space partition parent, which would allow access to all children.
176        Another possibility is to include traced kd-cells in the ray casing process.
177
178        Accordingly, the object space heuristics is evaluated by storing a pvs of view cells with each object.
179        the contribution to an object to the pvs is the number of view cells it can be seen from.
180
181        @note
182        There is a potential efficiency problem involved in a sense that once a certain type
183        of split is chosen for view space / object space, the candidates for the next split of
184        object space / view space must be reevaluated.
185*/
186class HierarchyManager
187{
188public:
189        /** Constructor with the view space partition tree and
190                the object space hierarchy type as argument.
191        */
192        HierarchyManager(const int objectSpaceHierarchyType);
193        /** Hack: OspTree will copy the content from this kd tree.
194                Only view space hierarchy will be constructed.
195        */
196        HierarchyManager(KdTree *kdTree);
197
198        /** Deletes space partition and view space partition.
199        */
200        ~HierarchyManager();
201
202        /** Constructs the view space and object space subdivision from a given set of rays
203                and a set of objects.
204                @param sampleRays the set of sample rays the construction is based on
205                @param objects the set of objects
206        */
207        void Construct(
208                const VssRayContainer &sampleRays,
209                const ObjectContainer &objects,
210                AxisAlignedBox3 *forcedViewSpace);
211
212        enum
213        {
214                NO_OBJ_SUBDIV,
215                KD_BASED_OBJ_SUBDIV,
216                BV_BASED_OBJ_SUBDIV
217        };
218
219        enum
220        {
221                NO_VIEWSPACE_SUBDIV,
222                KD_BASED_VIEWSPACE_SUBDIV
223        };
224
225        /** The type of object space subdivison
226        */
227        int GetObjectSpaceSubdivisionType() const;     
228        /** The type of view space space subdivison
229        */
230        int GetViewSpaceSubdivisionType() const;
231        /** Sets a pointer to the view cells manager.
232        */             
233        void SetViewCellsManager(ViewCellsManager *vcm);
234        /** Sets a pointer to the view cells tree.
235        */
236        void SetViewCellsTree(ViewCellsTree *vcTree);
237        /** Exports the object hierarchy to disc.
238        */
239        void ExportObjectSpaceHierarchy(OUT_STREAM &stream);
240       
241        /** Print out statistics.
242        */
243        void PrintHierarchyStatistics(ostream &stream) const;
244
245        /** Returns the view space partition tree.
246        */
247        VspTree *GetVspTree();
248
249        /** Returns view space bounding box.
250        */
251        //AxisAlignedBox3 GetViewSpaceBox() const;
252
253        /** Returns object space bounding box.
254        */
255        AxisAlignedBox3 GetObjectSpaceBox() const;
256
257        /** Exports object space hierarchy for visualization.
258        */
259        void ExportObjectSpaceHierarchy(Exporter *exporter,
260                                                                        const ObjectContainer &objects,
261                                                                        AxisAlignedBox3 *bbox,
262                                                                        const bool exportBounds = true) const;
263
264        /** Returns intersectable pierced by this ray.
265        */
266        Intersectable *GetIntersectable(const VssRay &ray, const bool isTermination) const;
267 
268        Intersectable *GetIntersectable(Intersectable *obj, const Vector3 &point) const;
269
270        /** Export object space partition bounding boxes.
271        */
272        void ExportBoundingBoxes(OUT_STREAM &stream, const ObjectContainer &objects);
273
274        friend ostream &operator<<(ostream &s, const HierarchyManager &hm)
275        {
276                hm.PrintHierarchyStatistics(s);
277                return s;
278        }
279
280        HierarchyStatistics &GetHierarchyStats() { return mHierarchyStats; };
281
282        inline bool ConsiderMemory() const { return mConsiderMemory; }
283       
284        void EvaluateSubdivision(const VssRayContainer &sampleRays,                                                                                     
285                                                         const ObjectContainer &objects,
286                                                         const string &filename);
287
288        void EvaluateSubdivision2(ofstream &splitsStats,
289                                                          const int splitsStepSize,
290                                                          const bool useFilter,
291                                                          const bool useHisto,
292                                                          const int histoMem,
293                                                          const int pass);
294
295
296        void CollectObjects(const AxisAlignedBox3 &box, ObjectContainer &objects);
297
298        int CompressObjectSpace();
299        void CreateUniqueObjectIds();
300
301        float EvalCorrectedPvs(const float pvsFront,
302                                                   const float totalPvs,
303                                                   const float avgRayContri) const;
304
305
306protected:
307
308        /** Returns true if the global termination criteria were met.
309        */
310        bool GlobalTerminationCriteriaMet(SubdivisionCandidate *candidate) const;
311
312        /** Prepare construction of the hierarchies, set parameters, compute
313                first split candidates.
314        */
315        void PrepareObjectSpaceSubdivision(SplitQueue &tQueue,
316                                                                           const VssRayContainer &sampleRays,
317                                                                           const ObjectContainer &objects);
318
319
320        /** Create bounding box and root.
321        */
322        void InitialiseObjectSpaceSubdivision(const ObjectContainer &objects);
323
324        /** Returns memory usage of object space hierarchy.
325        */
326        float GetObjectSpaceMemUsage() const;
327
328
329        //////////////////////////////
330        // the main loop
331
332        /** This is for interleaved construction / sequential construction.
333        */
334        void RunConstruction(const bool repairQueue,
335                                                 const VssRayContainer &sampleRays,
336                                                 const ObjectContainer &objects,
337                                                 AxisAlignedBox3 *forcedViewSpace);
338       
339        /** This is for interleaved construction using some objects
340                and some view space splits.
341        */
342        int RunConstruction(SplitQueue &splitQueue,
343                                                SubdivisionCandidateContainer &chosenCandidates,
344                                                //const float minRenderCostDecr,
345                                                SubdivisionCandidate *oldCandidate,
346                                                const int minSteps,
347                                                const int maxSteps);
348
349        /** Default subdivision method.
350        */
351        void RunConstruction(const bool repairQueue);
352               
353        ////////////////////////////////////////////////
354
355        /** Evaluates the subdivision candidate and executes the split.
356        */
357        bool ApplySubdivisionCandidate(SubdivisionCandidate *sc,
358                                                                   SplitQueue &splitQueue,
359                                                                   const bool repairQueue);
360
361        /** Tests if hierarchy construction is finished.
362        */
363        bool FinishedConstruction() const;
364
365        /** Returns next subdivision candidate from the split queue.
366        */
367        SubdivisionCandidate *NextSubdivisionCandidate(SplitQueue &splitQueue);
368
369        /** Repairs the dirty entries of the subdivision candidate queue. The
370                list of entries is given in the dirty list.
371
372                @returns number of repaired candidates
373        */
374        int RepairQueue(const SubdivisionCandidateContainer &dirtyList,
375                                        SplitQueue &splitQueue,
376                                        const bool recomputeSplitPlaneOnRepair);
377
378        /** Collect subdivision candidates which were affected by the splits from the
379                chosenCandidates list.
380        */
381        void CollectDirtyCandidates(const SubdivisionCandidateContainer &chosenCandidates,
382                                                                SubdivisionCandidateContainer &dirtyList);
383
384        /** Evaluate subdivision stats for log.
385        */
386        void EvalSubdivisionStats();
387
388        void AddSubdivisionStats(const int splits,
389                                                         const float renderCostDecr,
390                                                         const float totalRenderCost,
391                                                         const int totalPvsEntries,
392                                                         const float memory,
393                                                         const float renderCostPerStorage,
394                                                         const float vspOspRatio);
395
396        /** Collect affected view space candidates.
397        */
398        void CollectViewSpaceDirtyList(SubdivisionCandidate *sc,
399                                                                   SubdivisionCandidateContainer &dirtyList);
400
401        /** Collect affected object space candidates.
402        */
403        void CollectObjectSpaceDirtyList(SubdivisionCandidate *sc,
404                                                                         SubdivisionCandidateContainer &dirtyList);
405               
406        /** Export object space partition tree.
407        */
408        void ExportOspTree(Exporter *exporter,
409                                           const ObjectContainer &objects) const;
410
411        /** Parse the environment variables.
412        */
413        void ParseEnvironment();
414
415        bool StartObjectSpaceSubdivision() const;
416        bool StartViewSpaceSubdivision() const;
417
418
419        ////////////////////////////
420        // Helper function for preparation of subdivision
421
422        /** Prepare bv hierarchy for subdivision
423        */
424        void PrepareBvHierarchy(SplitQueue &tQueue,
425                                                        const VssRayContainer &sampleRays,
426                                                        const ObjectContainer &objects);
427
428        /** Prepare object space kd tree for subdivision.
429        */
430        void PrepareOspTree(SplitQueue &tQueue,
431                                                const VssRayContainer &sampleRays,
432                                                const ObjectContainer &objects);
433
434        /** Prepare view space subdivision and add candidate to queue.
435        */
436        void PrepareViewSpaceSubdivision(SplitQueue &tQueue,
437                                                                         const VssRayContainer &sampleRays,
438                                                                         const ObjectContainer &objects);
439
440        /** Was object space subdivision already constructed?
441        */
442        bool ObjectSpaceSubdivisionConstructed() const;
443       
444        /** Was view space subdivision already constructed?
445        */
446        bool ViewSpaceSubdivisionConstructed() const;
447
448        /** Reset the split queue, i.e., reevaluate the split candidates.
449        */
450    void ResetQueue(SplitQueue &splitQueue, const bool recomputeSplitPlane);
451
452        /** After the suddivision has ended, do some final tasks.
453        */
454        void FinishObjectSpaceSubdivision(const ObjectContainer &objects,
455                                                                          const bool removeRayRefs = true) const;
456
457        /** Returns depth of object space subdivision.
458        */
459        int GetObjectSpaceSubdivisionDepth() const;
460
461        /** Returns number of leaves in object space subdivision.
462        */
463        int GetObjectSpaceSubdivisionLeaves() const;
464        int GetObjectSpaceSubdivisionNodes() const;
465
466        /** Construct object space partition interleaved with view space partition.
467                Each time the best object or view space candidate is selected
468                for the next split.
469        */
470        void ConstructInterleaved(const VssRayContainer &sampleRays,
471                                                          const ObjectContainer &objects,
472                                                          AxisAlignedBox3 *forcedViewSpace);
473
474        /** Construct object space partition interleaved with view space partition.
475                The method chooses a number candidates of each type for subdivision.
476                The number is determined by the "gradient", i.e., the render cost decrease.
477                Once this render cost decrease is lower than the render cost decrease
478                for the splits of previous type, the method will stop current subdivision and
479                evaluate if view space or object space would be the beneficial for the
480                next number of split.
481        */
482        void ConstructInterleavedWithGradient(const VssRayContainer &sampleRays,
483                                                                                  const ObjectContainer &objects,
484                                                                                  AxisAlignedBox3 *forcedViewSpace);
485
486        /** Use iteration to construct the object space hierarchy.
487        */
488        void ConstructMultiLevel(const VssRayContainer &sampleRays,
489                                                         const ObjectContainer &objects,
490                                                         AxisAlignedBox3 *forcedViewSpace);
491
492        /** Based on a given subdivision, we try to optimize using an
493                multiple iteration over view and object space.
494        */
495        void OptimizeMultiLevel(const VssRayContainer &sampleRays,                                                                                       
496                                                        const ObjectContainer &objects,
497                                                        AxisAlignedBox3 *forcedViewSpace);
498
499        /** Reset the object space subdivision.
500                E.g., deletes hierarchy and resets stats.
501                so construction can be restarted.
502        */
503        void ResetObjectSpaceSubdivision(SplitQueue &tQueue,
504                                                                         const VssRayContainer &rays,
505                                                                         const ObjectContainer &objects);
506
507        void ResetViewSpaceSubdivision(SplitQueue &tQueue,
508                                                                   const VssRayContainer &rays,
509                                                                   const ObjectContainer &objects,
510                                                                   AxisAlignedBox3 *forcedViewSpace);
511
512
513        ///////////////////////////
514
515        void ExportStats(ofstream &stats,
516                                         SplitQueue &tQueue,
517                                         const ObjectContainer &objects);
518
519        void CollectBestSet(const int maxSplits,
520                                                const float maxMemoryCost,
521                                                ViewCellContainer &viewCells,
522                                                vector<BvhNode *> &bvhNodes);
523
524        int ExtractStatistics(const int maxSplits,
525                                                  const float maxMemoryCost,
526                                                  float &renderCost,
527                                                  float &memory,
528                                                  int &pvsEntries,
529                                                  int &viewSpaceSplits,
530                                                  int &objectSpaceSplits,
531                                                  const bool useFilter,
532                                                  const bool useHisto,
533                                                  const int histoMem,
534                                                  const int pass,
535                                                  bool &histoUsed);
536
537        void ComputePvs(const ObjectPvs &pvs, float &rc, int &pvsEntries);
538        void GetPvsIncrementially(ViewCell *vc, ObjectPvs &pvs) const;
539        void PullUpPvsIncrementally(ViewCell *viewCell) const;
540        void GetPvsRecursive(ViewCell *vc, ObjectPvs &pvs) const;
541        void GetPvsEfficiently(ViewCell *vc, ObjectPvs &pvs) const;
542
543        float EvalFullMem() const;
544
545
546protected:
547
548        /** construction types
549                sequential: construct first view space, then object space
550                interleaved: construct view space and object space fully interleaved
551                gradient: construct view space / object space until a threshold is reached
552                multilevel: iterate until subdivisions converge to the optimum.
553        */
554        enum {SEQUENTIAL, INTERLEAVED, GRADIENT, MULTILEVEL};
555
556        /// type of hierarchy construction
557        int mConstructionType;
558
559        /// Type of object space partition
560        int mObjectSpaceSubdivisionType;
561        /// Type of view space partition
562    int mViewSpaceSubdivisionType;
563
564        /// the traversal queue
565        SplitQueue mTQueue;
566       
567        ////////////
568        //-- helper variables
569       
570        // the original osp type
571        int mSavedObjectSpaceSubdivisionType;
572        // the original vsp type
573        int mSavedViewSpaceSubdivisionType;
574       
575
576        ///////////////////
577        // Hierarchies
578
579        /// view space hierarchy
580        VspTree *mVspTree;
581        /// object space partition kd tree
582        OspTree *mOspTree;
583
584        float mInitialRenderCost;
585       
586        float mMaxAvgRayContri;
587
588        float mMinAvgRayContri;
589
590        // quick hack:
591public:
592        /// bounding volume hierarchy
593        BvHierarchy *mBvHierarchy;
594       
595protected:
596
597
598        //////////
599        //-- global termination criteria
600
601        /// the mininal acceptable cost ratio for a split
602        float mTermMinGlobalCostRatio;
603        /// the threshold for global cost miss tolerance
604        int mTermGlobalCostMissTolerance;
605        /// maximum number of leaves
606        int mTermMaxLeaves;
607        /// Maximal allowed memory consumption.
608        float mTermMaxMemory;
609
610
611        ////////////////////
612
613        /// number of minimal steps of the same type
614        int mMinStepsOfSameType;
615        int mMaxStepsOfSameType;
616
617        /// statistics about the hierarchy
618        HierarchyStatistics mHierarchyStats;
619
620        int mMinDepthForObjectSpaceSubdivion;
621        int mMinDepthForViewSpaceSubdivion;
622       
623        //int mMinRenderCostDecrease;
624
625        ofstream mSubdivisionStats;
626
627        /// if the queue should be repaired after a subdivision steps
628        bool mRepairQueue;
629
630        bool mStartWithObjectSpace;
631        /** if multi level construction method should be used
632                where we iterate over both hierarchies until we
633                converge to the optimum.
634        */
635        bool mUseMultiLevelConstruction;
636
637        /// number of iteration steps for multilevel approach   
638        int mNumMultiLevels;
639
640        /** if split plane should be recomputed for the repair.
641                Otherwise only the priority is recomputed, the
642                split plane itself stays the same
643        */
644        bool mRecomputeSplitPlaneOnRepair;
645
646        /** If memory should be considered during choosing
647                of the next split type during gradient method.
648        */
649        bool mConsiderMemory;
650
651        int mMaxRepairs;
652
653        int mTimeStamp;
654        friend VspTree;
655        friend OspTree;
656        friend BvHierarchy;
657
658        float mPriority;
659
660        friend ViewCellsParseHandlers;
661
662        ViewCellContainer mOldViewCells;
663
664        ObjectPvs mOldPvs;
665};
666
667}
668
669#endif
Note: See TracBrowser for help on using the repository browser.