1 #include "bstm_time_block.h"
2 #include <cassert>
3 #ifdef _MSC_VER
4 #  include "vcl_msvc_warnings.h"
5 #endif
6 //:
7 // \file
8 
bstm_time_block(const bstm_block_id & id,bstm_block_metadata data,char * buffer,std::size_t length)9 bstm_time_block::bstm_time_block(const bstm_block_id& id, bstm_block_metadata data, char* buffer, std::size_t length)
10 {
11   //data has already been read, save length
12   byte_count_ = length;
13   buffer_ = buffer;
14 
15   time_trees_ = boxm2_array_1d<uchar8>( length / sizeof(uchar8), (uchar8*) (buffer_));
16 
17   //this info is not so relevant (now) but save it anyway
18   init_level_t_ = data.init_level_t_;
19   max_level_t_  = data.max_level_t_;
20   sub_block_num_t_ = data.sub_block_num_t_;
21   block_id_ = id;
22 
23   read_only_ = false; // make sure that it is written back to disc
24 }
25 
bstm_time_block(const bstm_block_id & id,bstm_block_metadata data,unsigned num_el)26 bstm_time_block::bstm_time_block(const bstm_block_id& id, bstm_block_metadata data, unsigned num_el)
27 {
28   //this info is not so relevant (now) but save it anyway
29   init_level_t_ = data.init_level_t_;
30   max_level_t_  = data.max_level_t_;
31 
32   sub_block_num_t_ = data.sub_block_num_t_;
33   block_id_ = id;
34 
35   //create data based on num_el
36   byte_count_ = num_el * sizeof(uchar8) * sub_block_num_t_;
37   buffer_ = new char[num_el * sizeof(uchar8) * sub_block_num_t_ ];
38 
39   time_trees_ = boxm2_array_1d<uchar8>( byte_count_ / sizeof(uchar8), (uchar8*) (buffer_));
40   init_empty_block();
41 
42   read_only_ = false; // make sure that it is written back to disc
43 }
44 
45 
bstm_time_block(bstm_block_metadata data)46 bstm_time_block::bstm_time_block(bstm_block_metadata data)
47 {
48   init_level_t_ = data.init_level_t_;
49   max_level_t_  = data.max_level_t_;
50   sub_block_num_t_ = data.sub_block_num_t_;
51 
52   block_id_ = data.id_;
53 
54   byte_count_ = calc_byte_count(data);
55 
56   buffer_ = new char[byte_count_];
57   //setup big arrays (1d block of trees)
58   time_trees_     = boxm2_array_1d<uchar8>(byte_count_ / sizeof(uchar8) , (uchar8*) (buffer_));
59 
60   this->init_empty_block();
61   read_only_ = false;  // make sure that it is written back to disc
62 }
63 
64 
65 //: initializes empty scene
init_empty_block()66 bool bstm_time_block::init_empty_block()
67 {
68   //--- Now initialize blocks and their pointers --------- ---------------------
69   //6. initialize blocks in order
70   int tree_index = 0;
71   boxm2_array_1d<uchar8>::iterator iter;
72   for (iter = time_trees_.begin(); iter != time_trees_.end(); ++iter)
73   {
74     //initialize empty tree
75     uchar8 treeBlk( (unsigned char) 0 );
76 
77     //store root data index in bits [4,5,6,7];
78     treeBlk[4] = (tree_index) & 0xff;
79     treeBlk[5] = (tree_index>>8)  & 0xff;
80     treeBlk[6] = (tree_index>>16) & 0xff;
81     treeBlk[7] = (tree_index>>24) & 0xff;
82 
83     //Set Init_Level, 1=just root, 2=2 generations, 3=3 generations...etc.
84     if (init_level_t_== 1) {
85       treeBlk[0] = 0;
86       ++tree_index;
87     }
88     else if (init_level_t_== 6) {
89       for (int i=0; i<4; ++i)
90         treeBlk[i] = 0xff;
91       tree_index += 32;
92     }
93     else
94       std::cerr << "Init lvl " << init_level_t_ << " not supported. Only init level 1 or 6 is supported for time trees currently...\n";
95 
96     //store this tree in the buffer
97     for (int i=0; i<TT_NUM_BYTES; i++)
98       (*iter)[i] = treeBlk[i];
99   }
100   return true;
101 }
102 
103 //: given a data offset from bstm_block and a time instance, return the corresponding time tree
get_cell_tt(int cell_data_offset,double local_time)104 vnl_vector_fixed<unsigned char, 8>&  bstm_time_block::get_cell_tt(int cell_data_offset, double local_time)
105 {
106   unsigned index = tree_index(local_time);
107   return time_trees_[cell_data_offset*sub_block_num_t_ + index];
108 }
109 
set_cell_tt(int cell_data_offset,const uchar8 & input,double local_t)110 void  bstm_time_block::set_cell_tt(int cell_data_offset, const uchar8& input, double local_t)
111 {
112   unsigned index = tree_index(local_t);
113   time_trees_[cell_data_offset*sub_block_num_t_ + index] = input;
114 }
115 
get_cell_all_tt(int cell_data_offset)116 boxm2_array_1d<vnl_vector_fixed<unsigned char, 8> >  bstm_time_block::get_cell_all_tt(int cell_data_offset)
117 {
118   return boxm2_array_1d<vnl_vector_fixed<unsigned char, 8> > (sub_block_num_t_, &(time_trees_[cell_data_offset*sub_block_num_t_ ]));
119 }
120 
set_cell_all_tt(int cell_data_offset,const boxm2_array_1d<uchar8> & input)121 void bstm_time_block::set_cell_all_tt(int cell_data_offset, const boxm2_array_1d<uchar8>& input)
122 {
123   assert(input.size() == sub_block_num_t_);
124   for (unsigned i = 0; i < sub_block_num_t_; i++) //copy each tt
125     time_trees_[cell_data_offset*sub_block_num_t_ + i] = input[i];
126 }
127 
tree_index(double local_time)128 unsigned bstm_time_block::tree_index(double local_time)
129 {
130   //compute the index of the time tree that contains local_time
131   return (unsigned)std::floor(local_time);
132 }
133 
octree_num_cell_calc(bstm_block_metadata & data,long & num_cells)134 void bstm_time_block::octree_num_cell_calc(bstm_block_metadata& data, long& num_cells)
135 {
136   //determine number of cells to allocate - based on init_level
137   long init_cells_per_tree;
138 
139   if ( data.init_level_ == 1) {
140     init_cells_per_tree = 1;
141   }
142   else if ( data.init_level_ == 2) {
143     init_cells_per_tree = 1 + 8;
144   }
145   else if ( data.init_level_ == 3) {
146     init_cells_per_tree = 1 + 8 + 64;
147   }
148   else if ( data.init_level_ == 4) {
149     init_cells_per_tree = 1 + 8 + 64 + 512;
150   }
151   else
152     init_cells_per_tree = 0; // dummy setting, to avoid compiler warning
153 
154   //total number of cells = numTrees * init_cells_per_tree
155   num_cells = data.sub_block_num_.x() *
156               data.sub_block_num_.y() *
157               data.sub_block_num_.z() * init_cells_per_tree;
158 }
159 
160 
161 // \return size of byte stream
calc_byte_count(bstm_block_metadata & data)162 long bstm_time_block::calc_byte_count(bstm_block_metadata& data)
163 {
164   //get the number of octree cells expected in block
165   long num_octree_cells;
166   octree_num_cell_calc(data, num_octree_cells);
167 
168   return num_octree_cells * sub_block_num_t_ * sizeof(uchar8);
169 }
170 
171 
172 //------------ I/O -------------------------------------------------------------
operator <<(std::ostream & s,bstm_time_block & block)173 std::ostream& operator <<(std::ostream &s, bstm_time_block& block)
174 {
175   return
176   s << "Block ID=" << block.block_id() << '\n'
177     << "Byte Count=" << block.byte_count() << '\n'
178     << "Init level=" << block.init_level() << '\n'
179     << "Max level=" << block.max_level() << '\n'
180     << "Read only=" << block.read_only() << '\n'
181     << "Sub Block Num=" << block.sub_block_num()<< std::endl;
182 }
183 
184 //: Binary write bstm_time_block to stream.
185 // DUMMY IMPLEMENTATION: does nothing!
vsl_b_write(vsl_b_ostream &,bstm_time_block_sptr const &)186 void vsl_b_write(vsl_b_ostream&, bstm_time_block_sptr const&) {}
187 
188 //: Binary load bstm_time_block from stream.
189 // DUMMY IMPLEMENTATION: does nothing!
vsl_b_read(vsl_b_istream &,bstm_time_block_sptr &)190 void vsl_b_read(vsl_b_istream&, bstm_time_block_sptr&) {}
191 //: Binary load bstm_time_block from stream.
192 // DUMMY IMPLEMENTATION: does nothing!
vsl_b_read(vsl_b_istream &,bstm_time_block_sptr const &)193 void vsl_b_read(vsl_b_istream&, bstm_time_block_sptr const&) {}
194