source: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp @ 643

Revision 643, 81.7 KB checked in by mattausch, 18 years ago (diff)

made demo running

RevLine 
[440]1#include "ViewCellsManager.h"
2#include "RenderSimulator.h"
3#include "Mesh.h"
4#include "Triangle3.h"
5#include "ViewCell.h"
6#include "Environment.h"
7#include "X3dParser.h"
8#include "ViewCellBsp.h"
9#include "KdTree.h"
10#include "VspKdTree.h"
11#include "Exporter.h"
[442]12#include "VspBspTree.h"
[508]13#include "ViewCellsParser.h"
[532]14#include "Beam.h"
[540]15#include "VssPreprocessor.h"
16#include "RssPreprocessor.h"
[440]17
[643]18#define SAMPLE_AFTER_SUBDIVISION 0
[517]19
[532]20
[440]21ViewCellsManager::ViewCellsManager():
[480]22mRenderer(NULL),
[574]23mInitialSamples(0),
[440]24mConstructionSamples(0),
25mPostProcessSamples(0),
[470]26mVisualizationSamples(0),
27mTotalAreaValid(false),
[517]28mTotalArea(0.0f),
[547]29mViewCellsFinished(false),
[562]30mMaxPvsSize(9999999),
[564]31mMinPvsSize(0), // one means only empty view cells are invalid
[561]32mMaxPvsRatio(1.0)
[440]33{
[542]34        mViewSpaceBox.Initialize();
[482]35        ParseEnvironment();
[580]36
37        mViewCellsTree = new ViewCellsTree(this);
[440]38}
39
[517]40
[482]41void ViewCellsManager::ParseEnvironment()
42{
[503]43        // visualization stuff
[485]44        environment->GetBoolValue("ViewCells.Visualization.exportRays", mExportRays);
45        environment->GetBoolValue("ViewCells.Visualization.exportGeometry", mExportGeometry);
[547]46        environment->GetFloatValue("ViewCells.maxPvsRatio", mMaxPvsRatio);
[564]47        bool emptyViewCells = false;
48        environment->GetBoolValue("ViewCells.pruneEmptyViewCells", emptyViewCells);
49        environment->GetBoolValue("ViewCells.processOnlyValidViewCells", mOnlyValidViewCells);
[485]50
[574]51        environment->GetIntValue("ViewCells.Construction.samples", mConstructionSamples);
52        environment->GetIntValue("ViewCells.PostProcess.samples", mPostProcessSamples);
[595]53        environment->GetBoolValue("ViewCells.PostProcess.useRaysForMerge", mUseRaysForMerge);
54
[574]55        environment->GetIntValue("ViewCells.Visualization.samples", mVisualizationSamples);
56
57        environment->GetIntValue("ViewCells.Construction.samplesPerPass", mSamplesPerPass);
[577]58        environment->GetBoolValue("ViewCells.exportToFile", mExportViewCells);
[581]59       
[593]60       
[600]61        environment->GetIntValue("ViewCells.active", mNumActiveViewCells);
[586]62        environment->GetBoolValue("ViewCells.PostProcess.compress", mCompressViewCells);
[591]63        environment->GetBoolValue("ViewCells.Visualization.useCuttingPlane", mUseCuttingPlaneForViz);
[580]64
[591]65        environment->GetBoolValue("ViewCells.PostProcess.merge", mMergeViewCells);
66
[564]67        mMinPvsSize = emptyViewCells ? 1 : 0;
68
[482]69        char buf[50];
70        environment->GetStringValue("ViewCells.Visualization.colorCode", buf);
[503]71
[482]72        if (strcmp(buf, "PVS") == 0)
73                mColorCode = 1;
74        else if (strcmp(buf, "MergedLeaves") == 0)
75                mColorCode = 2;
76        else if (strcmp(buf, "MergedTreeDiff") == 0)
77                mColorCode = 3;
78        else
79                mColorCode = 0;
80
81        Debug << "colorCode: " << mColorCode << endl;
[440]82}
83
[485]84
[440]85ViewCellsManager::~ViewCellsManager()
86{
[480]87        DEL_PTR(mRenderer);
[580]88
[598]89        if (!ViewCellsTreeConstructed())
90                CLEAR_CONTAINER(mViewCells);
91        else
92                DEL_PTR(mViewCellsTree);
93
[503]94        CLEAR_CONTAINER(mMeshContainer);
[440]95}
96
[485]97
[574]98int ViewCellsManager::CastPassSamples(const int samplesPerPass,
99                                                                          const int sampleType,
100                                                                          VssRayContainer &passSamples) const
[527]101{
[570]102        SimpleRayContainer simpleRays;
[540]103
[573]104        preprocessor->GenerateRays(samplesPerPass,
105                                                           sampleType,
[570]106                                                           simpleRays);
[564]107
[573]108        // shoot simple ray and add it to importance samples
109        preprocessor->CastRays(simpleRays, passSamples);
[570]110
[574]111        return (int)passSamples.size();
112}
[570]113
[574]114
[607]115
[574]116/// helper function which destroys rays or copies them into the output ray container
[639]117inline void disposeRays(VssRayContainer &rays, VssRayContainer *outRays)
[574]118{
119        cout << "disposing samples ... ";
[582]120        long startTime = GetTime();
121        int n = (int)rays.size();
122
[573]123        if (outRays)
[542]124        {
[574]125                VssRayContainer::const_iterator it, it_end = rays.end();
126
127                for (it = rays.begin(); it != it_end; ++ it)
128                {
129                        outRays->push_back(*it);
130                }
[573]131        }
132        else
133        {
[639]134                VssRayContainer::const_iterator it, it_end = rays.end();
135
136                for (it = rays.begin(); it != it_end; ++ it)
137                {
138                        //(*it)->Unref();
139                        if (!(*it)->IsActive())
140                                delete (*it);
141                }
[573]142        }
[639]143
[574]144        cout << "finished" << endl;
[582]145        Debug << "disposed " << n << " samples in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
[573]146}
[570]147
148
[573]149int ViewCellsManager::Construct(Preprocessor *preprocessor, VssRayContainer *outRays)
150{
151        int numSamples = 0;
152        SimpleRayContainer simpleRays;
153       
[574]154        VssRayContainer initialSamples;
[540]155
[574]156        cout << "view cell construction: casting " << mInitialSamples << " initial samples ... ";
[573]157        //-- construction rays => we use uniform samples for this
[574]158        CastPassSamples(mInitialSamples,
[575]159                                        //Preprocessor::DIRECTION_BASED_DISTRIBUTION,
160                                        Preprocessor::SPATIAL_BOX_BASED_DISTRIBUTION,
[574]161                                        initialSamples);
[573]162       
[574]163        cout << "finished" << endl;
164
[573]165        // construct view cells
[574]166        const int numInitialSamples =
167                ConstructSubdivision(preprocessor->mObjects, initialSamples);
[540]168
[574]169        numSamples += numInitialSamples;
[542]170
[574]171        // rays can be passed or deleted
[639]172        disposeRays(initialSamples, outRays);
[574]173       
[570]174
[573]175        //-- guided rays are used for further sampling
[574]176        const int n = mConstructionSamples; //+initialSamples;
[570]177
[574]178        bool dirSamples = false;
[573]179
180        while (numSamples < n)
181        {
[596]182                cout << "casting " << mSamplesPerPass << " samples of " << n << " ... ";
[574]183                VssRayContainer constructionSamples;
184
185                const int samplingType =
186                        dirSamples ?
187                                                Preprocessor::DIRECTION_BASED_DISTRIBUTION :
188                                                Preprocessor::SPATIAL_BOX_BASED_DISTRIBUTION;
189
[600]190                if (0)
[575]191                dirSamples = !dirSamples; // toggle sampling method
[574]192                numSamples += CastPassSamples(mSamplesPerPass,
193                                                                          samplingType,
194                                                                          constructionSamples);
195
196                cout << "finished" << endl;
197
198                cout << "computing sample contribution for " << (int)constructionSamples.size() << " samples ... ";
199
200                // TODO: leak?
[605]201                if (SAMPLE_AFTER_SUBDIVISION)
202                        ComputeSampleContributions(constructionSamples, true, false);
[574]203                cout << "finished" << endl;
204
205
[639]206                disposeRays(constructionSamples, outRays);
[574]207
208                cout << "total samples: " << numSamples << endl;
[542]209        }
[573]210       
[570]211
[573]212        //-- post processing
213        VssRayContainer postProcessSamples;
[570]214
[573]215        //-- construction rays => we use uniform samples for this
[574]216        CastPassSamples(mPostProcessSamples,
217                                    Preprocessor::DIRECTION_BASED_DISTRIBUTION,
218                                        postProcessSamples);
[573]219       
[574]220        cout << "starting post processing and visualization" << endl;
221
222        // store viewCells for postprocessing
223        const bool storeViewCells = true;
[605]224
225        if (SAMPLE_AFTER_SUBDIVISION)
226                ComputeSampleContributions(postProcessSamples, true, storeViewCells);
[570]227        // merge the view cells
[573]228        PostProcess(preprocessor->mObjects, postProcessSamples);
[570]229
230
[574]231        //-- visualization
232        VssRayContainer visualizationSamples;
233
234        //-- construction rays => we use uniform samples for this
235        CastPassSamples(mVisualizationSamples,
236                                    Preprocessor::DIRECTION_BASED_DISTRIBUTION,
237                                        visualizationSamples);
238
[605]239        if (SAMPLE_AFTER_SUBDIVISION)
240                ComputeSampleContributions(visualizationSamples, true, storeViewCells);
[574]241
242        //Debug << "visualizationsamples: " << mVisualizationSamples << " " << visualizationSamples.size() << endl;
243        // different visualizations
244        Visualize(preprocessor->mObjects, visualizationSamples);
245
[639]246        disposeRays(visualizationSamples, outRays);
[574]247
[573]248        return numSamples;
[527]249}
250
[547]251
[564]252bool ViewCellsManager::CheckValidity(ViewCell *vc,
253                                                                         int minPvsSize,
[562]254                                                                         int maxPvsSize) const
[547]255{
[569]256
257  if ((vc->GetPvs().GetSize() > maxPvsSize) ||
258          (vc->GetPvs().GetSize() < minPvsSize))
[564]259        {
[569]260          return false;
[561]261        }
[570]262
[569]263  return true;
[547]264}
265
266
[581]267bool ViewCellsManager::ViewCellsTreeConstructed() const
268{
269        return mViewCellsTree->GetRoot();
270}
271
272
[564]273void ViewCellsManager::SetValidity(ViewCell *vc,
274                                                                   int minPvs,
[562]275                                                                   int maxPvs) const
276{
277        vc->SetValid(CheckValidity(vc, minPvs, maxPvs));
278}
279
[577]280
[569]281void
282ViewCellsManager::SetValidity(
[570]283                                                          int minPvsSize,
[569]284                                                          int maxPvsSize) const
285{
286  ViewCellContainer::const_iterator it, it_end = mViewCells.end();
[570]287
[569]288  for (it = mViewCells.begin(); it != it_end; ++ it) {
289        SetValidity(*it, minPvsSize, maxPvsSize);
290  }
291}
[562]292
[569]293void
294ViewCellsManager::SetValidityPercentage(
295                                                                                const float minValid,
296                                                                                const float maxValid
297                                                                                )
298{
299  sort(mViewCells.begin(), mViewCells.end(), ViewCell::SmallerPvs);
[570]300
[569]301  int start = mViewCells.size()*minValid;
302  int end = mViewCells.size()*maxValid;
[570]303
[569]304  for (int i=0; i < mViewCells.size(); i++)
305        mViewCells[i]->SetValid(i >= start && i <= end);
306}
307
308int
309ViewCellsManager::CountValidViewcells() const
310{
311  ViewCellContainer::const_iterator it, it_end = mViewCells.end();
312  int valid = 0;
313  for (it = mViewCells.begin(); it != it_end; ++ it) {
314        if ((*it)->GetValid())
315          valid++;
316  }
317  return valid;
318}
319
[577]320
321bool ViewCellsManager::LoadViewCellsGeometry(const string filename)
[440]322{
323        X3dParser parser;
[503]324
[440]325        environment->GetFloatValue("ViewCells.height", parser.mViewCellHeight);
[503]326
[440]327        bool success = parser.ParseFile(filename, *this);
328        Debug << (int)mViewCells.size() << " view cells loaded" << endl;
329
330        return success;
331}
332
[485]333
[487]334bool ViewCellsManager::GetViewPoint(Vector3 &viewPoint) const
335{
[542]336        viewPoint = mViewSpaceBox.GetRandomPoint();
[487]337
338        return true;
339}
340
341
[557]342float ViewCellsManager::GetViewSpaceVolume()
343{
[610]344        return mViewSpaceBox.GetVolume() * (2.0f * sqr((float)M_PI));
[557]345}
346
347
[490]348bool ViewCellsManager::ViewPointValid(const Vector3 &viewPoint) const
349{
[569]350  if (!ViewCellsConstructed())
[542]351        return mViewSpaceBox.IsInside(viewPoint);
[569]352  else {
353        if (!mViewSpaceBox.IsInside(viewPoint))
354          return false;
355        ViewCell *viewcell = GetViewCell(viewPoint);
356        if (!viewcell || !viewcell->GetValid())
357          return false;
358  }
359  return true;
[490]360}
361
[501]362
[563]363float
364ViewCellsManager::ComputeSampleContributions(const VssRayContainer &rays,
[574]365                                                                                         const bool addRays,
366                                                                                         const bool storeViewCells
[563]367                                                                                         )
[440]368{
[563]369  // view cells not yet constructed
370  if (!ViewCellsConstructed())
371        return 0.0f;
[564]372
[563]373  VssRayContainer::const_iterator it, it_end = rays.end();
[503]374
[563]375  float sum = 0.0f;
376  for (it = rays.begin(); it != it_end; ++ it) {
[574]377        sum += ComputeSampleContributions(*(*it), addRays, storeViewCells);
[567]378        //ComputeSampleContributions(*(*it), addRays);
379        //      sum += (*it)->mPvsContribution;
[563]380  }
381  return sum;
[440]382}
383
[485]384
[479]385void ViewCellsManager::EvaluateViewCellsStats()
386{
387        mViewCellsStats.Reset();
388
389        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
390
391        for (it = mViewCells.begin(); it != it_end; ++ it)
[487]392        {
[605]393                mViewCellsTree->UpdateViewCellsStats(*it, mViewCellsStats);
[487]394        }
[479]395}
396
[485]397
[580]398void ViewCellsManager::EvaluateRenderStatistics(float &totalRenderCost,
[579]399                                                                                                float &expectedRenderCost,
[580]400                                                                                                float &deviation,
401                                                                                                float &variance,
402                                                                                                int &totalPvs,
403                                                                                                float &avgRenderCost)
[579]404{
405        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
406
[580]407
[579]408        //-- compute expected value
409
410        totalRenderCost = 0;
[580]411        totalPvs = 0;
[579]412
413        for (it = mViewCells.begin(); it != it_end; ++ it)
414        {
415                ViewCell *vc = *it;
416                totalRenderCost += vc->GetPvs().GetSize() * vc->GetVolume();
[580]417                totalPvs += (int)vc->GetPvs().GetSize();
[579]418        }
419
[580]420        // normalize with view space box
421        totalRenderCost /= mViewSpaceBox.GetVolume();
[579]422        expectedRenderCost = totalRenderCost / (float)mViewCells.size();
[580]423        avgRenderCost = totalPvs / (float)mViewCells.size();
[579]424
425
[580]426        //-- compute standard defiation
[579]427        variance = 0;
[580]428        deviation = 0;
[579]429
430        for (it = mViewCells.begin(); it != it_end; ++ it)
431        {
432                ViewCell *vc = *it;
433
434                float renderCost = vc->GetPvs().GetSize() * vc->GetVolume();
[580]435                float dev;
[579]436
[580]437                if (1)
438                        dev = fabs(avgRenderCost - (float)vc->GetPvs().GetSize());
439                else
440                        dev = fabs(expectedRenderCost - renderCost);
[579]441
[580]442                deviation += dev;
443                variance += dev * dev;
[579]444        }
[580]445
[579]446        variance /= (float)mViewCells.size();
[580]447        deviation /= (float)mViewCells.size();
[579]448}
449
450
451
[440]452void ViewCellsManager::AddViewCell(ViewCell *viewCell)
453{
454        mViewCells.push_back(viewCell);
455}
456
[485]457
[478]458float ViewCellsManager::GetArea(ViewCell *viewCell) const
459{
460        return viewCell->GetArea();
461}
462
463
464float ViewCellsManager::GetVolume(ViewCell *viewCell) const
465{
466        return viewCell->GetVolume();
467}
468
[485]469
[503]470void ViewCellsManager::DeriveViewCells(const ObjectContainer &objects,
471                                                                           ViewCellContainer &viewCells,
[440]472                                                                           const int maxViewCells) const
473{
474        // maximal max viewcells
[503]475        int limit = maxViewCells > 0 ?
[440]476                Min((int)objects.size(), maxViewCells) : (int)objects.size();
477
478        for (int i = 0; i < limit; ++ i)
479        {
480                Intersectable *object = objects[i];
[503]481
[440]482                // extract the mesh instances
483                if (object->Type() == Intersectable::MESH_INSTANCE)
484                {
485                        MeshInstance *inst = dynamic_cast<MeshInstance *>(object);
486
487                        ViewCell *viewCell = GenerateViewCell(inst->GetMesh());
488                        viewCells.push_back(viewCell);
489                }
490                //TODO: transformed meshes
491        }
492}
493
[485]494
[503]495ViewCell *ViewCellsManager::ExtrudeViewCell(const Triangle3 &baseTri,
[440]496                                                                                        const float height) const
497{
498        // one mesh per view cell
499        Mesh *mesh = new Mesh();
[503]500
[440]501        //-- construct prism
502
[503]503        // bottom
[440]504        mesh->mFaces.push_back(new Face(2,1,0));
505        // top
506    mesh->mFaces.push_back(new Face(3,4,5));
507        // sides
508        mesh->mFaces.push_back(new Face(1, 4, 3, 0));
509        mesh->mFaces.push_back(new Face(2, 5, 4, 1));
510        mesh->mFaces.push_back(new Face(3, 5, 2, 0));
511
512        //--- extrude new vertices for top of prism
513        Vector3 triNorm = baseTri.GetNormal();
514
[503]515        Triangle3 topTri;
[440]516
517        // add base vertices and calculate top vertices
518        for (int i = 0; i < 3; ++ i)
519                mesh->mVertices.push_back(baseTri.mVertices[i]);
[503]520
521        // add top vertices
[440]522        for (int i = 0; i < 3; ++ i)
523                mesh->mVertices.push_back(baseTri.mVertices[i] + height * triNorm);
[503]524
[440]525        mesh->Preprocess();
526
527        return GenerateViewCell(mesh);
528}
529
[485]530
[551]531void ViewCellsManager::FinalizeViewCells(const bool createMesh)
532{
533        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
534        for (it = mViewCells.begin(); it != it_end; ++ it)
535        {
536                Finalize(*it, createMesh);
537        }
[555]538
539        mTotalAreaValid = false;
[551]540}
541
542
543void ViewCellsManager::Finalize(ViewCell *viewCell, const bool createMesh)
544{
545        // implemented in subclasses
546}
547
548
[582]549ViewCellInterior *ViewCellsManager::MergeViewCells(ViewCell *left, ViewCell *right) const
[440]550{
[580]551        // generate parent view cell
552        ViewCellInterior *vc = new ViewCellInterior();//GenerateViewCell();
[462]553
[610]554        vc->GetPvs() = left->GetPvs();
[440]555        // merge pvs
[610]556        vc->GetPvs().Merge(right->GetPvs());
[440]557
[462]558        //-- merge ray sets
[564]559        if (0)
560        {
[582]561                stable_sort(left->mPiercingRays.begin(), left->mPiercingRays.end());
562                stable_sort(right->mPiercingRays.begin(), right->mPiercingRays.end());
[440]563
[582]564                std::merge(left->mPiercingRays.begin(), left->mPiercingRays.end(),
565                                   right->mPiercingRays.begin(), right->mPiercingRays.end(),
[564]566                                   vc->mPiercingRays.begin());
567        }
[440]568
[580]569
[582]570        vc->SetupChildLink(left);
571        vc->SetupChildLink(right);
[580]572
573
[440]574        return vc;
575}
576
[485]577
[582]578ViewCellInterior *ViewCellsManager::MergeViewCells(ViewCellContainer &children) const
579{
580        ViewCellInterior *vc = new ViewCellInterior();//GenerateViewCell();
581
582        ViewCellContainer::const_iterator it, it_end = children.end();
583
584        for (it = children.begin(); it != it_end; ++ it)
585        {
586                // merge pvs
[610]587                vc->GetPvs().Merge((*it)->GetPvs());
[582]588
589                vc->SetupChildLink(*it);
590        }
591
592        return vc;
593}
594
595
[480]596void ViewCellsManager::SetRenderer(Renderer *renderer)
597{
598        mRenderer = renderer;
599}
[441]600
[485]601
[580]602ViewCellsTree *ViewCellsManager::GetViewCellsTree()
[440]603{
[580]604        return mViewCellsTree;
[440]605}
606
607
608void ViewCellsManager::SetVisualizationSamples(const int visSamples)
609{
[444]610        mVisualizationSamples = visSamples;
[440]611}
612
[485]613
[440]614void ViewCellsManager::SetConstructionSamples(const int constructionSamples)
615{
616        mConstructionSamples = constructionSamples;
617}
618
[485]619
[574]620void ViewCellsManager::SetInitialSamples(const int initialSamples)
621{
622        mInitialSamples = initialSamples;
623}
624
625
[440]626void ViewCellsManager::SetPostProcessSamples(const int postProcessSamples)
627{
628        mPostProcessSamples = postProcessSamples;
629}
630
[485]631
[440]632int ViewCellsManager::GetVisualizationSamples() const
633{
634        return mVisualizationSamples;
635}
636
[485]637
[440]638int ViewCellsManager::GetConstructionSamples() const
639{
640        return mConstructionSamples;
641}
642
[485]643
[440]644int ViewCellsManager::GetPostProcessSamples() const
645{
646        return mPostProcessSamples;
647}
648
[485]649
650void ViewCellsManager::GetPvsStatistics(PvsStatistics &stat)
[467]651{
652  ViewCellContainer::const_iterator it = mViewCells.begin();
653  stat.viewcells = 0;
654  stat.minPvs = 100000000;
655  stat.maxPvs = 0;
656  stat.avgPvs = 0.0f;
657
658  for (; it != mViewCells.end(); ++it) {
659        ViewCell *viewcell = *it;
660        int pvsSize = viewcell->GetPvs().GetSize();
661        if ( pvsSize < stat.minPvs)
662          stat.minPvs = pvsSize;
663        if (pvsSize > stat.maxPvs)
664          stat.maxPvs = pvsSize;
665        stat.avgPvs += pvsSize;
666        stat.viewcells++;
667  }
668  if (stat.viewcells)
669        stat.avgPvs/=stat.viewcells;
670}
671
[485]672
[480]673void ViewCellsManager::PrintPvsStatistics(ostream &s)
[467]674{
675  s<<"############# Viewcell PVS STAT ##################\n";
676  PvsStatistics pvsStat;
677  GetPvsStatistics(pvsStat);
678  s<<"#AVG_PVS\n"<<pvsStat.avgPvs<<endl;
679  s<<"#MAX_PVS\n"<<pvsStat.maxPvs<<endl;
680  s<<"#MIN_PVS\n"<<pvsStat.minPvs<<endl;
681}
682
[485]683
[532]684int ViewCellsManager::CastBeam(Beam &beam)
685{
686        return 0;
687}
688
[547]689
[468]690ViewCellContainer &ViewCellsManager::GetViewCells()
691{
692        return mViewCells;
693}
694
[485]695
[487]696void ViewCellsManager::SetViewSpaceBox(const AxisAlignedBox3 &box)
697{
[542]698        mViewSpaceBox = box;
[591]699
700        CreateCuttingPlane();
701       
[577]702        mTotalAreaValid = false;
[487]703}
704
705
[591]706void ViewCellsManager::CreateCuttingPlane()
707{
708        int axis = 0;
709
[609]710        const float factor = 0.65;
[598]711        Vector3 point = mViewSpaceBox.Min() +  mViewSpaceBox.Size() * factor;
[591]712
713        if (mUseCuttingPlaneForViz)
714        environment->GetIntValue("ViewCells.Visualization.cuttingPlaneAxis", axis);
715
716        Vector3 normal(0,0,0);
717        normal[axis] = 1;
718
719        mCuttingPlane = Plane3(normal, point);
720}
721
722
[519]723AxisAlignedBox3 ViewCellsManager::GetViewSpaceBox() const
724{
[542]725        return mViewSpaceBox;
[519]726}
727
728
[480]729void ViewCellsManager::ResetViewCells()
730{
731        mViewCells.clear();
[590]732       
[480]733        CollectViewCells();
[590]734       
[480]735        mViewCellsStats.Reset();
736        EvaluateViewCellsStats();
[590]737
[520]738        // has to be recomputed
[480]739        mTotalAreaValid = false;
740}
741
[485]742
[547]743int ViewCellsManager::GetMaxPvsSize() const
744{
745        return mMaxPvsSize;
746}
747
[590]748
[563]749void
750ViewCellsManager::AddSampleContributions(const VssRayContainer &rays)
751{
752  if (!ViewCellsConstructed())
753        return;
[564]754
[563]755  VssRayContainer::const_iterator it, it_end = rays.end();
[564]756
[563]757  for (it = rays.begin(); it != it_end; ++ it) {
758        AddSampleContributions(*(*it));
759  }
760}
[547]761
[581]762
[562]763int ViewCellsManager::GetMinPvsSize() const
764{
765        return mMinPvsSize;
766}
767
768
769
[561]770float ViewCellsManager::GetMaxPvsRatio() const
771{
772        return mMaxPvsRatio;
773}
774
775
[563]776void
777ViewCellsManager::AddSampleContributions(VssRay &ray)
[468]778{
[563]779  // assumes viewcells have been stored...
780  ViewCellContainer *viewcells = &ray.mViewCells;
781  ViewCellContainer::const_iterator it;
782  for (it = viewcells->begin(); it != viewcells->end(); ++it) {
783        ViewCell *viewcell = *it;
[569]784        if (viewcell->GetValid()) {
785          // if ray not outside of view space
786          viewcell->GetPvs().AddSample(ray.mTerminationObject, ray.mPdf);
787        }
[563]788  }
789}
[503]790
[574]791
[570]792float ViewCellsManager::ComputeSampleContributions(VssRay &ray,
[574]793                                                                                                   const bool addRays,
794                                                                                                   const bool storeViewCells)
[563]795{
[570]796        ViewCellContainer viewcells;
[564]797
[570]798        ray.mPvsContribution = 0;
799        ray.mRelativePvsContribution = 0.0f;
[485]800
[570]801        static Ray hray;
[564]802        hray.Init(ray);
803        //hray.mFlags |= Ray::CULL_BACKFACES;
804        //Ray hray(ray);
805
806        float tmin = 0, tmax = 1.0;
807
808        if (!GetViewSpaceBox().GetRaySegment(hray, tmin, tmax) || (tmin > tmax))
[565]809                return 0;
[564]810
811        Vector3 origin = hray.Extrap(tmin);
812        Vector3 termination = hray.Extrap(tmax);
813
814        CastLineSegment(origin, termination, viewcells);
815        //Debug << "constribution: " << (int)viewcells.size() << endl;
816
[570]817        // copy viewcells memory efficiently
[574]818        //const bool storeViewcells = !addRays;
[564]819
[574]820        if (storeViewCells)
[570]821        {
822                ray.mViewCells.reserve(viewcells.size());
823                ray.mViewCells = viewcells;
824        }
[564]825
[570]826        ViewCellContainer::const_iterator it = viewcells.begin();
[564]827
828
[563]829  for (; it != viewcells.end(); ++it) {
830        ViewCell *viewcell = *it;
[569]831        if (viewcell->GetValid()) {
832          // if ray not outside of view space
833          float contribution;
834          if (viewcell->GetPvs().GetSampleContribution(ray.mTerminationObject,
835                                                                                                   ray.mPdf,
836                                                                                                   contribution
837                                                                                                   ))
838                ray.mPvsContribution++;
839          ray.mRelativePvsContribution += contribution;
840        }
[563]841  }
[564]842
[563]843  if (addRays)
844        for (it = viewcells.begin(); it != viewcells.end(); ++it) {
845          ViewCell *viewcell = *it;
[569]846          if (viewcell->GetValid()) {
847                // if ray not outside of view space
848                viewcell->GetPvs().AddSample(ray.mTerminationObject, ray.mPdf);
849          }
[563]850        }
[570]851
852        return ray.mRelativePvsContribution;
[468]853}
854
855
[469]856void ViewCellsManager::GetRaySets(const VssRayContainer &sourceRays,
[485]857                                                                  const int maxSize,
[503]858                                                                  VssRayContainer &usedRays,
[485]859                                                                  VssRayContainer *savedRays) const
[469]860{
[485]861        const int limit = min(maxSize, (int)sourceRays.size());
[473]862        const float prop = (float)limit / ((float)sourceRays.size() + Limits::Small);
[469]863
[485]864        VssRayContainer::const_iterator it, it_end = sourceRays.end();
[469]865        for (it = sourceRays.begin(); it != it_end; ++ it)
866        {
[473]867                if (Random(1.0f) < prop)
[485]868                        usedRays.push_back(*it);
869                else if (savedRays)
870                        savedRays->push_back(*it);
[469]871        }
872}
873
[477]874
[605]875float ViewCellsManager::GetRendercost(ViewCell *viewCell, float objRendercost) const
876{
877        return mViewCellsTree->GetPvsSize(viewCell) * objRendercost;
878}
879
880
[477]881float ViewCellsManager::GetAccVcArea()
[470]882{
883        // if already computed
884        if (mTotalAreaValid)
885                return mTotalArea;
886
887        mTotalArea = 0;
888        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
889
890        for (it = mViewCells.begin(); it != it_end; ++ it)
[480]891        {
892                //Debug << "area: " << GetArea(*it);
[470]893        mTotalArea += GetArea(*it);
[480]894        }
895
[470]896        mTotalAreaValid = true;
897
898        return mTotalArea;
899}
900
[482]901
[475]902void ViewCellsManager::PrintStatistics(ostream &s) const
903{
904        s << mViewCellsStats << endl;
905}
906
[477]907
[508]908void ViewCellsManager::CreateUniqueViewCellIds()
[482]909{
[508]910        for (int i = 0; i < (int)mViewCells.size(); ++ i)
911                mViewCells[i]->SetId(i);
912}
913
914
915void ViewCellsManager::ExportViewCellsForViz(Exporter *exporter) const
916{
[482]917        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
918
919        for (it = mViewCells.begin(); it != it_end; ++ it)
920        {
[574]921                if (!mOnlyValidViewCells || (*it)->GetValid())
922                {
[582]923                        ExportColor(exporter, *it);             
[591]924                        ExportViewCellGeometry(exporter, *it,
925                                mUseCuttingPlaneForViz ? &mCuttingPlane : NULL);
[574]926                }
[482]927        }
[582]928
[482]929}
930
931
[517]932void ViewCellsManager::CreateViewCellMeshes()
[503]933{
934        // convert to meshes
935        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
936
937        for (it = mViewCells.begin(); it != it_end; ++ it)
938        {
[517]939                if (!(*it)->GetMesh())
940                        CreateMesh(*it);
[503]941        }
942}
943
[508]944
[564]945bool ViewCellsManager::ExportViewCells(const string filename)
946{
[508]947        return false;
948}
949
950
[610]951void ViewCellsManager::CollectViewCells(const int n)
[508]952{
[610]953        mNumActiveViewCells = n;
954        mViewCells.clear();
955        CollectViewCells();
956}
[508]957
958
959
[440]960/**********************************************************************/
961/*                   BspViewCellsManager implementation               */
962/**********************************************************************/
963
[482]964
[574]965BspViewCellsManager::BspViewCellsManager(BspTree *bspTree):
966ViewCellsManager(), mBspTree(bspTree)
[440]967{
[574]968        environment->GetIntValue("BspTree.Construction.samples", mInitialSamples);
[587]969        mBspTree->SetViewCellsManager(this);
[590]970        mBspTree->mViewCellsTree = mViewCellsTree;
[440]971}
972
[462]973
[440]974bool BspViewCellsManager::ViewCellsConstructed() const
975{
976        return mBspTree->GetRoot() != NULL;
977}
978
[480]979
[440]980ViewCell *BspViewCellsManager::GenerateViewCell(Mesh *mesh) const
981{
982        return new BspViewCell(mesh);
983}
984
[480]985
[574]986int BspViewCellsManager::ConstructSubdivision(const ObjectContainer &objects,
987                                                                                          const VssRayContainer &rays)
[440]988{
[441]989        // if view cells were already constructed
[440]990        if (ViewCellsConstructed())
991                return 0;
992
993        int sampleContributions = 0;
[503]994
[469]995        // construct view cells using the collected samples
996        RayContainer constructionRays;
997        VssRayContainer savedRays;
[440]998
[574]999        const int limit = min(mInitialSamples, (int)rays.size());
[440]1000
[469]1001        VssRayContainer::const_iterator it, it_end = rays.end();
[448]1002
[473]1003        const float prop = (float)limit / ((float)rays.size() + Limits::Small);
1004
[469]1005        for (it = rays.begin(); it != it_end; ++ it)
1006        {
[473]1007                if (Random(1.0f) < prop)
[469]1008                        constructionRays.push_back(new Ray(*(*it)));
1009                else
1010                        savedRays.push_back(*it);
1011        }
[440]1012
[503]1013    if (mViewCells.empty())
1014        {
1015                // no view cells loaded
[587]1016                mBspTree->Construct(objects, constructionRays, &mViewSpaceBox);
[469]1017                // collect final view cells
1018                mBspTree->CollectViewCells(mViewCells);
[503]1019        }
[469]1020        else
1021        {
1022                mBspTree->Construct(mViewCells);
1023        }
1024
1025        // destroy rays created only for construction
1026        CLEAR_CONTAINER(constructionRays);
1027
[440]1028        Debug << mBspTree->GetStatistics() << endl;
[503]1029
1030        //EvaluateViewCellsStats();
[480]1031        Debug << "\nView cells after construction:\n" << mViewCellsStats << endl;
1032
[469]1033        // recast rest of the rays
[574]1034        ComputeSampleContributions(savedRays, true, false);
[469]1035
[503]1036
[587]1037        ResetViewCells();
1038   
1039        Debug << "\nView cells after " << (int)savedRays.size()
1040                  << " samples:\n" << mViewCellsStats << endl;
1041
1042        if (1) // export initial view cells
1043        {
1044                cout << "exporting initial view cells (=leaves) ... ";
1045                Exporter *exporter = Exporter::GetExporter("view_cells.x3d");
1046
1047                if (exporter)
1048                {
[600]1049                       
[587]1050                        if (0 && mExportRays)
1051                                exporter->ExportRays(rays, RgbColor(1, 1, 1));
1052
[600]1053                       
[587]1054                        if (mExportGeometry)
1055                                exporter->ExportGeometry(objects);
1056
[600]1057                        //exporter->SetWireframe();
1058                        exporter->SetFilled();
1059                        ExportViewCellsForViz(exporter);
1060
1061
[587]1062                        delete exporter;
1063                }
1064                cout << "finished" << endl;
1065        }
1066
1067
[440]1068        return sampleContributions;
1069}
1070
[503]1071
[480]1072void BspViewCellsManager::CollectViewCells()
1073{
[587]1074        // view cells tree constructed
1075        if (!ViewCellsTreeConstructed())
[591]1076        {               
[587]1077                mBspTree->CollectViewCells(mViewCells);
1078        }
1079        else
1080        {
1081                // we can use the view cells tree hierarchy to get the right set
[591]1082                mViewCellsTree->CollectBestViewCellSet(mViewCells,
[600]1083                                                                                           mNumActiveViewCells);
[587]1084        }
[480]1085}
[468]1086
[503]1087
[471]1088float BspViewCellsManager::GetProbability(ViewCell *viewCell)
[440]1089{
[471]1090        // compute view cell area as subsititute for probability
[591]1091        if (1)
1092                return GetVolume(viewCell) / GetViewSpaceBox().GetVolume();
1093        else
1094                return GetArea(viewCell) / GetAccVcArea();
[466]1095}
[440]1096
[503]1097
[440]1098
[468]1099int BspViewCellsManager::CastLineSegment(const Vector3 &origin,
1100                                                                                 const Vector3 &termination,
1101                                                                                 ViewCellContainer &viewcells)
[440]1102{
[468]1103        return mBspTree->CastLineSegment(origin, termination, viewcells);
1104}
1105
1106
[503]1107int BspViewCellsManager::PostProcess(const ObjectContainer &objects,
[468]1108                                                                         const VssRayContainer &rays)
1109{
[469]1110        if (!ViewCellsConstructed())
[441]1111        {
1112                Debug << "view cells not constructed" << endl;
1113                return 0;
1114        }
1115
[590]1116       
1117        // view cells already finished before post processing step (i.e. because they were loaded)
1118        if (mViewCellsFinished)
1119        {
1120                FinalizeViewCells(true);
1121                EvaluateViewCellsStats();
1122
1123                return 0;
1124        }
1125
[440]1126        //-- post processing of bsp view cells
[600]1127
[440]1128    int vcSize = 0;
1129        int pvsSize = 0;
1130
[480]1131        EvaluateViewCellsStats();
[485]1132        Debug << "\noriginal view cell partition:\n" << mViewCellsStats << endl;
[480]1133
1134        mRenderer->RenderScene();
1135        SimulationStatistics ss;
1136        dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss);
1137
1138    Debug << ss << endl;
1139
[591]1140       
[503]1141
[591]1142        //-- merge view cells
1143        int merged;
[587]1144       
[592]1145        if (mMergeViewCells)
[591]1146        {
1147                cout << "starting post processing using " << mPostProcessSamples << " samples ... ";
1148                long startTime = GetTime();
1149       
1150                VssRayContainer postProcessRays;
1151                GetRaySets(rays, mPostProcessSamples, postProcessRays);
[440]1152
[591]1153                merged = mViewCellsTree->ConstructMergeTree(rays, objects);
[440]1154
[591]1155                //-- stats and visualizations
1156                cout << "finished" << endl;
1157                cout << "merged " << merged << " view cells in "
1158                         << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
[440]1159
[591]1160                Debug << "Postprocessing: Merged " << merged << " view cells in "
1161                        << TimeDiff(startTime, GetTime()) *1e-3 << " secs"
1162                        << "using " << (int)rays.size() << " samples" << endl << endl;
1163        }
[503]1164
[600]1165    // reset view cells and stats
[480]1166        ResetViewCells();
[605]1167        Debug << "\nView cells after merge:\n" << mViewCellsStats << endl;
[600]1168
1169        int savedColorCode  = mColorCode;
[605]1170       
[600]1171        //BspLeaf::NewMail();
1172        if (1) // export merged view cells
1173        {
1174                mColorCode = 0;
[605]1175               
[600]1176                Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d");
[605]1177               
[600]1178
1179                cout << "exporting view cells after merge ... ";
1180
1181                if (exporter)
1182                {
1183                        if (mExportGeometry)
1184                                exporter->ExportGeometry(objects);
1185
1186                        //exporter->SetWireframe();
1187                        exporter->SetFilled();
1188                        ExportViewCellsForViz(exporter);
1189
1190
1191                        delete exporter;
1192                }
1193                cout << "finished" << endl;
1194        }
1195
1196        if (1) // export merged view cells
1197        {
1198                mColorCode = 1;
1199
1200                Exporter *exporter = Exporter::GetExporter("merged_view_cells_pvs.x3d");
1201       
1202                cout << "exporting view cells after merge (pvs size) ... ";     
1203
1204                if (exporter)
1205                {
1206                        //exporter->SetWireframe();
1207                       
1208                        if (mExportGeometry)
1209                                exporter->ExportGeometry(objects);
1210
1211                        //exporter->SetWireframe();
1212                        exporter->SetFilled();
1213                        ExportViewCellsForViz(exporter);
1214
1215                        delete exporter;
1216                }
1217                cout << "finished" << endl;
1218        }
1219
1220        mColorCode = savedColorCode;
1221
[587]1222        FinalizeViewCells(true);
1223       
1224        // write view cells to disc
1225        if (mExportViewCells)
1226        {
1227                char buff[100];
1228                environment->GetStringValue("ViewCells.filename", buff);
1229                string vcFilename(buff);
1230
1231                ExportViewCells(buff);
1232        }
1233
[440]1234        return merged;
1235}
1236
[477]1237
1238BspViewCellsManager::~BspViewCellsManager()
1239{
1240}
1241
1242
[440]1243int BspViewCellsManager::GetType() const
1244{
1245        return BSP;
1246}
1247
1248
1249void BspViewCellsManager::Visualize(const ObjectContainer &objects,
[466]1250                                                                        const VssRayContainer &sampleRays)
[440]1251{
[469]1252        if (!ViewCellsConstructed())
1253                return;
[574]1254       
[600]1255        int savedColorCode = mColorCode;
1256
1257       
1258       
1259        if (1) // export final view cells
[440]1260        {
[600]1261                mColorCode = 1;
[587]1262
[600]1263                Exporter *exporter = Exporter::GetExporter("final_view_cells.x3d");
1264       
1265                cout << "exporting view cells after merge (pvs size) ... ";     
[587]1266
[469]1267                if (exporter)
[440]1268                {
[600]1269                        //exporter->SetWireframe();
1270                       
1271                        if (mExportGeometry)
1272                                exporter->ExportGeometry(objects);
[590]1273
[600]1274                        //exporter->SetWireframe();
1275                        exporter->SetFilled();
[508]1276                        ExportViewCellsForViz(exporter);
[587]1277
[469]1278                        delete exporter;
[440]1279                }
[469]1280                cout << "finished" << endl;
[503]1281        }
[477]1282
[600]1283        mColorCode = savedColorCode;
1284
[469]1285        //-- visualization of the BSP splits
1286        bool exportSplits = false;
1287        environment->GetBoolValue("BspTree.Visualization.exportSplits", exportSplits);
[503]1288
[469]1289        if (exportSplits)
[440]1290        {
[469]1291                cout << "exporting splits ... ";
[477]1292                ExportSplits(objects);
[469]1293                cout << "finished" << endl;
[440]1294        }
[477]1295
[600]1296        // export single view cells
[477]1297        ExportBspPvs(objects);
[440]1298}
1299
1300
[503]1301inline bool vc_gt(ViewCell *a, ViewCell *b)
1302{
[440]1303        return a->GetPvs().GetSize() > b->GetPvs().GetSize();
1304}
1305
[477]1306
1307void BspViewCellsManager::ExportSplits(const ObjectContainer &objects)
[440]1308{
1309        Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d");
1310
[503]1311        if (exporter)
1312        {
[598]1313                //exporter->SetFilled();
1314
1315                if (mExportGeometry)
1316                        exporter->ExportGeometry(objects);
1317
[503]1318                Material m;
[440]1319                m.mDiffuseColor = RgbColor(1, 0, 0);
1320                exporter->SetForcedMaterial(m);
1321                exporter->SetWireframe();
[503]1322
[440]1323                exporter->ExportBspSplits(*mBspTree, true);
1324
[482]1325                //NOTE: take forced material, else big scenes cannot be viewed
[440]1326                m.mDiffuseColor = RgbColor(0, 1, 0);
1327                exporter->SetForcedMaterial(m);
[482]1328                //exporter->ResetForcedMaterial();
1329
[440]1330                delete exporter;
1331        }
1332}
1333
[477]1334
1335void BspViewCellsManager::ExportBspPvs(const ObjectContainer &objects)
[440]1336{
[477]1337        const int leafOut = 10;
[503]1338
[477]1339        ViewCell::NewMail();
[440]1340
[477]1341        //-- some rays for output
1342        const int raysOut = min((int)mBspRays.size(), mVisualizationSamples);
[503]1343
[477]1344        cout << "visualization using " << mVisualizationSamples << " samples" << endl;
1345        Debug << "\nOutput view cells: " << endl;
[503]1346
[478]1347        // sort view cells to get largest view cells
[587]1348        if (0)
1349                stable_sort(mViewCells.begin(), mViewCells.end(), vc_gt);
1350
[503]1351        int limit = min(leafOut, (int)mViewCells.size());
1352
[478]1353        for (int i = 0; i < limit; ++ i)
[477]1354        {
[478]1355                cout << "creating output for view cell " << i << " ... ";
1356                VssRayContainer vcRays;
1357                Intersectable::NewMail();
[582]1358                ViewCell *vc;
1359
1360                if (0)
1361                        vc = mViewCells[i];
1362                else
1363                        vc = mViewCells[Random((int)mViewCells.size())];
1364
[478]1365                cout << "creating output for view cell " << i << " ... ";
[469]1366
[587]1367                if(0)
[477]1368                {
[587]1369                        // check whether we can add the current ray to the output rays
1370                        for (int k = 0; k < raysOut; ++ k)
[477]1371                        {
[587]1372                                BspRay *ray = mBspRays[k];
1373                                for     (int j = 0; j < (int)ray->intersections.size(); ++ j)
1374                                {
1375                                        BspLeaf *leaf = ray->intersections[j].mLeaf;
1376                                        if (vc == leaf->GetViewCell())
1377                                                vcRays.push_back(ray->vssRay);
1378                                }
[477]1379                        }
1380                }
[587]1381
[478]1382                //bspLeaves[j]->Mail();
1383                char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
[477]1384
[478]1385                Exporter *exporter = Exporter::GetExporter(s);
[503]1386
[478]1387                exporter->SetWireframe();
[477]1388
[478]1389                Material m;//= RandomMaterial();
1390                m.mDiffuseColor = RgbColor(0, 1, 0);
1391                exporter->SetForcedMaterial(m);
[477]1392
[587]1393                ExportViewCellGeometry(exporter, vc);
1394               
[478]1395                // export rays piercing this view cell
1396                exporter->ExportRays(vcRays, RgbColor(0, 1, 0));
[580]1397
[478]1398                m.mDiffuseColor = RgbColor(1, 0, 0);
1399                exporter->SetForcedMaterial(m);
[440]1400
[478]1401                ObjectPvsMap::const_iterator it,
1402                        it_end = vc->GetPvs().mEntries.end();
[440]1403
[478]1404                exporter->SetFilled();
[469]1405
[478]1406                // output PVS of view cell
[503]1407                for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)
[478]1408                {
1409                        Intersectable *intersect = (*it).first;
[469]1410
[478]1411                        if (!intersect->Mailed())
1412                        {
1413                                Material m = RandomMaterial();
1414                                exporter->SetForcedMaterial(m);
1415
1416                                exporter->ExportIntersectable(intersect);
1417                                intersect->Mail();
[503]1418                        }
[477]1419                }
[503]1420
[478]1421                DEL_PTR(exporter);
1422                cout << "finished" << endl;
[477]1423        }
1424
1425        Debug << endl;
[440]1426}
1427
[441]1428
[503]1429void BspViewCellsManager::ExportColor(Exporter *exporter,
[482]1430                                                                          ViewCell *vc) const
1431{
[600]1432        const bool vcValid = CheckValidity(vc, mMinPvsSize, mMaxPvsSize);
[482]1433
1434        float importance = 0;
[598]1435        static Material m;
[482]1436
1437        switch (mColorCode)
1438        {
[598]1439        case 0: // Random
1440                {
1441                        if (vcValid)
1442                        {
1443                                m.mDiffuseColor.r = 0.5f + RandomValue(0.0f, 0.5f);
1444                                m.mDiffuseColor.g = 0.5f + RandomValue(0.0f, 0.5f);
[600]1445                                m.mDiffuseColor.b = 0.5f + RandomValue(0.0f, 0.5f);
[598]1446                        }
1447                        else
1448                        {
1449                                m.mDiffuseColor.r = 0.0f;
1450                                m.mDiffuseColor.g = 1.0f;
1451                                m.mDiffuseColor.b = 0.0f;
1452                        }
1453
1454                        exporter->SetForcedMaterial(m);
1455                        return;
1456                }
1457               
[482]1458        case 1: // pvs
1459                {
[503]1460                        importance = (float)vc->GetPvs().GetSize() /
[482]1461                                (float)mViewCellsStats.maxPvs;
[598]1462
[482]1463                }
1464                break;
1465        case 2: // merges
1466                {
[598]1467            int lSize = mViewCellsTree->GetSize(vc);
1468                        importance = (float)lSize / (float)mViewCellsStats.maxLeaves;
[482]1469                }
[598]1470                //break;
[482]1471        case 3: // merge tree differene
1472                {
1473                        // TODO
[598]1474                        //importance = (float)GetMaxTreeDiff(vc) /
1475                        //      (float)(mVspBspTree->GetStatistics().maxDepth * 2);
1476
[482]1477                }
1478                break;
1479        default:
1480                break;
1481        }
1482
[598]1483        // special color code for invalid view cells
[482]1484        m.mDiffuseColor.r = importance;
1485        m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r;
[598]1486        m.mDiffuseColor.b = vcValid ? 1.0f : 0.0f;
[503]1487
[598]1488        //Debug << "importance: " << importance << endl;
[482]1489        exporter->SetForcedMaterial(m);
1490}
1491
[587]1492
[580]1493void BspViewCellsManager::ExportViewCellGeometry(Exporter *exporter,
[591]1494                                                                                                 ViewCell *vc,
1495                                                                                                 const Plane3 *cuttingPlane) const
[482]1496{
1497        if (vc->GetMesh())
1498        {
[587]1499                exporter->ExportMesh(vc->GetMesh());
1500                return;
[482]1501        }
[587]1502
1503        BspNodeGeometry geom;
1504        mBspTree->ConstructGeometry(vc, geom);
[591]1505
1506
1507        if (cuttingPlane)
1508        {
1509                BspNodeGeometry front;
1510                BspNodeGeometry back;
1511
1512                geom.SplitGeometry(front,
1513                                                   back,
1514                                                   *cuttingPlane,
1515                                                   mViewSpaceBox,
[600]1516                                                   0.0001f);
[591]1517
[600]1518                if ((int)back.mPolys.size() >= 3)
1519                        exporter->ExportPolygons(back.mPolys);
[591]1520        }
1521        else
1522        {
[600]1523               
[591]1524                exporter->ExportPolygons(geom.mPolys);
1525        }
[482]1526}
1527
[503]1528
1529void BspViewCellsManager::CreateMesh(ViewCell *vc)
1530{
[587]1531        if (vc->GetMesh())
1532                delete vc->GetMesh();
1533
1534        BspNodeGeometry geom;
1535       
1536        mBspTree->ConstructGeometry(vc, geom);
1537
1538        Mesh *mesh = new Mesh();
1539        geom.AddToMesh(*mesh);
1540        vc->SetMesh(mesh);
1541        mMeshContainer.push_back(mesh);
[503]1542}
1543
[551]1544
[587]1545void BspViewCellsManager::Finalize(ViewCell *viewCell,
1546                                                                   const bool createMesh)
[502]1547{
[587]1548        CreateMesh(viewCell);
[572]1549
[587]1550        float area = 0;
1551        float volume = 0;
[572]1552
[587]1553        ViewCellContainer leaves;
1554        mViewCellsTree->CollectLeaves(viewCell, leaves);
1555
1556        ViewCellContainer::const_iterator it, it_end = leaves.end();
1557
1558        for (it = leaves.begin(); it != it_end; ++ it)
1559        {
1560                BspNodeGeometry geom;
1561                BspLeaf *leaf = dynamic_cast<BspViewCell *>(*it)->mLeaf;
1562                mBspTree->ConstructGeometry(leaf, geom);
1563
1564                area += geom.GetArea();
1565                volume += geom.GetVolume();
1566        }
1567
1568        viewCell->SetVolume(volume);
1569        viewCell->SetArea(area);
[502]1570}
1571
[580]1572
[587]1573ViewCell *BspViewCellsManager::GetViewCell(const Vector3 &point) const
[580]1574{
[587]1575        if (!mBspTree)
1576                return NULL;
1577
1578        if (!mViewSpaceBox.IsInside(point))
1579                return NULL;
1580       
1581        return mBspTree->GetViewCell(point);
[580]1582}
1583
1584
[587]1585void BspViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays,
1586                                                                                                 vector<MergeCandidate> &candidates)
1587{
1588        cout << "collecting merge candidates ... " << endl;
1589
1590        if (mUseRaysForMerge)
1591        {
1592                mBspTree->CollectMergeCandidates(rays, candidates);
1593        }
1594        else
1595        {
1596                vector<BspLeaf *> leaves;
1597                mBspTree->CollectLeaves(leaves);
1598                mBspTree->CollectMergeCandidates(leaves, candidates);
1599        }
1600
1601        cout << "fininshed collecting candidates" << endl;
1602}
1603
1604
[440]1605
[590]1606bool BspViewCellsManager::ExportViewCells(const string filename)
1607{
1608        cout << "exporting view cells to xml ... ";
1609        std::ofstream stream;
[503]1610
[590]1611        // for output we need unique ids for each view cell
1612        CreateUniqueViewCellIds();
[503]1613
[590]1614
1615        stream.open(filename.c_str());
1616        stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<endl;
1617        stream << "<Visibility_Solution>" << endl;
1618
1619        //-- the view space bounding box
1620        stream << "<ViewSpaceBox"
1621                   << " min=\"" << mViewSpaceBox.Min().x << " " << mViewSpaceBox.Min().y << " " << mViewSpaceBox.Min().z << "\""
1622                   << " max=\"" << mViewSpaceBox.Max().x << " " << mViewSpaceBox.Max().y << " " << mViewSpaceBox.Max().z << "\" />" << endl;
1623
1624        //-- the type of the view cells hierarchy
1625        //stream << "<Hierarchy name=\"bspTree\" />" << endl;
1626        stream << "<Hierarchy name=\"vspBspTree\" />" << endl; // write vsp bsp here because can use same tree and is bug free
1627        //-- load the view cells itself, i.e., the ids and the pvs
1628        stream << "<ViewCells>" << endl;
[610]1629
1630#if 0
1631       
[590]1632        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
[610]1633               
[590]1634        for (it = mViewCells.begin(); it != it_end; ++ it)
1635                ExportViewCell(*it, stream);
[610]1636#else
1637        mViewCellsTree->Export(stream);
1638#endif
[590]1639
1640        stream << "</ViewCells>" << endl;
1641
1642        //-- load the hierarchy
1643        stream << "<Hierarchy>" << endl;
1644        mBspTree->Export(stream);
1645        stream << endl << "</Hierarchy>" << endl;
1646
1647        stream << "</Visibility_Solution>" << endl;
1648        stream.close();
1649
1650        cout << "finished" << endl;
1651
1652        return true;
1653}
1654
1655
1656void BspViewCellsManager::AddCurrentViewCellsToHierarchy()
1657{
1658        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
1659        for (it = mViewCells.begin(); it != it_end; ++ it)
1660        {
1661                ViewCell *vc = *it;
1662                ViewCellContainer leaves;
1663                mViewCellsTree->CollectLeaves(vc, leaves);
1664               
1665                ViewCellContainer::const_iterator lit, lit_end = leaves.end();
1666
1667                for (lit = leaves.begin(); lit != lit_end; ++ lit)
1668                {
1669                        BspViewCell *bspVc = dynamic_cast<BspViewCell *>(*lit);
1670                        bspVc->mLeaf->SetViewCell(vc);
1671                }
1672        }
1673}
1674
[610]1675
1676void BspViewCellsManager::CreateMergeHierarchy()
1677{
1678        TraversalQueue tQueue;
1679
1680        tQueue.push(TraversalData(mBspTree->GetRoot(), NULL));
1681
1682        while (!tQueue.empty())
1683        {
1684                TraversalData tData = tQueue.top();
1685                tQueue.pop();
1686
1687                if (tData.mNode->IsLeaf())
1688                {
1689                        ViewCell *viewCell = dynamic_cast<BspLeaf *>(tData.mNode)->GetViewCell();
1690                        viewCell->SetMergeCost((float)tData.mNode->mTimeStamp);
1691
1692                        if (tData.mParentViewCell)
1693                        {
1694                                tData.mParentViewCell->SetupChildLink(viewCell);
1695                                // probagate up pvs
1696                                mViewCellsTree->PropagateUpPvs(viewCell);
1697                        }
1698                }
1699                else
1700                {
1701                        BspInterior *interior = dynamic_cast<BspInterior *>(tData.mNode);
1702                        ViewCellInterior *viewCellInterior = new ViewCellInterior();
1703                        viewCellInterior->SetMergeCost((float)tData.mNode->mTimeStamp);
1704
1705
1706                        tQueue.push(TraversalData(interior->GetBack(), viewCellInterior));
1707                        tQueue.push(TraversalData(interior->GetFront(), viewCellInterior));
1708
1709                        if (tData.mParentViewCell)
1710                                tData.mParentViewCell->SetupChildLink(viewCellInterior);
1711                }
1712        }
1713}
1714
[590]1715/************************************************************************/
1716/*                   KdViewCellsManager implementation                  */
1717/************************************************************************/
1718
1719
1720
[440]1721KdViewCellsManager::KdViewCellsManager(KdTree *kdTree):
[469]1722ViewCellsManager(), mKdTree(kdTree), mKdPvsDepth(100)
[440]1723{
1724}
1725
[605]1726
[471]1727float KdViewCellsManager::GetProbability(ViewCell *viewCell)
[468]1728{
[479]1729        // compute view cell area / volume as subsititute for probability
[605]1730        if (0)
1731                return GetArea(viewCell) / GetViewSpaceBox().SurfaceArea();
1732        else
1733                return GetVolume(viewCell) / GetViewSpaceBox().GetVolume();
[468]1734}
1735
1736
1737
[479]1738
[480]1739void KdViewCellsManager::CollectViewCells()
1740{
1741        //mKdTree->CollectViewCells(mViewCells); TODO
1742}
[479]1743
[519]1744
[574]1745int KdViewCellsManager::ConstructSubdivision(const ObjectContainer &objects,
[487]1746                                                                  const VssRayContainer &rays)
[440]1747{
[441]1748        // if view cells already constructed
[440]1749        if (ViewCellsConstructed())
1750                return 0;
[441]1751
[440]1752        mKdTree->Construct();
1753
[480]1754        mTotalAreaValid = false;
[469]1755        // create the view cells
1756        mKdTree->CreateAndCollectViewCells(mViewCells);
[503]1757
[480]1758        // cast rays
[574]1759        ComputeSampleContributions(rays, true, false);
[480]1760
[479]1761        EvaluateViewCellsStats();
[480]1762        Debug << "\nView cells after construction:\n" << mViewCellsStats << endl;
[469]1763
[440]1764        return 0;
1765}
1766
[587]1767
[440]1768bool KdViewCellsManager::ViewCellsConstructed() const
1769{
1770        return mKdTree->GetRoot() != NULL;
1771}
1772
[503]1773int KdViewCellsManager::PostProcess(const ObjectContainer &objects,
[466]1774                                                                        const VssRayContainer &rays)
[440]1775{
1776        return 0;
1777}
1778
1779void KdViewCellsManager::Visualize(const ObjectContainer &objects,
[466]1780                                                                   const VssRayContainer &sampleRays)
[440]1781{
[441]1782        if (!ViewCellsConstructed())
1783                return;
1784
[469]1785        // using view cells instead of the kd PVS of objects
1786        const bool useViewCells = true;
1787        bool exportRays = false;
[440]1788
1789        int limit = min(mVisualizationSamples, (int)sampleRays.size());
[469]1790        const int pvsOut = min((int)objects.size(), 10);
[466]1791        VssRayContainer *rays = new VssRayContainer[pvsOut];
[440]1792
[469]1793        if (useViewCells)
[440]1794        {
[469]1795                const int leafOut = 10;
[503]1796
[469]1797                ViewCell::NewMail();
[503]1798
[469]1799                //-- some rays for output
1800                const int raysOut = min((int)sampleRays.size(), mVisualizationSamples);
1801                Debug << "visualization using " << raysOut << " samples" << endl;
1802
1803                //-- some random view cells and rays for output
1804                vector<KdLeaf *> kdLeaves;
[503]1805
[469]1806                for (int i = 0; i < leafOut; ++ i)
1807                        kdLeaves.push_back(dynamic_cast<KdLeaf *>(mKdTree->GetRandomLeaf()));
[503]1808
[469]1809                for (int i = 0; i < kdLeaves.size(); ++ i)
[440]1810                {
[469]1811                        KdLeaf *leaf = kdLeaves[i];
1812                        RayContainer vcRays;
[503]1813
[469]1814                        cout << "creating output for view cell " << i << " ... ";
[503]1815#if 0
[469]1816                        // check whether we can add the current ray to the output rays
[503]1817                        for (int k = 0; k < raysOut; ++ k)
[440]1818                        {
[469]1819                                Ray *ray = sampleRays[k];
[503]1820
[469]1821                                for (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)
1822                                {
1823                                        BspLeaf *leaf2 = ray->bspIntersections[j].mLeaf;
[503]1824
1825                                        if (leaf->GetViewCell() == leaf2->GetViewCell())
[469]1826                                        {
1827                                                vcRays.push_back(ray);
1828                                        }
1829                                }
[479]1830                        }
[503]1831#endif
[469]1832                        Intersectable::NewMail();
[503]1833
[469]1834                        ViewCell *vc = leaf->mViewCell;
[503]1835
[469]1836                        //bspLeaves[j]->Mail();
1837                        char s[64]; sprintf(s, "kd-pvs%04d.x3d", i);
[503]1838
[469]1839                        Exporter *exporter = Exporter::GetExporter(s);
1840                        exporter->SetFilled();
1841
1842                        exporter->SetWireframe();
1843                        //exporter->SetFilled();
[503]1844
[469]1845                        Material m;//= RandomMaterial();
1846                        m.mDiffuseColor = RgbColor(1, 1, 0);
1847                        exporter->SetForcedMaterial(m);
[503]1848
[469]1849                        AxisAlignedBox3 box = mKdTree->GetBox(leaf);
1850                        exporter->ExportBox(box);
1851
1852                        // export rays piercing this view cell
[503]1853                        exporter->ExportRays(vcRays, 1000, RgbColor(0, 1, 0));
1854
[469]1855                        m.mDiffuseColor = RgbColor(1, 0, 0);
1856                        exporter->SetForcedMaterial(m);
[503]1857
[469]1858                        // exporter->SetWireframe();
1859                        exporter->SetFilled();
[503]1860
[469]1861                        ObjectPvsMap::iterator it, it_end = vc->GetPvs().mEntries.end();
1862                        // output PVS of view cell
[503]1863                        for (it = vc->GetPvs().mEntries.begin(); it !=  it_end; ++ it)
[469]1864                        {
1865                                Intersectable *intersect = (*it).first;
1866                                if (!intersect->Mailed())
1867                                {
1868                                        exporter->ExportIntersectable(intersect);
1869                                        intersect->Mail();
[503]1870                                }
[440]1871                        }
[503]1872
[469]1873                        DEL_PTR(exporter);
1874                        cout << "finished" << endl;
[440]1875                }
[469]1876
1877                DEL_PTR(rays);
[440]1878        }
[469]1879        else // using kd PVS of objects
1880        {
1881                for (int i = 0; i < limit; ++ i)
1882                {
1883                        VssRay *ray = sampleRays[i];
[503]1884
[469]1885                        // check whether we can add this to the rays
[503]1886                        for (int j = 0; j < pvsOut; j++)
[469]1887                        {
1888                                if (objects[j] == ray->mTerminationObject)
1889                                {
1890                                        rays[j].push_back(ray);
1891                                }
1892                        }
1893                }
[440]1894
[503]1895                if (exportRays)
[469]1896                {
1897                        Exporter *exporter = NULL;
1898                        exporter = Exporter::GetExporter("sample-rays.x3d");
1899                        exporter->SetWireframe();
1900                        exporter->ExportKdTree(*mKdTree);
[503]1901
1902                        for (i=0; i < pvsOut; i++)
[469]1903                                exporter->ExportRays(rays[i], RgbColor(1, 0, 0));
1904
1905                        exporter->SetFilled();
[503]1906
[469]1907                        delete exporter;
1908                }
[440]1909
[503]1910                for (int k=0; k < pvsOut; k++)
[469]1911                {
1912                        Intersectable *object = objects[k];
[503]1913                        char s[64];
[469]1914                        sprintf(s, "sample-pvs%04d.x3d", k);
[440]1915
[469]1916                        Exporter *exporter = Exporter::GetExporter(s);
1917                        exporter->SetWireframe();
[503]1918
[469]1919                        KdPvsMap::iterator i = object->mKdPvs.mEntries.begin();
1920                        Intersectable::NewMail();
[503]1921
[469]1922                        // avoid adding the object to the list
1923                        object->Mail();
1924                        ObjectContainer visibleObjects;
[503]1925
1926                        for (; i != object->mKdPvs.mEntries.end(); i++)
[469]1927                        {
1928                                KdNode *node = (*i).first;
1929                                exporter->ExportBox(mKdTree->GetBox(node));
[503]1930
[469]1931                                mKdTree->CollectObjects(node, visibleObjects);
1932                        }
[503]1933
[469]1934                        exporter->ExportRays(rays[k],  RgbColor(0, 1, 0));
1935                        exporter->SetFilled();
[503]1936
[469]1937                        for (int j = 0; j < visibleObjects.size(); j++)
1938                                exporter->ExportIntersectable(visibleObjects[j]);
[503]1939
[469]1940                        Material m;
1941                        m.mDiffuseColor = RgbColor(1, 0, 0);
1942                        exporter->SetForcedMaterial(m);
1943                        exporter->ExportIntersectable(object);
[503]1944
[469]1945                        delete exporter;
[440]1946                }
[503]1947        }
[440]1948}
1949
[469]1950
[482]1951void KdViewCellsManager::ExportColor(Exporter *exporter,
1952                                                                         ViewCell *vc) const
1953{
1954        // TODO
1955}
1956
[580]1957ViewCell *KdViewCellsManager::GenerateViewCell(Mesh *mesh) const
1958{
1959        return new KdViewCell(mesh);
1960}
[482]1961
[580]1962
1963void KdViewCellsManager::ExportViewCellGeometry(Exporter *exporter,
[591]1964                                                                                                ViewCell *vc,
1965                                                                                                const Plane3 *cuttingPlane) const
[482]1966{
[580]1967        ViewCellContainer leaves;
[485]1968
[580]1969        mViewCellsTree->CollectLeaves(vc, leaves);
1970        ViewCellContainer::const_iterator it, it_end = leaves.end();
1971
1972        for (it = leaves.begin(); it != it_end; ++ it)
1973        {
1974                KdViewCell *kdVc = dynamic_cast<KdViewCell *>(*it);
1975       
1976                exporter->ExportBox(mKdTree->GetBox(kdVc->mLeaf));
1977        }
[482]1978}
1979
1980
[440]1981int KdViewCellsManager::GetType() const
1982{
1983        return ViewCellsManager::KD;
1984}
1985
1986
[441]1987
[440]1988KdNode *KdViewCellsManager::GetNodeForPvs(KdLeaf *leaf)
1989{
1990        KdNode *node = leaf;
1991
1992        while (node->mParent && node->mDepth > mKdPvsDepth)
1993                node = node->mParent;
1994        return node;
1995}
1996
[469]1997int KdViewCellsManager::CastLineSegment(const Vector3 &origin,
1998                                                                                const Vector3 &termination,
1999                                                                                ViewCellContainer &viewcells)
[466]2000{
[469]2001        return mKdTree->CastLineSegment(origin, termination, viewcells);
[466]2002}
2003
[469]2004
[503]2005void KdViewCellsManager::CreateMesh(ViewCell *vc)
2006{
[551]2007        // TODO
[503]2008}
2009
[580]2010
2011
2012void KdViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays,
2013                                                                                                vector<MergeCandidate> &candidates)
2014{
2015        // TODO
2016}
2017
2018
[440]2019/**********************************************************************/
2020/*                   VspKdViewCellsManager implementation             */
2021/**********************************************************************/
2022
[482]2023
[574]2024VspKdViewCellsManager::VspKdViewCellsManager(VspKdTree *vspKdTree):
2025ViewCellsManager(), mVspKdTree(vspKdTree)
[440]2026{
[574]2027        environment->GetIntValue("VspKdTree.Construction.samples", mInitialSamples);
[468]2028        mVspKdTree->SetViewCellsManager(this);
2029}
[462]2030
[471]2031float VspKdViewCellsManager::GetProbability(ViewCell *viewCell)
[468]2032{
[605]2033        // compute view cell area / volume as subsititute for probability
2034        if (0)
2035                return GetArea(viewCell) / GetViewSpaceBox().SurfaceArea();
2036        else
2037                return GetVolume(viewCell) / GetViewSpaceBox().GetVolume();
[440]2038}
2039
[462]2040
[468]2041
[503]2042
[480]2043void VspKdViewCellsManager::CollectViewCells()
2044{
2045        mVspKdTree->CollectViewCells(mViewCells);
2046}
[462]2047
[570]2048
[574]2049int VspKdViewCellsManager::ConstructSubdivision(const ObjectContainer &objects,
2050                                                                                                const VssRayContainer &rays)
[440]2051{
[441]2052        // if view cells already constructed
[440]2053        if (ViewCellsConstructed())
2054                return 0;
[503]2055
[469]2056        VssRayContainer constructionRays;
2057        VssRayContainer savedRays;
[440]2058
[503]2059        GetRaySets(rays,
[574]2060                           mInitialSamples,
[503]2061                           constructionRays,
[485]2062                           &savedRays);
[503]2063
2064        Debug << "constructing vsp kd tree using "
[469]2065                  << (int)constructionRays.size() << " samples" << endl;
[452]2066
[542]2067        mVspKdTree->Construct(constructionRays, &mViewSpaceBox);
[452]2068        Debug << mVspKdTree->GetStatistics() << endl;
2069
[482]2070        // export leaf building blocks
2071        ExportLeaves(objects, rays);
[480]2072
[469]2073        // finally merge kd leaf building blocks to view cells
[485]2074        const int merged = mVspKdTree->MergeViewCells(rays);
2075
2076        // collapse siblings belonging to the same view cell
[486]2077        mVspKdTree->RefineViewCells(rays);
[485]2078
[542]2079        // collapse siblings belonging to the same view cell
[503]2080        mVspKdTree->CollapseTree();
2081
[482]2082        // evaluale view cell stats
2083        ResetViewCells();
[469]2084
[482]2085        Debug << "\nView cells after construction:\n" << mViewCellsStats << endl;
2086
[485]2087        long startTime = GetTime();
[469]2088        // recast rest of rays
[574]2089        ComputeSampleContributions(savedRays, true, false);
[503]2090
2091        Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3
[485]2092                  << " secs" << endl;
[469]2093
2094        return merged;
[440]2095}
2096
2097bool VspKdViewCellsManager::ViewCellsConstructed() const
2098{
2099        return mVspKdTree->GetRoot() != NULL;
2100}
2101
[441]2102
[462]2103ViewCell *VspKdViewCellsManager::GenerateViewCell(Mesh *mesh) const
2104{
2105        return new VspKdViewCell(mesh);
2106}
2107
[503]2108int VspKdViewCellsManager::PostProcess(const ObjectContainer &objects,
[466]2109                                                                           const VssRayContainer &rays)
[440]2110{
[441]2111        if (!ViewCellsConstructed())
2112                return 0;
2113
[482]2114        // recalculate stats
2115        EvaluateViewCellsStats();
2116
[469]2117        return 0;
[440]2118}
2119
[482]2120
2121void VspKdViewCellsManager::ExportLeaves(const ObjectContainer &objects,
2122                                                                                 const VssRayContainer &sampleRays)
[440]2123{
[441]2124        if (!ViewCellsConstructed())
2125                return;
2126
[482]2127        //-- export leaf building blocks
[503]2128        Exporter *exporter = Exporter::GetExporter("vspkdtree.x3d");
[482]2129        if (!exporter)
2130                return;
2131
[598]2132        if (mExportGeometry)
2133                exporter->ExportGeometry(objects);
2134       
[482]2135        //exporter->SetWireframe();
2136        //exporter->ExportVspKdTree(*mVspKdTree, mVspKdTree->GetStatistics().maxPvsSize);
2137        exporter->ExportVspKdTree(*mVspKdTree);
2138
[503]2139        if (mExportRays)
[440]2140        {
[503]2141                const float prob = (float)mVisualizationSamples
[482]2142                        / ((float)sampleRays.size() + Limits::Small);
[440]2143
[482]2144                exporter->SetWireframe();
[440]2145
[482]2146                //-- collect uniformly distributed rays
2147                VssRayContainer rays;
[440]2148
[482]2149                for (int i = 0; i < sampleRays.size(); ++ i)
2150                {
2151                        if (RandomValue(0,1) < prob)
2152                                rays.push_back(sampleRays[i]);
[440]2153                }
[482]2154                exporter->ExportRays(rays, RgbColor(1, 0, 0));
[440]2155        }
2156
[482]2157        delete exporter;
2158}
2159
2160void VspKdViewCellsManager::Visualize(const ObjectContainer &objects,
2161                                                                          const VssRayContainer &sampleRays)
2162{
2163        if (!ViewCellsConstructed())
2164                return;
[503]2165
[482]2166        //-- export single view cells
2167        for (int i = 0; i < 10; ++ i)
[440]2168        {
[482]2169                char s[64];
2170                sprintf(s, "vsp_viewcell%04d.x3d", i);
2171                Exporter *exporter = Exporter::GetExporter(s);
[503]2172                const int idx =
[482]2173                        (int)RandomValue(0.0, (Real)((int)mViewCells.size() - 1));
[440]2174
[503]2175                VspKdViewCell *vc = dynamic_cast<VspKdViewCell *>(mViewCells[idx]);
[482]2176
2177                //-- export geometry
2178                Material m;
2179                m.mDiffuseColor = RgbColor(0, 1, 1);
[503]2180
[482]2181                exporter->SetForcedMaterial(m);
2182                exporter->SetWireframe();
2183
[580]2184                ExportViewCellGeometry(exporter, vc);
[482]2185
2186                //-- export stored rays
[580]2187               
[485]2188                if (mExportRays)
[440]2189                {
[580]2190                        ViewCellContainer leaves;
2191                        mViewCellsTree->CollectLeaves(vc, leaves);
[440]2192
[580]2193                        ViewCellContainer::const_iterator it,
2194                                it_end = leaves.end();
2195
2196                        for (it = leaves.begin(); it != it_end; ++ it)
[482]2197                        {
[580]2198                                VspKdViewCell *vspKdVc = dynamic_cast<VspKdViewCell *>(*it);
2199                                VspKdLeaf *leaf = vspKdVc->mLeaf;
[482]2200                                AxisAlignedBox3 box = mVspKdTree->GetBBox(leaf);
[440]2201
[482]2202                                VssRayContainer vssRays;
[483]2203
2204                                VssRayContainer castRays;
2205                                VssRayContainer initRays;
2206
[482]2207                                leaf->GetRays(vssRays);
[440]2208
[482]2209                                VssRayContainer::const_iterator it, it_end = vssRays.end();
[483]2210                                const float prop = 200.0f / (float)vssRays.size();
[440]2211
[482]2212                                for (it = vssRays.begin(); it != it_end; ++ it)
[483]2213                                {
[485]2214                                        if (Random(1) < prop)
[483]2215                                                if ((*it)->mTerminationObject == NULL)
2216                                                        castRays.push_back(*it);
[503]2217                                                else
[483]2218                                                        initRays.push_back(*it);
2219                                }
2220
2221                                exporter->ExportRays(castRays, RgbColor(1, 0, 0));
2222                                exporter->ExportRays(initRays, RgbColor(0, 1, 0));
[482]2223                        }
2224                }
[580]2225       
[482]2226                //-- output PVS of view cell
2227                m.mDiffuseColor = RgbColor(1, 0, 0);
2228                exporter->SetForcedMaterial(m);
[440]2229
[483]2230                Intersectable::NewMail();
2231
[482]2232                ObjectPvsMap::const_iterator it,
2233                        it_end = vc->GetPvs().mEntries.end();
2234
2235                exporter->SetFilled();
2236
[503]2237                for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)
[482]2238                {
2239                        Intersectable *intersect = (*it).first;
2240
2241                        if (!intersect->Mailed())
2242                        {
2243                                Material m = RandomMaterial();
2244                                exporter->SetForcedMaterial(m);
2245
2246                                exporter->ExportIntersectable(intersect);
2247                                intersect->Mail();
[503]2248                        }
[482]2249                }
2250
2251                delete exporter;
[440]2252        }
[462]2253
2254        //-- export final view cells
[503]2255        Exporter *exporter = Exporter::GetExporter("vspkdtree_merged.x3d");
2256
[485]2257        //if (exportGeometry) exporter->SetWireframe();
2258        //else exporter->SetFilled();
[483]2259
[508]2260        ExportViewCellsForViz(exporter);
[462]2261
[503]2262        if (mExportGeometry)
[465]2263        {
2264                exporter->SetFilled();
[462]2265                exporter->ExportGeometry(objects);
[465]2266        }
[469]2267
[503]2268        if (mExportRays)
[462]2269        {
[503]2270                const float prob = (float)mVisualizationSamples
[482]2271                        / ((float)sampleRays.size() + Limits::Small);
[503]2272
[462]2273                exporter->SetWireframe();
[503]2274
[466]2275                VssRayContainer rays;
[503]2276
[462]2277                for (int i = 0; i < sampleRays.size(); ++ i)
2278                {
[466]2279                  if (RandomValue(0,1) < prob)
2280                        rays.push_back(sampleRays[i]);
[462]2281                }
[503]2282                exporter->ExportRays(rays, RgbColor(1, 0, 0));
[462]2283        }
2284
2285        delete exporter;
[440]2286}
2287
2288int VspKdViewCellsManager::GetType() const
2289{
2290        return VSP_KD;
2291}
[442]2292
[462]2293
[469]2294int VspKdViewCellsManager::CastLineSegment(const Vector3 &origin,
2295                                                                                   const Vector3 &termination,
2296                                                                                   ViewCellContainer &viewcells)
[466]2297{
[469]2298        return mVspKdTree->CastLineSegment(origin, termination, viewcells);
[466]2299}
2300
[477]2301
[482]2302void VspKdViewCellsManager::ExportColor(Exporter *exporter,
2303                                                                                ViewCell *vc) const
2304{
2305        if (mColorCode == 0) // Random color
2306                return;
[503]2307
[482]2308        float importance = 0;
[477]2309
[482]2310        switch (mColorCode)
2311        {
2312        case 1: // pvs
2313                {
[503]2314                        importance = (float)vc->GetPvs().GetSize() /
[482]2315                                (float)mViewCellsStats.maxPvs;
2316                }
2317                break;
[580]2318        case 2: // merged leaves
[482]2319                {
[580]2320                int lSize = mViewCellsTree->GetSize(vc);
2321                        importance = (float)lSize /
[482]2322                                (float)mViewCellsStats.maxLeaves;
2323                }
2324                break;
[485]2325        case 3: // merged tree depth difference
[482]2326                {
[503]2327                        //importance = (float)GetMaxTreeDiff(vc) /
[482]2328                        //      (float)(mVspBspTree->GetStatistics().maxDepth * 2);
2329                }
2330                break;
2331        default:
2332                break;
2333        }
2334
2335        Material m;
2336        m.mDiffuseColor.b = 1.0f;
2337        m.mDiffuseColor.r = importance;
2338        m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r;
2339        //Debug << "importance: " << importance << endl;
2340        exporter->SetForcedMaterial(m);
2341}
2342
2343
[580]2344void VspKdViewCellsManager::ExportViewCellGeometry(Exporter *exporter,
[591]2345                                                                                                   ViewCell *vc,
2346                                                                                                   const Plane3 *cuttingPlane) const
[482]2347{
2348        VspKdViewCell *kdVc = dynamic_cast<VspKdViewCell *>(vc);
2349
[486]2350        Mesh m;
[580]2351
2352        ViewCellContainer leaves;
2353        mViewCellsTree->CollectLeaves(vc, leaves);
2354
2355        ViewCellContainer::const_iterator it, it_end = leaves.end();
2356
2357        for (it = leaves.begin(); it != it_end; ++ it)
[486]2358        {
[580]2359                VspKdLeaf *l = dynamic_cast<VspKdViewCell *>(*it)->mLeaf;
2360                mVspKdTree->GetBBox(l).AddBoxToMesh(&m);
[486]2361        }
2362
2363        exporter->ExportMesh(&m);
[482]2364}
2365
2366
[503]2367void VspKdViewCellsManager::CreateMesh(ViewCell *vc)
2368{
[551]2369        //TODO
[503]2370}
[442]2371
[574]2372
[584]2373void VspKdViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays,
2374                                                                                                   vector<MergeCandidate> &candidates)
[580]2375{
2376        // TODO
2377}
[574]2378
[580]2379
[503]2380/**************************************************************************/
2381/*                   VspBspViewCellsManager implementation                */
2382/**************************************************************************/
[482]2383
[503]2384
[574]2385VspBspViewCellsManager::VspBspViewCellsManager(VspBspTree *vspBspTree):
2386ViewCellsManager(), mVspBspTree(vspBspTree)
[442]2387{
[574]2388        environment->GetIntValue("VspBspTree.Construction.samples", mInitialSamples);
[478]2389        mVspBspTree->SetViewCellsManager(this);
[590]2390        mVspBspTree->mViewCellsTree = mViewCellsTree;
[442]2391}
2392
[477]2393
[475]2394VspBspViewCellsManager::~VspBspViewCellsManager()
2395{
2396}
2397
[477]2398
[471]2399float VspBspViewCellsManager::GetProbability(ViewCell *viewCell)
[468]2400{
[551]2401        if (0 && mVspBspTree->mUseAreaForPvs)
[547]2402                return GetArea(viewCell) / GetAccVcArea();
2403        else
2404                return GetVolume(viewCell) / mViewSpaceBox.GetVolume();
[468]2405}
2406
[477]2407
[480]2408void VspBspViewCellsManager::CollectViewCells()
2409{
[581]2410        // view cells tree constructed
2411        if (!ViewCellsTreeConstructed())
2412        {
[590]2413                mVspBspTree->CollectViewCells(mViewCells, false);
[581]2414        }
2415        else
2416        {
2417                // we can use the view cells tree hierarchy to get the right set
[600]2418                mViewCellsTree->CollectBestViewCellSet(mViewCells, mNumActiveViewCells);
[581]2419        }
2420
[480]2421}
2422
2423
[468]2424
[442]2425bool VspBspViewCellsManager::ViewCellsConstructed() const
2426{
2427        return mVspBspTree->GetRoot() != NULL;
2428}
2429
[462]2430
[442]2431ViewCell *VspBspViewCellsManager::GenerateViewCell(Mesh *mesh) const
2432{
2433        return new BspViewCell(mesh);
2434}
2435
[569]2436
[600]2437/*void VspBspViewCellsManager::CollectNodes(ViewCell *vc, vector<BspNode *>nodes)
2438{
2439        void ViewCellsTree::CollectLeaves(ViewCell *vc, vector<BspNode *> &nodes) const
2440       
2441        if (vc->IsLeaf())
2442        {
2443                BspViewCell *bvc = dynamic_cast<BspViewCell *>(vc);
2444                nodes->push_back(bvc->mLeaf);
2445        }
2446        else
2447        {
2448                ViewCellContainer::const_iterator it, it_end = interior->mChildren.end();
2449
2450                for (it = interior->mChildren.begin; it != it_end; ++ it)
2451                {
2452                        vector<BspNode *> mynodes;
2453                        CollectNodes(*it, mynodes);
2454
2455                        if (mynodes[0]->GetParent() && (mynodes[0]->GetParent() == mynodes[1]->GetParent()))
2456                        {
2457                                nodes.push_back(nodes[0]->GetParent());
2458                        }
2459
2460                }
2461        }
2462}*/
2463
2464
[574]2465int VspBspViewCellsManager::ConstructSubdivision(const ObjectContainer &objects,
[600]2466                                                                                                 const VssRayContainer &rays)
[442]2467{
[503]2468        // if view cells were already constructed
2469        if (ViewCellsConstructed())
2470                return 0;
[442]2471
[503]2472        Debug << "Constructing bsp view cells" << endl;
2473
2474        int sampleContributions = 0;
2475
2476        VssRayContainer sampleRays;
2477
[574]2478        int limit = min (mInitialSamples, (int)rays.size());
[503]2479
[469]2480        VssRayContainer constructionRays;
2481        VssRayContainer savedRays;
[442]2482
[587]2483        Debug << "samples used for subdivision: " << mInitialSamples
2484                  << " rays: " << (int)rays.size() << endl;
2485
[574]2486        GetRaySets(rays, mInitialSamples, constructionRays, &savedRays);
[487]2487
[574]2488        Debug << "initial rays: " << (int)constructionRays.size() << endl;
[508]2489        Debug << "saved rays: " << (int)savedRays.size() << endl;
[485]2490
[547]2491        mMaxPvsSize = (int)(mMaxPvsRatio * (float)objects.size());
[564]2492
[542]2493        mVspBspTree->Construct(constructionRays, &mViewSpaceBox);
[503]2494
[480]2495        Debug << mVspBspTree->GetStatistics() << endl;
[491]2496
[490]2497        // collapse invalid regions
[491]2498        cout << "collapsing invalid tree regions ... ";
[495]2499        long startTime = GetTime();
[503]2500        int collapsedLeaves = mVspBspTree->CollapseTree();
[587]2501        Debug << "collapsed in " << TimeDiff(startTime, GetTime()) * 1e-3
2502                  << " seconds" << endl;
2503
[495]2504    cout << "finished" << endl;
[503]2505
[491]2506        cout << "reseting view cell stats ... ";
[480]2507        ResetViewCells();
[491]2508        cout << "finished" << endl;
[503]2509
[480]2510        Debug << "\nView cells after construction:\n" << mViewCellsStats << endl;
[491]2511
[612]2512        if (0) // export initial view cells
[491]2513        {
2514                cout << "exporting initial view cells (=leaves) ... ";
2515                Exporter *exporter = Exporter::GetExporter("view_cells.x3d");
[503]2516
[491]2517                if (exporter)
2518                {
[495]2519                        if (0 && mExportRays)
2520                                exporter->ExportRays(rays, RgbColor(1, 1, 1));
[503]2521
[491]2522                        if (mExportGeometry)
2523                                exporter->ExportGeometry(objects);
[503]2524
[598]2525                        //exporter->SetWireframe();
2526                        exporter->SetFilled();
2527                        ExportViewCellsForViz(exporter);
2528
[491]2529                        delete exporter;
2530                }
2531                cout << "finished" << endl;
2532        }
2533
[495]2534        startTime = GetTime();
[503]2535
2536        // reset view cells and stats
2537        ResetViewCells();
2538
[491]2539        cout << "Computing remaining ray contributions ... ";
[605]2540
[469]2541        // recast rest of rays
[605]2542        if (SAMPLE_AFTER_SUBDIVISION)
2543                ComputeSampleContributions(savedRays, true, false);
[491]2544        cout << "finished" << endl;
2545
[503]2546        Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3
[485]2547                  << " secs" << endl;
[442]2548
[485]2549        cout << "construction finished" << endl;
[503]2550
[442]2551        return sampleContributions;
2552}
2553
[489]2554
[503]2555void VspBspViewCellsManager::MergeViewCells(const VssRayContainer &rays,
2556                                                                                        const ObjectContainer &objects)
[475]2557{
[442]2558        //-- post processing of bsp view cells
2559    int vcSize = 0;
2560        int pvsSize = 0;
2561
[480]2562        mRenderer->RenderScene();
2563        SimulationStatistics ss;
2564        dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss);
2565    Debug << ss << endl;
2566
[442]2567        //-- merge or subdivide view cells
2568        int merged = 0;
[597]2569        if (mMergeViewCells)
2570        {
2571                cout << "starting merge using " << mPostProcessSamples << " samples ... " << endl;
2572                long startTime = GetTime();
[503]2573
[580]2574       
[597]2575                // TODO: should be done BEFORE the ray casting
2576                merged = mViewCellsTree->ConstructMergeTree(rays, objects);
[442]2577
[597]2578                //-- stats and visualizations
2579                cout << "finished merging" << endl;
2580                cout << "merged " << merged << " view cells in "
2581                         << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
[485]2582
[597]2583                Debug << "Postprocessing: Merged " << merged << " view cells in "
2584                          << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl;
2585        }
[503]2586
[600]2587        int savedColorCode = mColorCode;
2588       
[485]2589        //BspLeaf::NewMail();
[612]2590        if (0) // export merged view cells
[483]2591        {
[600]2592                mColorCode = 0;
[574]2593                cout << "reseting view cells ... ";
2594                ResetViewCells();
[587]2595
[574]2596                cout << "finished" << endl;
2597
[485]2598                Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d");
2599                Debug << "\nView cells after merge:\n" << mViewCellsStats << endl;
[483]2600
[485]2601                cout << "exporting view cells after merge ... ";
2602
2603                if (exporter)
[483]2604                {
[600]2605                        if (0)
2606                                exporter->SetWireframe();
2607                        else
2608                                exporter->SetFilled();
2609
2610                        ExportViewCellsForViz(exporter);
2611
[485]2612                        if (mExportGeometry)
[483]2613                        {
[485]2614                                Material m;
2615                                m.mDiffuseColor = RgbColor(0, 1, 0);
2616                                exporter->SetForcedMaterial(m);
2617                                exporter->SetFilled();
[442]2618
[485]2619                                exporter->ExportGeometry(objects);
[442]2620                        }
[485]2621
[600]2622                        delete exporter;
2623                }
2624                cout << "finished" << endl;
2625        }
2626
[612]2627        if (0) // export merged view cells using pvs coding
[600]2628        {
2629                mColorCode = 1;
2630
2631                Exporter *exporter = Exporter::GetExporter("merged_view_cells_pvs.x3d");
2632       
2633                cout << "exporting view cells after merge (pvs size) ... ";     
2634
2635                if (exporter)
2636                {
[598]2637                        if (0)
2638                                exporter->SetWireframe();
2639                        else
2640                                exporter->SetFilled();
2641
2642                        ExportViewCellsForViz(exporter);
2643
[600]2644                        if (mExportGeometry)
2645                        {
2646                                Material m;
2647                                m.mDiffuseColor = RgbColor(0, 1, 0);
2648                                exporter->SetForcedMaterial(m);
2649                                exporter->SetFilled();
2650
2651                                exporter->ExportGeometry(objects);
2652                        }
2653
[485]2654                        delete exporter;
[442]2655                }
[485]2656                cout << "finished" << endl;
[442]2657        }
[600]2658
2659        mColorCode = savedColorCode;
2660
[503]2661}
[475]2662
[503]2663
[609]2664bool VspBspViewCellsManager::EqualToSpatialNode(ViewCell *viewCell) const
[607]2665{
[609]2666        return GetSpatialNode(viewCell) != NULL;
[607]2667}
2668
2669
[609]2670BspNode *VspBspViewCellsManager::GetSpatialNode(ViewCell *viewCell) const
[607]2671{
2672        if (!viewCell->IsLeaf())
2673        {
2674                BspViewCell *bspVc = dynamic_cast<BspViewCell *>(viewCell);
2675
[609]2676                return bspVc->mLeaf;
2677        }
[607]2678        else
2679        {
2680                ViewCellInterior *interior = dynamic_cast<ViewCellInterior *>(viewCell);
2681
2682                // cannot be node of binary tree
2683                if (interior->mChildren.size() != 2)
[609]2684                        return NULL;
[607]2685
2686                ViewCell *left = interior->mChildren[0];
2687                ViewCell *right = interior->mChildren[1];
2688
[609]2689                BspNode *leftNode = GetSpatialNode(left);
2690                BspNode *rightNode = GetSpatialNode(right);
[607]2691
[609]2692                if (leftNode && rightNode && leftNode->IsSibling(rightNode))
[607]2693                {
[609]2694                        return leftNode->GetParent();
[607]2695                }
[609]2696        }
[607]2697
[609]2698        return NULL;
[607]2699}
2700
2701
[564]2702void VspBspViewCellsManager::RefineViewCells(const VssRayContainer &rays,
2703                                                                                         const ObjectContainer &objects)
[503]2704{
[485]2705        Debug << "render time before refine:" << endl;
2706        mRenderer->RenderScene();
[503]2707        SimulationStatistics ss;
[485]2708        dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss);
2709    Debug << ss << endl;
2710
[489]2711        cout << "Refining the merged view cells ... ";
[503]2712        long startTime = GetTime();
[485]2713
2714        // refining the merged view cells
[580]2715        const int refined = mViewCellsTree->RefineViewCells(rays, objects);
[485]2716
[442]2717        //-- stats and visualizations
2718        cout << "finished" << endl;
[485]2719        cout << "refined " << refined << " view cells in "
[442]2720                 << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
2721
[485]2722        Debug << "Postprocessing: refined " << refined << " view cells in "
[475]2723                  << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl;
[503]2724}
[495]2725
[517]2726
[503]2727int VspBspViewCellsManager::PostProcess(const ObjectContainer &objects,
2728                                                                                const VssRayContainer &rays)
2729{
2730        if (!ViewCellsConstructed())
2731        {
[517]2732                Debug << "postprocess error: no view cells constructed" << endl;
[503]2733                return 0;
2734        }
[520]2735
[564]2736
[609]2737        // view cells already finished before post processing step
2738        // (i.e. because they were loaded)
[520]2739        if (mViewCellsFinished)
[542]2740        {
[551]2741                FinalizeViewCells(true);
[542]2742                EvaluateViewCellsStats();
[577]2743
[517]2744                return 0;
[542]2745        }
[448]2746
[564]2747
[542]2748        // check if new view cells turned invalid
[574]2749        SetValidity(mMinPvsSize, mMaxPvsSize);
2750        // update valid view space according to valid view cells
[544]2751        mVspBspTree->ValidateTree();
[542]2752
[574]2753        // recompute view cell statistics
2754        mViewCellsStats.Reset();
2755        EvaluateViewCellsStats();
[580]2756
[574]2757        // has to be recomputed
2758        mTotalAreaValid = false;
[542]2759
[574]2760
[517]2761        VssRayContainer postProcessRays;
2762
[605]2763        GetRaySets(rays, mPostProcessSamples, postProcessRays);
2764
[517]2765        Debug << "post processing using " << (int)postProcessRays.size() << " samples" << endl;
[564]2766
[517]2767        Debug << "\nview cell partition after sampling:\n" << mViewCellsStats << endl << endl;
2768
[552]2769        // should maybe be done here to allow merge working with area or volume
2770        // and to correct the rendering statistics
[554]2771        if (0)
[551]2772        {
2773                FinalizeViewCells(false);
2774        }
2775
[597]2776        //-- merge the individual view cells
2777        MergeViewCells(postProcessRays, objects);
[591]2778       
[580]2779
[597]2780        //-- refines the merged view cells
2781        if (0)
2782                RefineViewCells(postProcessRays, objects);
[568]2783
[600]2784        //-- render simulation after merge
[605]2785        cout << "\nevaluating bsp view cells render time before compress ... ";
2786        dynamic_cast<RenderSimulator *>(mRenderer)->RenderScene();
2787        SimulationStatistics ss;
2788        dynamic_cast<RenderSimulator *>(mRenderer)->GetStatistics(ss);
[600]2789 
[580]2790
[605]2791        cout << " finished" << endl;
2792        cout << ss << endl;
2793        Debug << ss << endl;
[600]2794
2795
[605]2796
[600]2797        //-- compression
2798
2799        if (ViewCellsTreeConstructed() && mCompressViewCells)
2800        {
2801                int pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot());
2802                Debug << "number of entries before compress: " << pvsEntries << endl;
2803
2804                mViewCellsTree->CompressViewCellsPvs();
2805
2806                pvsEntries = mViewCellsTree->GetNumPvsEntries(mViewCellsTree->GetRoot());
2807                Debug << "number of entries after compress: " << pvsEntries << endl;
2808        }
2809
[517]2810        // collapse sibling leaves that share the same view cell
[586]2811        if (0)
2812                mVspBspTree->CollapseTree();
2813
[574]2814        // recompute view cell list and statistics
[520]2815        ResetViewCells();
2816
[508]2817        // real meshes are only contructed only at this stage
[551]2818        FinalizeViewCells(true);
[517]2819
[508]2820        // write view cells to disc
2821        if (mExportViewCells)
2822        {
[517]2823                char buff[100];
2824                environment->GetStringValue("ViewCells.filename", buff);
2825                string vcFilename(buff);
2826
2827                ExportViewCells(buff);
[508]2828        }
[503]2829
2830        return 0;
[442]2831}
2832
[490]2833
[442]2834int VspBspViewCellsManager::GetType() const
2835{
2836        return VSP_BSP;
2837}
2838
2839
[609]2840void VspBspViewCellsManager::CreateMergeHierarchy()
2841{
[610]2842        TraversalQueue tQueue;
2843
2844        tQueue.push(TraversalData(mVspBspTree->GetRoot(), NULL));
2845
2846        while (!tQueue.empty())
2847        {
2848                TraversalData tData = tQueue.top();
2849                tQueue.pop();
2850
2851                if (tData.mNode->IsLeaf())
2852                {
2853                        ViewCell *viewCell = dynamic_cast<BspLeaf *>(tData.mNode)->GetViewCell();
2854
2855                        if (tData.mParentViewCell)
2856                        {
2857                                tData.mParentViewCell->SetupChildLink(viewCell);
2858                                // probagate up pvs
2859                                mViewCellsTree->PropagateUpPvs(viewCell);
2860                        }
2861                }
2862                else
2863                {
2864                        BspInterior *interior = dynamic_cast<BspInterior *>(tData.mNode);
2865                        ViewCellInterior *viewCellInterior = new ViewCellInterior();
2866                       
2867                        tQueue.push(TraversalData(interior->GetBack(), viewCellInterior));
2868                        tQueue.push(TraversalData(interior->GetFront(), viewCellInterior));
2869
2870                        if (tData.mParentViewCell)
2871                                tData.mParentViewCell->SetupChildLink(viewCellInterior);
2872                }
2873        }
[609]2874}
2875
2876
[490]2877bool VspBspViewCellsManager::GetViewPoint(Vector3 &viewPoint) const
2878{
2879        if (!ViewCellsConstructed())
2880                return ViewCellsManager::GetViewPoint(viewPoint);
2881
2882        // TODO: set reasonable limit
2883        const int limit = 20;
2884
2885        for (int i = 0; i < limit; ++ i)
2886        {
[542]2887                viewPoint = mViewSpaceBox.GetRandomPoint();
[490]2888                if (mVspBspTree->ViewPointValid(viewPoint))
2889                {
2890                        return true;
2891                }
2892        }
2893        Debug << "failed to find valid view point, taking " << viewPoint << endl;
2894        return false;
2895}
2896
2897
2898bool VspBspViewCellsManager::ViewPointValid(const Vector3 &viewPoint) const
2899{
[569]2900  // $$JB -> implemented in viewcellsmanager (slower, but allows dynamic
2901  // validy update in preprocessor for all managers)
2902  return ViewCellsManager::ViewPointValid(viewPoint);
[570]2903
[569]2904  //    return mViewSpaceBox.IsInside(viewPoint) &&
2905  //               mVspBspTree->ViewPointValid(viewPoint);
[490]2906}
2907
2908
[442]2909void VspBspViewCellsManager::Visualize(const ObjectContainer &objects,
[466]2910                                                                           const VssRayContainer &sampleRays)
[442]2911{
2912        if (!ViewCellsConstructed())
2913                return;
2914
[485]2915        VssRayContainer visRays;
2916        GetRaySets(sampleRays, mVisualizationSamples, visRays);
[483]2917
[600]2918       
[612]2919        if (0) // export view cells
2920        {       // hack pvs
[600]2921                int savedColorCode = mColorCode;
2922                mColorCode = 1;
[485]2923                Exporter *exporter = Exporter::GetExporter("final_view_cells.x3d");
[600]2924               
[442]2925                if (exporter)
2926                {
[580]2927                        cout << "exporting view cells after post process ... ";
2928
[600]2929                        if (0)
[542]2930                        {
2931                                exporter->SetWireframe();
2932                                exporter->ExportBox(mViewSpaceBox);
2933                                exporter->SetFilled();
2934                        }
2935
[485]2936                        if (mExportGeometry)
[542]2937                        {
[485]2938                                exporter->ExportGeometry(objects);
[542]2939                        }
[489]2940
2941                        // export rays
[490]2942                        if (mExportRays)
[489]2943                        {
[490]2944                                exporter->ExportRays(visRays, RgbColor(0, 1, 0));
2945                        }
[564]2946
[508]2947                        ExportViewCellsForViz(exporter);
[442]2948                        delete exporter;
[580]2949                        cout << "finished" << endl;
[442]2950                }
[600]2951
2952                mColorCode = savedColorCode;
[557]2953        }
[503]2954
[600]2955        if (0)
[577]2956        {
2957                cout << "exporting depth map ... ";
2958
2959                Exporter *exporter = Exporter::GetExporter("depth_map.x3d");
2960                if (exporter)
2961                {
2962                        if (1)
2963                        {
2964                                exporter->SetWireframe();
2965                                exporter->ExportBox(mViewSpaceBox);
2966                                exporter->SetFilled();
2967                        }
2968
2969                        if (mExportGeometry)
2970                        {
2971                                exporter->ExportGeometry(objects);
2972                        }
2973
2974                        const int maxDepth = mVspBspTree->mBspStats.maxDepth;
2975
2976                        ViewCellContainer::const_iterator vit, vit_end = mViewCells.end();
2977
2978                        for (vit = mViewCells.begin(); vit != mViewCells.end(); ++ vit)
2979                        {
[582]2980                                ViewCell *vc = *vit;
[577]2981
[580]2982                                ViewCellContainer leaves;
2983                                mViewCellsTree->CollectLeaves(vc, leaves);
[577]2984
[580]2985                                ViewCellContainer::const_iterator lit, lit_end = leaves.end();
2986
2987                                for (lit = leaves.begin(); lit != lit_end; ++ lit)
[577]2988                                {
[580]2989                                        BspLeaf *leaf = dynamic_cast<BspViewCell *>(*lit)->mLeaf;
[577]2990
2991                                        Material m;
2992
2993                                        float relDepth = (float)leaf->GetDepth() / (float)maxDepth;
2994                                        m.mDiffuseColor.r = relDepth;
2995                                        m.mDiffuseColor.g = 0.0f;
2996                                        m.mDiffuseColor.b = 1.0f - relDepth;
2997
2998                    exporter->SetForcedMaterial(m);
2999                               
3000
3001                                        BspNodeGeometry geom;
3002                                        mVspBspTree->ConstructGeometry(leaf, geom);
3003                                        exporter->ExportPolygons(geom.mPolys);
3004                                }
3005                        }
3006
3007                        delete exporter;
3008                }
3009
3010
3011                cout << "finished" << endl;
3012        }
3013
[442]3014        //-- visualization of the BSP splits
3015        bool exportSplits = false;
[489]3016        environment->GetBoolValue("VspBspTree.Visualization.exportSplits", exportSplits);
[503]3017
[442]3018        if (exportSplits)
3019        {
3020                cout << "exporting splits ... ";
[485]3021                ExportSplits(objects, visRays);
[442]3022                cout << "finished" << endl;
3023        }
3024
[542]3025        //-- export single view cells
[485]3026        ExportBspPvs(objects, visRays);
[442]3027}
3028
[503]3029
[485]3030void VspBspViewCellsManager::ExportSplits(const ObjectContainer &objects,
3031                                                                                  const VssRayContainer &rays)
[442]3032{
3033        Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d");
3034
[503]3035        if (exporter)
3036        {
3037                Material m;
[442]3038                m.mDiffuseColor = RgbColor(1, 0, 0);
3039                exporter->SetForcedMaterial(m);
3040                exporter->SetWireframe();
[503]3041
[448]3042                exporter->ExportBspSplits(*mVspBspTree, true);
[442]3043
3044                // take forced material, else big scenes cannot be viewed
3045                m.mDiffuseColor = RgbColor(0, 1, 0);
3046                exporter->SetForcedMaterial(m);
3047                exporter->SetFilled();
3048
3049                exporter->ResetForcedMaterial();
[503]3050
[442]3051                // export rays
[485]3052                if (mExportRays)
3053                        exporter->ExportRays(rays, RgbColor(1, 1, 0));
[503]3054
[485]3055                if (mExportGeometry)
[442]3056                        exporter->ExportGeometry(objects);
3057
3058                delete exporter;
3059        }
3060}
3061
[503]3062
[485]3063void VspBspViewCellsManager::ExportBspPvs(const ObjectContainer &objects,
3064                                                                                  const VssRayContainer &rays)
[442]3065{
[639]3066        const int leafOut = 20;
[503]3067
[442]3068        ViewCell::NewMail();
[503]3069
[639]3070        cout << "visualization using " << (int)rays.size() << " samples" << endl;
3071        Debug << "visualization using " << (int)rays.size() << " samples" << endl;
[475]3072        Debug << "\nOutput view cells: " << endl;
[503]3073
[485]3074        // sort view cells to visualize the largest view cells
[587]3075        if (0)
3076                stable_sort(mViewCells.begin(), mViewCells.end(), vc_gt);
[639]3077       
[503]3078        int limit = min(leafOut, (int)mViewCells.size());
[483]3079
[639]3080        int raysOut = 0;
[587]3081
[485]3082        //-- some rays for output
[478]3083        for (int i = 0; i < limit; ++ i)
[442]3084        {
[478]3085                cout << "creating output for view cell " << i << " ... ";
[503]3086
[639]3087       
[582]3088                ViewCell *vc;
[574]3089       
3090                if (0) // largest view cell pvs first
[582]3091                        vc = mViewCells[i];
[574]3092                else
[639]3093                        vc = mViewCells[(int)RandomValue(0, (float)mViewCells.size() - 1)];
[442]3094
[639]3095                //bspLeaves[j]->Mail();
3096                char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
3097                Exporter *exporter = Exporter::GetExporter(s);
3098               
3099                Debug << i << ": pvs size=" << (int)mViewCellsTree->GetPvsSize(vc) << endl;
[587]3100
[639]3101                if (1 || mExportRays)
[442]3102                {
[643]3103                        if (0)
[442]3104                        {
[639]3105                                VssRayContainer vcRays;
3106                VssRayContainer collectRays;
3107
3108                                raysOut = min((int)rays.size(), 100);
3109
3110                                // collect intial view cells
3111                                ViewCellContainer leaves;
3112                                mViewCellsTree->CollectLeaves(vc, leaves);
3113
3114                                ViewCellContainer::const_iterator vit, vit_end = leaves.end();
3115       
3116                                for (vit = leaves.begin(); vit != vit_end; ++ vit)
[574]3117                                {
[639]3118                                        BspLeaf *vcLeaf = dynamic_cast<BspViewCell *>(*vit)->mLeaf;
3119                               
3120                                        VssRayContainer::const_iterator rit, rit_end = vcLeaf->mVssRays.end();
[587]3121
[639]3122                                        for (rit = vcLeaf->mVssRays.begin(); rit != rit_end; ++ rit)
3123                                        {
3124                                                collectRays.push_back(*rit);
3125                                        }
[574]3126                                }
[639]3127
3128                                VssRayContainer::const_iterator rit, rit_end = collectRays.end();
3129
3130                                for (rit = collectRays.begin(); rit != rit_end; ++ rit)
3131                                {
3132                                        float p = RandomValue(0.0f, (float)collectRays.size());
3133                       
3134                                        if (p < raysOut)
3135                                                vcRays.push_back(*rit);
3136                                }
3137                                //-- export rays piercing this view cell
3138                                exporter->ExportRays(vcRays, RgbColor(1, 1, 1));
[442]3139                        }
[639]3140
3141                       
3142
[643]3143                        if (1)
[639]3144                        {
3145                                VssRayContainer vcRays;
3146                                raysOut = min((int)rays.size(), mVisualizationSamples);
3147                                // check whether we can add the current ray to the output rays
3148                                for (int k = 0; k < raysOut; ++ k)
3149                                {
3150                                        VssRay *ray = rays[k];
3151                                        for     (int j = 0; j < (int)ray->mViewCells.size(); ++ j)
3152                                        {
3153                                                ViewCell *rayvc = ray->mViewCells[j];
3154       
3155                                                if (rayvc == vc)
3156                                                        vcRays.push_back(ray);
3157                                        }
3158                                }       
3159                               
3160                                //-- export rays piercing this view cell
3161                                exporter->ExportRays(vcRays, RgbColor(1, 1, 0));
3162                        }
3163
[442]3164                }
[639]3165               
3166               
[574]3167
[639]3168
[478]3169                exporter->SetWireframe();
[442]3170
[478]3171                Material m;//= RandomMaterial();
3172                m.mDiffuseColor = RgbColor(0, 1, 0);
3173                exporter->SetForcedMaterial(m);
[442]3174
[580]3175                ExportViewCellGeometry(exporter, vc);
[639]3176       
3177                exporter->SetFilled();
[503]3178
[639]3179
[574]3180                if (1)
3181                {
[639]3182                        ObjectPvsMap::const_iterator oit,
3183                                oit_end = vc->GetPvs().mEntries.end();
[483]3184
[580]3185
[639]3186                        exporter->SetFilled();
[580]3187
[639]3188                        Intersectable::NewMail();
[574]3189       
[639]3190                        // output PVS of view cell
3191                        for (oit = vc->GetPvs().mEntries.begin(); oit != oit_end; ++ oit)
3192                        {               
3193                                Intersectable *intersect = (*oit).first;
[442]3194
[639]3195                                if (!intersect->Mailed())
3196                                {
[643]3197                                        m = RandomMaterial();
3198                                        exporter->SetForcedMaterial(m);
[442]3199
[639]3200                                        exporter->ExportIntersectable(intersect);
3201                                        intersect->Mail();
3202                                }
[503]3203                        }
[442]3204                }
[639]3205                else
3206                {
[643]3207                        m.mDiffuseColor = RgbColor(1, 0, 0);
3208                        exporter->SetForcedMaterial(m);
3209
[639]3210                        exporter->ExportGeometry(objects);
3211                }
[503]3212
[478]3213                DEL_PTR(exporter);
3214                cout << "finished" << endl;
[442]3215        }
[475]3216
3217        Debug << endl;
[442]3218}
3219
3220
[469]3221int VspBspViewCellsManager::CastLineSegment(const Vector3 &origin,
3222                                                                                        const Vector3 &termination,
3223                                                                                        ViewCellContainer &viewcells)
[466]3224{
[469]3225        return mVspBspTree->CastLineSegment(origin, termination, viewcells);
[466]3226}
[482]3227
3228
[503]3229void VspBspViewCellsManager::ExportColor(Exporter *exporter,
[482]3230                                                                                 ViewCell *vc) const
3231{
[564]3232        const bool vcValid = CheckValidity(vc, mMinPvsSize, mMaxPvsSize);
[503]3233
[482]3234        float importance = 0;
[564]3235        static Material m;
3236
[482]3237        switch (mColorCode)
3238        {
[564]3239        case 0: // Random
3240                {
3241                        if (vcValid)
3242                        {
[598]3243                                m.mDiffuseColor.r = 0.5f + RandomValue(0.0f, 0.5f);
3244                                m.mDiffuseColor.g = 0.5f + RandomValue(0.0f, 0.5f);
3245                                m.mDiffuseColor.b = 0.5f + RandomValue(0.f, 0.5f);
[564]3246                        }
3247                        else
3248                        {
3249                                m.mDiffuseColor.r = 0.0f;
3250                                m.mDiffuseColor.g = 1.0f;
3251                                m.mDiffuseColor.b = 0.0f;
3252                        }
[591]3253
3254                        exporter->SetForcedMaterial(m);
3255                        return;
[564]3256                }
[591]3257               
[482]3258        case 1: // pvs
3259                {
[503]3260                        importance = (float)vc->GetPvs().GetSize() /
[482]3261                                (float)mViewCellsStats.maxPvs;
[570]3262
[482]3263                }
3264                break;
3265        case 2: // merges
3266                {
[580]3267            int lSize = mViewCellsTree->GetSize(vc);
3268                        importance = (float)lSize / (float)mViewCellsStats.maxLeaves;
[482]3269                }
3270                break;
3271        case 3: // merge tree differene
3272                {
[503]3273                        importance = (float)GetMaxTreeDiff(vc) /
[482]3274                                (float)(mVspBspTree->GetStatistics().maxDepth * 2);
[547]3275
[482]3276                }
3277                break;
3278        default:
3279                break;
3280        }
3281
[564]3282        // special color code for invalid view cells
[482]3283        m.mDiffuseColor.r = importance;
3284        m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r;
[564]3285        m.mDiffuseColor.b = vcValid ? 1.0f : 0.0f;
[547]3286
[482]3287        //Debug << "importance: " << importance << endl;
3288        exporter->SetForcedMaterial(m);
3289}
3290
3291
[580]3292void VspBspViewCellsManager::ExportViewCellGeometry(Exporter *exporter,
[591]3293                                                    ViewCell *vc,
3294                                                                                                        const Plane3 *cuttingPlane) const
[482]3295{
[542]3296        if (vc->GetMesh())
[503]3297        {
3298                exporter->ExportMesh(vc->GetMesh());
[590]3299       
[503]3300                return;
3301        }
3302
[591]3303       
3304        if (cuttingPlane)
3305        {
3306                ViewCellContainer leaves;
3307                mViewCellsTree->CollectLeaves(vc, leaves);
3308                ViewCellContainer::const_iterator it, it_end = leaves.end();
3309
3310                for (it = leaves.begin(); it != it_end; ++ it)
3311                {
3312                        BspNodeGeometry geom;
3313
3314                        BspNodeGeometry front;
3315                        BspNodeGeometry back;
3316
3317       
3318                        BspLeaf *leaf = dynamic_cast<BspViewCell *>(*it)->mLeaf;
3319
3320                        mVspBspTree->ConstructGeometry(leaf, geom);
3321                       
3322                        geom.SplitGeometry(front,
3323                                                           back,
3324                                                           *cuttingPlane,
3325                                                           mViewSpaceBox,
[600]3326                                                           0.0001f);
[591]3327
[600]3328                        if ((int)back.mPolys.size() >= 3)
3329                                exporter->ExportPolygons(back.mPolys);
[591]3330                }
3331        }
3332        else
3333        {
3334                BspNodeGeometry geom;
3335                mVspBspTree->ConstructGeometry(vc, geom);
3336                       
3337                exporter->ExportPolygons(geom.mPolys);
3338        }
[482]3339}
3340
3341
3342int VspBspViewCellsManager::GetMaxTreeDiff(ViewCell *vc) const
3343{
[580]3344        ViewCellContainer leaves;
3345        mViewCellsTree->CollectLeaves(vc, leaves);
[482]3346
3347        int maxDist = 0;
[580]3348       
[482]3349        // compute max height difference
[580]3350        for (int i = 0; i < (int)leaves.size(); ++ i)
3351                for (int j = 0; j < (int)leaves.size(); ++ j)
[482]3352        {
[580]3353                BspLeaf *leaf = dynamic_cast<BspViewCell *>(leaves[i])->mLeaf;
[482]3354
3355                if (i != j)
3356                {
[580]3357                        BspLeaf *leaf2 =dynamic_cast<BspViewCell *>(leaves[j])->mLeaf;
[482]3358                        int dist = mVspBspTree->TreeDistance(leaf, leaf2);
3359                        if (dist > maxDist)
3360                                maxDist = dist;
3361                }
3362        }
[580]3363
[492]3364        return maxDist;
3365}
[482]3366
[492]3367
[569]3368ViewCell *VspBspViewCellsManager::GetViewCell(const Vector3 &point) const
[492]3369{
[508]3370        if (!mVspBspTree)
3371                return NULL;
[572]3372
3373        if (!mViewSpaceBox.IsInside(point))
3374          return NULL;
3375
[508]3376        return mVspBspTree->GetViewCell(point);
[492]3377}
[503]3378
3379
3380void VspBspViewCellsManager::CreateMesh(ViewCell *vc)
3381{
[577]3382        if (vc->GetMesh())
3383                delete vc->GetMesh();
3384
[590]3385       
[503]3386        BspNodeGeometry geom;
[590]3387
3388        mVspBspTree->ConstructGeometry(vc, geom);
[582]3389       
[503]3390        Mesh *mesh = new Mesh();
3391        geom.AddToMesh(*mesh);
3392        vc->SetMesh(mesh);
3393        mMeshContainer.push_back(mesh);
3394}
[508]3395
3396
[577]3397ViewCellsManager *ViewCellsManager::LoadViewCells(const string filename,
3398                                                                                                  ObjectContainer *objects)
[508]3399{
3400        ViewCellsParser parser;
[564]3401
[577]3402        ViewCellsManager *vm = NULL;
[564]3403
[577]3404        if (parser.ParseFile(filename, &vm, objects))
3405        {
[590]3406                //vm->PrepareLoadedViewCells();
[577]3407                vm->ResetViewCells();
[564]3408
[577]3409                vm->mViewCellsFinished = true;
3410                vm->mMaxPvsSize = (int)objects->size();
[517]3411
[577]3412                vm->FinalizeViewCells(true);
[564]3413
[577]3414                Debug << (int)vm->mViewCells.size() << " view cells loaded" << endl;
3415        }
3416        else
3417        {
3418                Debug << "failed loading view cells" << endl;
3419                DEL_PTR(vm);
3420        }
3421
3422
3423        return vm;
[508]3424}
3425
3426
3427inline bool ilt(Intersectable *obj1, Intersectable *obj2)
3428{
3429        return obj1->mId < obj2->mId;
3430}
3431
3432
3433bool VspBspViewCellsManager::ExportViewCells(const string filename)
3434{
[564]3435        cout << "exporting view cells to xml ... ";
[508]3436        std::ofstream stream;
3437
[577]3438        // for output we need unique ids for each view cell
[590]3439        CreateUniqueViewCellIds();
[508]3440
[590]3441
[508]3442        stream.open(filename.c_str());
3443        stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"<<endl;
3444        stream << "<Visibility_Solution>" << endl;
[564]3445
[577]3446        //-- the view space bounding box
3447        stream << "<ViewSpaceBox"
3448                   << " min=\"" << mViewSpaceBox.Min().x << " " << mViewSpaceBox.Min().y << " " << mViewSpaceBox.Min().z << "\""
3449                   << " max=\"" << mViewSpaceBox.Max().x << " " << mViewSpaceBox.Max().y << " " << mViewSpaceBox.Max().z << "\" />" << endl;
3450
3451        //-- the type of the view cells hierarchy
3452        stream << "<Hierarchy name=\"vspBspTree\" />" << endl;
3453
[508]3454        //-- load the view cells itself, i.e., the ids and the pvs
3455        stream << "<ViewCells>" << endl;
[610]3456       
3457#if 0
3458       
[508]3459        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
[610]3460               
[508]3461        for (it = mViewCells.begin(); it != it_end; ++ it)
3462                ExportViewCell(*it, stream);
[610]3463#else
3464        mViewCellsTree->Export(stream);
3465#endif
[564]3466
[508]3467        stream << "</ViewCells>" << endl;
[564]3468
[508]3469        //-- load the hierarchy
[590]3470        stream << "<Hierarchy>" << endl;
[508]3471        mVspBspTree->Export(stream);
[590]3472        stream << endl << "</Hierarchy>" << endl;
[564]3473
[508]3474        stream << "</Visibility_Solution>" << endl;
3475        stream.close();
3476
3477        cout << "finished" << endl;
3478
3479        return true;
[532]3480}
3481
3482
3483int VspBspViewCellsManager::CastBeam(Beam &beam)
3484{
[535]3485        return mVspBspTree->CastBeam(beam);
[532]3486}
[551]3487
3488
[587]3489void VspBspViewCellsManager::Finalize(ViewCell *viewCell,
3490                                                                          const bool createMesh)
[551]3491{
[582]3492        CreateMesh(viewCell);
[551]3493
3494        float area = 0;
3495        float volume = 0;
3496
[580]3497        ViewCellContainer leaves;
[582]3498        mViewCellsTree->CollectLeaves(viewCell, leaves);
[580]3499
3500        ViewCellContainer::const_iterator it, it_end = leaves.end();
3501
3502        for (it = leaves.begin(); it != it_end; ++ it)
[551]3503        {
3504                BspNodeGeometry geom;
[580]3505                BspLeaf *leaf = dynamic_cast<BspViewCell *>(*it)->mLeaf;
[551]3506                mVspBspTree->ConstructGeometry(leaf, geom);
3507
3508                area += geom.GetArea();
3509                volume += geom.GetVolume();
3510        }
3511
3512        viewCell->SetVolume(volume);
3513        viewCell->SetArea(area);
[563]3514}
[575]3515
3516
[577]3517void VspBspViewCellsManager::PrepareLoadedViewCells()
3518{
3519        // TODO: do I still need this here?
[590]3520        if (0)
[577]3521        mVspBspTree->RepairViewCellsLeafLists();
3522}
[575]3523
[577]3524
[580]3525
3526void VspBspViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays,
3527                                                                                                        vector<MergeCandidate> &candidates)
3528{       
3529        cout << "collecting merge candidates ... " << endl;
3530
3531        if (mUseRaysForMerge)
3532        {
3533                mVspBspTree->CollectMergeCandidates(rays, candidates);
3534        }
3535        else
3536        {
3537                vector<BspLeaf *> leaves;
3538                mVspBspTree->CollectLeaves(leaves);
3539                mVspBspTree->CollectMergeCandidates(leaves, candidates);
3540        }
3541
3542        cout << "fininshed collecting candidates" << endl;
3543}
3544
3545
[590]3546void VspBspViewCellsManager::AddCurrentViewCellsToHierarchy()
3547{
3548        ViewCellContainer::const_iterator it, it_end = mViewCells.end();
3549        for (it = mViewCells.begin(); it != it_end; ++ it)
3550        {
3551        }
3552}
[580]3553
3554//////////////////////////////////
[575]3555ViewCellsManager *ViewCellsManagerFactory::Create(const string mName)
3556{
3557        //TODO
3558        return NULL;// new VspBspViewCellsManager();
3559}
[580]3560
Note: See TracBrowser for help on using the repository browser.