inline bool operator== ( const BoundingBox3<Real>& box ) const { return ( box_min ( ) == box.box_min ( ) and box_max ( ) == box.box_max ( ) ); }
void bvh_stream:: read_bvh(const std::string& filename, bvh& bvh) { open_stream(filename, bvh_stream_type::BVH_STREAM_IN); if (type_ != BVH_STREAM_IN) { throw std::runtime_error( "PLOD: bvh_stream::Failed to read bvh from: " + filename_); } if (!file_.is_open()) { throw std::runtime_error( "PLOD: bvh_stream::Failed to read bvh from: " + filename_); } //scan stream file_.seekg(0, std::ios::end); size_t filesize = (size_t)file_.tellg(); file_.seekg(0, std::ios::beg); num_segments_ = 0; bvh_tree_seg tree; bvh_tree_extension_seg tree_ext; std::vector<bvh_node_seg> nodes; std::vector<bvh_node_extension_seg> nodes_ext; uint32_t tree_id = 0; uint32_t tree_ext_id = 0; uint32_t node_id = 0; uint32_t node_ext_id = 0; //go through entire stream and fetch the segments while (true) { bvh_sig sig; sig.deserialize(file_); if (sig.signature_[0] != 'B' || sig.signature_[1] != 'V' || sig.signature_[2] != 'H' || sig.signature_[3] != 'X') { throw std::runtime_error( "PLOD: bvh_stream::Invalid magic encountered: " + filename_); } size_t anchor = (size_t)file_.tellg(); switch (sig.signature_[4]) { case 'F': { //"BVHXFILE" bvh_file_seg seg; seg.deserialize(file_); break; } case 'T': { switch (sig.signature_[5]) { case 'R': { //"BVHXTREE" tree.deserialize(file_); ++tree_id; break; } case 'E': { //"BVHXTEXT" tree_ext.deserialize(file_); ++tree_ext_id; break; } default: { throw std::runtime_error( "PLOD: bvh_stream::Stream corrupt -- Invalid segment encountered"); break; } } break; } case 'N': { switch (sig.signature_[5]) { case 'O': { //"BVHXNODE" bvh_node_seg node; node.deserialize(file_); nodes.push_back(node); if (node_id != node.node_id_) { throw std::runtime_error( "PLOD: bvh_stream::Stream corrupt -- Invalid node order"); } ++node_id; break; } case 'E': { //"BVHXNEXT" bvh_node_extension_seg node_ext; node_ext.deserialize(file_); nodes_ext.push_back(node_ext); if (node_ext_id != node_ext.node_id_) { throw std::runtime_error( "PLOD: bvh_stream::Stream corrupt -- Invalid node extension order"); } ++node_ext_id; break; } default: { throw std::runtime_error( "PLOD: bvh_stream::Stream corrupt -- Invalid segment encountered"); break; } } break; } default: { throw std::runtime_error( "PLOD: bvh_stream::file corrupt -- Invalid segment encountered"); break; } } if (anchor + sig.allocated_size_ < filesize) { file_.seekg(anchor + sig.allocated_size_, std::ios::beg); } else { break; } } close_stream(false); if (tree_id != 1) { throw std::runtime_error( "PLOD: bvh_stream::Stream corrupt -- Invalid number of bvh segments"); } if (tree_ext_id > 1) { throw std::runtime_error( "PLOD: bvh_stream::Stream corrupt -- Invalid number of bvh extensions"); } //Note: This is the preprocessing library version of the file reader! //setup bvh bvh.set_depth(tree.depth_); bvh.set_fan_factor(tree.fan_factor_); bvh.set_max_surfels_per_node(tree.max_surfels_per_node_); scm::math::vec3f translation(tree.translation_.x_, tree.translation_.y_, tree.translation_.z_); bvh.set_translation(vec3r(translation)); if (tree.num_nodes_ != node_id) { throw std::runtime_error( "PLOD: bvh_stream::Stream corrupt -- Invalid number of node segments"); } if (tree_ext_id > 0) { if (tree.num_nodes_ != node_ext_id) { throw std::runtime_error( "PLOD: bvh_stream::Stream corrupt -- Invalid number of node extensions"); } } std::vector<shared_file> level_temp_files; bvh::state_type current_state = static_cast<bvh::state_type>(tree.state_); //check if intermediate state bool interm_state = current_state == bvh::state_type::after_downsweep || current_state == bvh::state_type::after_upsweep; boost::filesystem::path base_path; if (interm_state) { if (tree_ext_id != 1) { throw std::runtime_error( "PLOD: bvh_stream::Stream corrupt -- Stream is missing tree extension"); } //working_directory = tree_ext.working_directory_.string_; //basename_ = boost::filesystem::path(tree_ext.filename_.string_); base_path = boost::filesystem::path(tree_ext.filename_.string_); //setup level temp files for (uint32_t i = 0; i < tree_ext.num_disk_accesses_; ++i) { level_temp_files.push_back(std::make_shared<file>()); level_temp_files.back()->open(tree_ext.disk_accesses_[i].string_, false); } } else { base_path = boost::filesystem::canonical(boost::filesystem::path(filename)); base_path.replace_extension(""); } bvh.set_base_path(base_path); //setup nodes std::vector<bvh_node> bvh_nodes(tree.num_nodes_); for (uint32_t i = 0; i < tree.num_nodes_; ++i) { const auto& node = nodes[i]; if (i != node.node_id_) { throw std::runtime_error( "PLOD: bvh_stream::Stream corrupt -- Invalid node ordering"); } scm::math::vec3f centroid(node.centroid_.x_, node.centroid_.y_, node.centroid_.z_); scm::math::vec3f box_min(node.bounding_box_.min_.x_, node.bounding_box_.min_.y_, node.bounding_box_.min_.z_); scm::math::vec3f box_max(node.bounding_box_.max_.x_, node.bounding_box_.max_.y_, node.bounding_box_.max_.z_); if (interm_state) { const auto& node_ext = nodes_ext[i]; if (i != node_ext.node_id_) { throw std::runtime_error( "PLOD: bvh_stream::Stream corrupt -- Invalid extension ordering"); } if (node_ext.empty_ == 1) { bvh_nodes[i] = bvh_node(node.node_id_, node.depth_, bounding_box(vec3r(box_min), vec3r(box_max))); } else { const auto& disk_array = node_ext.disk_array_; surfel_disk_array sdarray = surfel_disk_array(level_temp_files[disk_array.disk_access_ref_], disk_array.offset_, disk_array.length_); bvh_nodes[i] = bvh_node(node.node_id_, node.depth_, bounding_box(vec3r(box_min), vec3r(box_max)), sdarray); } } else { //init empty nodes. We don't use surfelDIskArray //because we deal with serialized data bvh_nodes[i] = bvh_node(node.node_id_, node.depth_, bounding_box(vec3r(box_min), vec3r(box_max))); } //set node params bvh_nodes[i].set_reduction_error(node.reduction_error_); bvh_nodes[i].set_centroid(vec3r(centroid)); bvh_nodes[i].set_avg_surfel_radius(node.avg_surfel_radius_); bvh_nodes[i].set_visibility((bvh_node::node_visibility)node.visibility_); bvh_nodes[i].set_max_surfel_radius_deviation(node.max_surfel_radius_deviation_); } bvh.set_first_leaf(tree.num_nodes_ - std::pow(tree.fan_factor_, tree.depth_)); bvh.set_state(current_state); bvh.set_nodes(bvh_nodes); }