source: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.cpp @ 2114

Revision 2114, 37.3 KB checked in by mattausch, 17 years ago (diff)
Line 
1// ---------------------------------------------------------------------------
2//  Includes for all the program files to see
3// ---------------------------------------------------------------------------
4#include <string.h>
5#include <stdlib.h>
6#include <iostream>
7//#include <ext/algorithm>
8
9using namespace std;
10#include <xercesc/util/PlatformUtils.hpp>
11
12// ---------------------------------------------------------------------------
13//  Includes
14// ---------------------------------------------------------------------------
15#include <xercesc/framework/StdInInputSource.hpp>
16#include <xercesc/parsers/SAXParser.hpp>
17#include <xercesc/util/OutOfMemoryException.hpp>
18
19// ---------------------------------------------------------------------------
20//  Includes
21// ---------------------------------------------------------------------------
22#include <xercesc/sax/AttributeList.hpp>
23#include <xercesc/sax/SAXParseException.hpp>
24#include <xercesc/sax/SAXException.hpp>
25
26#include "ViewCellsParser.h"
27
28#include "ViewCellsParserXerces.h"
29#include "Mesh.h"
30#include "VspBspTree.h"
31#include "ViewCellBsp.h"
32#include "ViewCellsManager.h"
33#include "GzFileInputSource.h"
34#include "OspTree.h"
35#include "VspTree.h"
36#include "KdTree.h"
37#include "BvHierarchy.h"
38#include "HierarchyManager.h"
39
40
41namespace GtpVisibilityPreprocessor {
42
43
44// ---------------------------------------------------------------------------
45//  Local data
46//
47//  doNamespaces
48//      Indicates whether namespace processing should be enabled or not.
49//      The default is no, but -n overrides that.
50//
51//  doSchema
52//      Indicates whether schema processing should be enabled or not.
53//      The default is no, but -s overrides that.
54//
55//  schemaFullChecking
56//      Indicates whether full schema constraint checking should be enabled or not.
57//      The default is no, but -s overrides that.
58//
59//  valScheme
60//      Indicates what validation scheme to use. It defaults to 'auto', but
61//      can be set via the -v= command.
62// ---------------------------------------------------------------------------
63static bool     doNamespaces       = false;
64static bool     doSchema           = false;
65static bool     schemaFullChecking = false;
66static SAXParser::ValSchemes    valScheme       = SAXParser::Val_Auto;
67
68// hack for loading bvh nodes
69#define PVS_HACK 0
70
71inline static bool ilt(Intersectable *obj1, Intersectable *obj2)
72{
73        return obj1->mId < obj2->mId;
74}
75
76
77// ---------------------------------------------------------------------------
78//  StdInParseHandlers: Constructors and Destructor
79// ---------------------------------------------------------------------------
80ViewCellsParseHandlers::ViewCellsParseHandlers(ObjectContainer &pvsObjects,
81                                                                                           ObjectContainer &preprocessorObjects,
82                                                                                           BoundingBoxConverter *bconverter
83                                                                                           ):
84  mElementCount(0)
85  , mAttrCount(0)
86  , mCharacterCount(0)
87  , mSpaceCount(0)
88  , mViewCellsManager(NULL)
89  , mVspBspTree(NULL)
90  , mBspTree(NULL)
91  , mViewCellsTree(NULL)
92  , mCurrentState(PARSE_OPTIONS)
93  , mCurrentViewCell(NULL)
94  , mCurrentBspNode(NULL)
95  , mCurrentVspNode(NULL)
96  , mCurrentOspNode(NULL)
97  , mCurrentBvhNode(NULL)
98  , mPvsObjects(pvsObjects)
99  , mPreprocessorObjects(preprocessorObjects)
100  , mBoundingBoxConverter(bconverter)
101  , mHierarchyManager(NULL)
102  , nViewCells(0)
103  , nObjects(0)
104{
105        // pvs objects empty => have to create new ones
106        mCreatePvsObjects = mPvsObjects.empty();
107
108        // sort objects so we can search in them
109        //if (!is_sorted(mPvsObjects.begin(), mPvsObjects.end(), ilt))
110                sort(mPvsObjects.begin(), mPvsObjects.end(), ilt);
111
112        //if (!is_sorted(mPreprocessorObjects.begin(), mPreprocessorObjects.end(), ilt))
113                sort(mPreprocessorObjects.begin(), mPreprocessorObjects.end(), ilt);
114}
115
116
117ViewCellsParseHandlers::~ViewCellsParseHandlers()
118{
119}
120
121
122// ---------------------------------------------------------------------------
123//  StdInParseHandlers: Implementation of the SAX DocumentHandler interface
124// ---------------------------------------------------------------------------
125
126
127void ViewCellsParseHandlers::endElement(const XMLCh* const name)
128{
129        StrX lname(name);
130        string element(lname.LocalForm());
131
132        if (element == "BoundingBoxes")
133        {
134                EndBoundingBoxes();
135        }
136
137        if (element == "ViewCells")
138        {       
139                EndViewCells();
140        }
141
142        if (element == "ObjectSpaceHierarchy")
143        {
144                EndObjectSpaceHierarchy();
145        }
146
147        // finished, create view cells manager
148        if (element == "VisibilitySolution")
149        {
150                CreateViewCellsManager();
151        }
152
153        if (element == "Interior")
154        {
155                switch (mCurrentState)
156                {
157                case PARSE_VIEWCELLS:
158                        EndViewCellInterior();
159                        break;
160                case PARSE_OBJECTSPACE_HIERARCHY:
161                        EndObjectSpaceHierarchyInterior();
162                        break;
163                case PARSE_VIEWSPACE_HIERARCHY:
164                        EndViewSpaceHierarchyInterior();
165                        break;
166                default:
167                        break;
168                }
169        }
170}
171
172
173void ViewCellsParseHandlers::EndObjectSpaceHierarchy()
174{
175        if (mObjectSpaceHierarchyType == OSP)
176        {
177                // for a spatial subdivision, it is not necessary to store
178                // the objects with the leaves, they can be classified geometrically
179                mHierarchyManager->mOspTree->
180                        InsertObjects(mHierarchyManager->mOspTree->mRoot, mPvsObjects);
181        }
182}
183
184
185void ViewCellsParseHandlers::EndViewSpaceHierarchyInterior()
186{
187        switch (mViewSpaceHierarchyType)
188        {
189        case BSP:
190                EndBspInterior();
191                break;
192        case VSP:
193                EndVspInterior();
194                break; 
195        default:
196                Debug << "not implemented view space hierarchy type " << mViewSpaceHierarchyType << endl;
197                break;
198        }
199}
200
201
202void ViewCellsParseHandlers::EndObjectSpaceHierarchyInterior()
203{
204        switch (mObjectSpaceHierarchyType)
205        {
206        case OSP:
207                EndOspInterior();
208                break;
209        case BVH:
210                EndBvhInterior();
211                break; 
212        default:
213                Debug << "not implemented object space hierarchy type " << mViewSpaceHierarchyType << endl;
214                break;
215        }
216}
217
218
219void ViewCellsParseHandlers::EndBspInterior()
220{
221        // go one up in the tree
222        if (mCurrentBspNode->GetParent())
223        {       //cout << "]";
224                mCurrentBspNode = mCurrentBspNode->GetParent();
225        }
226}
227
228
229void ViewCellsParseHandlers::EndBvhInterior()
230{
231        // go one up in the tree
232        if (mCurrentBvhNode->GetParent())
233        {       //cout << "]";
234                mCurrentBvhNode = mCurrentBvhNode->GetParent();
235        }
236}
237
238
239void ViewCellsParseHandlers::EndOspInterior()
240{
241        // go one up in the tree
242        if (mCurrentOspNode->mParent)
243        {       
244                //cout << "]";
245                mCurrentOspNode = mCurrentOspNode->mParent;
246        }
247}
248
249
250void ViewCellsParseHandlers::EndVspInterior()
251{
252        // go one up in the tree
253        if (mCurrentVspNode->GetParent())
254        {       
255                //cout << "]";
256                mCurrentVspNode = mCurrentVspNode->GetParent();
257        }
258}
259
260
261void ViewCellsParseHandlers::EndViewCellInterior()
262{
263        // go one up in the tree
264        if (mCurrentViewCell->GetParent())
265        {       
266                //cout << "]";
267                mCurrentViewCell = mCurrentViewCell->GetParent();
268        }
269}
270
271
272inline static bool vlt(ViewCell *v1, ViewCell *v2)
273{
274        return v1->mId < v2->mId;
275}
276
277
278void ViewCellsParseHandlers::EndViewCells()
279{
280        // sort view cells to help associating view cells according to their id
281        sort(mViewCells.begin(), mViewCells.end(), vlt);
282
283        // not parsing view cells anymore
284        mCurrentState = PARSE_OPTIONS;
285}
286
287
288void ViewCellsParseHandlers::EndBoundingBoxes()
289{
290        const long startTime = GetTime();
291       
292        if (mBoundingBoxConverter)
293        {
294                // all bounding boxes gathered in this step =>
295                // associate object ids with bounding boxes
296                mBoundingBoxConverter->IdentifyObjects(mIBoundingBoxes, mPvsObjects);
297        }
298
299        Debug << "\nconverted bounding boxes to objects in "
300                  << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
301}
302
303
304void ViewCellsParseHandlers::StartBspElement(string element,
305                                                                                         AttributeList& attributes)
306{
307        if (element == "Interior")
308        {
309                //cout << "[";
310                StartBspInterior(attributes);
311        }
312
313        if (element == "Leaf")
314        {
315                //cout << "l";
316                StartBspLeaf(attributes);
317        }
318}
319
320
321void ViewCellsParseHandlers::StartVspElement(string element,
322                                                                                         AttributeList& attributes)
323{
324        if (element == "Interior")
325        {
326                //cout << "[";
327                StartVspInterior(attributes);
328        }
329        if (element == "Leaf")
330        {
331                //cout << "l";
332                StartVspLeaf(attributes);
333        }
334}
335
336
337void ViewCellsParseHandlers::StartOspElement(string element,
338                                                                                         AttributeList& attributes)
339{
340        if (element == "Interior")
341        {
342                //cout << "[";
343                StartOspInterior(attributes);
344        }
345
346        if (element == "Leaf")
347        {
348                //cout << "l";
349                StartOspLeaf(attributes);
350        }
351}
352
353
354void ViewCellsParseHandlers::StartBvhElement(string element,
355                                                                                         AttributeList& attributes)
356{
357        if (element == "Interior")
358        {
359                //cout << "[";
360                StartBvhInterior(attributes);
361        }
362
363        if (element == "Leaf")
364        {
365                //cout << "l";
366                StartBvhLeaf(attributes);
367        }
368}
369
370
371void ViewCellsParseHandlers::StartViewSpaceHierarchyElement(const std::string &element,
372                                                                                                                        AttributeList& attributes)
373{
374        //-- use cell type according to the chosen method
375        switch (mViewSpaceHierarchyType)
376        {
377        case BSP:
378                StartBspElement(element, attributes);
379                break;
380        case VSP:
381                StartVspElement(element, attributes);
382                break;
383        default:
384                Debug << "not implemented" << endl;
385                break;
386        }
387}
388
389
390void ViewCellsParseHandlers::StartObjectSpaceHierarchyElement(const std::string &element,
391                                                                                                                          AttributeList& attributes)
392{
393        //-- use cell type according to the chosen method
394        switch (mObjectSpaceHierarchyType)
395        {
396                case OSP:
397                        StartOspElement(element, attributes);
398                        break;
399                case BVH:
400                        StartBvhElement(element, attributes);
401                        break;
402                default:
403                        Debug << "not implemented" << endl;
404                        break;
405        }
406}
407
408
409void ViewCellsParseHandlers::ReplaceBvhPvs(ViewCell *vc)
410{
411        //cout << "exchanging pvs" << endl;
412        ObjectPvs newPvs;
413
414        ObjectPvsIterator pit = vc->GetPvs().GetIterator();
415
416        BvhLeaf *dummyInst = new BvhLeaf(AxisAlignedBox3());
417
418        ObjectContainer oldIntersectables;
419
420        // output PVS of view cell
421        while (pit.HasMoreEntries())
422        {               
423                ObjectPvsEntry entry = pit.Next();
424
425                Intersectable *intersect = entry.mObject;
426                oldIntersectables.push_back(intersect);
427
428                DummyIntersectable *dummyIntersect = static_cast<DummyIntersectable *>(intersect);
429
430                const int objId = dummyIntersect->GetItem();   
431                dummyInst->SetId(objId);
432
433                vector<BvhLeaf *>::iterator oit =
434                        lower_bound(mBvhLeaves.begin(),
435                                                mBvhLeaves.end(),
436                                                dummyInst, ilt);       
437
438                if ((oit != mBvhLeaves.end()) && ((*oit)->GetId() == objId))
439                {
440                        // $$JB we should store a float a per object which corresponds
441                        // to sumof pdfs, i.e. its relative visibility
442                        // temporarily set to 1.0f
443                        //cout << (*oit)->GetId() << " ";
444                       
445                        newPvs.AddSample(*oit, 1.0f);
446                }
447                else
448                {
449                        Debug << "exchangePvs error: object with id " << objId << " does not exist" << endl;
450                }
451        }
452
453        //newPvs.SimpleSort();
454        delete dummyInst;
455        vc->SetPvs(newPvs);
456
457        CLEAR_CONTAINER(oldIntersectables);
458}
459
460
461void ViewCellsParseHandlers::ReplacePvs()
462{
463        // sort the pvs entries
464        sort(mPvsObjects.begin(), mPvsObjects.end(), ilt);
465
466        ViewCellContainer::const_iterator vit, vit_end = mViewCells.end();
467       
468        //cout << "viewcells : " << mViewCells.size() << endl;
469        for (vit = mViewCells.begin(); vit != vit_end; ++ vit)
470        {
471                ReplaceBvhPvs(*vit);
472        }
473}
474
475
476void ViewCellsParseHandlers::StartViewCellHierarchyElement(const std::string &element,
477                                                                                                                   AttributeList& attributes)
478{
479        // interiors + leaves interpreted view cells else
480        if (element == "Interior")
481        {
482                //cout << "[";
483                StartViewCell(attributes, false);
484        }
485
486        if (element == "Leaf")
487        {
488                //cout << "l";
489                StartViewCell(attributes, true);
490        }
491}
492
493
494void ViewCellsParseHandlers::startElement(const XMLCh* const name,
495                                                                                  AttributeList& attributes)
496{
497        StrX lname(name);
498        string element(lname.LocalForm());
499
500        if (element == "ViewCells")
501        {
502                cout << "\nparsing view cells" << endl;
503                Debug << "\nparsing view cells" << endl;
504               
505                mCurrentState = PARSE_VIEWCELLS;
506
507                // create new view cells hierarchy
508                mViewCellsTree = new ViewCellsTree();
509        }
510
511        // decides about the view cell hierarchy
512        if (element == "ViewSpaceHierarchy")
513        {               
514                Debug << "\nparsing view space hierarchy" << endl;
515                cout << "\nparsing view space hierarchy" << endl;
516                mCurrentState = PARSE_VIEWSPACE_HIERARCHY;
517                StartViewSpaceHierarchy(attributes);
518        }
519
520        // decides about the view cell hierarchy
521        if (element == "ObjectSpaceHierarchy")
522        {
523                cout << "\nparsing object space hierarchy" << endl;
524                Debug << "\nparsing object space hierarchy" << endl;
525
526                mCurrentState = PARSE_OBJECTSPACE_HIERARCHY;
527                StartObjectSpaceHierarchy(attributes);
528        }
529       
530        // decides the used view cell hierarchy
531        if (element == "BoundingBox")
532        {
533                // cout << "b";
534                StartBoundingBox(attributes);
535        }
536
537        // parse view space hierarchy
538        switch (mCurrentState)
539        {
540        case PARSE_VIEWSPACE_HIERARCHY:
541                if ((++ nViewCells % 1000) == 0)
542                        cout<<"\r"<<nViewCells<<" view cells parsed\r";
543               
544                StartViewSpaceHierarchyElement(element, attributes);
545                break;
546        case PARSE_OBJECTSPACE_HIERARCHY:
547                if ((++ nObjects % 1000) == 0)
548                 cout<<"\r"<< nObjects <<" objects parsed\r";
549               
550                StartObjectSpaceHierarchyElement(element, attributes);
551                break;
552        case PARSE_VIEWCELLS:
553                StartViewCellHierarchyElement(element, attributes);
554                break;
555        default:
556                break;
557        }
558       
559        ++ mElementCount;
560        mAttrCount += attributes.getLength();
561}
562
563
564void ViewCellsParseHandlers::StartViewCellPvs(ObjectPvs &pvs, const char *ptr)
565{
566        // handle obect indices
567        vector<int> objIndices;
568        char *endptr;
569                       
570        while (1)
571        {       // read object ids
572                const int index = strtol(ptr, &endptr, 10);
573                if (ptr == endptr)
574                        break;
575                objIndices.push_back(index);
576                ptr = endptr;
577        }
578
579        // TODO:
580        // 1) find objects and add them to pvs
581        // 2) get view cell with specified id
582        MeshInstance dummyInst(NULL);
583
584        vector<int>::const_iterator it, it_end = objIndices.end();
585        for (it = objIndices.begin(); it != it_end; ++ it)
586        {
587                if (mCreatePvsObjects)
588                {
589                        // pvs entries will be created => just use dummy proxy
590                        pvs.AddSample(new DummyIntersectable(*it), 1);
591                }
592                else
593                {
594                        const int objId = *it; 
595                        dummyInst.SetId(objId);
596
597                        ObjectContainer::iterator oit =
598                                                                lower_bound(mPvsObjects.begin(),
599                                                                                        mPvsObjects.end(),
600                                                                                        (Intersectable *)&dummyInst, ilt);     
601
602                        if ((oit != mPvsObjects.end()) && ((*oit)->GetId() == objId))
603                        {
604                                // $$JB we should store a float a per object which corresponds
605                                // to sumof pdfs, i.e. its relative visibility
606                                // temporarily set to 1.0f
607                                pvs.AddSample(*oit, 1.0f);
608                        }
609                        else
610                        {
611                                //Debug << "x";
612                                //Debug << "StartViewCellPvs error: object with id " << objId << " does not exist" << endl;
613                        }
614                }
615        }
616}
617
618
619void ViewCellsParseHandlers::StartViewSpaceHierarchy(AttributeList& attributes)
620{
621        int len = attributes.getLength();
622
623        Vector3 bmin, bmax;
624
625        for (int i = 0; i < len; ++ i)
626        {
627                string attrName(StrX(attributes.getName(i)).LocalForm());
628                StrX attrValue(attributes.getValue(i));
629                const char *ptr = attrValue.LocalForm();
630
631                // hierarchy type
632                if (attrName == "type")
633                {
634                        if (strcmp(ptr, "bsp") == 0)
635                        {
636                                Debug << "\nview space hierarchy: Bsp" << endl;
637                                mViewSpaceHierarchyType = BSP;
638                        }
639                        else if (strcmp(ptr, "vsp") == 0)
640                        {
641                                Debug << "\nview space hierarchy: Vsp" << endl;
642                                mViewSpaceHierarchyType = VSP;
643                        }
644                }
645                else if (attrName == "min") // the view space extent
646                {
647                        sscanf(ptr, "%f %f %f",
648                                   &bmin.x, &bmin.y, &bmin.z);
649                }
650                else if (attrName == "max")
651                {
652                        sscanf(ptr, "%f %f %f",
653                                   &bmax.x, &bmax.y, &bmax.z);
654                }
655        }
656
657        mViewSpaceBox = AxisAlignedBox3(bmin, bmax);
658
659        // create the hierarchy based on this information
660        CreateViewSpaceHierarchy();
661}
662
663
664void ViewCellsParseHandlers::StartObjectSpaceHierarchy(AttributeList& attributes)
665{
666        const int len = attributes.getLength();
667        Vector3 bmin, bmax;
668
669        for (int i = 0; i < len; ++ i)
670        {
671                string attrName(StrX(attributes.getName(i)).LocalForm());
672                StrX attrValue(attributes.getValue(i));
673                const char *ptr = attrValue.LocalForm();
674
675                // hierarchy type
676                if (attrName == "type")
677                {
678                        if (strcmp(ptr, "osp") == 0)
679                        {
680                                Debug << "\nobject space hierarchy: Osp" << endl;
681
682                                mHierarchyManager =
683                                        new HierarchyManager(HierarchyManager::KD_BASED_OBJ_SUBDIV);
684
685                                DEL_PTR(mHierarchyManager->mVspTree);
686                                mHierarchyManager->mVspTree = mVspTree;
687
688                                mObjectSpaceHierarchyType = OSP;
689
690                                //std::stable_sort(objects.begin(), objects.end(), ilt);
691                                mHierarchyManager->mOspTree->mBoundingBox.Initialize();
692                                ObjectContainer::const_iterator oit, oit_end = mPvsObjects.end();
693                               
694                                //-- compute bounding box
695                                for (oit = mPvsObjects.begin(); oit != oit_end; ++ oit)
696                                {
697                                        Intersectable *obj = *oit;
698                                        // compute bounding box of view space
699                                        mHierarchyManager->mOspTree->mBoundingBox.Include(obj->GetBox());
700                                }
701                        }
702                        else if (strcmp(ptr, "bvh") == 0)
703                        {
704                                Debug << "\nobject space hierarchy: Bvh" << endl;
705                                mObjectSpaceHierarchyType = BVH;
706                                mHierarchyManager =
707                                        new HierarchyManager(HierarchyManager::BV_BASED_OBJ_SUBDIV);
708
709                                DEL_PTR(mHierarchyManager->mVspTree);
710                                mHierarchyManager->mVspTree = mVspTree;
711                        }
712                }
713        }
714}
715
716
717void ViewCellsParseHandlers::StartBoundingBox(AttributeList& attributes)
718{
719        int len = attributes.getLength();
720
721        Vector3 bmin, bmax;
722        int id;
723
724        for (int i = 0; i < len; ++ i)
725        {
726                string attrName(StrX(attributes.getName(i)).LocalForm());
727                StrX attrValue(attributes.getValue(i));
728                const char *ptr = attrValue.LocalForm();
729
730                if (attrName == "id")
731                {
732                        sscanf(ptr, "%d", &id);
733                }
734                if (attrName == "min")
735                {
736                        sscanf(ptr, "%f %f %f", &bmin.x, &bmin.y, &bmin.z);
737                }
738                else if (attrName == "max")
739                {
740                        sscanf(ptr, "%f %f %f", &bmax.x, &bmax.y, &bmax.z);
741                }
742        }
743
744        AxisAlignedBox3 box(bmin, bmax);
745        mIBoundingBoxes.push_back(IndexedBoundingBox(id, box));
746        //Debug << "bbox: " << box << endl;
747}
748
749
750void ViewCellsParseHandlers::StartBspLeaf(AttributeList& attributes)
751{
752        BspLeaf * leaf;
753
754        if (mCurrentBspNode) // replace front or (if not NULL) back child
755        {
756                BspInterior *interior = static_cast<BspInterior *>(mCurrentBspNode);
757
758                leaf = new BspLeaf(interior);
759                interior->ReplaceChildLink(NULL, leaf);
760        }
761        else
762        {
763                leaf = new BspLeaf();
764                mVspBspTree->mRoot = leaf;
765        }
766
767        ///////////
768        //-- find associated view cell
769
770        int viewCellId;
771        const int len = attributes.getLength();
772         
773        for (int i = 0; i < len; ++ i)
774        {
775                string attrName(StrX(attributes.getName(i)).LocalForm());
776                StrX attrValue(attributes.getValue(i));
777
778                const char *ptr = attrValue.LocalForm();
779                char *endptr = NULL;
780
781                if (attrName == "viewCellId")
782                {
783                        viewCellId = strtol(ptr, &endptr, 10);
784                }
785        }
786       
787        if (viewCellId >= 0) // valid view cell found
788        {
789                // TODO: get view cell with specified id
790                ViewCellInterior dummyVc;
791                dummyVc.SetId(viewCellId);
792
793                ViewCellContainer::iterator vit =
794                        lower_bound(mViewCells.begin(), mViewCells.end(), &dummyVc, vlt);
795               
796                //ViewCellsMap::iterator vit = mViewCells.find(viewCellId);
797//              BspViewCell *viewCell = static_cast<BspViewCell *>((*vit).second);
798
799                BspViewCell *viewCell = static_cast<BspViewCell *>(*vit);
800                if (viewCell->GetId() == viewCellId)
801                {
802                        // create new view cell for bsp nodes
803                        leaf->SetViewCell(viewCell);
804                        viewCell->mLeaves.push_back(leaf);
805                }
806                else
807                {
808                        cerr << "error: view cell does not exist" << endl;
809                }
810        }
811        else
812        {
813                // add to invalid view space
814                leaf->SetViewCell(mVspBspTree->GetOrCreateOutOfBoundsCell());
815                leaf->SetTreeValid(false);
816                mVspBspTree->PropagateUpValidity(leaf);
817        }
818}
819
820
821void ViewCellsParseHandlers::StartBspInterior(AttributeList& attributes)
822{
823        Plane3 plane;
824        int len = attributes.getLength();
825
826        for (int i = 0; i < len; ++ i)
827        {
828                string attrName(StrX(attributes.getName(i)).LocalForm());
829                StrX attrValue(attributes.getValue(i));
830                const char *ptr = attrValue.LocalForm();
831
832                if (attrName == "plane")
833                {
834                        sscanf(ptr, "%f %f %f %f",
835                                   &plane.mNormal.x, &plane.mNormal.y, &plane.mNormal.z, &plane.mD);
836                }
837        }
838
839        BspInterior* interior = new BspInterior(plane);
840       
841        if (mCurrentBspNode) // replace NULL child of parent with current node
842        {
843                BspInterior *parent = static_cast<BspInterior *>(mCurrentBspNode);
844
845                parent->ReplaceChildLink(NULL, interior);
846                interior->SetParent(parent);
847        }
848        else
849        {
850                mVspBspTree->mRoot = interior;
851        }
852
853        mCurrentBspNode = interior;
854}
855
856
857void ViewCellsParseHandlers::StartViewCell(AttributeList& attributes, const bool isLeaf)
858{
859        ViewCell *viewCell = NULL;
860       
861        const int len = attributes.getLength();
862        float mergeCost;
863       
864        if (isLeaf)
865        {
866                viewCell = new ViewCellLeaf();
867        }
868        else
869        {
870                viewCell = new ViewCellInterior();
871        }
872
873        for (int i = 0; i < len; ++ i)
874        {
875                const string attrName(StrX(attributes.getName(i)).LocalForm());
876       
877                if (attrName == "id")
878                {
879                        const StrX attrValue(attributes.getValue(i));
880                        const char *ptr = attrValue.LocalForm();
881                        char *endptr = NULL;
882                        const int id = strtol(ptr, &endptr, 10);
883
884                        // create new view cell, otherwise use reference.
885                        viewCell->SetId(id);
886
887                        if (mCurrentViewCell) // replace front or (if not NULL) back child
888                        {       
889                                ViewCellInterior *interior =
890                                        static_cast<ViewCellInterior *>(mCurrentViewCell);
891                                interior->SetupChildLink(viewCell);
892                        }
893                        else
894                        {       // set the new root
895                                mViewCellsTree->SetRoot(viewCell);
896                        }
897                       
898                        if (!isLeaf)
899                        {
900                                mCurrentViewCell = viewCell;
901                        }
902                }
903                if (attrName == "pvs")
904                {
905                        StrX attrValue(attributes.getValue(i));
906                        const char *ptr = attrValue.LocalForm();
907
908                        // note: id must come before pvs!
909                        // otherwise view cell is undefined
910
911                        // hack: assume that view cell comes before pvs
912                        StartViewCellPvs(viewCell->GetPvs(), ptr);
913                        //StartViewCellPvs(pvs, ptr);
914                }
915                else if (attrName == "active")
916                {
917                        StrX attrValue(attributes.getValue(i));
918                        const char *ptr = attrValue.LocalForm();
919                        char *endptr = NULL;
920                        const bool isActive = (bool)strtol(ptr, &endptr, 10);
921
922                        if (isActive)
923                        {
924                                // TODO
925                        }
926                }
927                else if (attrName == "mergecost")
928                {
929                        StrX attrValue(attributes.getValue(i));
930                       
931                        const char *ptr = attrValue.LocalForm();
932                        char *endptr = NULL;
933                        mergeCost = (float)strtod(ptr, &endptr);
934                }
935        }
936
937        viewCell->SetMergeCost(mergeCost);
938        //viewCell->SetPvs(pvs);
939        mViewCells.push_back(viewCell);
940}
941
942
943void ViewCellsParseHandlers::CreateViewSpaceHierarchy()
944{
945        if (mViewSpaceHierarchyType == BSP)
946        {
947                Debug << "hierarchy type: Bsp" << endl;
948                mVspBspTree = new VspBspTree();
949
950                // set view space box
951                mVspBspTree->mBoundingBox = mViewSpaceBox;
952
953                //ViewCellsMap::iterator vit, vit_end = mViewCells.end();
954                ViewCellContainer::iterator vit, vit_end = mViewCells.end();
955
956                int i = 0;
957                // remove view cells and exchange them with the
958                // view cells specialized for the current hierarchy node type
959                for (vit = mViewCells.begin(); vit != vit_end; ++ vit, ++ i)
960                {
961                        //if ((i % 1000) == 0)
962                        //      Debug << "\n exchanged " << i << " boxes" << endl;
963                        ViewCell *vc = (*vit);
964
965                        if (!vc->IsLeaf()) // exchange only leaves
966                                continue;
967               
968                        BspViewCell *bspVc = new BspViewCell();
969
970                        bspVc->SetId(vc->GetId());
971                        //bspVc->GetPvs().reserve(vc->GetPvs().size());
972                        bspVc->SetPvs(vc->GetPvs());
973
974                        if (vc->IsRoot())
975                        {
976                                mViewCellsTree->mRoot = bspVc;
977                        }
978                        else
979                        {
980                vc->GetParent()->ReplaceChildLink(vc, bspVc);
981                        }
982
983                        // delete old view cell
984                        DEL_PTR(vc);
985
986//                      (*vit).second = bspVc;
987                        (*vit) = bspVc;
988                }
989                cout << "finished creating view space hierarchy" << endl;
990        }
991        else if (mViewSpaceHierarchyType == VSP)
992        {
993                Debug << "hierarchy type: Vsp" << endl;
994                mVspTree = new VspTree();
995
996                // set view space box
997                mVspTree->mBoundingBox = mViewSpaceBox;
998
999                // ViewCellsMap::iterator vit, vit_end = mViewCells.end();
1000                ViewCellContainer::iterator vit, vit_end = mViewCells.end();
1001
1002                // reset view cells using the current node type
1003                for (vit = mViewCells.begin(); vit != vit_end; ++ vit)
1004                {
1005                        //ViewCell *vc = (*vit).second;
1006                        ViewCell *vc = (*vit);
1007                       
1008                        if (!vc->IsLeaf()) // exchange only leaves
1009                                continue;
1010
1011                        VspViewCell *vspVc = new VspViewCell();
1012
1013                        vspVc->SetPvs(vc->GetPvs());
1014                        vspVc->SetId(vc->GetId());
1015
1016                        if (vc->IsRoot())
1017                        {
1018                                mViewCellsTree->mRoot = vspVc;
1019                        }
1020                        else
1021                        {
1022                                vc->GetParent()->ReplaceChildLink(vc, vspVc);
1023                        }
1024                       
1025                        // exchange view cell with new one
1026                        DEL_PTR(vc);
1027
1028                        //(*vit).second = vspVc;
1029                        (*vit) = vspVc;
1030                }
1031
1032                if (mHierarchyManager)
1033                {
1034                        // come here only if object space hierarchy already constructed
1035                        mHierarchyManager->mVspTree = mVspTree;
1036                        mVspTree->mHierarchyManager = mHierarchyManager;
1037                }
1038        }
1039}
1040
1041
1042void ViewCellsParseHandlers::CreateViewCellsManager()
1043{
1044        if (mViewSpaceHierarchyType == BSP)
1045        {
1046                Debug << "\ncreating view cells manager: VspBsp" << endl;
1047                mViewCellsManager = new VspBspViewCellsManager(mViewCellsTree, mVspBspTree);
1048        }
1049        else if (mViewSpaceHierarchyType == VSP)
1050        {
1051                Debug << "\ncreating view cells manager: VspOsp" << endl;
1052                mViewCellsManager = new VspOspViewCellsManager(mViewCellsTree, mHierarchyManager);
1053        }
1054
1055        mViewCellsManager->SetViewSpaceBox(mViewSpaceBox);
1056}
1057
1058
1059void ViewCellsParseHandlers::characters(const XMLCh* const chars,
1060                                                                                const unsigned int length)
1061{
1062        mCharacterCount += length;
1063}
1064
1065
1066void ViewCellsParseHandlers::ignorableWhitespace(const XMLCh* const chars,
1067                                                                                                 const unsigned int length)
1068{
1069        mSpaceCount += length;
1070}
1071
1072
1073void ViewCellsParseHandlers::resetDocument()
1074{
1075        mAttrCount = 0;
1076        mCharacterCount = 0;
1077        mElementCount = 0;
1078        mSpaceCount = 0;
1079}
1080
1081
1082void ViewCellsParseHandlers::StartVspLeaf(AttributeList& attributes)
1083{
1084        VspLeaf * leaf;
1085               
1086        if (mCurrentVspNode) // replace front or (if not NULL) back child
1087        {
1088                VspInterior *interior = static_cast<VspInterior *>(mCurrentVspNode);
1089                leaf = new VspLeaf(interior);
1090                interior->ReplaceChildLink(NULL, leaf);
1091        }
1092        else
1093        {
1094                leaf = new VspLeaf();
1095                mVspTree->mRoot = leaf;
1096        }
1097
1098        /////////////
1099        //-- find view cell associated with the id
1100
1101        int viewCellId;
1102        const int len = attributes.getLength();
1103         
1104        for (int i = 0; i < len; ++ i)
1105        {
1106                string attrName(StrX(attributes.getName(i)).LocalForm());
1107                StrX attrValue(attributes.getValue(i));
1108
1109                const char *ptr = attrValue.LocalForm();
1110                char *endptr = NULL;
1111
1112                if (attrName == "viewCellId")
1113                {
1114                        viewCellId = strtol(ptr, &endptr, 10);
1115                }
1116        }
1117       
1118        if (viewCellId >= 0) // valid view cell found
1119        {
1120                // TODO: get view cell with specified id
1121                ViewCellInterior dummyVc;
1122                dummyVc.SetId(viewCellId);
1123
1124                ViewCellContainer::iterator vit =
1125                        lower_bound(mViewCells.begin(), mViewCells.end(), &dummyVc, vlt);
1126               
1127                //ViewCellsMap::iterator vit = mViewCells.find(viewCellId);
1128                if (vit == mViewCells.end())
1129                        Debug << "error: view cell " << viewCellId << " not found" << endl;
1130       
1131                //VspViewCell *viewCell = static_cast<VspViewCell *>((*vit).second);
1132                VspViewCell *viewCell = static_cast<VspViewCell *>(*vit);
1133               
1134                if (viewCell->GetId() == viewCellId)
1135                {
1136                        leaf->SetViewCell(viewCell);
1137                        viewCell->mLeaves.push_back(leaf);
1138                }
1139                else
1140                {
1141                        Debug << "error: view cell does not exist" << endl;
1142                }
1143        }
1144        else
1145        {       
1146                // add to invalid view space
1147                leaf->SetViewCell(mVspTree->GetOrCreateOutOfBoundsCell());
1148                leaf->SetTreeValid(false);
1149                mVspTree->PropagateUpValidity(leaf);
1150        }
1151}
1152
1153
1154void ViewCellsParseHandlers::StartVspInterior(AttributeList& attributes)
1155{
1156        AxisAlignedPlane plane;
1157        const int len = attributes.getLength();
1158
1159        for (int i = 0; i < len; ++ i)
1160        {
1161                string attrName(StrX(attributes.getName(i)).LocalForm());
1162                StrX attrValue(attributes.getValue(i));
1163                const char *ptr = attrValue.LocalForm();
1164
1165                if (attrName == "plane")
1166                {
1167                        sscanf(ptr, "%f %d", &plane.mPosition, &plane.mAxis);
1168                }
1169        }
1170
1171        VspInterior* interior = new VspInterior(plane);
1172       
1173        if (mCurrentVspNode) // replace NULL child of parent with current node
1174        {
1175                VspInterior *parent = static_cast<VspInterior *>(mCurrentVspNode);
1176
1177                parent->ReplaceChildLink(NULL, interior);
1178                interior->SetParent(parent);
1179               
1180                AxisAlignedBox3 frontBox, backBox;
1181
1182                parent->GetBoundingBox().Split(
1183                        parent->GetPlane().mAxis,
1184                        parent->GetPlane().mPosition,
1185                        frontBox,
1186                        backBox);
1187
1188                if (parent->GetFront() == interior)
1189                        interior->SetBoundingBox(frontBox);
1190                else
1191                        interior->SetBoundingBox(backBox);
1192        }
1193        else
1194        {
1195                mVspTree->mRoot = interior;
1196                interior->SetBoundingBox(mVspTree->GetBoundingBox());
1197        }
1198
1199        mCurrentVspNode = interior;
1200}
1201
1202
1203void ViewCellsParseHandlers::StartOspInterior(AttributeList& attributes)
1204{
1205        AxisAlignedPlane plane;
1206        int len = attributes.getLength();
1207
1208        for (int i = 0; i < len; ++ i)
1209        {
1210                string attrName(StrX(attributes.getName(i)).LocalForm());
1211                StrX attrValue(attributes.getValue(i));
1212                const char *ptr = attrValue.LocalForm();
1213
1214                if (attrName == "plane")
1215                {
1216                        sscanf(ptr, "%f %d", &plane.mPosition, &plane.mAxis);
1217                }
1218        }
1219
1220        KdInterior* interior = new KdInterior(NULL);
1221       
1222        interior->mAxis = plane.mAxis;
1223        interior->mPosition = plane.mPosition;
1224
1225        if (mCurrentOspNode) // replace NULL child of parent with current node
1226        {
1227                KdInterior *parent = static_cast<KdInterior *>(mCurrentOspNode);
1228                parent->ReplaceChildLink(NULL, interior);
1229                interior->mParent = parent;
1230
1231                AxisAlignedBox3 frontBox, backBox;
1232
1233                parent->mBox.Split(parent->mAxis, parent->mPosition, frontBox, backBox);
1234
1235                if (parent->mFront == interior)
1236                        interior->mBox = frontBox;
1237                else
1238                        interior->mBox = backBox;
1239        }
1240        else
1241        {
1242                mHierarchyManager->mOspTree->mRoot = interior;
1243                interior->mBox = mHierarchyManager->mOspTree->mBoundingBox;
1244        }
1245
1246        mCurrentOspNode = interior;
1247}
1248
1249
1250void ViewCellsParseHandlers::StartOspLeaf(AttributeList& attributes)
1251{
1252        KdLeaf * leaf = new KdLeaf(static_cast<KdInterior *>(mCurrentOspNode), NULL);
1253
1254        if (mCurrentOspNode)
1255        {
1256                 // replace front or (if not NULL) back child
1257                static_cast<KdInterior *>(mCurrentOspNode)->ReplaceChildLink(NULL, leaf);
1258        }
1259        else
1260        {
1261                mHierarchyManager->mOspTree->mRoot = leaf;
1262        }
1263}
1264
1265
1266void ViewCellsParseHandlers::StartBvhLeaf(AttributeList& attributes)
1267{
1268        const int len = attributes.getLength();
1269        Vector3 minBox, maxBox;
1270
1271        ObjectContainer objects;
1272
1273        for (int i = 0; i < len; ++ i)
1274        {
1275                string attrName(StrX(attributes.getName(i)).LocalForm());
1276                StrX attrValue(attributes.getValue(i));
1277                const char *ptr = attrValue.LocalForm();
1278
1279                if (attrName == "min")
1280                {
1281                        sscanf(ptr, "%f %f %f", &minBox.x, &minBox.y, &minBox.z);
1282                }
1283                if (attrName == "max")
1284                {
1285                        sscanf(ptr, "%f %f %f", &maxBox.x, &maxBox.y, &maxBox.z);
1286                }
1287                if (attrName == "objects")
1288                {
1289                        StartBvhLeafObjects(objects, ptr);
1290                }
1291        }
1292
1293        AxisAlignedBox3 box = AxisAlignedBox3(minBox, maxBox);
1294
1295        BvhLeaf *leaf;
1296
1297        if (mCurrentBvhNode) // replace front or (if not NULL) back child
1298        {
1299                BvhInterior *interior = static_cast<BvhInterior *>(mCurrentBvhNode);
1300                leaf = new BvhLeaf(box, interior, (int)objects.size());
1301                interior->ReplaceChildLink(NULL, leaf);
1302        }
1303        else
1304        {
1305                leaf = new BvhLeaf(box, NULL, (int)objects.size());
1306                mHierarchyManager->mBvHierarchy->mRoot = leaf;
1307        }
1308
1309        leaf->mObjects = objects;
1310        BvHierarchy::AssociateObjectsWithLeaf(leaf);
1311       
1312        if (mCreatePvsObjects)
1313        {
1314                // Temp matt: leaves should already have right id
1315                if (0) leaf->SetId((int)mBvhLeaves.size());
1316               
1317                mPvsObjects.push_back(leaf);   
1318        }
1319}
1320
1321
1322void ViewCellsParseHandlers::StartBvhLeafObjects(ObjectContainer &objects,
1323                                                                                                 const char *ptr)
1324{
1325        vector<int> objIndices;
1326        char *endptr;
1327                       
1328        while (1)
1329        {
1330                const int index = strtol(ptr, &endptr, 10);
1331                if (ptr == endptr) break;
1332
1333                objIndices.push_back(index);
1334                ptr = endptr;
1335        }
1336
1337        MeshInstance dummyInst(NULL);
1338
1339        vector<int>::const_iterator it, it_end = objIndices.end();
1340
1341        for (it = objIndices.begin(); it != it_end; ++ it)
1342        {
1343                const int objId = *it; 
1344                dummyInst.SetId(objId);
1345
1346                ObjectContainer::iterator oit =
1347                        lower_bound(mPvsObjects.begin(),
1348                                                mPvsObjects.end(),
1349                                                (Intersectable *)&dummyInst,
1350                                                ilt);   
1351                                                       
1352                if ((oit != mPvsObjects.end()) && ((*oit)->GetId() == objId))
1353                {
1354                        objects.push_back(*oit);
1355                        Debug << "x";
1356                }
1357                else
1358                {
1359                        Debug << "y";
1360                        //cerr << "StartBvhLeafObjects error: object with id " << objId << " does not exist" << endl;
1361                }
1362        }
1363}
1364
1365
1366void ViewCellsParseHandlers::StartBvhInterior(AttributeList& attributes)
1367{
1368        const int len = attributes.getLength();
1369        Vector3 minBox, maxBox;
1370
1371        for (int i = 0; i < len; ++ i)
1372        {
1373                string attrName(StrX(attributes.getName(i)).LocalForm());
1374                StrX attrValue(attributes.getValue(i));
1375                const char *ptr = attrValue.LocalForm();
1376
1377                if (attrName == "min")
1378                {
1379                        sscanf(ptr, "%f %f %f", &minBox.x, &minBox.y, &minBox.z);
1380                }
1381                if (attrName == "max")
1382                {
1383                        sscanf(ptr, "%f %f %f", &maxBox.x, &maxBox.y, &maxBox.z);
1384                }
1385        }
1386
1387        BvhInterior* interior = new BvhInterior(AxisAlignedBox3(minBox, maxBox));
1388
1389        if (mCurrentBvhNode) // replace NULL child of parent with current node
1390        {
1391                BvhInterior *parent = static_cast<BvhInterior *>(mCurrentBvhNode);
1392                parent->ReplaceChildLink(NULL, interior);
1393                interior->SetParent(parent);
1394        }
1395        else
1396        {
1397                mHierarchyManager->mBvHierarchy->mRoot = interior;
1398        }
1399
1400        mCurrentBvhNode = interior;
1401}
1402
1403
1404// ---------------------------------------------------------------------------
1405//  StdInParseHandlers: Overrides of the SAX ErrorHandler interface
1406// ---------------------------------------------------------------------------
1407
1408
1409void
1410ViewCellsParseHandlers::error(const SAXParseException& e)
1411{
1412  XERCES_STD_QUALIFIER cerr << "\nError at (file " << StrX(e.getSystemId())
1413                            << ", line " << e.getLineNumber()
1414                            << ", char " << e.getColumnNumber()
1415                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1416}
1417
1418void
1419ViewCellsParseHandlers::fatalError(const SAXParseException& e)
1420{
1421  XERCES_STD_QUALIFIER cerr << "\nFatal Error at (file " << StrX(e.getSystemId())
1422                            << ", line " << e.getLineNumber()
1423                            << ", char " << e.getColumnNumber()
1424                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1425}
1426
1427void
1428ViewCellsParseHandlers::warning(const SAXParseException& e)
1429{
1430  XERCES_STD_QUALIFIER cerr << "\nWarning at (file " << StrX(e.getSystemId())
1431                            << ", line " << e.getLineNumber()
1432                            << ", char " << e.getColumnNumber()
1433                            << "): " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl;
1434}
1435
1436
1437bool ViewCellsParser::ParseViewCellsFile(const string &filename,
1438                                                                                 ViewCellsManager **viewCells,
1439                                                                                 ObjectContainer &pvsObjects,
1440                                                                                 ObjectContainer &preprocessorObjects,
1441                                                                                 BoundingBoxConverter *bconverter)
1442{
1443        // Initialize the XML4C system
1444        try {
1445                XMLPlatformUtils::Initialize();
1446        }
1447
1448        catch (const XMLException& toCatch)
1449        {
1450                XERCES_STD_QUALIFIER cerr << "Error during initialization! Message:\n"
1451                        << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl;
1452                return false;
1453        }
1454
1455        //  cout<<"parsing started"<<endl<<flush;
1456
1457        //
1458        //  Create a SAX parser object. Then, according to what we were told on
1459        //  the command line, set the options.
1460        //
1461        SAXParser* parser = new SAXParser;
1462        parser->setValidationScheme(valScheme);
1463        parser->setDoNamespaces(doNamespaces);
1464        parser->setDoSchema(doSchema);
1465        parser->setValidationSchemaFullChecking(schemaFullChecking);
1466
1467
1468        //
1469        //  Create our SAX handler object and install it on the parser, as the
1470        //  document and error handler. We are responsible for cleaning them
1471        //  up, but since its just stack based here, there's nothing special
1472        //  to do.
1473        //
1474        ViewCellsParseHandlers handler(pvsObjects, preprocessorObjects, bconverter);
1475        parser->setDocumentHandler(&handler);
1476        parser->setErrorHandler(&handler);
1477
1478        unsigned long duration;
1479        int errorCount = 0;
1480        // create a faux scope so that 'src' destructor is called before
1481        // XMLPlatformUtils::Terminate
1482        {
1483                //
1484                //  Kick off the parse and catch any exceptions. Create a standard
1485                //  input input source and tell the parser to parse from that.
1486                //
1487                //    StdInInputSource src;
1488                try
1489                {
1490                        const unsigned long startMillis = XMLPlatformUtils::getCurrentMillis();
1491
1492#if USE_GZLIB
1493                        XMLCh *myFilePath = XMLString::transcode(filename.c_str());
1494
1495                        GzFileInputSource isource(myFilePath);
1496                        parser->parse(isource);
1497#else
1498                        parser->parse(filename.c_str());
1499
1500#endif
1501
1502                        //if (mCreatePvsObjects)
1503                        //      handler.ReplacePvs();
1504
1505                        const unsigned long endMillis = XMLPlatformUtils::getCurrentMillis();
1506                        duration = endMillis - startMillis;
1507                        errorCount = parser->getErrorCount();
1508                }
1509                catch (const OutOfMemoryException&)
1510                {
1511                        XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
1512                        errorCount = 2;
1513                        return false;
1514                }
1515                catch (const XMLException& e)
1516                {
1517                        XERCES_STD_QUALIFIER cerr << "\nError during parsing: \n"
1518                                << StrX(e.getMessage())
1519                                << "\n" << XERCES_STD_QUALIFIER endl;
1520                        errorCount = 1;
1521                        return false;
1522                }
1523
1524
1525                // Print out the stats that we collected and time taken
1526                if (!errorCount)
1527                {
1528                        XERCES_STD_QUALIFIER cerr << filename << ": " << duration << " ms ("
1529                                << handler.GetElementCount() << " elems, "
1530                                << handler.GetAttrCount() << " attrs, "
1531                                << handler.GetSpaceCount() << " spaces, "
1532                                << handler.GetCharacterCount() << " chars)" << XERCES_STD_QUALIFIER endl;
1533                }
1534        }
1535
1536        cout<<"parsed - will delete the parser"<<endl<<flush;
1537        //
1538        //  Delete the parser itself.  Must be done prior to calling Terminate, below.
1539        //
1540        delete parser;
1541
1542        XMLPlatformUtils::Terminate();
1543
1544        //-- assign new view cells manager
1545        *viewCells = handler.mViewCellsManager;
1546
1547        if (errorCount > 0)
1548                return false;
1549        else
1550                return true;
1551}
1552
1553}
Note: See TracBrowser for help on using the repository browser.