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

Revision 2005, 35.1 KB checked in by mattausch, 17 years ago (diff)

using large address space

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