예제 #1
0
INLINE void
mem_incr(struct svalue *var)
{
    switch(var->type)
    {
    case T_FUNCTION:
	function_size += sizeof (struct closure);
	num_func++;
	if (var->u.func->funargs)
	    mem_array(var->u.func->funargs);
	break;
    case T_MAPPING:
	mapping_elem += var->u.map->size;
	num_map++;
	mem_mapping(var->u.map);
	break;
    case T_POINTER:
	array_elem += var->u.vec->size;
	num_arr++;
	mem_array(var->u.vec);
	break;
    case T_STRING:
	string_size += strlen(var->u.string);
	num_string++;
	break;
    case T_OBJECT:
	/* Check for destructed objects while we'r at it :) */
	if (var->u.ob->flags & O_DESTRUCTED)
	{
	    num_num++;
	    free_svalue(var);
	    break;
	}
	num_ob++;
	break;
    case T_FLOAT:
	num_float++;
	break;
    case T_NUMBER:
	num_num++;
	break;
    default:
	;
    }
}
예제 #2
0
surfel_mem_array reduction_entropy::
create_lod(real& reduction_error,
          const std::vector<surfel_mem_array*>& input,
          const uint32_t surfels_per_node,
          const bvh& tree,
          const size_t start_node_id) const {

    //create output array
    surfel_mem_array mem_array(std::make_shared<surfel_vector>(surfel_vector()), 0, 0);

    //container for all input surfels including entropy (entropy_surfel_array = ESA)
    shared_entropy_surfel_vector entropy_surfel_array;
    //priority queue as vector with min entropy surfels at the back
    shared_entropy_surfel_vector min_entropy_surfel_ptr_queue;

    //final surfels
    shared_entropy_surfel_vector finalized_surfels;

    // wrap all surfels of the input array to entropy_surfels and push them in the ESA
    for (size_t node_id = 0; node_id < input.size(); ++node_id) {
        for (size_t surfel_id = input[node_id]->offset();
                    surfel_id < input[node_id]->offset() + input[node_id]->length();
                    ++surfel_id){
            
            //this surfel will be referenced in the entropy surfel
            auto current_surfel = input[node_id]->mem_data()->at(input[node_id]->offset() + surfel_id);
            
            // ignore outlier radii of any kind
            if (current_surfel.radius() == 0.0) {
                continue;
            } 
            //create new entropy surfel
            entropy_surfel current_entropy_surfel(current_surfel, surfel_id, node_id);

        // only place where shared pointers should be created
        entropy_surfel_array.push_back( std::make_shared<entropy_surfel>(current_entropy_surfel) );
       }
    }   

    // iterate all wrapped surfels 
    for ( auto& current_entropy_surfel_ptr : entropy_surfel_array ){

        shared_entropy_surfel_vector overlapping_neighbour_ptrs 
            = get_locally_overlapping_neighbours(current_entropy_surfel_ptr, entropy_surfel_array);

        //assign/compute missing attributes
        current_entropy_surfel_ptr->neighbours = overlapping_neighbour_ptrs;
        update_entropy( current_entropy_surfel_ptr, overlapping_neighbour_ptrs);

        //if overlapping neighbours were found, put the entropy surfel back into the priority_queue
        if( !overlapping_neighbour_ptrs.empty() ) {
            min_entropy_surfel_ptr_queue.push_back( current_entropy_surfel_ptr );
        } else { //otherwise, consider this surfel to be finalized
            //std::cout << "**Pushing into finalized surfels (size so far: "<<finalized_surfels.size() << "): " << (int)current_entropy_surfel_ptr->contained_surfel->color()[0] << "\n";
            finalized_surfels.push_back( current_entropy_surfel_ptr );
            //std::cout << "did not find any Neighbours!!!!\n";
            //std::cout << current_entropy_surfel_ptr->contained_surfel->pos() << " -- " << current_entropy_surfel_ptr->contained_surfel->radius() << " ------\n";
        }
    }

    // the queue was modified, therefore it is resorted
    std::sort(min_entropy_surfel_ptr_queue.begin(), min_entropy_surfel_ptr_queue.end(), min_entropy_order());

    size_t num_valid_surfels = min_entropy_surfel_ptr_queue.size() + finalized_surfels.size();


    while(true) {

        if( !min_entropy_surfel_ptr_queue.empty() ){
            shared_entropy_surfel current_entropy_surfel = min_entropy_surfel_ptr_queue.back();
            
            min_entropy_surfel_ptr_queue.pop_back();

            //the back element is still valid, so we still got something to do
            if(current_entropy_surfel->validity){
                //std::cout << "Working on the surfel\n";
                // if merge returns true, the surfel still has neighbours

                
                if( merge(current_entropy_surfel, entropy_surfel_array, num_valid_surfels, surfels_per_node) ) {
                    min_entropy_surfel_ptr_queue.push_back(current_entropy_surfel);
                    /*min_entropy_surfel_ptr_queue.insert(min_entropy_surfel_ptr_queue.end(),
                                                        finalized_surfels.begin(),
                                                        finalized_surfels.end());
                    */
                    //finalized_surfels.clear();

                } else { //otherwise we can push it directly into the finalized surfel list
                    finalized_surfels.push_back(current_entropy_surfel);
                }


                std::sort(min_entropy_surfel_ptr_queue.begin(), min_entropy_surfel_ptr_queue.end(), min_entropy_order());


                if(num_valid_surfels <= surfels_per_node) {
                    break;
                } else {
                    //break
                }
            }    

        } else {
            break;
        }

    }


    // put valid surfels into final array

    //end of entropy simplification
    while( (!min_entropy_surfel_ptr_queue.empty()) ) {
        shared_entropy_surfel en_surfel_to_push = min_entropy_surfel_ptr_queue.back();

        if(en_surfel_to_push->validity == true) {
            finalized_surfels.push_back(en_surfel_to_push);
        }
        
        min_entropy_surfel_ptr_queue.pop_back();
    }


    std::sort(finalized_surfels.begin(), finalized_surfels.end(), min_entropy_order());

    while( num_valid_surfels > surfels_per_node ) {
        auto const& min_entropy_surfel = finalized_surfels.back();

        if(min_entropy_surfel->validity) {
            --num_valid_surfels;
        }

        finalized_surfels.pop_back();
    }

    size_t chosen_surfels = 0;
    for(auto const& en_surf : finalized_surfels) {

        if(en_surf->validity) {
            if(chosen_surfels++ < surfels_per_node) {
                mem_array.mem_data()->push_back(*(en_surf->contained_surfel));
            } else {   
                break;
            }
        }
    }

    mem_array.set_length(mem_array.mem_data()->size());
    reduction_error = 0.0;

    return mem_array;
};
surfel_mem_array reduction_spatially_subdivided_random::
create_lod(real& reduction_error,
          const std::vector<surfel_mem_array*>& input,
          const uint32_t surfels_per_node,
          const bvh& tree,
          const size_t start_node_id) const
{
    surfel_mem_array mem_array(std::make_shared<surfel_vector>(surfel_vector()), 0, 0);

    std::vector<surfel> already_picked_surfel;
    std::vector<surfel> original_surfels;


    auto const& tree_nodes = tree.nodes();
    auto combined_bounding_box = tree_nodes[start_node_id].get_bounding_box();

    for( uint8_t non_first_child_ids = 1; 
         non_first_child_ids < tree.fan_factor(); 
         ++non_first_child_ids) {

        auto const& sibling_bb = tree_nodes[start_node_id + non_first_child_ids].get_bounding_box();
        combined_bounding_box.expand( sibling_bb.max() );
        combined_bounding_box.expand( sibling_bb.min() );
    }


    uint32_t const num_divisions_for_shortest_axis = 8;

    vec3r step_length(-1.0, -1.0, -1.0);

    uint8_t shortest_axis = -1;
    real min_length = std::numeric_limits<real>::max();

    vec3r axis_lengths = combined_bounding_box.max() - combined_bounding_box.min();

    for( uint8_t axis_idx = 0; axis_idx < 3; ++axis_idx ) {
        if( axis_lengths[axis_idx] < min_length ) {
            min_length = axis_lengths[axis_idx];
            shortest_axis = axis_idx;
        }
    }

    step_length[shortest_axis] = axis_lengths[shortest_axis] / num_divisions_for_shortest_axis;

    vec3b steps_per_axis(-1,-1,-1);

    steps_per_axis[shortest_axis] = num_divisions_for_shortest_axis;

    for( uint8_t axis_idx = 0; axis_idx < 3; ++axis_idx ) {
        if (axis_idx != shortest_axis) {
            uint32_t num_axis_steps = std::max(1, int(std::ceil(  axis_lengths[axis_idx] / step_length[shortest_axis] ) ) );
            step_length[axis_idx] = axis_lengths[axis_idx] / num_axis_steps;

            steps_per_axis[axis_idx] = num_axis_steps;
        }
    }


    std::vector< std::vector<surfel> > spatially_divided_surfels;
    
    spatially_divided_surfels.resize( steps_per_axis[0]*steps_per_axis[1]*steps_per_axis[2] );


    for (size_t node_id = 0; node_id < input.size(); ++node_id) {
        for (size_t surfel_id = input[node_id]->offset();
                    surfel_id < input[node_id]->offset() + input[node_id]->length();
                    ++surfel_id){
            
            //this surfel will be referenced in the entropy surfel
            auto current_surfel = input[node_id]->mem_data()->at(input[node_id]->offset() + surfel_id);
            
            // ignore outlier radii of any kind
            if (current_surfel.radius() == 0.0) {
                continue;
            } 


            uint32_t x_summand = std::max(uint8_t(0), std::min( uint8_t( steps_per_axis[0] - 1), uint8_t( ( current_surfel.pos()[0] - combined_bounding_box.min()[0] ) /
                                 ( combined_bounding_box.max()[0] - combined_bounding_box.min()[0] ) *
                                 steps_per_axis[0]) ) ) * steps_per_axis[1] * steps_per_axis[2];

            uint32_t y_summand = std::max(uint8_t(0), std::min( uint8_t(steps_per_axis[1] - 1), uint8_t( ( current_surfel.pos()[1] - combined_bounding_box.min()[1] ) /
                                 ( combined_bounding_box.max()[1] - combined_bounding_box.min()[1] ) *
                                 steps_per_axis[1]) ) ) * steps_per_axis[2];

            uint32_t z_summand = std::max(uint8_t(0), std::min( uint8_t(steps_per_axis[2] - 1), uint8_t( ( current_surfel.pos()[2] - combined_bounding_box.min()[2] ) /
                                 ( combined_bounding_box.max()[2] - combined_bounding_box.min()[2] ) *
                                 steps_per_axis[2]) ) );

            uint32_t box_id = x_summand + y_summand + z_summand;


            spatially_divided_surfels[box_id].push_back(current_surfel);
            original_surfels.push_back(current_surfel);
       }
    }

    std::sort(std::begin(spatially_divided_surfels), std::end(spatially_divided_surfels), [](std::vector<surfel> const& lhs, std::vector<surfel> const& rhs) { return lhs.size() > rhs.size();});    

    while( spatially_divided_surfels.back().empty() ){
        spatially_divided_surfels.pop_back();
    } 

    std::set<size_t> picked_box_ids;

    while( already_picked_surfel.size () < surfels_per_node ) {

        size_t box_id;

        do {
            box_id = rand() % spatially_divided_surfels.size();
        } while(picked_box_ids.find(box_id) != picked_box_ids.end());

        picked_box_ids.insert(box_id);
 
        if( picked_box_ids.size() == spatially_divided_surfels.size() ) {
            picked_box_ids.clear();
        }


        auto& current_surfel_box = spatially_divided_surfels[box_id];

        int32_t surf_id;

        surf_id = rand() % current_surfel_box.size();

        surfel picked_surfel = current_surfel_box[surf_id];

        already_picked_surfel.push_back(picked_surfel);

        current_surfel_box.erase(current_surfel_box.begin() + surf_id);
        
        if(current_surfel_box.empty()) {
            spatially_divided_surfels.erase( spatially_divided_surfels.begin() + box_id);

            if(picked_box_ids.find(box_id) != picked_box_ids.end())
                picked_box_ids.erase(box_id);
        }

    }

    for (auto& final_candidate : already_picked_surfel) {

        interpolate_approx_natural_neighbours(final_candidate, original_surfels, tree);

        mem_array.mem_data()->push_back(final_candidate);
    }

    mem_array.set_length(mem_array.mem_data()->size());

    reduction_error = 0.0;

    return mem_array;
}