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