| 3256 | } |
| 3257 | |
| 3258 | void PCCEncoder::packTetris( PCCFrameContext& frame, size_t presetWidth, size_t presetHeight, int safeguard ) { |
| 3259 | auto& width = frame.getWidth(); |
| 3260 | auto& height = frame.getHeight(); |
| 3261 | auto& patches = frame.getPatches(); |
| 3262 | // set no matched patches, since this function does not take into account the previous frame |
| 3263 | frame.setNumMatchedPatches( 0 ); |
| 3264 | if ( patches.empty() ) { return; } |
| 3265 | // sorting by patch largest dimension |
| 3266 | std::sort( patches.begin(), patches.end(), []( PCCPatch& a, PCCPatch& b ) { return a.gt( b ); } ); |
| 3267 | if ( g_printDetailedInfo ) { |
| 3268 | std::cout << "Patch order:" << std::endl; |
| 3269 | for ( auto& patch : patches ) { |
| 3270 | std::cout << "Patch[" << patch.getIndex() << "]=(" << patch.getSizeU0() << "," << patch.getSizeV0() << ")" |
| 3271 | << std::endl; |
| 3272 | } |
| 3273 | } |
| 3274 | size_t occupancySizeU = presetWidth / params_.occupancyResolution_; |
| 3275 | size_t occupancySizeV = (std::max)( patches[0].getSizeV0(), patches[0].getSizeU0() ); |
| 3276 | for ( auto& patch : patches ) { occupancySizeU = (std::max)( occupancySizeU, patch.getSizeU0() + 1 ); } |
| 3277 | width = occupancySizeU * params_.occupancyResolution_; |
| 3278 | height = occupancySizeV * params_.occupancyResolution_; |
| 3279 | size_t maxOccupancyRow = 0; |
| 3280 | std::vector<bool> occupancyMap; |
| 3281 | occupancyMap.resize( occupancySizeU * occupancySizeV, false ); |
| 3282 | std::vector<int> horizon; |
| 3283 | horizon.resize( occupancySizeU, 0 ); |
| 3284 | if ( g_printDetailedInfo ) { |
| 3285 | std::cout << "Horizon :["; |
| 3286 | for ( int i = 0; i < occupancySizeU; i++ ) { std::cout << horizon[i] << ","; } |
| 3287 | std::cout << "]" << std::endl; |
| 3288 | } |
| 3289 | for ( auto& patch : patches ) { |
| 3290 | assert( patch.getSizeU0() <= occupancySizeU ); |
| 3291 | assert( patch.getSizeV0() <= occupancySizeV ); |
| 3292 | auto& occupancy = patch.getOccupancy(); |
| 3293 | // getting the horizons using the rotation 0 position |
| 3294 | if ( g_printDetailedInfo ) { patch.print(); } |
| 3295 | std::vector<int> topHorizon; |
| 3296 | std::vector<int> bottomHorizon; |
| 3297 | std::vector<int> rightHorizon; |
| 3298 | std::vector<int> leftHorizon; |
| 3299 | patch.getPatchHorizons( topHorizon, bottomHorizon, rightHorizon, leftHorizon ); |
| 3300 | bool locationFound = false; |
| 3301 | // try to place the patch tetris-style |
| 3302 | int numOrientations = params_.useEightOrientations_ ? 8 : 2; |
| 3303 | while ( !locationFound ) { |
| 3304 | int best_wasted_space = (std::numeric_limits<int>::max)(); |
| 3305 | size_t bestU; |
| 3306 | size_t bestV; |
| 3307 | int bestOrientation; |
| 3308 | for ( size_t u = 0; u < occupancySizeU; ++u ) { |
| 3309 | for ( size_t v = 0; v < occupancySizeV; ++v ) { |
| 3310 | patch.setU0( u ); |
| 3311 | patch.setV0( v ); |
| 3312 | for ( size_t orientationIdx = 0; orientationIdx < numOrientations; orientationIdx++ ) { |
| 3313 | patch.setPatchOrientation( g_orientationVertical[orientationIdx] ); |
| 3314 | if ( !patch.isPatchLocationAboveHorizon( horizon, topHorizon, bottomHorizon, rightHorizon, leftHorizon ) ) { |
| 3315 | if ( g_printDetailedInfo ) { |
nothing calls this directly
no test coverage detected