Fix a crash in rectpack2D when unable to pack footprints.

This commit is contained in:
Alex 2023-02-10 22:44:51 +03:00
parent f4825cdd8f
commit 89429996da
3 changed files with 16 additions and 10 deletions

View File

@ -5,7 +5,7 @@
* Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net> * Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
* *
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -35,6 +35,7 @@
*/ */
#include <spread_footprints.h> #include <spread_footprints.h>
#include <optional>
#include <algorithm> #include <algorithm>
#include <refdes_utils.h> #include <refdes_utils.h>
#include <string_utils.h> #include <string_utils.h>
@ -77,12 +78,13 @@ static bool compareFootprintsbyRef( FOOTPRINT* ref, FOOTPRINT* compare )
// Spread a list of rectangles inside a placement area // Spread a list of rectangles inside a placement area
rectpack2D::rect_wh spreadRectangles( rect_vector& vecSubRects, int areaSizeX, int areaSizeY ) std::optional<rectpack2D::rect_wh> spreadRectangles( rect_vector& vecSubRects, int areaSizeX,
int areaSizeY )
{ {
areaSizeX /= scale; areaSizeX /= scale;
areaSizeY /= scale; areaSizeY /= scale;
rectpack2D::rect_wh result; std::optional<rectpack2D::rect_wh> result;
int max_side = std::max( areaSizeX, areaSizeY ); int max_side = std::max( areaSizeX, areaSizeY );
@ -107,7 +109,7 @@ rectpack2D::rect_wh spreadRectangles( rect_vector& vecSubRects, int areaSizeX, i
make_finder_input( max_side, discard_step, report_successful, report_unsuccessful, make_finder_input( max_side, discard_step, report_successful, report_unsuccessful,
rectpack2D::flipping_option::DISABLED ) ); rectpack2D::flipping_option::DISABLED ) );
if( anyUnsuccessful ) if( !result || anyUnsuccessful )
{ {
max_side = (int) ( max_side * 1.2 ); max_side = (int) ( max_side * 1.2 );
continue; continue;

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include <optional>
#include <variant> #include <variant>
#include <cassert> #include <cassert>
#include "rect_structs.h" #include "rect_structs.h"
@ -213,7 +214,7 @@ namespace rectpack2D {
class F, class F,
class I class I
> >
rect_wh find_best_packing_impl(F for_each_order, const I input) { std::optional<rect_wh> find_best_packing_impl(F for_each_order, const I input) {
const auto max_bin = rect_wh(input.max_bin_side, input.max_bin_side); const auto max_bin = rect_wh(input.max_bin_side, input.max_bin_side);
OrderType* best_order = nullptr; OrderType* best_order = nullptr;
@ -258,9 +259,8 @@ namespace rectpack2D {
} }
}); });
if( best_order != nullptr )
{ {
assert(best_order != nullptr);
root.reset(best_bin); root.reset(best_bin);
for (auto& rr : *best_order) { for (auto& rr : *best_order) {
@ -281,6 +281,10 @@ namespace rectpack2D {
} }
return root.get_rects_aabb(); return root.get_rects_aabb();
} }
else
{
return std::nullopt;
}
} }
} }

View File

@ -69,7 +69,7 @@ namespace rectpack2D {
*/ */
template <class empty_spaces_type, class F, class G, class Comparator, class... Comparators> template <class empty_spaces_type, class F, class G, class Comparator, class... Comparators>
rect_wh find_best_packing( std::optional<rect_wh> find_best_packing(
std::vector<output_rect_t<empty_spaces_type>>& subjects, std::vector<output_rect_t<empty_spaces_type>>& subjects,
const finder_input<F, G>& input, const finder_input<F, G>& input,
@ -122,7 +122,7 @@ namespace rectpack2D {
*/ */
template <class empty_spaces_type, class F, class G> template <class empty_spaces_type, class F, class G>
rect_wh find_best_packing( std::optional<rect_wh> find_best_packing(
std::vector<output_rect_t<empty_spaces_type>>& subjects, std::vector<output_rect_t<empty_spaces_type>>& subjects,
const finder_input<F, G>& input const finder_input<F, G>& input
) { ) {