Changeset 564 for trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp
- Timestamp:
- 01/23/06 02:56:48 (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp
r562 r564 30 30 31 31 int BspMergeCandidate::sMaxPvsSize = 0; 32 //int BspMergeCandidate::sMinPvsSize = 0; 32 33 33 34 int VspBspTree::sFrontId = 0; … … 66 67 environment->GetFloatValue("VspBspTree.Termination.maxCostRatio", mTermMaxCostRatio); 67 68 environment->GetIntValue("VspBspTree.Termination.missTolerance", mTermMissTolerance); 69 environment->GetIntValue("VspBspTree.Termination.maxViewCells", mMaxViewCells); 70 //-- max cost ratio for early tree termination 71 environment->GetFloatValue("VspBspTree.Termination.maxCostRatio", mTermMaxCostRatio); 68 72 69 73 //-- factors for bsp tree split plane heuristics … … 72 76 environment->GetFloatValue("VspBspTree.Termination.ct_div_ci", mCtDivCi); 73 77 74 //-- max cost ratio for early tree termination75 environment->GetFloatValue("VspBspTree.Termination.maxCostRatio", mTermMaxCostRatio);76 78 77 79 //-- partition criteria … … 83 85 environment->GetIntValue("VspBspTree.maxTests", mMaxTests); 84 86 85 // maximum and minimum number of view cells 86 environment->GetIntValue("VspBspTree.Termination.maxViewCells", mMaxViewCells); 87 87 // if only the driving axis is used for axis aligned split 88 88 environment->GetBoolValue("VspBspTree.splitUseOnlyDrivingAxis", mOnlyDrivingAxis); 89 89 … … 103 103 environment->GetFloatValue("VspBspTree.maxStaticMemory", mMaxMemory); 104 104 105 105 environment->GetBoolValue("VspBspTree.Visualization.exportMergedViewCells", mExportMergedViewCells); 106 environment->GetBoolValue("VspBspTree.PostProcess.exportMergeStats", mExportMergeStats); 107 108 106 109 mStats.open("bspStats.log"); 107 110 … … 123 126 Debug << "using area for pvs: " << mUseAreaForPvs << endl; 124 127 Debug << "Split plane strategy: "; 128 125 129 if (mSplitPlaneStrategy & RANDOM_POLYGON) 126 130 { … … 329 333 float minT, maxT; 330 334 331 //static Ray hray;332 //hray.Init(ray.GetOrigin(), ray.GetDir(), Ray::LINE_SEGMENT);335 static Ray hray; 336 hray.Init(*ray); 333 337 334 338 // TODO: not very efficient to implictly cast between rays types 335 if (mBox.GetRaySegment( *ray, minT, maxT))339 if (mBox.GetRaySegment(hray, minT, maxT)) 336 340 { 337 341 float len = ray->Length(); … … 515 519 leaf->mVssRays.push_back((*it).mRay); 516 520 } 517 521 // should I check here? 518 522 if (0 && !mViewCellsManager->CheckValidity(viewCell, 0, mViewCellsManager->GetMaxPvsSize())) 519 523 { … … 1726 1730 if (node->IsLeaf()) 1727 1731 { 1728 if (!onlyValid || node->TreeValid())1732 if (!onlyValid || node->TreeValid()) 1729 1733 { 1730 1734 ViewCell *viewCell = dynamic_cast<BspLeaf *>(node)->GetViewCell(); … … 2572 2576 2573 2577 // clean up old view cells 2574 if ( 0)2578 if (mExportMergedViewCells) 2575 2579 { 2576 2580 DEL_PTR(fVc); … … 2631 2635 if ((*nit)->GetViewCell() != leaf->GetViewCell()) 2632 2636 { 2633 mMergeQueue.push(BspMergeCandidate(leaf, *nit)); 2637 BspMergeCandidate mc(leaf, *nit); 2638 mc.EvalMergeCost(); 2639 2640 mMergeQueue.push(mc); 2634 2641 ++ candidates; 2635 2642 } … … 2637 2644 } 2638 2645 2639 Debug << "found " << candidates << " new merge candidates" << endl; 2646 Debug << "mergequeue: " << (int)mMergeQueue.size() << endl; 2647 Debug << "leaves in queue: " << candidates << endl; 2648 Debug << "overall cost: " << BspMergeCandidate::sOverallCost << endl; 2649 2640 2650 2641 2651 return (int)leaves.size(); … … 2726 2736 if (!found) 2727 2737 { 2728 // this pair is not in map already2738 // this pair is not in map yet 2729 2739 // => insert into the neighbor map and the queue 2730 2740 neighbors.push_back(prevLeaf); … … 2734 2744 prevLeaf->Mail(); 2735 2745 2736 mMergeQueue.push(BspMergeCandidate(leaf, prevLeaf)); 2746 BspMergeCandidate mc(leaf, prevLeaf); 2747 mc.EvalMergeCost(); 2748 2749 mMergeQueue.push(mc); 2750 2751 if (((int)mMergeQueue.size() % 1000) == 0) 2752 { 2753 cout << "collected " << (int)mMergeQueue.size() << " merge candidates" << endl; 2754 } 2737 2755 } 2738 2756 } 2739 2757 } 2758 2740 2759 Debug << "neighbormap size: " << (int)neighborMap.size() << endl; 2741 2760 Debug << "mergequeue: " << (int)mMergeQueue.size() << endl; … … 2804 2823 { 2805 2824 BspMergeCandidate::sMaxPvsSize = mViewCellsManager->GetMaxPvsSize(); 2825 //BspMergeCandidate::sMinPvsSize = mViewCellsManager->GetMinPvsSize(); 2806 2826 BspMergeCandidate::sUseArea = mUseAreaForPvs; 2807 2827 2808 2828 // the current view cells are kept in this container 2809 2829 ViewCellContainer viewCells; 2810 ViewCell::NewMail(); 2811 CollectViewCells(mRoot, true, viewCells, true); 2830 if (mExportMergedViewCells) 2831 { 2832 ViewCell::NewMail(); 2833 CollectViewCells(mRoot, true, viewCells, true); 2834 } 2812 2835 ViewCell::NewMail(); 2813 2836 2814 2837 MergeStatistics mergeStats; 2815 2838 mergeStats.Start(); 2816 // TODO: REMOVE LATER for performance! 2817 const bool showMergeStats = false; 2818 2839 2819 2840 //BspMergeCandidate::sOverallCost = mBox.SurfaceArea() * mStat.maxPvs; 2820 2841 long startTime = GetTime(); 2821 2842 2843 cout << "collecting merge candidates ... "; 2844 2822 2845 if (mUseRaysForMerge) 2823 2846 { 2824 cout << "collecting merge candidates (rays) ... ";2825 2847 mergeStats.nodes = CollectMergeCandidates(rays); 2826 cout << "fininshed collecting candidates" << endl;2827 2848 } 2828 2849 else … … 2832 2853 mergeStats.nodes = CollectMergeCandidates(leaves); 2833 2854 } 2834 2855 2856 cout << "fininshed collecting candidates" << endl; 2835 2857 2836 2858 mergeStats.collectTime = TimeDiff(startTime, GetTime()); … … 2840 2862 // number of view cells withouth the invalid ones 2841 2863 int nViewCells = mStat.Leaves() - mStat.invalidLeaves; 2842 Debug << "number of view cells taken into account: " << nViewCells << endl; 2864 2865 2843 2866 // pass is needed for statistics. the last n passes are 2844 2867 // recorded 2845 2868 const int maxPasses = 1000; 2869 const int nextPass = 50; 2870 2846 2871 int pass = max(nViewCells - mMergeMinViewCells - maxPasses, 0); 2847 const int nextPass = 50; 2848 2849 cout << "starting merge ... " << endl; 2872 2873 cout << "actual merge starts now ... " << endl; 2850 2874 2851 2875 //-- use priority queue to merge leaf pairs … … 2881 2905 ++ mergeStats.merged; 2882 2906 2883 if (showMergeStats) 2907 if ((mergeStats.merged % 500) == 0) 2908 cout << "merged " << mergeStats.merged << " view cells" << endl; 2909 2910 // stats and visualizations 2911 if (mExportMergeStats) 2884 2912 { 2885 2913 if (mc.GetLeaf1()->IsSibling(mc.GetLeaf2())) … … 2892 2920 mergeStats.accTreeDist += dist; 2893 2921 2894 //Debug << "viewcells: " << nViewCells << " mergemin " << mMergeMinViewCells << endl;2895 2922 if ((mergeStats.merged == pass) || (nViewCells == mMergeMinViewCells)) 2896 2923 { … … 2903 2930 << "#CurrentCost\n" << mergeCost << endl 2904 2931 << "#RelativeCost\n" << mergeCost / BspMergeCandidate::sOverallCost << endl 2905 << "#CurrentPvs\n" << mc.GetLeaf1()->GetViewCell()->GetPvs().GetSize() << endl; 2906 2907 ViewCellContainer::const_iterator vit, vit_end = viewCells.end(); 2908 2909 // find all already merged view cells and remove them from view cells 2910 int i = 0; 2911 while (1) 2912 { 2913 //while (!viewCells.empty() && (viewCells.back()->mMailbox == -1)) 2914 while (!viewCells.empty() && (viewCells.back()->GetId() == -2)) 2915 { 2916 //DEL_PTR(viewCells.back()); 2917 viewCells.pop_back(); 2918 } 2919 // all merged view cells have been found 2920 if (i >= viewCells.size()) 2921 break; 2922 2923 // already merged view cell, put it to end of vector 2924 //if (viewCells[i]->mMailbox == -1) 2925 if (viewCells[i]->GetId() == -2) 2926 swap(viewCells[i], viewCells.back()); 2927 2928 ++ i; 2929 } 2930 2931 int newVcSize = 0; 2932 // add new view cells to container only if they don't have been 2933 // merged in the mean time 2934 while (!mNewViewCells.empty()) 2935 { 2936 if (mNewViewCells.back()->GetId() != -2) 2937 { 2938 viewCells.push_back(mNewViewCells.back()); 2939 ++ newVcSize; 2940 } 2941 2942 mNewViewCells.pop_back(); 2943 } 2944 2945 // delete the view cells which were merged 2946 CLEAR_CONTAINER(mOldViewCells); 2947 2948 char s[64]; 2949 sprintf(s, "merged_viewcells%07d.x3d", nViewCells); 2950 Exporter *exporter = Exporter::GetExporter(s); 2951 2952 if (exporter) 2953 { 2954 cout << "exporting " << nViewCells << " merged view cells ... "; 2955 exporter->ExportGeometry(objects); 2956 //Debug << "vc size " << (int)viewCells.size() << " merge queue size: " << (int)mMergeQueue.size() << endl; 2957 ViewCellContainer::const_iterator it, it_end = viewCells.end(); 2958 2959 int i = 0; 2960 for (it = viewCells.begin(); it != it_end; ++ it) 2961 { 2962 Material m; 2963 // assign special material to new view cells 2964 // new view cells are on the back of container 2965 if (i ++ >= (viewCells.size() - newVcSize)) 2966 { 2967 //m = RandomMaterial(); 2968 m.mDiffuseColor.r = RandomValue(0.5f, 1.0f); 2969 m.mDiffuseColor.g = RandomValue(0.5f, 1.0f); 2970 m.mDiffuseColor.b = RandomValue(0.5f, 1.0f); 2971 } 2972 else 2973 { 2974 float col = RandomValue(0.1f, 0.4f); 2975 m.mDiffuseColor.r = col; 2976 m.mDiffuseColor.g = col; 2977 m.mDiffuseColor.b = col; 2978 } 2979 2980 exporter->SetForcedMaterial(m); 2981 mViewCellsManager->ExportVcGeometry(exporter, *it); 2982 } 2983 delete exporter; 2984 cout << "finished" << endl; 2985 } 2986 2932 << "#CurrentPvs\n" << mc.GetLeaf1()->GetViewCell()->GetPvs().GetSize() << endl 2933 << "#MergedSiblings\n" << mergeStats.siblings << endl 2934 << "#AvgTreeDist\n" << mergeStats.AvgTreeDist() << endl; 2935 2936 if (mExportMergedViewCells) 2937 ExportMergedViewCells(viewCells, objects, nViewCells); 2987 2938 } 2988 2939 } 2989 mNewViewCells.clear();2990 2940 } 2991 2941 // merge candidate not valid, because one of the leaves was already … … 2998 2948 } 2999 2949 3000 // view cells which were merged and are not part of any leaf 3001 CLEAR_CONTAINER(mOldViewCells); 3002 3003 cout << "finished merge" << endl; 2950 mergeStats.overallCost = BspMergeCandidate::sOverallCost; 2951 3004 2952 mergeStats.mergeTime = TimeDiff(startTime, GetTime()); 3005 2953 mergeStats.Stop(); 3006 2954 3007 if (showMergeStats) 3008 Debug << mergeStats << endl << endl; 2955 Debug << mergeStats << endl << endl; 2956 2957 // delete the view cells which were already merged 2958 CLEAR_CONTAINER(mOldViewCells); 3009 2959 3010 2960 … … 3047 2997 3048 2998 3049 int VspBspTree::RefineViewCells(const VssRayContainer &rays) 2999 void VspBspTree::ExportMergedViewCells(ViewCellContainer &viewCells, 3000 const ObjectContainer &objects, 3001 const int nViewCells) 3002 { 3003 ViewCellContainer::const_iterator vit, vit_end = viewCells.end(); 3004 3005 // find all already merged view cells and remove them from view cells 3006 int i = 0; 3007 3008 while (1) 3009 { 3010 //while (!viewCells.empty() && (viewCells.back()->mMailbox == -1)) 3011 while (!viewCells.empty() && (viewCells.back()->GetId() == -2)) 3012 { 3013 //DEL_PTR(viewCells.back()); 3014 viewCells.pop_back(); 3015 } 3016 // all merged view cells have been found 3017 if (i >= viewCells.size()) 3018 break; 3019 3020 // already merged view cell, put it to end of vector 3021 //if (viewCells[i]->mMailbox == -1) 3022 if (viewCells[i]->GetId() == -2) 3023 swap(viewCells[i], viewCells.back()); 3024 3025 ++ i; 3026 } 3027 3028 int newVcSize = 0; 3029 // add new view cells to container only if they don't have been 3030 // merged in the mean time 3031 while (!mNewViewCells.empty()) 3032 { 3033 if (mNewViewCells.back()->GetId() != -2) 3034 { 3035 viewCells.push_back(mNewViewCells.back()); 3036 ++ newVcSize; 3037 } 3038 3039 mNewViewCells.pop_back(); 3040 } 3041 3042 char s[64]; 3043 sprintf(s, "merged_viewcells%07d.x3d", nViewCells); 3044 Exporter *exporter = Exporter::GetExporter(s); 3045 3046 if (exporter) 3047 { 3048 cout << "exporting " << nViewCells << " merged view cells ... "; 3049 exporter->ExportGeometry(objects); 3050 //Debug << "vc size " << (int)viewCells.size() << " merge queue size: " << (int)mMergeQueue.size() << endl; 3051 ViewCellContainer::const_iterator it, it_end = viewCells.end(); 3052 3053 int i = 0; 3054 for (it = viewCells.begin(); it != it_end; ++ it) 3055 { 3056 Material m; 3057 // assign special material to new view cells 3058 // new view cells are on the back of container 3059 if (i ++ >= (viewCells.size() - newVcSize)) 3060 { 3061 //m = RandomMaterial(); 3062 m.mDiffuseColor.r = RandomValue(0.5f, 1.0f); 3063 m.mDiffuseColor.g = RandomValue(0.5f, 1.0f); 3064 m.mDiffuseColor.b = RandomValue(0.5f, 1.0f); 3065 } 3066 else 3067 { 3068 float col = RandomValue(0.1f, 0.4f); 3069 m.mDiffuseColor.r = col; 3070 m.mDiffuseColor.g = col; 3071 m.mDiffuseColor.b = col; 3072 } 3073 3074 exporter->SetForcedMaterial(m); 3075 mViewCellsManager->ExportVcGeometry(exporter, *it); 3076 } 3077 delete exporter; 3078 cout << "finished" << endl; 3079 } 3080 3081 // delete the view cells which were merged 3082 CLEAR_CONTAINER(mOldViewCells); 3083 // remove the new view cells 3084 mNewViewCells.clear(); 3085 } 3086 3087 3088 int VspBspTree::RefineViewCells(const VssRayContainer &rays, const ObjectContainer &objects) 3050 3089 { 3051 3090 int shuffled = 0; … … 3055 3094 3056 3095 // Use priority queue of remaining leaf pairs 3057 // The secandidates either share the same view cells or3096 // The candidates either share the same view cells or 3058 3097 // are border leaves which share a boundary. 3059 3098 // We test if they can be shuffled, i.e., … … 3061 3100 // leaf is made part of the other view cell. It is tested if the 3062 3101 // remaining view cells are "better" than the old ones. 3102 // 3103 // repeat the merging test numPasses times. For example, it could be 3104 // that a shuffle only makes sense if another pair was shuffled before. 3105 // Therefore we keep two queues and shift the merge candidates between 3106 // those two queues until numPasses is reached 3107 3108 queue<BspMergeCandidate> queue1; 3109 queue<BspMergeCandidate> queue2; 3110 3111 queue<BspMergeCandidate> *shuffleQueue = &queue1; 3112 queue<BspMergeCandidate> *backQueue = &queue2; 3113 3114 Exporter *exporter = Exporter::GetExporter("neighors.x3d"); 3115 3116 if (exporter) 3117 { 3118 cout << "exporting neighbors ... "; 3119 exporter->ExportGeometry(objects); 3120 } 3121 3122 // HACK for visualization 3123 ViewCellContainer viewCells; 3124 ViewCell::NewMail(); 3125 CollectViewCells(mRoot, true, viewCells, true); 3126 for (int i = 0; i < viewCells.size(); ++i) 3127 viewCells[i]->SetId((int)RandomValue(0, Real(256*256*256))); 3128 3129 Material m; 3130 m.mDiffuseColor.r = 0; 3131 m.mDiffuseColor.g = 0; 3132 m.mDiffuseColor.b = 0; 3133 3063 3134 while (!mMergeQueue.empty()) 3064 3135 { 3065 3136 BspMergeCandidate mc = mMergeQueue.top(); 3137 shuffleQueue->push(mc); 3066 3138 mMergeQueue.pop(); 3067 3139 3068 // both view cells equal or already shuffled 3069 if ((mc.GetLeaf1()->GetViewCell() == mc.GetLeaf2()->GetViewCell()) || 3070 (mc.GetLeaf1()->Mailed()) || (mc.GetLeaf2()->Mailed())) 3071 continue; 3140 m = RandomMaterial(); 3141 // visualize neighbors 3142 exporter->SetForcedMaterial(m); 3072 3143 3073 // candidate for shuffling 3074 const bool wasShuffled = 3075 ShuffleLeaves(mc.GetLeaf1(), mc.GetLeaf2()); 3144 BspNodeGeometry geom1, geom2; 3145 3146 ConstructGeometry(mc.GetLeaf1(), geom1); 3147 ConstructGeometry(mc.GetLeaf1(), geom2); 3148 3149 //m.mDiffuseColor.r = (mc.GetLeaf1()->GetViewCell()->GetId() & 256)/ 255.0f; 3150 //m.mDiffuseColor.g = ((mc.GetLeaf1()->GetViewCell()->GetId()>>8) & 256)/ 255.0f; 3151 //m.mDiffuseColor.b = ((mc.GetLeaf1()->GetViewCell()->GetId()>>16) & 256)/ 255.0f; 3152 exporter->SetForcedMaterial(m); 3153 3154 exporter->ExportPolygons(geom1.mPolys); 3076 3155 3077 //-- stats 3078 if (wasShuffled) 3079 ++ shuffled; 3156 //m.mDiffuseColor.r = (mc.GetLeaf2()->GetViewCell()->GetId() & 256)/ 255.0f; 3157 //m.mDiffuseColor.g = ((mc.GetLeaf2()->GetViewCell()->GetId()>>8) & 256)/ 255.0f; 3158 //m.mDiffuseColor.b = ((mc.GetLeaf2()->GetViewCell()->GetId()>>16) & 256)/ 255.0f; 3159 //exporter->SetForcedMaterial(m); 3160 3161 exporter->ExportPolygons(geom2.mPolys); 3162 } 3163 3164 if (exporter) 3165 { 3166 cout << "finished" << endl; 3167 delete exporter; 3168 } 3169 3170 const int numPasses = 5; 3171 int pass = 0; 3172 int passShuffled = 0; 3173 3174 3175 do 3176 { 3177 passShuffled = 0; 3178 while (!shuffleQueue->empty()) 3179 { 3180 BspMergeCandidate mc = shuffleQueue->front(); 3181 shuffleQueue->pop(); 3182 3183 // both view cells equal or already shuffled 3184 if ((mc.GetLeaf1()->GetViewCell() == mc.GetLeaf2()->GetViewCell()))// || 3185 // (mc.GetLeaf1()->Mailed()) || (mc.GetLeaf2()->Mailed())) 3186 continue; 3187 3188 // candidate for shuffling 3189 const bool wasShuffled = 3190 ShuffleLeaves(mc.GetLeaf1(), mc.GetLeaf2()); 3191 3192 if (wasShuffled) 3193 ++ passShuffled; 3194 else 3195 backQueue->push(mc); 3196 } 3197 3198 // now the back queue is the current shuffle queue 3199 swap(shuffleQueue, backQueue); 3200 shuffled += passShuffled; 3201 Debug << "shuffled in pass: " << passShuffled << endl; 3202 } 3203 while (((++ pass) < numPasses) && passShuffled); 3204 3205 while (!shuffleQueue->empty()) 3206 { 3207 shuffleQueue->pop(); 3080 3208 } 3081 3209 … … 3312 3440 mLeaf2Id(l2->GetViewCell()->mMailbox) 3313 3441 { 3314 EvalMergeCost();3442 //EvalMergeCost(); 3315 3443 } 3316 3444 … … 3336 3464 BspViewCell *vc = mLeaf2->GetViewCell(); 3337 3465 return GetCost(vc); 3466 } 3467 3468 3469 int ComputeMergedPvsSize(const ObjectPvs &pvs1, const ObjectPvs &pvs2) 3470 { 3471 int pvs = pvs1.GetSize(); 3472 3473 // compute new pvs size 3474 ObjectPvsMap::const_iterator it, it_end = pvs1.mEntries.end(); 3475 3476 Intersectable::NewMail(); 3477 3478 for (it = pvs1.mEntries.begin(); it != it_end; ++ it) 3479 { 3480 (*it).first->Mail(); 3481 } 3482 3483 it_end = pvs2.mEntries.end(); 3484 3485 for (it = pvs2.mEntries.begin(); it != it_end; ++ it) 3486 { 3487 Intersectable *obj = (*it).first; 3488 if (!obj->Mailed()) 3489 ++ pvs; 3490 } 3491 3492 return pvs; 3338 3493 } 3339 3494 … … 3345 3500 BspViewCell *vc2 = mLeaf2->GetViewCell(); 3346 3501 3347 const int diff1 = vc1->GetPvs().Diff(vc2->GetPvs()); 3348 const int newPvs = diff1 + vc1->GetPvs().GetSize(); 3502 //const int diff1 = vc1->GetPvs().Diff(vc2->GetPvs()); 3503 //const int newPvs = diff1 + vc1->GetPvs().GetSize(); 3504 const int newPvs = ComputeMergedPvsSize(vc1->GetPvs(), vc2->GetPvs()); 3349 3505 3350 3506 //-- compute ratio of old cost … … 3360 3516 if (newPvs > sMaxPvsSize) // strong penalty if pvs size too large 3361 3517 { 3362 mMergeCost = 1e15 f;3518 mMergeCost = 1e15; 3363 3519 } 3364 3520 else … … 3417 3573 3418 3574 /************************************************************************/ 3419 /* MergeStatistics implementation*/3575 /* MergeStatistics implementation */ 3420 3576 /************************************************************************/ 3421 3577 … … 3438 3594 3439 3595 app << "#N_MERGEDSIBLINGS ( Number of merged siblings )\n" << siblings << "\n"; 3596 3597 app << "#OVERALLCOST ( overall merge cost )\n" << overallCost << "\n"; 3598 3440 3599 app << "#N_MERGEDNODES ( Number of merged nodes )\n" << merged << "\n"; 3441 3600
Note: See TracChangeset
for help on using the changeset viewer.