1 #ifndef boxm2_scene_h_ 2 #define boxm2_scene_h_ 3 //: 4 // \file 5 // \brief Boxm2 Scene models a very generic scene, only specifies dimensions 6 // \author Andrew Miller 7 // \date 26 Oct 2010 8 // 9 #include <iostream> 10 #include <iosfwd> 11 #include <vector> 12 #include <string> 13 #include <cassert> 14 #include <boxm2/basic/boxm2_block_id.h> 15 #include <boxm2/boxm2_block_metadata.h> 16 #include <vpgl/vpgl_lvcs.h> 17 #include <vgl/vgl_point_3d.h> 18 #include <vgl/vgl_box_3d.h> 19 #include <vgl/vgl_box_2d.h> 20 #ifdef _MSC_VER 21 # include <vcl_msvc_warnings.h> 22 #endif 23 #include <vul/vul_file.h> 24 25 //smart pointer stuff 26 #include <vbl/vbl_ref_count.h> 27 #include <vbl/vbl_smart_ptr.h> 28 29 //vpgl camera 30 #include <vpgl/vpgl_generic_camera.h> 31 #include <vpgl/vpgl_perspective_camera.h> 32 #include <vpgl/vpgl_affine_camera.h> 33 34 35 //: block info that can be easily made into a buffer and sent to gpu 36 struct boxm2_scene_info 37 { 38 //world information 39 float scene_origin[4]; // scene origin (point) 40 int scene_dims[4]; // number of blocks in each dimension 41 float block_len; // size of each block (can only be 1 number now that we've established blocks are cubes) 42 float epsilon; // block_len/100.0 (placed here to avoid using a register) 43 float pinit; 44 // tree meta information 45 int root_level; // root_level of trees 46 int num_buffer; // number of buffers (both data and tree) 47 int tree_buffer_length; // length of tree buffer (number of cells/trees) 48 int data_buffer_length; // length of data buffer (number of cells) 49 }; 50 51 class boxm2_scene_info_wrapper : public vbl_ref_count 52 { 53 public: 54 boxm2_scene_info * info; 55 }; 56 //Smart_Pointer typedef for boxm2_scene 57 class boxm2_scene; 58 typedef vbl_smart_ptr<boxm2_scene> boxm2_scene_sptr; 59 typedef vbl_smart_ptr<boxm2_scene_info_wrapper> boxm2_scene_info_wrapper_sptr; 60 61 //: boxm2_scene: simple scene model that maintains (in world coordinates) 62 // - scene origin 63 // - number of blocks in each dimension 64 // - size of each block in each dimension 65 // - lvcs information 66 // - xml path on disk and data path (directory) on disk 67 class boxm2_scene : public vbl_ref_count 68 { 69 public: 70 //: empty scene, needs to be initialized manually boxm2_scene()71 boxm2_scene() {boxm2_scene::get_count()++;} 72 73 boxm2_scene(std::string const& data_path, vgl_point_3d<double> const& origin, int version = 2); 74 75 //: create a scene with a single block 76 // scene_dir - path to scene directory 77 // scene_name - path to xml file is scene_dir + scene_name.xml 78 // data_path - binary data is stored in scene_dir + data_path 79 // prefixes - the set of prefix strings defining the databases stored in the model(appearances) 80 // scene_box - the 3-d bounding box for the scene in global coordinates 81 // sub_block_len - the length of the octree block (sub_block) assumed to be a cube 82 // init/max level - the number of levels in the refined tree 83 // max_mb - the maximum storage for a block (not typically used) 84 // p_init - the initial probability of surface occupancy 85 // n_illum_bins - number of illumination bins 86 // version - scene format version 87 boxm2_scene(std::string const& scene_dir, std::string const& scene_name, std::string const& data_path, std::vector<std::string> const& prefixes, 88 vgl_box_3d<double> const& scene_box, double sub_block_len, int init_level = 1, 89 int max_level = 4, double max_mb=1200, double p_init=0.001, int n_illum_bins = 1, int version = 2); 90 91 //: initializes the scene from the buffer that loaded an XML file in. 92 // this is added for decoupling from the local filesystem to load the scene 93 boxm2_scene(const char* buffer); 94 95 //: initializes scene from xmlFile 96 boxm2_scene(std::string const& filename); 97 98 //: copy constructor 99 boxm2_scene(boxm2_scene const& other_scene); 100 101 //: destructor 102 ~boxm2_scene() override = default; 103 104 //:create an in-memory copy of the scene with unique id 105 boxm2_scene_sptr clone_no_disk(); 106 107 //: save scene xml file 108 void save_scene(); 109 110 //: return a vector of block ids in visibility order 111 std::vector<boxm2_block_id> get_vis_blocks(vpgl_generic_camera<double>* cam, double dist = -1.0); 112 std::vector<boxm2_block_id> get_vis_blocks(vpgl_perspective_camera<double>* cam, double dist = -1.0); 113 std::vector<boxm2_block_id> get_vis_blocks(vpgl_affine_camera<double>* cam); 114 std::vector<boxm2_block_id> get_vis_blocks(vpgl_camera_double_sptr & cam, double dist = -1.0) { 115 if ( cam->type_name() == "vpgl_generic_camera" ) 116 return this->get_vis_blocks( (vpgl_generic_camera<double>*) cam.ptr(), dist ); 117 else if ( cam->type_name() == "vpgl_perspective_camera" ) 118 return this->get_vis_blocks( (vpgl_perspective_camera<double>*) cam.ptr(), dist ); 119 else if ( cam->type_name() == "vpgl_affine_camera" ) 120 return this->get_vis_blocks( (vpgl_affine_camera<double>*) cam.ptr() ); 121 else 122 std::cout<<"boxm2_scene::get_vis_blocks doesn't support camera type "<<cam->type_name()<<std::endl; 123 //else return empty 124 std::vector<boxm2_block_id> empty; 125 return empty; 126 } 127 //: visibility order from point, blocks must intersect with cam box 128 std::vector<boxm2_block_id> 129 get_vis_order_from_pt(vgl_point_3d<double> const& pt, 130 vgl_box_2d<double> camBox = vgl_box_2d<double>(), double distance=-1.0); 131 std::vector<boxm2_block_id> get_vis_blocks_opt(vpgl_perspective_camera<double>* cam, unsigned int ni, unsigned int nj); 132 //: visibility order using a ray given by origin and direction vector, the block needs to be in the front direction as given by this ray 133 std::vector<boxm2_block_id> 134 get_vis_order_from_ray(vgl_point_3d<double> const& origin, vgl_vector_3d<double> const& dir, double distance); 135 136 //: return all blocks with center less than dist from the given point 137 std::vector<boxm2_block_id> get_vis_blocks(vgl_point_3d<double> const& pt, double dist); 138 139 //: return a heap pointer to a scene info 140 boxm2_scene_info* get_blk_metadata(boxm2_block_id const& id); block_exists(boxm2_block_id const & id)141 bool block_exists(boxm2_block_id const& id) const { return blocks_.find(id) != blocks_.end(); } block_on_disk(boxm2_block_id const & id)142 bool block_on_disk(boxm2_block_id const& id) const { return vul_file::exists( data_path_ + id.to_string() + ".bin"); } data_on_disk(boxm2_block_id const & id,std::string const & data_type)143 bool data_on_disk(boxm2_block_id const& id, std::string const& data_type) { 144 return vul_file::exists(data_path_ + data_type + "_" + id.to_string() + ".bin"); 145 } 146 147 //: a list of block metadata... blocks()148 std::map<boxm2_block_id, boxm2_block_metadata>& blocks() { return blocks_; } num_blocks()149 unsigned num_blocks() const { return (unsigned) blocks_.size(); } 150 151 float finest_resolution(); 152 //: mutable reference get_block_metadata(boxm2_block_id const & id)153 boxm2_block_metadata& get_block_metadata(boxm2_block_id const& id) 154 { 155 assert(blocks_.find(id) != blocks_.end()); 156 return blocks_[id]; 157 } 158 //: const so return a copy 159 boxm2_block_metadata get_block_metadata_const(boxm2_block_id const& id) const; 160 161 //: return number of trees in block num_trees_in_block(boxm2_block_id const & id)162 int num_trees_in_block(boxm2_block_id const& id) { 163 assert(blocks_.find(id) != blocks_.end()); 164 boxm2_block_metadata& d = blocks_[id]; 165 return d.sub_block_num_.x() * d.sub_block_num_.y() * d.sub_block_num_.z(); 166 } 167 168 std::vector<boxm2_block_id> get_block_ids() const; 169 170 //: gets a tight bounding box for the scene 171 vgl_box_3d<double> bounding_box() const; 172 //: gets a tight bounding box for the scene 173 vgl_box_3d<int> bounding_box_blk_ids() const; 174 175 //: gets the smallest block index in all dimensions 176 void min_block_index(vgl_point_3d<int> &idx, 177 vgl_point_3d<double> &local_origin) const; 178 //: gets max block index in all dims 179 void max_block_index(vgl_point_3d<int> &idx, 180 vgl_point_3d<double> &local_origin) const; 181 182 // returns the dimesnsion of the scene grid where each grid element is a block 183 vgl_vector_3d<unsigned int> scene_dimensions() const; 184 185 //: If a block contains a 3-d point, set the local coordinates of the point 186 bool block_contains(vgl_point_3d<double> const& p, boxm2_block_id const& bid, 187 vgl_point_3d<double>& local_coords) const; 188 189 //: If a scene contains a 3-d point, set the block id, else return false. The local coordinates of the point are also returned 190 bool contains(vgl_point_3d<double> const& p, boxm2_block_id& bid, 191 vgl_point_3d<double>& local_coords) const; 192 193 //: scene dimensions accessors local_origin()194 vgl_point_3d<double> local_origin()const { return local_origin_; } rpc_origin()195 vgl_point_3d<double> rpc_origin() const { return rpc_origin_; } lvcs()196 vpgl_lvcs lvcs() const { return lvcs_; } 197 198 //: scene path accessors xml_path()199 std::string xml_path() const { return xml_path_; } data_path()200 std::string data_path() const { return data_path_; } 201 202 //: appearance model accessor appearances()203 std::vector<std::string> appearances() const { return appearances_; } 204 bool has_data_type(std::string const& data_type); num_illumination_bins()205 int num_illumination_bins() const {return num_illumination_bins_;} 206 207 //: scene version number version()208 int version() const { return version_; } set_version(int v)209 void set_version(int v) { version_ = v; } 210 //: unique scene id id()211 unsigned id() const {return id_;} 212 //: scene mutators set_local_origin(vgl_point_3d<double> org)213 void set_local_origin(vgl_point_3d<double> org) { local_origin_ = org; } set_rpc_origin(vgl_point_3d<double> rpc)214 void set_rpc_origin(vgl_point_3d<double> rpc) { rpc_origin_ = rpc; } set_lvcs(vpgl_lvcs lvcs)215 void set_lvcs(vpgl_lvcs lvcs) { lvcs_ = lvcs; } set_blocks(std::map<boxm2_block_id,boxm2_block_metadata> blocks)216 void set_blocks(std::map<boxm2_block_id, boxm2_block_metadata> blocks) { blocks_ = blocks; } 217 void add_block_metadata(boxm2_block_metadata data); set_appearances(std::vector<std::string> const & appearances)218 void set_appearances(std::vector<std::string> const& appearances){ this->appearances_ = appearances; } set_num_illumination_bins(int num_bins)219 void set_num_illumination_bins(int num_bins) { this->num_illumination_bins_ = num_bins; } 220 221 //: scene path mutators set_xml_path(std::string const & path)222 void set_xml_path(std::string const& path) { xml_path_ = path; } set_data_path(std::string const & path)223 void set_data_path(std::string const& path) { data_path_ = path+"/"; } 224 225 private: 226 //: unique scene id 227 unsigned id_; 228 // count of constructed scenes to generate a unique id 229 static unsigned& get_count(); 230 //: world scene information 231 vpgl_lvcs lvcs_; 232 vgl_point_3d<double> local_origin_; 233 vgl_point_3d<double> rpc_origin_; 234 235 //: location on disk of xml file and data/block files 236 std::string data_path_, xml_path_; 237 238 //: list of block meta data available to this scene 239 std::map<boxm2_block_id, boxm2_block_metadata> blocks_; 240 241 //: list of appearance models/observation models used by this scene 242 std::vector<std::string> appearances_; 243 int num_illumination_bins_; 244 int version_; 245 246 bool is_block_visible(boxm2_block_metadata & data, vpgl_camera<double> const& cam, unsigned ni, unsigned nj ); 247 }; 248 249 250 //: utility class for sorting id's by their distance 251 class boxm2_dist_id_pair 252 { 253 public: boxm2_dist_id_pair(double dist,boxm2_block_id const & id)254 boxm2_dist_id_pair(double dist, boxm2_block_id const& id) : dist_(dist), id_(id) {} 255 double dist_; 256 boxm2_block_id id_; 257 258 inline bool operator < (boxm2_dist_id_pair const& v) const { 259 return dist_ < v.dist_; 260 } 261 }; 262 263 //: scene output stream operator 264 std::ostream& operator<<(std::ostream &s, boxm2_scene& scene); 265 266 //: scene xml write function 267 void x_write(std::ostream &os, boxm2_scene& scene, std::string const& name); 268 269 270 //--- IO read/write for sptrs-------------------------------------------------- 271 //: Binary write boxm2_scene scene to stream 272 void vsl_b_write(vsl_b_ostream& os, boxm2_scene const& scene); 273 void vsl_b_write(vsl_b_ostream& os, const boxm2_scene* &p); 274 void vsl_b_write(vsl_b_ostream& os, boxm2_scene_sptr& sptr); 275 void vsl_b_write(vsl_b_ostream& os, boxm2_scene_sptr const& sptr); 276 277 //: Binary load boxm2_scene scene from stream. 278 void vsl_b_read(vsl_b_istream& is, boxm2_scene &scene); 279 void vsl_b_read(vsl_b_istream& is, boxm2_scene* p); 280 void vsl_b_read(vsl_b_istream& is, boxm2_scene_sptr& sptr); 281 void vsl_b_read(vsl_b_istream& is, boxm2_scene_sptr const& sptr); 282 283 //: Binary write boxm2_scene scene to stream 284 void vsl_b_write(vsl_b_ostream& os, boxm2_scene_info_wrapper const& scene); 285 void vsl_b_write(vsl_b_ostream& os, const boxm2_scene_info_wrapper* &p); 286 void vsl_b_write(vsl_b_ostream& os, boxm2_scene_info_wrapper_sptr& sptr); 287 void vsl_b_write(vsl_b_ostream& os, boxm2_scene_info_wrapper_sptr const& sptr); 288 289 //: Binary load boxm2_scene scene from stream. 290 void vsl_b_read(vsl_b_istream& is, boxm2_scene_info_wrapper &scene); 291 void vsl_b_read(vsl_b_istream& is, boxm2_scene_info_wrapper* p); 292 void vsl_b_read(vsl_b_istream& is, boxm2_scene_info_wrapper_sptr& sptr); 293 void vsl_b_read(vsl_b_istream& is, boxm2_scene_info_wrapper_sptr const& sptr); 294 295 296 #endif // boxm2_scene_h_ 297