- Timestamp:
- 09/12/05 18:24:44 (19 years ago)
- Location:
- trunk/VUT/GtpVisibilityPreprocessor
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
r263 r264 12 12 # filename ../data/soda/soda5.dat 13 13 # viewcells ../data/atlanta/atlanta_viewcells_large.x3d 14 viewcells ../data/vienna/viewcells-25-sel.x3d 14 #viewcells ../data/atlanta/atlanta_viewcells_large2.x3d 15 # viewcells ../data/vienna/viewcells-25-sel.x3d 16 viewcells ../data/vienna/viewcells-25.x3d 17 # viewcells ../data/vienna/viewcells-large-sel.x3d 15 18 } 16 19 … … 60 63 61 64 BspTree { 62 #splitPlaneStrategy leastSplits63 splitPlaneStrategy balancedTree65 splitPlaneStrategy leastSplits 66 # splitPlaneStrategy balancedTree 64 67 # splitPlaneStrategy nextPolygon 68 # splitPlaneStrategy combined 65 69 # constructionMethod rays 66 70 constructionMethod viewCells 67 71 # constructionMethod sceneGeometry 68 maxCandidates 2 072 maxCandidates 25 69 73 maxViewCells 9999 70 74 Termination { -
trunk/VUT/GtpVisibilityPreprocessor/src/Polygon3.cpp
r262 r264 11 11 12 12 Polygon3::Polygon3(Face *face, Mesh *parent) 13 { 14 VertexIndexContainer::reverse_iterator it = face->mVertexIndices.rbegin(); 15 16 for (; it != face->mVertexIndices.rend(); ++it) 13 { 14 VertexIndexContainer::iterator it = face->mVertexIndices.begin(); 15 for (; it != face->mVertexIndices.end(); ++it) 17 16 { 18 17 mVertices.push_back(parent->mVertices[*it]); … … 123 122 onBackSide = true; 124 123 } 125 126 if (onFrontSide && onBackSide) // split //TODO: check if through vvertex124 //TODO: check if split goes through vertex 125 if (onFrontSide && onBackSide) // split 127 126 { 128 127 return SPLIT; -
trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp
r263 r264 152 152 153 153 if (bsptree) { 154 exporter->SetWireframe();154 //exporter->SetWireframe(); 155 155 exporter->ExportBspTree(*mBspTree); 156 156 } -
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp
r263 r264 91 91 92 92 // bottom 93 mesh->mFaces.push_back(new Face( 0,1,2));93 mesh->mFaces.push_back(new Face(2,1,0)); 94 94 // top 95 mesh->mFaces.push_back(new Face( 5,4,3));95 mesh->mFaces.push_back(new Face(3,4,5)); 96 96 // sides 97 mesh->mFaces.push_back(new Face(0, 3, 4, 1)); 98 mesh->mFaces.push_back(new Face(1, 4, 5, 2)); 99 mesh->mFaces.push_back(new Face(0, 2, 5, 3)); 100 97 mesh->mFaces.push_back(new Face(1, 4, 3, 0)); 98 mesh->mFaces.push_back(new Face(2, 5, 4, 1)); 99 mesh->mFaces.push_back(new Face(3, 5, 2, 0)); 101 100 102 101 //--- extrude new vertices for top of prism -
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
r263 r264 30 30 int BspTree::sBalancedTreeTable[4] = {-1, 1, 0, 0}; 31 31 32 int counter = 0; 32 33 /****************************************************************/ 33 34 /* class BspNode implementation */ 34 35 /****************************************************************/ 35 36 36 BspNode::BspNode(): mParent(NULL) 37 BspNode::BspNode(): mParent(NULL), mPolygons(NULL) 38 { 39 } 40 41 BspNode::BspNode(BspInterior *parent): mParent(parent), mPolygons(NULL) 37 42 {} 38 43 39 BspNode::BspNode(BspInterior *parent): mParent(parent) 40 {} 41 42 44 BspNode::~BspNode() 45 { 46 if (mPolygons) 47 { 48 CLEAR_CONTAINER(*mPolygons); 49 DEL_PTR(mPolygons); 50 } 51 } 43 52 bool BspNode::IsRoot() const 44 53 { … … 58 67 PolygonContainer *BspNode::GetPolygons() 59 68 { 60 return &mPolygons; 61 } 62 63 void BspNode::AddPolygons(PolygonContainer *polys) 64 { 65 while (!polys->empty()) 66 { 67 mPolygons.push_back(polys->back()); 68 polys->pop_back(); 69 } 69 if (!mPolygons) 70 mPolygons = new PolygonContainer(); 71 72 return mPolygons; 73 } 74 75 void BspNode::ProcessPolygons(PolygonContainer *polys, bool storePolys) 76 { 77 if (storePolys) 78 { 79 while (!polys->empty()) 80 { 81 GetPolygons()->push_back(polys->back()); 82 polys->pop_back(); 83 } 84 } 85 else CLEAR_CONTAINER(*polys); 86 87 delete polys; 70 88 } 71 89 … … 103 121 { 104 122 if (mBack == oldChild) 105 {106 123 mBack = newChild; 107 } 108 else 109 { 124 else 110 125 mFront = newChild; 111 }112 126 } 113 127 … … 118 132 } 119 133 120 void BspInterior::ProcessPolygon(Polygon3 *poly, bool storePolys)134 void BspInterior::ProcessPolygon(Polygon3 *poly, const bool storePolys) 121 135 { 122 136 if (storePolys) 123 mPolygons.push_back(poly);137 GetPolygons()->push_back(poly); 124 138 else 125 139 delete poly; 126 140 } 127 141 128 voidBspInterior::SplitPolygons(PolygonContainer *polys,142 bool BspInterior::SplitPolygons(PolygonContainer *polys, 129 143 PolygonContainer *frontPolys, 130 144 PolygonContainer *backPolys, 131 145 int &splits, bool storePolys) 132 146 { 147 #ifdef _Debug 148 Debug << "Splitting polygons of node " << this << " with plane " << mPlane << endl; 149 #endif 150 bool inside = false; 151 133 152 while (!polys->empty()) 134 153 { … … 141 160 Polygon3 *front_piece = NULL; 142 161 Polygon3 *back_piece = NULL; 143 162 144 163 switch (result) 145 164 { 146 165 case Polygon3::COINCIDENT: 166 167 if (!inside) 168 // same surface normal 169 inside = (DotProd(mPlane.mNormal, poly->GetSupportingPlane().mNormal) > 0); 170 171 //Debug << "coincident" << endl; 147 172 // discard polygons or saves them in node 148 173 ProcessPolygon(poly, storePolys); 149 174 break; 150 175 case Polygon3::FRONT_SIDE: 176 //Debug << "front" << endl; 151 177 frontPolys->push_back(poly); 152 178 break; 153 179 case Polygon3::BACK_SIDE: 180 inside = true; 181 //Debug << "back" << endl; 154 182 backPolys->push_back(poly); 155 183 break; 156 184 case Polygon3::SPLIT: 185 inside = true; 186 //Debug << "split" << endl; 187 157 188 front_piece = new Polygon3(); 158 189 back_piece = new Polygon3(); … … 179 210 // contains nothing 180 211 delete polys; 212 213 return inside; 181 214 } 182 215 … … 188 221 } 189 222 190 BspLeaf::BspLeaf(ViewCell *viewCell): mViewCell(viewCell) 223 BspLeaf::BspLeaf(ViewCell *viewCell): mViewCell(viewCell) 191 224 { 192 225 } … … 195 228 {} 196 229 230 BspLeaf::BspLeaf(BspInterior *parent, ViewCell *viewCell): 231 BspNode(parent), mViewCell(viewCell) 232 { 233 } 197 234 ViewCell *BspLeaf::GetViewCell() 198 235 { … … 219 256 mRoot(NULL), 220 257 mIsIncremential(false), 221 mStorePolys( true)258 mStorePolys(false) 222 259 { 223 260 Randomize(); // initialise random generator for heuristics … … 298 335 tStack.pop(); 299 336 300 /// if we stored the polygons301 CLEAR_CONTAINER(node->mPolygons);302 303 337 if (!node->IsLeaf()) 304 338 { … … 318 352 { 319 353 std::stack<BspTraversalData> tStack; 320 Debug << "getting polygons" << endl; Debug.flush();354 321 355 PolygonContainer *polys = new PolygonContainer(); 322 356 … … 328 362 BspNode *firstNode = mRoot ? mRoot : new BspLeaf(); 329 363 330 tStack.push(BspTraversalData(firstNode, NULL, polys, 0)); 331 332 Debug << "starting traversal" << endl; Debug.flush(); 364 tStack.push(BspTraversalData(firstNode, polys, 0, true)); 365 333 366 while (!tStack.empty()) 334 367 { 335 Debug << "new traversal step" << endl; Debug.flush();336 337 368 // filter polygons donw the tree 338 369 BspTraversalData tData = tStack.top(); 339 370 tStack.pop(); 340 371 341 Debug << "popped stack" << endl; Debug.flush();342 if (!tData.mNode)343 Debug << "ERROR NO NODE\n"; Debug.flush();344 372 if (!tData.mNode->IsLeaf()) 345 373 { 346 Debug << "no leaf" << endl; Debug.flush();347 374 BspInterior *interior = dynamic_cast<BspInterior *>(tData.mNode); 348 375 349 376 //-- filter view cell polygons down the tree until a leaf is reached 350 PolygonContainer *frontPolys = new PolygonContainer();351 PolygonContainer *backPolys = new PolygonContainer();352 353 int splits = 0;354 355 377 if ((int)tData.mPolygons->size() > 0) 356 378 { 357 Debug << "traversing down tree" << endl; Debug.flush(); 379 PolygonContainer *frontPolys = new PolygonContainer(); 380 PolygonContainer *backPolys = new PolygonContainer(); 381 382 int splits = 0; 383 358 384 // split viecell polygons with respect to split plane 359 interior->SplitPolygons(tData.mPolygons, frontPolys, backPolys, splits, mStorePolys); 360 Debug << "polygon splitted" << endl; Debug.flush(); 385 bool inside = interior->SplitPolygons(tData.mPolygons, frontPolys, backPolys, splits, mStorePolys); 361 386 //Debug << "Reached level " << tData.mDepth << " bk: " << backPolys->size() << " frnt: " << frontPolys->size() << endl; 362 387 mStat.splits += splits; 363 388 364 389 // push the children on the stack 365 tStack.push(BspTraversalData(interior->GetFront(), interior->GetParent(), 366 frontPolys, tData.mDepth + 1)); 367 368 tStack.push(BspTraversalData(interior->GetBack(), interior->GetParent(), 369 backPolys, tData.mDepth + 1)); 390 tStack.push(BspTraversalData(interior->GetFront(), frontPolys, tData.mDepth + 1, false)); 391 tStack.push(BspTraversalData(interior->GetBack(), backPolys, tData.mDepth + 1, inside)); 370 392 371 393 } 372 else 394 else // stop traversal 373 395 { 374 Debug << "deleting data" << endl; Debug.flush();375 396 DEL_PTR(tData.mPolygons); 376 Debug << "deleted data" << endl; Debug.flush();377 397 } 378 398 } 379 399 else // reached leaf => subdivide current viewcell 380 400 { 381 Debug << "reached leaf" << endl; Debug.flush();382 401 BspNode *root = Subdivide(tStack, tData, viewCell); 383 402 384 403 // tree empty => new root 385 404 if (!mRoot) 386 mRoot = root; 387 Debug << "subdivision done" << endl; Debug.flush(); 388 } 389 Debug << "ended one traversal step" << endl; Debug.flush(); 405 mRoot = root; 406 } 390 407 } 391 408 Debug << "ended traversal" << endl; Debug.flush(); … … 495 512 mStorePolys = savedStorePolys; 496 513 497 intcounter = 0;514 counter = 0; 498 515 499 516 Debug << "\n**** Started view cells insertion ****\n\n"; … … 502 519 Debug << "*** Inserting view cell " << counter << " ***" << endl; 503 520 InsertViewCell(*it); 504 Debug << "*** view cell " << ++ counter << " inserted ***" << endl;521 counter ++; 505 522 } 506 523 Debug << "**** finished view cells insertion ****" << endl; Debug.flush(); … … 533 550 std::stack<BspTraversalData> tStack; 534 551 535 BspTraversalData tData(new BspLeaf(), NULL, polys, 0);552 BspTraversalData tData(new BspLeaf(), polys, 0, true); 536 553 537 554 tStack.push(tData); … … 555 572 556 573 557 BspNode * BspTree::Subdivide(BspTraversalStack &tStack, 558 BspTraversalData &tData, 559 ViewCell *viewCell) 560 { 561 Debug << "subdividing" << endl; Debug.flush(); 574 BspNode *BspTree::Subdivide(BspTraversalStack &tStack, BspTraversalData &tData, 575 ViewCell *viewCell) 576 { 577 //-- terminate traversal 578 if (((tData.mPolygons->size() <= mTermMaxPolygons) || (tData.mDepth >= mTermMaxDepth)) 579 // if there is another view cell associated with this leaf => subdivide further 580 && !(viewCell && tData.mIsInside && dynamic_cast<BspLeaf *>(tData.mNode)->GetViewCell())) 581 { 582 #ifdef _DEBUG 583 Debug << "terminate subdivision, size " << (int)tData.mPolygons->size() << ", depth " << tData.mDepth << endl; 584 #endif 585 586 EvaluateLeafStats(tData); 587 588 // add view cell if inside object) 589 if (viewCell && tData.mIsInside) 590 // || (tData.mGeometry->size() > 0) // or if there is still geometry left 591 { 592 BspLeaf *leaf = dynamic_cast<BspLeaf *>(tData.mNode); 593 594 #ifdef _DEBUG 595 if (leaf->GetViewCell()) 596 Debug << "ERROR: leaf already has view cell" << endl; 597 598 Debug << "**** Inserted view cell ****" << endl; 599 #endif 600 leaf->SetViewCell(viewCell); 601 } 602 603 // add or delete remaining polygons 604 tData.mNode->ProcessPolygons(tData.mPolygons, mStorePolys); 605 606 return tData.mNode; 607 } 608 609 //-- create new subdivided node 562 610 PolygonContainer *backPolys = new PolygonContainer(); 563 611 PolygonContainer *frontPolys = new PolygonContainer(); 564 612 565 BspNode *node = SubdivideNode(dynamic_cast<BspLeaf *>(tData.mNode), 566 tData.mParent, 567 tData.mPolygons, 568 tData.mDepth, 569 frontPolys, 570 backPolys); 571 572 if (!node->IsLeaf()) // node was subdivided 573 { 574 Debug << "node was subdivided" << endl; Debug.flush(); 575 BspInterior *interior = dynamic_cast<BspInterior *>(node); 576 577 // push the children on the stack (there are always two children) 578 tStack.push(BspTraversalData(interior->GetBack(), interior, backPolys, tData.mDepth + 1)); 579 tStack.push(BspTraversalData(interior->GetFront(), interior, frontPolys, tData.mDepth + 1)); 580 } 581 else // traversal terminates 582 { 583 Debug << "eval stats" << endl; Debug.flush(); 584 EvaluateLeafStats(tData); 585 586 BspLeaf *leaf = dynamic_cast<BspLeaf *>(node); 587 588 // add view cell if in negative halfspace (== inside object) 589 // or if there is still geometry left 590 if (viewCell && 591 (!node->GetParent() || (node == node->GetParent()->GetBack()) || 592 (tData.mPolygons->size() > 0))) 593 { 594 Debug << "** view cell inserted **\n"; 595 leaf->SetViewCell(viewCell); 596 } 597 598 Debug << "storing or deleting polygons: " << mStorePolys << endl; Debug.flush(); 599 // add or delete remaining polygons 600 if (mStorePolys) 601 leaf->AddPolygons(tData.mPolygons); 602 else 603 CLEAR_CONTAINER(*tData.mPolygons); 604 605 DEL_PTR(tData.mPolygons); 606 Debug << "deleted polygon container" << endl; Debug.flush(); 607 } 608 609 return node; 610 } 611 612 613 BspNode *BspTree::SubdivideNode(BspLeaf *leaf, 614 BspInterior *parent, 615 PolygonContainer *polys, 616 const int depth, 617 PolygonContainer *frontPolys, 618 PolygonContainer *backPolys) 619 { 620 if (leaf->GetViewCell() && (polys->size() == 0)) 621 Debug << "error: no distinct view cells!!!!!!!!!!!\n"; 622 623 // terminate traversal 624 if (//!leaf->GetViewCell() && 625 ((polys->size() <= mTermMaxPolygons) || (depth >= mTermMaxDepth))) 626 {Debug << "subdividing node termination" << endl; Debug.flush(); 627 return leaf; 628 } 629 630 mStat.nodes += 2; 613 bool inside = false; 614 615 BspInterior *interior = SubdivideNode(dynamic_cast<BspLeaf *>(tData.mNode), 616 tData.mPolygons, 617 frontPolys, 618 backPolys, inside); 619 620 // push the children on the stack (there are always two children) 621 tStack.push(BspTraversalData(interior->GetBack(), backPolys, tData.mDepth + 1, inside)); 622 tStack.push(BspTraversalData(interior->GetFront(), frontPolys, tData.mDepth + 1, false)); 623 624 return interior; 625 } 626 627 628 BspInterior *BspTree::SubdivideNode(BspLeaf *leaf, 629 PolygonContainer *polys, 630 PolygonContainer *frontPolys, 631 PolygonContainer *backPolys, bool &inside) 632 { 633 mStat.nodes += 2; 631 634 632 635 // add the new nodes to the tree + select subdivision plane 633 BspInterior * node= new BspInterior(SelectPlane(polys));636 BspInterior *interior = new BspInterior(SelectPlane(polys)); 634 637 635 638 #ifdef _DEBUG 636 Debug << node<< endl;639 Debug << interior << endl; 637 640 #endif 638 641 … … 640 643 int splits = 0; 641 644 642 Debug << "splipoly" << endl; Debug.flush(); 643 node->SplitPolygons(polys, frontPolys, backPolys, splits, mStorePolys); 645 inside = interior->SplitPolygons(polys, frontPolys, backPolys, splits, mStorePolys); 644 646 645 647 mStat.splits += splits; 646 648 647 // two new leaves 648 BspLeaf *back = new BspLeaf(node); 649 BspLeaf *front = new BspLeaf(node); 649 BspInterior *parent = leaf->GetParent(); 650 650 651 651 // replace a link from node's parent 652 652 if (parent) 653 parent->ReplaceChildLink(leaf, node); 654 653 { 654 parent->ReplaceChildLink(leaf, interior); 655 interior->SetParent(parent); 656 } 657 655 658 // and setup child links 656 node->SetupChildLinks(back, front);657 658 DEL_PTR(leaf); // leaf not member of tree anymore659 660 return node;659 interior->SetupChildLinks(new BspLeaf(interior, leaf->mViewCell), new BspLeaf(interior)); 660 661 delete leaf; // leaf not member of tree anymore 662 663 return interior; 661 664 } 662 665 … … 715 718 int classification = (*it)->ClassifyPlane(candidatePlane); 716 719 717 if ((sSplitPlaneStrategy == BALANCED_TREE) || (sSplitPlaneStrategy == COMBINED))720 if ((sSplitPlaneStrategy == COMBINED) || (sSplitPlaneStrategy == BALANCED_TREE)) 718 721 { 719 722 sum += sBalancedTreeTable[classification]; 720 723 } 721 724 722 if ((sSplitPlaneStrategy == LEAST_SPLITS) || (sSplitPlaneStrategy == COMBINED))725 if ((sSplitPlaneStrategy == COMBINED) ||(sSplitPlaneStrategy == LEAST_SPLITS)) 723 726 { 724 727 sum2 += sLeastSplitsTable[classification]; -
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
r263 r264 107 107 public: 108 108 BspNode(); 109 virtual ~BspNode(); 109 110 BspNode(BspInterior *parent); 110 111 … … 126 127 void SetParent(BspInterior *parent); 127 128 129 /** Returns pointer to polygons. 130 */ 128 131 PolygonContainer *GetPolygons(); 129 132 130 /** Adds polygons to node.131 */132 void AddPolygons(PolygonContainer *polys);133 134 133 protected: 134 135 /** Adds or discards polygons according to storePolys. 136 */ 137 void ProcessPolygons(PolygonContainer *polys, const bool storePolys); 138 135 139 136 140 /// parent of this node 137 141 BspInterior *mParent; 138 142 139 PolygonContainer mPolygons; 143 /// store polygons created during BSP splits 144 PolygonContainer *mPolygons; 140 145 }; 141 146 … … 165 170 @param backPolys returns the polygons in the back of the split plane 166 171 @param splits number of splits 167 */ 168 void SplitPolygons(PolygonContainer *polys, PolygonContainer *frontPolys, 172 @returns true if one or more polygons are inside of the split plane 173 */ 174 bool SplitPolygons(PolygonContainer *polys, PolygonContainer *frontPolys, 169 175 PolygonContainer *backPolys, int &splits, bool storePolys = false); 170 176 … … 181 187 @param storePolys if the polygons should be stored or discarded 182 188 */ 183 void ProcessPolygon(Polygon3 *poly, bool storePolys);189 void ProcessPolygon(Polygon3 *poly, const bool storePolys); 184 190 185 191 /// Splitting plane corresponding to this node … … 201 207 BspLeaf(ViewCell *viewCell); 202 208 BspLeaf(BspInterior *parent); 209 BspLeaf(BspInterior *parent, ViewCell *viewCell); 203 210 204 211 /** @return true since it is an interior node … … 231 238 /// the current node 232 239 BspNode *mNode; 233 /// parent of current node234 BspInterior *mParent;235 240 /// polygonal data for splitting 236 241 PolygonContainer *mPolygons; 237 242 /// current depth 238 243 int mDepth; 239 244 /// if the node is an inside or outside node with respect to the parent plane 245 bool mIsInside; 240 246 BspTraversalData() {} 241 247 242 BspTraversalData(BspNode *node, BspInterior *parent, PolygonContainer *polys, const int depth):243 mNode(node), mP arent(parent), mPolygons(polys), mDepth(depth) {}248 BspTraversalData(BspNode *node, PolygonContainer *polys, const int depth, const bool inside): 249 mNode(node), mPolygons(polys), mDepth(depth), mIsInside(inside) {} 244 250 }; 245 251 … … 341 347 /** Subdivide leaf. 342 348 @param leaf the leaf to be subdivided 343 @param parent the parent node of this leaf344 349 @param polys the input polygons 345 @param depth the current tree depth346 350 @param frontPolys the polygons of the front child node as a result from splitting 347 351 @param backPolys the polygons of the back child node as a result from splitting 348 */349 BspNode *SubdivideNode(BspLeaf *leaf,350 BspInterior *parent,351 PolygonContainer *polys,352 const int depth,353 PolygonContainer *frontPolys,354 PolygonContainer *backPolys);352 @param if the polygons are outside or inside with respect to the interior node plane 353 @returns the root of the subdivision 354 */ 355 BspInterior *SubdivideNode(BspLeaf *leaf, 356 PolygonContainer *polys, 357 PolygonContainer *frontPolys, 358 PolygonContainer *backPolys, bool &inside); 355 359 356 360 /** Filters polygons down the tree. -
trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp
r263 r264 387 387 388 388 AxisAlignedBox3 box = tree.GetBoundingBox(); 389 bool savedWireframe = mWireframe; 390 391 SetWireframe(); 389 392 ExportBox(box); 390 393 394 if (!savedWireframe) 395 SetFilled(); 396 391 397 while (!tStack.empty()) 392 398 { -
trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp
r263 r264 7 7 #include "Camera.h" 8 8 #include "MeshKdTree.h" 9 #include "Exporter.h" 9 10 10 11 #define USE_EXE_PATH false … … 35 36 environment->GetStringValue("Scene.viewcells", buff); 36 37 37 string vcFile Name(buff);38 string vcFilename(buff); 38 39 39 40 // if BSP tree construction method needs predefined view cells 40 41 if (BspTree::sConstructionMethod == BspTree::VIEW_CELLS) 41 42 { 42 if (vcFileName != "") 43 p->LoadViewCells(vcFileName); 43 if (vcFilename != "") 44 { 45 p->LoadViewCells(vcFilename); 46 Exporter *exporter = Exporter::GetExporter("viewcells.x3d"); 47 if (exporter) 48 { 49 exporter->ExportViewCells(&p->mViewCells); 50 delete exporter; 51 } 52 } 44 53 else 45 54 p->GenerateViewCells();
Note: See TracChangeset
for help on using the changeset viewer.