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

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