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

Revision 1627, 14.0 KB checked in by mattausch, 18 years ago (diff)
RevLine 
[1237]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"
[1239]12#include "SubdivisionCandidate.h"
[1237]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;
[1259]41class BvHierarchy;
[1287]42class Exporter;
[1237]43
44
45
[1551]46/** View space / object space hierarchy statistics.
[1288]47*/
48class HierarchyStatistics: public StatisticsBase
49{
50public:
[1576]51        /// total number of entries in the pvs
[1624]52        int mPvsEntries;
[1576]53        /// storage cost
[1624]54        int mMemory;
[1288]55        /// total number of nodes
[1624]56        int mNodes;
[1288]57        /// maximal reached depth
[1624]58        int mMaxDepth;
[1288]59        /// accumulated depth
[1624]60        int mAccumDepth;
[1449]61        /// time spent for queue repair
[1624]62        float mRepairTime;
63
[1449]64        // global cost ratio violations
65        int mGlobalCostMisses;
[1624]66        /// total cost of subdivision
67        float mTotalCost;
68        /// render cost decrease of subdivision
69        float mRenderCostDecrease;
[1313]70
[1288]71        // Constructor
72        HierarchyStatistics()
73        {
74                Reset();
75        }
76
[1624]77        int Nodes() const {return mNodes;}
78        int Interior() const { return mNodes / 2; }
79        int Leaves() const { return (mNodes / 2) + 1; }
[1288]80       
81        // TODO: computation wrong
[1624]82        double AvgDepth() const { return mAccumDepth / (double)Leaves();}
[1288]83
[1449]84        void Reset()
[1288]85        {
[1449]86                mGlobalCostMisses = 0;
[1624]87                mTotalCost = 0;
88                mRenderCostDecrease = 0;
89
90                mNodes = 0;
91                mMaxDepth = 0;
92                mAccumDepth = 0;
93                mRepairTime = 0;
94                mMemory = 0;
95                mPvsEntries = 0;
[1288]96        }
97
98        void Print(ostream &app) const;
99
100        friend ostream &operator<<(ostream &s, const HierarchyStatistics &stat)
101        {
102                stat.Print(s);
103                return s;
104        }
105};
106
107
[1237]108typedef FlexibleHeap<SubdivisionCandidate *> SplitQueue;
109
110/** This class implements a structure holding two different hierarchies,
111        one for object space partitioning and one for view space partitioning.
112
113        The object space and the view space are subdivided using a cost heuristics.
114        If an object space split or a view space split is chosen is also evaluated
115        based on the heuristics.
116       
117        The view space heuristics is evaluated by weighting and adding the pvss of the back and
118        front node of each specific split. unlike for the standalone method vspbsp tree,
119        the pvs of an object would not be the pvs of single object but that of all objects
120        which are contained in the same leaf of the object subdivision. This could be done
121        by storing the pointer to the object space partition parent, which would allow access to all children.
122        Another possibility is to include traced kd-cells in the ray casing process.
123
124        Accordingly, the object space heuristics is evaluated by storing a pvs of view cells with each object.
125        the contribution to an object to the pvs is the number of view cells it can be seen from.
126
127        @note
128        There is a potential efficiency problem involved in a sense that once a certain type
129        of split is chosen for view space / object space, the candidates for the next split of
130        object space / view space must be reevaluated.
131*/
132class HierarchyManager
133{
[1259]134        friend VspTree;
135        friend OspTree;
136        friend BvHierarchy;
[1279]137        friend ViewCellsParseHandlers;
[1259]138
[1237]139public:
[1421]140        /** Constructor with the view space partition tree and
141                the object space hierarchy type as argument.
[1237]142        */
[1421]143        HierarchyManager(const int objectSpaceHierarchyType);
[1279]144        /** Hack: OspTree will copy the content from this kd tree.
145                Only view space hierarchy will be constructed.
146        */
[1421]147        HierarchyManager(KdTree *kdTree);
[1237]148
[1421]149        /** Deletes space partition and view space partition.
150        */
[1286]151        ~HierarchyManager();
152
[1237]153        /** Constructs the view space and object space subdivision from a given set of rays
154                and a set of objects.
155                @param sampleRays the set of sample rays the construction is based on
156                @param objects the set of objects
157        */
[1308]158        void Construct(
[1293]159                const VssRayContainer &sampleRays,
160                const ObjectContainer &objects,
161                AxisAlignedBox3 *forcedViewSpace);
[1237]162
[1259]163        enum
164        {
165                NO_OBJ_SUBDIV,
166                KD_BASED_OBJ_SUBDIV,
167                BV_BASED_OBJ_SUBDIV
168        };
[1237]169
[1370]170        enum
171        {
172                NO_VIEWSPACE_SUBDIV,
173                KD_BASED_VIEWSPACE_SUBDIV
174        };
175
[1259]176        /** The type of object space subdivison
177        */
[1370]178        int GetObjectSpaceSubdivisionType() const;     
179        /** The type of view space space subdivison
180        */
181        int GetViewSpaceSubdivisionType() const;
182        /** Sets a pointer to the view cells manager.
183        */             
[1279]184        void SetViewCellsManager(ViewCellsManager *vcm);
[1370]185        /** Sets a pointer to the view cells tree.
186        */
[1279]187        void SetViewCellsTree(ViewCellsTree *vcTree);
[1370]188        /** Exports the object hierarchy to disc.
189        */
[1279]190        void ExportObjectSpaceHierarchy(OUT_STREAM &stream);
[1370]191        /** Adds a sample to the pvs of the specified view cell.
192        */
[1279]193        bool AddSampleToPvs(
194                Intersectable *obj,
195                const Vector3 &hitPoint,
196                ViewCell *vc,
197                const float pdf,
198                float &contribution) const;
199
[1421]200        /** Print out statistics.
201        */
202        void PrintHierarchyStatistics(ostream &stream) const;
[1279]203
[1421]204        /** Returns the view space partition tree.
205        */
[1379]206        VspTree *GetVspTree();
[1279]207
[1421]208        /** Returns view space bounding box.
209        */
[1563]210        //AxisAlignedBox3 GetViewSpaceBox() const;
[1624]211
[1421]212        /** Returns object space bounding box.
213        */
[1416]214        AxisAlignedBox3 GetObjectSpaceBox() const;
[1379]215
[1421]216        /** Exports object space hierarchy for visualization.
217        */
[1626]218        void ExportObjectSpaceHierarchy(Exporter *exporter,
219                                                                        const ObjectContainer &objects,
220                                                                        const AxisAlignedBox3 *bbox,
221                                                                        const bool exportBounds = true) const;
[1279]222
[1421]223        /** Returns intersectable pierced by this ray.
224        */
[1626]225        Intersectable *GetIntersectable(const VssRay &ray, const bool isTermination) const;
[1418]226
[1626]227        /** Export object space partition bounding boxes.
228        */
229        void ExportBoundingBoxes(OUT_STREAM &stream, const ObjectContainer &objects);
230
[1419]231        friend ostream &operator<<(ostream &s, const HierarchyManager &hm)
232        {
[1421]233                hm.PrintHierarchyStatistics(s);
[1419]234                return s;
235        }
236
[1237]237protected:
238
[1625]239        /** Returns true if the global termination criteria were met.
240        */
[1237]241        bool GlobalTerminationCriteriaMet(SubdivisionCandidate *candidate) const;
242
243        /** Prepare construction of the hierarchies, set parameters, compute
244                first split candidates.
245        */
[1625]246        SubdivisionCandidate *PrepareObjectSpaceSubdivision(const VssRayContainer &sampleRays,
247                                                                                                                const ObjectContainer &objects);
[1237]248
[1625]249
250        //////////////////////////////
251        // the main loop
252        //////////////////////
253
254        /** This is for interleaved construction / sequential construction.
255        */
256        void RunConstruction(const bool repairQueue,
257                                                 const VssRayContainer &sampleRays,
258                                                 const ObjectContainer &objects,
259                                                 AxisAlignedBox3 *forcedViewSpace);
[1449]260       
[1625]261        /** This is for interleaved construction using some objects
262                and some view space splits.
263        */
264        int RunConstruction(SplitQueue &splitQueue,
265                                                SubdivisionCandidateContainer &chosenCandidates,
266                                                const float minRenderCostDecr,
267                                                const int maxSteps);
268
269        /** Default subdivision method.
270        */
[1449]271        void RunConstruction(const bool repairQueue);
272               
[1625]273        ////////////////////////////////////////////////
274
[1580]275        /** Evaluates the subdivision candidate and executes the split.
276        */
[1625]277        bool ApplySubdivisionCandidate(SubdivisionCandidate *sc,
278                                                                   SplitQueue &splitQueue,
279                                                                   const bool repairQueue);
[1237]280
[1625]281        /** Tests if hierarchy construction is finished.
282        */
[1237]283        bool FinishedConstruction() const;
284
[1625]285        /** Returns next subdivision candidate from the split queue.
286        */
287        SubdivisionCandidate *NextSubdivisionCandidate(SplitQueue &splitQueue);
[1237]288
[1625]289        /** Repairs the dirty entries of the subdivision candidate queue. The
290                list of entries is given in the dirty list.
[1580]291        */
[1625]292        void RepairQueue(const vector<SubdivisionCandidate *> &dirtyList, SplitQueue &splitQueue);
[1237]293
[1625]294        /** Collect subdivision candidates which were affected by the splits from the
295                chosenCandidates list.
296        */
297        void CollectDirtyCandidates(const SubdivisionCandidateContainer &chosenCandidates,
298                                                                SubdivisionCandidateContainer &dirtyList);
299
[1624]300        /** Collect the list of dirty candidates after the current
301                subdivision candidate split.
[1580]302        */
[1625]303        void CollectDirtyCandidates(SubdivisionCandidate *sc,
304                                                                vector<SubdivisionCandidate *> &dirtyList);
[1237]305
[1580]306        /** Evaluate subdivision stats for log.
307        */
[1624]308        void EvalSubdivisionStats();
[1237]309
[1625]310        void AddSubdivisionStats(const int splits,
311                                                         const float renderCostDecr,
312                                                         const float totalRenderCost,
313                                                         const int totalPvsEntries,
314                                                         const int memory,
315                                                         const float renderCostPerStorage);
[1237]316
[1625]317        bool AddSampleToPvs(Intersectable *obj,
318                                                const float pdf,
319                                                float &contribution) const;
[1237]320
[1625]321        /** Collect affected view space candidates.
322        */
323        void CollectViewSpaceDirtyList(SubdivisionCandidate *sc,
324                                                                   SubdivisionCandidateContainer &dirtyList);
[1259]325
[1625]326        /** Collect affected object space candidates.
327        */
328        void CollectObjectSpaceDirtyList(SubdivisionCandidate *sc,
329                                                                         SubdivisionCandidateContainer &dirtyList);
[1259]330               
[1625]331        /** Export object space partition tree.
332        */
333        void ExportOspTree(Exporter *exporter,
334                                           const ObjectContainer &objects) const;
[1259]335
[1625]336        /** Parse the environment variables.
337        */
[1418]338        void ParseEnvironment();
[1415]339
[1418]340        bool StartObjectSpaceSubdivision() const;
341        bool StartViewSpaceSubdivision() const;
342
[1625]343        ////////////////////////////
344        // Helper function for preparation of subdivision
345        ///////
[1286]346
[1625]347        /** Prepare bv hierarchy for subdivision
348        */
349        SubdivisionCandidate *PrepareBvHierarchy(const VssRayContainer &sampleRays,
350                                                                           const ObjectContainer &objects);
[1286]351
[1625]352        /** Prepare object space kd tree for subdivision.
353        */
354        SubdivisionCandidate *PrepareOspTree(const VssRayContainer &sampleRays,
355                                                                   const ObjectContainer &objects);
[1308]356
[1625]357        /** Prepare view space subdivision and add candidate to queue.
358        */
359        SubdivisionCandidate *PrepareViewSpaceSubdivision(const VssRayContainer &sampleRays,
360                                                                                                          const ObjectContainer &objects);
361
362        /** Was object space subdivision already constructed?
363        */
[1313]364        bool ObjectSpaceSubdivisionConstructed() const;
[1625]365       
366        /** Was view space subdivision already constructed?
367        */
[1329]368        bool ViewSpaceSubdivisionConstructed() const;
[1311]369
[1625]370        /** Reset the split queue, i.e., reevaluate the split candidates.
371        */
[1313]372    void ResetQueue();
373
[1625]374        /** After the suddivision has ended, do some final tasks.
375        */
[1418]376        void FinishObjectSpaceSubdivision(const ObjectContainer &objects) const;
[1313]377
[1625]378        /** Returns depth of object space subdivision.
379        */
[1370]380        int GetObjectSpaceSubdivisionDepth() const;
381
[1625]382        /** Construct object space partition interleaved with view space partition.
383                Each time the best object or view space candidate is selected
384                for the next split.
385        */
[1626]386        void ConstructInterleaved(const VssRayContainer &sampleRays,
387                                                          const ObjectContainer &objects,
388                                                          AxisAlignedBox3 *forcedViewSpace);
[1449]389
[1625]390        /** Construct object space partition interleaved with view space partition.
391                The method chooses a number candidates of each type for subdivision.
392                The number is determined by the "gradient", i.e., the render cost decrease.
393                Once this render cost decrease is lower than the render cost decrease
394                for the splits of previous type, the method will stop current subdivision and
395                evaluate if view space or object space would be the beneficial for the
396                next number of split.
397        */
[1626]398        void ConstructInterleavedWithGradient(const VssRayContainer &sampleRays,
399                                                                                  const ObjectContainer &objects,
400                                                                                  AxisAlignedBox3 *forcedViewSpace);
[1624]401
[1548]402        /** Use iteration to construct the object space hierarchy.
403        */
[1626]404        void ConstructMultiLevel(const VssRayContainer &sampleRays,
405                                                         const ObjectContainer &objects,
406                                                         AxisAlignedBox3 *forcedViewSpace);
[1449]407
[1548]408        /** Reset the object space subdivision.
409                E.g., deletes hierarchy and resets stats.
410                so construction can be restarted.
411        */
[1625]412        SubdivisionCandidate *ResetObjectSpaceSubdivision(const VssRayContainer &rays,
413                                                                                                          const ObjectContainer &objects);
[1449]414
[1625]415        SubdivisionCandidate *ResetViewSpaceSubdivision(const VssRayContainer &rays,
416                                                                                                        const ObjectContainer &objects);
[1557]417
[1614]418
[1237]419protected:
420
[1627]421        /** construction types
422                sequential: construct first view space, then object space
423                interleaved: construct view space and object space fully interleaved
424                gradient: construct view space / object space until a threshold is reached
425                multilevel: iterate until subdivisions converge to the optimum.
426        */
427        enum {SEQUENTIAL, INTERLEAVED, GRADIENT, MULTILEVEL};
428
[1580]429        /// type of hierarchy construction
430        int mConstructionType;
431
432        /// Type of object space partition
[1308]433        int mObjectSpaceSubdivisionType;
[1580]434        /// Type of view space partition
[1329]435    int mViewSpaceSubdivisionType;
436
[1589]437        /// the traversal queue
438        SplitQueue mTQueue;
439       
[1580]440        ////////////
441        //-- helper variables
442       
443        // the original osp type
[1323]444        int mSavedObjectSpaceSubdivisionType;
[1580]445        // the original vsp type
[1329]446        int mSavedViewSpaceSubdivisionType;
[1580]447        /// the current subdivision candidate
[1624]448        //SubdivisionCandidate *mCurrentCandidate;
[1323]449
[1259]450
[1580]451        ///////////////////
452        // Hierarchies
453
454        /// view space hierarchy
[1259]455        VspTree *mVspTree;
[1580]456        /// object space partition kd tree
[1259]457        OspTree *mOspTree;
[1625]458
[1589]459        public:
[1580]460        /// bounding volume hierarchy
[1259]461        BvHierarchy *mBvHierarchy;
[1580]462       
[1589]463protected:
[1237]464
465
[1580]466        //////////
[1576]467        //-- global termination criteria
468
[1580]469        /// the mininal acceptable cost ratio for a split
[1237]470        float mTermMinGlobalCostRatio;
[1580]471        /// the threshold for global cost miss tolerance
[1237]472        int mTermGlobalCostMissTolerance;
[1580]473        /// maximum number of leaves
474        int mTermMaxLeaves;
475
[1576]476        ////////////////////
477
[1580]478        /// statistics about the hierarchy
[1288]479        HierarchyStatistics mHierarchyStats;
480
[1308]481        int mMinDepthForObjectSpaceSubdivion;
[1370]482        int mMinDepthForViewSpaceSubdivion;
[1580]483       
[1625]484        //int mMinRenderCostDecrease;
[1624]485
[1237]486        ofstream mSubdivisionStats;
[1314]487
[1580]488        /// if the queue should be repaired after a subdivision steps
[1314]489        bool mRepairQueue;
[1370]490
491        bool mStartWithObjectSpace;
[1580]492        /** if multi level construction method should be used
493                where we iterate over both hierarchies until we
494                converge to the optimum.
495        */
[1449]496        bool mUseMultiLevelConstruction;
[1580]497        /// number of iteration steps for multilevel approach   
498        int mNumMultiLevels;
[1237]499};
500
501}
502
503#endif
Note: See TracBrowser for help on using the repository browser.