inline bool operator== ( const BoundingBox3<Real>& box ) const
			{
				return ( box_min ( ) == box.box_min ( ) and box_max ( ) == box.box_max ( ) );
			}
Exemple #2
0
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);

}