Changeset 265 for trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
- Timestamp:
- 09/13/05 18:31:48 (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
r264 r265 17 17 int BspTree::sTermMaxPolygons = 10; 18 18 int BspTree::sTermMaxDepth = 20; 19 int BspTree::sMaxCandidates = 10; 19 20 int BspTree::sSplitPlaneStrategy = NEXT_POLYGON; 20 int BspTree::sMaxCandidates = 10;21 21 int BspTree::sConstructionMethod = VIEW_CELLS; 22 22 … … 30 30 int BspTree::sBalancedTreeTable[4] = {-1, 1, 0, 0}; 31 31 32 int counter = 0;33 32 /****************************************************************/ 34 33 /* class BspNode implementation */ … … 36 35 37 36 BspNode::BspNode(): mParent(NULL), mPolygons(NULL) 38 { 39 } 37 {} 40 38 41 39 BspNode::BspNode(BspInterior *parent): mParent(parent), mPolygons(NULL) … … 50 48 } 51 49 } 50 52 51 bool BspNode::IsRoot() const 53 52 { … … 145 144 int &splits, bool storePolys) 146 145 { 147 #ifdef _Debug146 //#ifdef _Debug 148 147 Debug << "Splitting polygons of node " << this << " with plane " << mPlane << endl; 149 #endif148 //#endif 150 149 bool inside = false; 151 150 … … 156 155 157 156 // test if split is neccessary 158 int result = poly->ClassifyPlane(mPlane); 159 157 int classification = poly->ClassifyPlane(mPlane); 158 159 //Debug << "polygon plane: " << poly->GetSupportingPlane() << endl; 160 160 Polygon3 *front_piece = NULL; 161 161 Polygon3 *back_piece = NULL; 162 162 163 switch ( result)163 switch (classification) 164 164 { 165 165 case Polygon3::COINCIDENT: … … 169 169 inside = (DotProd(mPlane.mNormal, poly->GetSupportingPlane().mNormal) > 0); 170 170 171 //Debug << "coincident" << endl;171 Debug << "coincident" << endl; 172 172 // discard polygons or saves them in node 173 173 ProcessPolygon(poly, storePolys); 174 174 break; 175 175 case Polygon3::FRONT_SIDE: 176 //Debug << "front" << endl;176 Debug << "front" << endl; 177 177 frontPolys->push_back(poly); 178 178 break; 179 179 case Polygon3::BACK_SIDE: 180 180 inside = true; 181 //Debug << "back" << endl;181 Debug << "back" << endl; 182 182 backPolys->push_back(poly); 183 183 break; 184 184 case Polygon3::SPLIT: 185 185 inside = true; 186 //Debug << "split"<< endl;186 Debug << "split " << poly << endl; 187 187 188 188 front_piece = new Polygon3(); … … 279 279 app << "#N_NODES ( Number of nodes )\n" << nodes << "\n"; 280 280 281 app << "#N_LEAVES ( Number of interior nodes )\n" << Interior() << "\n"; 282 281 283 app << "#N_LEAVES ( Number of leaves )\n" << Leaves() << "\n"; 282 284 283 app << "#N_SPLITS ( Number of splits )\n" << splits << "\n";285 app << "#N_SPLITS ( Number of splits )\n" << splits << "\n"; 284 286 285 287 app << "#N_RAYREFS ( Number of rayRefs )\n" << … … 307 309 maxDepthNodes * 100 / (double)Leaves() << endl; 308 310 309 app << "#N_PMAXDEPTH ( Maximal reached depth )\n" << maxDepth <<endl; 310 311 app << "#N_ADDED_RAYREFS (Number of dynamically added ray references )\n"<< 312 addedRayRefs<<endl; 313 314 app << "#N_REMOVED_RAYREFS (Number of dynamically removed ray references )\n"<< 315 removedRayRefs<<endl; 316 317 // app << setprecision(4); 318 319 // app << "#N_CTIME ( Construction time [s] )\n" 320 // << Time() << " \n"; 321 311 app << "#N_PMAXDEPTH ( Maximal reached depth )\n" << maxDepth << endl; 312 313 app << "#N_PMINDEPTH ( Minimal reached depth )\n" << minDepth << endl; 314 315 app << "#AVGEPTH ( average depth )\n" << AvgDepth() << endl; 316 317 app << "#N_ADDED_RAYREFS ( Number of dynamically added ray references )\n"<< 318 addedRayRefs << endl; 319 320 app << "#N_REMOVED_RAYREFS ( Number of dynamically removed ray references )\n" << 321 removedRayRefs << endl; 322 323 app << "#N_INPUT_POLYGONS (number of input polygons )\n" << 324 polys << endl; 325 326 app << "#N_ROUTPUT_INPUT_POLYGONS ( ratio polygons after subdivision / input polygons )\n" << 327 (polys + splits) / (double)polys << endl; 328 322 329 app << "===== END OF BspTree statistics ==========\n"; 323 330 } … … 356 363 357 364 // extract polygons that guide the split process 358 AddMesh2Polygons(viewCell->GetMesh(), *polys);365 mStat.polys += AddMesh2Polygons(viewCell->GetMesh(), *polys); 359 366 mBox.Include(viewCell->GetBox()); // add to BSP aabb 360 367 … … 382 389 int splits = 0; 383 390 391 Debug << "Splitting poly, YEAHH\n"; 384 392 // split viecell polygons with respect to split plane 385 393 bool inside = interior->SplitPolygons(tData.mPolygons, frontPolys, backPolys, splits, mStorePolys); … … 399 407 else // reached leaf => subdivide current viewcell 400 408 { 409 if (tData.mPolygons->size() > 0) 410 Debug << "WARNING (should not come here): polygon size: " << tData.mPolygons->size() << " inside: " << tData.mIsInside << endl; 411 401 412 BspNode *root = Subdivide(tStack, tData, viewCell); 402 413 403 // tree empty => new root 404 if (!mRoot) 414 //if (!root->IsLeaf()) 415 // Debug << "WARNING should NOT have subdivided further\n"; 416 417 if (!mRoot) // tree empty => new root 405 418 mRoot = root; 406 419 } 407 420 } 408 Debug << "ended traversal" << endl; Debug.flush();409 421 } 410 422 … … 420 432 421 433 422 voidBspTree::AddMesh2Polygons(Mesh *mesh, PolygonContainer &polys)434 int BspTree::AddMesh2Polygons(Mesh *mesh, PolygonContainer &polys) 423 435 { 424 436 FaceContainer::const_iterator fi; 425 437 int polysNum = 0; 438 426 439 // copy the face data to polygons 427 440 for (fi = mesh->mFaces.begin(); fi != mesh->mFaces.end(); ++ fi) … … 429 442 Polygon3 *poly = new Polygon3((*fi), mesh); 430 443 polys.push_back(poly); 431 } 432 } 433 434 void BspTree::Copy2PolygonSoup(const ViewCellContainer &viewCells, PolygonContainer &polys, int maxObjects) 444 polysNum ++; 445 } 446 return polysNum; 447 } 448 449 int BspTree::Copy2PolygonSoup(const ViewCellContainer &viewCells, PolygonContainer &polys, int maxObjects) 435 450 { 436 451 int limit = (maxObjects > 0) ? Min((int)viewCells.size(), maxObjects) : (int)viewCells.size(); … … 444 459 } 445 460 } 446 } 447 448 void BspTree::Copy2PolygonSoup(const ObjectContainer &objects, PolygonContainer &polys, int maxObjects) 461 462 return (int)polys.size(); 463 } 464 465 int BspTree::Copy2PolygonSoup(const ObjectContainer &objects, PolygonContainer &polys, int maxObjects) 449 466 { 450 467 int limit = (maxObjects > 0) ? Min((int)objects.size(), maxObjects) : (int)objects.size(); … … 475 492 } 476 493 477 Debug << "Number of polygons: " << (int)polys.size() << ", BSP root box: " << mBox << endl;494 return (int)polys.size(); 478 495 } 479 496 … … 511 528 512 529 mStorePolys = savedStorePolys; 513 514 counter = 0; 515 516 Debug << "\n**** Started view cells insertion ****\n\n"; 530 mStat.polys = 0; 531 mStat.splits = 0; 532 //int counter = 0; 533 534 long startTime = GetTime(); 535 Debug << "**** Starting view cell insertion ****" << endl; 517 536 for (it = viewCells.begin(); it != viewCells.end(); ++ it) 518 537 { 519 Debug << "*** Inserting view cell " << counter<< " ***" << endl;538 //Debug << "*** Inserting view cell " << counter ++ << " ***" << endl; 520 539 InsertViewCell(*it); 521 counter ++;522 }523 Debug << " **** finished view cells insertion ****" << endl; Debug.flush();540 } 541 Debug << "**** Finished view cell insertion ****" << endl; 542 Debug << "insertion time: "<< TimeDiff(startTime, GetTime())*1e-3 << "s" << endl; 524 543 } 525 544 … … 533 552 534 553 // copy mesh instance polygons into one big polygon soup 535 Copy2PolygonSoup(objects, *polys, sMaxCandidates);554 mStat.polys = Copy2PolygonSoup(objects, *polys, sMaxCandidates); 536 555 537 556 // construct tree from polygon soup … … 546 565 } 547 566 548 void BspTree::Construct(PolygonContainer *polys )567 void BspTree::Construct(PolygonContainer *polys, ViewCellContainer *viewCells) 549 568 { 550 569 std::stack<BspTraversalData> tStack; … … 554 573 tStack.push(tData); 555 574 575 long startTime = GetTime(); 556 576 Debug << "**** Contructing tree using objects ****\n"; 557 577 while (!tStack.empty()) … … 559 579 tData = tStack.top(); 560 580 tStack.pop(); 561 581 582 ViewCell *viewCell = NULL; 583 584 if (viewCells) // generate new view cell in leaf 585 { 586 viewCell = new ViewCell(); 587 viewCells->push_back(viewCell); 588 } 589 562 590 // subdivide leaf node 563 BspNode *root = Subdivide(tStack, tData );591 BspNode *root = Subdivide(tStack, tData, viewCell); 564 592 565 593 // empty tree => new root corresponding to unbounded space … … 568 596 } 569 597 570 Debug << "**** tree construction finished ****\n"; 598 Debug << "**** Finished tree construction ****\n"; 599 Debug << "BSP tree contruction time: "<< TimeDiff(startTime, GetTime())*1e-3 << "s" << endl; 571 600 } 572 601 … … 576 605 { 577 606 //-- terminate traversal 578 if (( (tData.mPolygons->size() <= mTermMaxPolygons) || (tData.mDepth >= mTermMaxDepth))607 if ((tData.mPolygons->size() <= mTermMaxPolygons) || (tData.mDepth >= mTermMaxDepth)) 579 608 // if there is another view cell associated with this leaf => subdivide further 580 && !(viewCell && tData.mIsInside && dynamic_cast<BspLeaf *>(tData.mNode)->GetViewCell()))609 //&& !(viewCell && tData.mIsInside && dynamic_cast<BspLeaf *>(tData.mNode)->GetViewCell())) 581 610 { 582 611 #ifdef _DEBUG 583 Debug << "terminate subdivision, size " << (int)tData.mPolygons->size() << ", depth " << tData.mDepth<< endl;612 Debug << "subdivision terminated at depth " << tData.mDepth << ", #polys: " << (int)tData.mPolygons->size() << endl; 584 613 #endif 585 614 … … 587 616 588 617 // add view cell if inside object) 589 if (viewCell && tData.mIsInside) 590 // || (tData.mGeometry->size() > 0) // or if there is still geometry left 618 if (viewCell && tData.mIsInside) // || (tData.mGeometry->size() > 0) // or if there is still geometry left 591 619 { 592 620 BspLeaf *leaf = dynamic_cast<BspLeaf *>(tData.mNode); 593 621 594 #ifdef _DEBUG595 622 if (leaf->GetViewCell()) 596 623 Debug << "ERROR: leaf already has view cell" << endl; 597 624 598 Debug << "**** Inserted view cell ****" << endl;599 #endif600 625 leaf->SetViewCell(viewCell); 601 626 } … … 613 638 bool inside = false; 614 639 640 Debug << "Subdividing node at depth " << tData.mDepth << endl; 615 641 BspInterior *interior = SubdivideNode(dynamic_cast<BspLeaf *>(tData.mNode), 616 642 tData.mPolygons, … … 618 644 backPolys, inside); 619 645 620 // push the children on the stack (there are always two children) 646 // push the children on the stack 647 // inside information is only propagated with the back leaf 621 648 tStack.push(BspTraversalData(interior->GetBack(), backPolys, tData.mDepth + 1, inside)); 622 649 tStack.push(BspTraversalData(interior->GetFront(), frontPolys, tData.mDepth + 1, false)); … … 657 684 658 685 // and setup child links 659 interior->SetupChildLinks(new BspLeaf(interior, leaf->mViewCell), new BspLeaf(interior)); 686 //interior->SetupChildLinks(new BspLeaf(interior), new BspLeaf(interior, leaf->mViewCell)); 687 interior->SetupChildLinks(new BspLeaf(interior), new BspLeaf(interior)); 660 688 661 689 delete leaf; // leaf not member of tree anymore … … 685 713 { 686 714 int lowestCost = INITIAL_COST; 687 Plane3 *bestPlane = NULL;715 int bestPlaneIdx = 0; 688 716 689 717 int limit = Min((int)polygons->size(), maxTests); 690 718 691 for (int i = 0; i < limit; ++ i)692 { 693 int candidateIdx = Random((int)polygons->size()); 719 for (int i = 0; i < limit; ++ i) 720 { 721 int candidateIdx = Random((int)polygons->size()); // TODO: avoid testing same plane 2 times 694 722 Plane3 candidatePlane = (*polygons)[candidateIdx]->GetSupportingPlane(); 695 723 … … 699 727 if (candidateCost < lowestCost) 700 728 { 701 bestPlane = &candidatePlane;729 bestPlaneIdx = candidateIdx; 702 730 lowestCost = candidateCost; 703 731 //Debug << "new plane cost " << lowestCost << endl; 704 732 } 705 733 } 706 707 return *bestPlane; 734 735 if (lowestCost > 0) 736 Debug << "Split plane cost: " << lowestCost << " plane: " << (*polygons)[bestPlaneIdx]->GetSupportingPlane() << endl; 737 else 738 Debug << "no splits for plane: " << (*polygons)[bestPlaneIdx]->GetSupportingPlane() << endl; 739 return (*polygons)[bestPlaneIdx]->GetSupportingPlane(); 708 740 } 709 741 … … 712 744 PolygonContainer::const_iterator it; 713 745 714 int sum = 0, sum2= 0;715 716 for (it = polygons->begin(); it <polygons->end(); ++ it)746 int sumBalanced = 0, sumLeastSplits = 0; 747 748 for (it = polygons->begin(); it != polygons->end(); ++ it) 717 749 { 718 750 int classification = (*it)->ClassifyPlane(candidatePlane); … … 720 752 if ((sSplitPlaneStrategy == COMBINED) || (sSplitPlaneStrategy == BALANCED_TREE)) 721 753 { 722 sum += sBalancedTreeTable[classification];754 sumBalanced += sBalancedTreeTable[classification]; 723 755 } 724 756 725 if ((sSplitPlaneStrategy == COMBINED) ||(sSplitPlaneStrategy == LEAST_SPLITS)) 726 { 727 sum2 += sLeastSplitsTable[classification]; 728 } 729 } 757 if ((sSplitPlaneStrategy == COMBINED) || (sSplitPlaneStrategy == LEAST_SPLITS)) 758 { 759 sumLeastSplits += sLeastSplitsTable[classification]; 760 Debug << "Adding " << sLeastSplitsTable[classification] << " for poly " << *it << "!"; 761 } 762 } 763 764 Debug << "\n" << candidatePlane << " evaluation: " << abs(sumBalanced) + abs(sumLeastSplits) << endl; 730 765 731 766 // return linear combination of both sums 732 return abs(sum ) + abs(sum2);767 return abs(sumBalanced) + abs(sumLeastSplits); 733 768 } 734 769 … … 738 773 environment->GetIntValue("BspTree.Termination.maxPolygons", sTermMaxPolygons); 739 774 environment->GetIntValue("BspTree.maxCandidates", sMaxCandidates); 775 776 Debug << "BSP max depth: " << sTermMaxDepth << endl; 777 Debug << "BSP max polys: " << sTermMaxPolygons << endl; 778 Debug << "BSP max candidates: " << sMaxCandidates << endl; 740 779 741 780 //-- extract strategy to choose the next split plane … … 758 797 } 759 798 799 Debug << "Split plane heuristic: " << splitPlaneStrategyStr << endl; 800 760 801 //-- parse BSP tree construction method 761 char constructionMethodStr[6 4];802 char constructionMethodStr[60]; 762 803 763 804 environment->GetStringValue("BspTree.constructionMethod", constructionMethodStr); … … 777 818 } 778 819 820 Debug << "Construction method: " << constructionMethodStr << endl; 779 821 } 780 822 … … 879 921 } 880 922 881 // store maximal depth923 // store maximal and minimal depth 882 924 if (data.mDepth > mStat.maxDepth) 883 925 mStat.maxDepth = data.mDepth; 926 if (data.mDepth < mStat.minDepth) 927 mStat.minDepth = data.mDepth; 928 929 mStat.accumDepth += data.mDepth; 930 931 if (leaf->mViewCell) 932 ++ mStat.viewCellLeaves; 884 933 885 934 #ifdef _DEBUG 886 Debug << "BSP Traversal data. Depth: " << data.mDepth << " (max: " << mTermMaxDepth << "), #polygons: " <<935 Debug << "BSP Traversal data. Depth: " << data.mDepth << " (max: " << mTermMaxDepth << "), #polygons: " << 887 936 data.mPolygons->size() << " (max: " << mTermMaxPolygons << ")" << endl; 888 937 #endif
Note: See TracChangeset
for help on using the changeset viewer.