Subversion Repositories spk

Rev

Blame | Last modification | View Log | RSS feed

#ifndef NEW_POINT_MAP_INCLUDED
#define NEW_POINT_MAP_INCLUDED

#include "../common/ext_array.h"
#include "../common/ext_simple_list.h"

#include "../common/ext_patricia_trie.h"

class point_traits
{
        public:
                static const size_t element_bits=32;
                
                static size_t size(const int *key) { return 3; }
                static bool compare(const int *k1, const int *k2) 
                { 
                        if(k1==0 || k2==0) 
                                return false;
                        else
                                return 
                        k1[0]==k2[0] &&
                        k1[1]==k2[1] &&
                        k1[2]==k2[2];
                }
                
                static int * copy(const int *key) { return (int*)key; }
                static void free(int *key) { }
};

class bob_point_map
{
        private:
                class vertex_bucket;
                class bucket_allocator;
                typedef ext::array<bob_vertex*> vertex_array;
                typedef ext::array<int> int_array;
                typedef ext::simple_list<int> int_list;
                typedef ext::patricia_trie<int, vertex_bucket, point_traits, bucket_allocator> vertex_trie;

                vertex_trie m_trie;
                vertex_array m_points; // all points
                int_array m_indexes; // converted indexes
                int m_pointSize; // size of points

                int_list m_uniqueIndexes; // list of indexes to unique points in points array
                int_list::iterator m_unique_it;

        private:
                class vertex_bucket 
                {
                        private:
                                int m_index;
                        public:
                                int index() const { return m_index; }
                                void index(int i) { m_index=i; }
                                
                                vertex_bucket() { m_index=0; }
                };
                
                class bucket_allocator
                {
                        public:
                                static void deallocate(vertex_bucket pb) {  }
                };


        public:
                typedef vertex_array::iterator iterator;
                typedef vertex_array::const_iterator const_iterator;
                typedef int_list::const_iterator const_index_iterator;

                iterator begin() { return m_points.begin(); }
                iterator end() { return m_points.end(); }

                const_iterator begin() const { return m_points.begin(); }
                const_iterator end() const { return m_points.end(); }

                const_index_iterator indexBegin() const { return m_uniqueIndexes.begin(); }
                const_index_iterator indexEnd() const { return m_uniqueIndexes.end(); }

                size_t m_compCount;

                void create(size_t size)
                {
                        m_points.resize(size, 0);
                        m_indexes.resize(size);
                        m_pointSize=0;
                        m_compCount=0;
                }

                void addPoint(bob_vertex * pnt)
                {
                        vertex_bucket pb;
                        
                        const int *coords=pnt->getCoordArray();
                        
                        vertex_trie::iterator where=m_trie.find(coords);
                        if(where==m_trie.end()) {
                                pb.index((int)m_uniqueIndexes.size());
                                m_uniqueIndexes.push_back(m_pointSize);
                                
                                m_trie.insert(vertex_trie::value_type(coords, pb));
                        }
                        else
                                pb=(*where).second;

                        m_points[m_pointSize]=pnt;
                        m_indexes[m_pointSize]=pb.index();
                        m_pointSize++;
                        
                }

                bob_point_map() { m_pointSize=0; m_unique_it=m_uniqueIndexes.end(); }
                ~bob_point_map() { clear(); }

                void clear()
                {
                        m_trie.clear();

                        for(vertex_array::iterator &it=m_points.begin(); it!=m_points.end(); ++it){
                                delete *it;
                        }
                        m_points.clear();
                        m_indexes.clear();
                        m_pointSize=0;

                        m_unique_it=m_uniqueIndexes.end();
                }

                bob_vertex * operator[](int idx) { return m_points[idx]; }
                const bob_vertex * operator[](int idx) const { return m_points[idx]; }

                int uniqueIndex(int idx) const { return (size_t)idx < m_points.size() ? m_indexes[idx] : -1; }

                size_t pointsSize() const { return m_points.size(); }
                size_t uniquePointsSize() const { return m_uniqueIndexes.size(); }

                bob_vertex * nextUniquePoint()
                {
                        ++m_unique_it;
                        bob_vertex *p=(m_unique_it!=m_uniqueIndexes.end() ? m_points[*m_unique_it] : 0);
                        return p;
                }
                
                void test_trie_clear() { m_trie.test_clear(); }
                
};

#endif // !defined(NEW_POINT_MAP_INCLUDED)