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

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