61    RESULTS( 
int aOutline1, 
int aOutline2, 
int aVertex1, 
int aVertex2 ) :
 
 
 
  108        SEG::ecoord min_dist = std::numeric_limits<SEG::ecoord>::max();
 
  111        auto check_pt = [&]( 
VERTEX* p )
 
  113            VECTOR2D diff( p->x - aPt->
x, p->y - aPt->
y );
 
  116            if( dist2 > 0 && dist2 < limit2 && dist2 < min_dist && p->isEar( 
true ) )
 
  125        while( p && p->
z <= maxZ )
 
  133        while( p && p->
z >= minZ )
 
 
  148        std::set<VERTEX*> visited;
 
  161            if( ( visited.empty() || !visited.contains( p ) ) && ( q = 
getPoint( p ) ) )
 
  165                if( !visited.contains( q ) &&
 
  167                                        p->
i, q->
i ).second )
 
  171                    visited.insert( p->
prev );
 
  173                    visited.insert( p->
next );
 
  176                    visited.insert( q->
prev );
 
  178                    visited.insert( q->
next );
 
 
 
  222    wxASSERT_MSG( 
m_commit, wxT( 
"ZONE_FILLER must have a valid commit to call SetProgressReporter" ) );
 
 
  238    std::lock_guard<KISPINLOCK> lock( 
m_board->GetConnectivity()->GetLock() );
 
  240    std::vector<std::pair<ZONE*, PCB_LAYER_ID>>               toFill;
 
  241    std::map<std::pair<ZONE*, PCB_LAYER_ID>, 
HASH_128>        oldFillHashes;
 
  242    std::map<ZONE*, std::map<PCB_LAYER_ID, ISOLATED_ISLANDS>> isolatedIslandsMap;
 
  244    std::shared_ptr<CONNECTIVITY_DATA> connectivity = 
m_board->GetConnectivity();
 
  251    connectivity->ClearRatsnest();
 
  259                                           : 
_( 
"Building zone fills..." ) );
 
  272        zone->CacheBoundingBox();
 
  276        for( 
PAD* 
pad : footprint->Pads() )
 
  280                pad->BuildEffectiveShapes();
 
  285        for( 
ZONE* zone : footprint->Zones() )
 
  286            zone->CacheBoundingBox();
 
  289        footprint->BuildCourtyardCaches();
 
  290        footprint->BuildNetTieCache();
 
  295    auto findHighestPriorityZone =
 
  297                 const std::function<bool( 
const ZONE* )>& testFn ) -> 
ZONE*
 
  299                unsigned highestPriority = 0;
 
  300                ZONE*    highestPriorityZone = 
nullptr;
 
  305                    if( zone->GetIsRuleArea() )
 
  308                    if( zone->GetAssignedPriority() < highestPriority )
 
  311                    if( !zone->IsOnLayer( itemLayer ) )
 
  315                    if( zone->GetNumCorners() <= 2 )
 
  318                    if( !zone->GetBoundingBox().Intersects( bbox ) )
 
  321                    if( !testFn( zone ) )
 
  325                    if( zone->GetAssignedPriority() > highestPriority
 
  326                            || zone->GetNetCode() == netcode )
 
  328                        highestPriority = zone->GetAssignedPriority();
 
  329                        highestPriorityZone = zone;
 
  333                return highestPriorityZone;
 
  336    auto isInPourKeepoutArea =
 
  341                    if( !zone->GetIsRuleArea() )
 
  344                    if( !zone->HasKeepoutParametersSet() )
 
  347                    if( !zone->GetDoNotAllowZoneFills() )
 
  350                    if( !zone->IsOnLayer( itemLayer ) )
 
  354                    if( zone->GetNumCorners() <= 2 )
 
  357                    if( !zone->GetBoundingBox().Intersects( bbox ) )
 
  360                    if( zone->Outline()->Contains( testPoint ) )
 
  377            via->ClearZoneLayerOverrides();
 
  379            if( !
via->GetRemoveUnconnected() )
 
  384            int      holeRadius = 
via->GetDrillValue() / 2 + 1;
 
  385            int      netcode = 
via->GetNetCode();
 
  386            LSET     layers = 
via->GetLayerSet() & boardCuMask;
 
  390                    [&]( 
const ZONE* aZone ) -> 
bool 
  392                        return aZone->Outline()->Contains( 
center, -1, holeRadius );
 
  397                if( !
via->ConditionallyFlashed( layer ) )
 
  400                if( isInPourKeepoutArea( bbox, layer, 
center ) )
 
  406                    ZONE* zone = findHighestPriorityZone( bbox, layer, netcode, viaTestFn );
 
  411                                  || layer == padstack.
Drill().
end ) )
 
  427        for( 
PAD* 
pad : footprint->Pads() )
 
  429            pad->ClearZoneLayerOverrides();
 
  431            if( !
pad->GetRemoveUnconnected() )
 
  436            int      netcode = 
pad->GetNetCode();
 
  437            LSET     layers = 
pad->GetLayerSet() & boardCuMask;
 
  440                    [&]( 
const ZONE* aZone ) -> 
bool 
  442                        return aZone->Outline()->Contains( 
center );
 
  447                if( !
pad->ConditionallyFlashed( layer ) )
 
  450                if( isInPourKeepoutArea( bbox, layer, 
center ) )
 
  456                    ZONE* zone = findHighestPriorityZone( bbox, layer, netcode, padTestFn );
 
  467    for( 
ZONE* zone : aZones )
 
  470        if( zone->GetIsRuleArea() )
 
  474        if( zone->GetNumCorners() <= 2 )
 
  484            zone->BuildHashValue( layer );
 
  485            oldFillHashes[ { zone, layer } ] = zone->GetHashValue( layer );
 
  488            toFill.emplace_back( std::make_pair( zone, layer ) );
 
  497    auto check_fill_dependency =
 
  505                if( aOtherZone->GetFillFlag( aLayer ) )
 
  510                if( aOtherZone->GetIsRuleArea() )
 
  514                if( aOtherZone->GetNumCorners() <= 2 )
 
  518                if( !aOtherZone->GetLayerSet().test( aLayer ) )
 
  525                if( aOtherZone->SameNet( aZone ) )
 
  533                if( !inflatedBBox.
Intersects( aOtherZone->GetBoundingBox() ) )
 
  540            [&]( std::pair<ZONE*, PCB_LAYER_ID> aFillItem ) -> 
int 
  543                ZONE*        zone = aFillItem.first;
 
  548                for( 
ZONE* otherZone : aZones )
 
  550                    if( otherZone == zone )
 
  553                    if( check_fill_dependency( zone, layer, otherZone ) )
 
  568                    std::unique_lock<std::mutex> zoneLock( zone->
GetLock(), std::try_to_lock );
 
  570                    if( !zoneLock.owns_lock() )
 
  587    auto tesselate_lambda =
 
  588            [&]( std::pair<ZONE*, PCB_LAYER_ID> aFillItem ) -> 
int 
  594                ZONE*        zone = aFillItem.first;
 
  597                    std::unique_lock<std::mutex> zoneLock( zone->
GetLock(), std::try_to_lock );
 
  599                    if( !zoneLock.owns_lock() )
 
  611    std::vector<std::pair<std::future<int>, 
int>> returns;
 
  612    returns.reserve( toFill.size() );
 
  614    bool cancelled = 
false;
 
  618    for( 
const std::pair<ZONE*, PCB_LAYER_ID>& fillItem : toFill )
 
  619        returns.emplace_back( std::make_pair( 
tp.submit_task( [&, fillItem]() { return fill_lambda( fillItem ); } ), 0 ) );
 
  621    while( !cancelled && finished != 2 * toFill.size() )
 
  623        for( 
size_t ii = 0; ii < returns.size(); ++ii )
 
  625            auto& ret = returns[ii];
 
  630            std::future_status status = ret.first.wait_for( std::chrono::seconds( 0 ) );
 
  632            if( status == std::future_status::ready )
 
  634                if( ret.first.get() )   
 
  643                    if( ret.second == 0 )
 
  644                        returns[ii].first = 
tp.submit_task( [&, idx = ii]() { 
return fill_lambda( toFill[idx] ); } );
 
  645                    else if( ret.second == 1 )
 
  646                        returns[ii].first = 
tp.submit_task( [&, idx = ii]() { 
return tesselate_lambda( toFill[idx] ); } );
 
  651        std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
 
  665    for( 
auto& ret : returns )
 
  667        if( ret.first.valid() )
 
  669            std::future_status status = ret.first.wait_for( std::chrono::seconds( 0 ) );
 
  671            while( status != std::future_status::ready )
 
  676                status = ret.first.wait_for( std::chrono::milliseconds( 100 ) );
 
  695    connectivity->FillIsolatedIslandsMap( isolatedIslandsMap );
 
  696    connectivity->SetProgressReporter( 
nullptr );
 
  701    for( 
ZONE* zone : aZones )
 
  704        if( zone->GetIsRuleArea() )
 
  707        zone->SetIsFilled( 
true );
 
  713    for( 
const auto& [ zone, zoneIslands ] : isolatedIslandsMap )
 
  716        bool allIslands = 
true;
 
  718        for( 
const auto& [ layer, layerIslands ] : zoneIslands )
 
  720            if( layerIslands.m_IsolatedOutlines.size()
 
  721                    != 
static_cast<size_t>( zone->GetFilledPolysList( layer )->OutlineCount() ) )
 
  731        for( 
const auto& [ layer, layerIslands ] : zoneIslands )
 
  736            if( layerIslands.m_IsolatedOutlines.empty() )
 
  739            std::vector<int> islands = layerIslands.m_IsolatedOutlines;
 
  743            std::sort( islands.begin(), islands.end(), std::greater<int>() );
 
  745            std::shared_ptr<SHAPE_POLY_SET> poly = zone->GetFilledPolysList( layer );
 
  746            long long int                   minArea = zone->GetMinIslandArea();
 
  749            for( 
int idx : islands )
 
  754                    poly->DeletePolygonAndTriangulationData( idx, 
false );
 
  756                    poly->DeletePolygonAndTriangulationData( idx, 
false );
 
  758                    zone->SetIsIsland( layer, idx );
 
  761            poly->UpdateTriangulationDataHash();
 
  762            zone->CalculateFilledArea();
 
  771    using island_check_return = std::vector<std::pair<std::shared_ptr<SHAPE_POLY_SET>, 
int>>;
 
  773    std::vector<std::pair<std::shared_ptr<SHAPE_POLY_SET>, 
double>> polys_to_check;
 
  776    polys_to_check.reserve( 
m_board->GetCopperLayerCount() * aZones.size() );
 
  778    for( 
ZONE* zone : aZones )
 
  788        double minArea = (double) zone->GetMinThickness() * zone->GetMinThickness() * 3;
 
  795            polys_to_check.emplace_back( zone->GetFilledPolysList( layer ), minArea );
 
  800            [&]( 
int aStart, 
int aEnd ) -> island_check_return
 
  802                island_check_return retval;
 
  804                for( 
int ii = aStart; ii < aEnd && !cancelled; ++ii )
 
  806                    auto [poly, minArea] = polys_to_check[ii];
 
  808                    for( 
int jj = poly->OutlineCount() - 1; jj >= 0; jj-- )
 
  813                        double island_area = test_poly.
Area();
 
  815                        if( island_area < minArea )
 
  827                        if( intersection.
Area() < island_area / 2.0 )
 
  828                            retval.emplace_back( poly, jj );
 
  835    auto island_returns = 
tp.submit_blocks( 0, polys_to_check.size(), island_lambda );
 
  839    for( 
size_t ii = 0; ii < island_returns.size(); ++ii )
 
  841        std::future<island_check_return>& ret = island_returns[ii];
 
  845            std::future_status status = ret.wait_for( std::chrono::seconds( 0 ) );
 
  847            while( status != std::future_status::ready )
 
  857                status = ret.wait_for( std::chrono::milliseconds( 100 ) );
 
  865    for( 
size_t ii = 0; ii < island_returns.size(); ++ii )
 
  867        std::future<island_check_return>& ret = island_returns[ii];
 
  871            for( 
auto& action_item : ret.get() )
 
  872                action_item.first->DeletePolygonAndTriangulationData( action_item.second, 
true );
 
  876    for( 
ZONE* zone : aZones )
 
  877        zone->CalculateFilledArea();
 
  882        bool outOfDate = 
false;
 
  884        for( 
ZONE* zone : aZones )
 
  887            if( zone->GetIsRuleArea() )
 
  892                zone->BuildHashValue( layer );
 
  894                if( oldFillHashes[ { zone, layer } ] != zone->GetHashValue( layer ) )
 
  900              && 
m_board->GetProject()->GetLocalSettings().m_PrototypeZoneFill ) )
 
  902            KIDIALOG dlg( aParent, 
_( 
"Prototype zone fill enabled. Disable setting and refill?" ),
 
  903                          _( 
"Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
 
  909                m_board->GetProject()->GetLocalSettings().m_PrototypeZoneFill = 
false;
 
  911            else if( !outOfDate )
 
  919            KIDIALOG dlg( aParent, 
_( 
"Zone fills are out-of-date. Refill?" ),
 
  920                          _( 
"Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
 
 
  963            std::vector<VECTOR2I> convex_hull;
 
  968            for( 
const VECTOR2I& pt : convex_hull )
 
 
  999        minorAxis = std::min( padSize.
x, padSize.
y );
 
 1005        minorAxis = 
via->GetWidth( aLayer );
 
 
 1019    switch( aItem->
Type() )
 
 1026        if( 
text->IsVisible() )
 
 1028            if( 
text->IsKnockout() )
 
 
 1085                                          std::vector<BOARD_ITEM*>& aThermalConnectionPads,
 
 1086                                          std::vector<PAD*>& aNoConnectionPads )
 
 1092    std::shared_ptr<SHAPE> padShape;
 
 1098        for( 
PAD* 
pad : footprint->Pads() )
 
 1100            if( !
pad->IsOnLayer( aLayer ) )
 
 1103            BOX2I padBBox = 
pad->GetBoundingBox();
 
 1109            bool noConnection = 
pad->GetNetCode() != aZone->
GetNetCode();
 
 1116                    noConnection = 
true;
 
 1123                aNoConnectionPads.push_back( 
pad );
 
 1133                aThermalConnectionPads.push_back( 
pad );
 
 1151            switch( connection )
 
 1156                if( aFill.
Collide( padShape.get(), 0 ) )
 
 1162                    aThermalConnectionPads.push_back( 
pad );
 
 1177                if( 
pad->FlashLayer( aLayer ) )
 
 1181                else if( 
pad->GetDrillSize().x > 0 )
 
 1184                                                             pad, aZone, aLayer );
 
 1189                        holeClearance = padClearance;
 
 1214                if( !
via->IsOnLayer( aLayer ) )
 
 1217                BOX2I viaBBox = 
via->GetBoundingBox();
 
 1223                bool noConnection = 
via->GetNetCode() != aZone->
GetNetCode()
 
 1224                        || ( 
via->Padstack().UnconnectedLayerMode()
 
 1226                             && aLayer != 
via->Padstack().Drill().start
 
 1227                             && aLayer != 
via->Padstack().Drill().end );
 
 1232                aThermalConnectionPads.push_back( 
via );
 
 
 1247                                             const std::vector<PAD*>& aNoConnectionPads,
 
 1253    auto checkForCancel =
 
 1256                return aReporter && ( ticker++ % 50 ) == 0 && aReporter->IsCancelled();
 
 1269    auto evalRulesForItems =
 
 1283    auto knockoutPadClearance =
 
 1288                bool hasHole = aPad->GetDrillSize().x > 0;
 
 1289                bool flashLayer = aPad->FlashLayer( aLayer );
 
 1292                if( flashLayer || platedHole )
 
 1295                                                            aZone, aPad, aLayer ) );
 
 1298                if( flashLayer && gap >= 0 )
 
 1299                    addKnockout( aPad, aLayer, gap + extra_margin, aHoles );
 
 1308                                                            aZone, aPad, aLayer ) );
 
 1311                                                            aZone, aPad, aLayer ) );
 
 1318    for( 
PAD* 
pad : aNoConnectionPads )
 
 1323        knockoutPadClearance( 
pad );
 
 1328    auto knockoutTrackClearance =
 
 1331                if( aTrack->GetBoundingBox().Intersects( zone_boundingbox ) )
 
 1333                    bool sameNet = aTrack->GetNetCode() == aZone->
GetNetCode();
 
 1339                                                  aZone, aTrack, aLayer );
 
 1352                                                                aZone, aTrack, aLayer ) );
 
 1359                        if( 
via->FlashLayer( aLayer ) && gap > 0 )
 
 1361                            via->TransformShapeToPolygon( aHoles, aLayer, gap + extra_margin,
 
 1366                                                                aZone, 
via, aLayer ) );
 
 1371                                                                    aZone, 
via, aLayer ) );
 
 1379                                                      radius + gap + extra_margin,
 
 1387                            aTrack->TransformShapeToPolygon( aHoles, aLayer, gap + extra_margin,
 
 1396        if( !track->IsOnLayer( aLayer ) )
 
 1402        knockoutTrackClearance( track );
 
 1407    auto knockoutGraphicClearance =
 
 1413                    shapeNet = 
static_cast<PCB_SHAPE*
>( aItem )->GetNetCode();
 
 1415                bool sameNet = shapeNet == aZone->
GetNetCode();
 
 1421                if( aItem->IsOnLayer( aLayer )
 
 1423                        || aItem->IsOnLayer( 
Margin ) )
 
 1425                    if( aItem->GetBoundingBox().Intersects( zone_boundingbox ) )
 
 1427                        bool ignoreLineWidths = 
false;
 
 1429                                                      aZone, aItem, aLayer );
 
 1431                        if( aItem->IsOnLayer( aLayer ) && !sameNet )
 
 1434                                                                    aZone, aItem, aLayer ) );
 
 1436                        else if( aItem->IsOnLayer( 
Edge_Cuts ) )
 
 1439                                                                    aZone, aItem, aLayer ) );
 
 1440                            ignoreLineWidths = 
true;
 
 1442                        else if( aItem->IsOnLayer( 
Margin ) )
 
 1445                                                                    aZone, aItem, aLayer ) );
 
 1450                            gap += extra_margin;
 
 1451                            addKnockout( aItem, aLayer, gap, ignoreLineWidths, aHoles );
 
 1457    auto knockoutCourtyardClearance =
 
 1460                if( aFootprint->GetBoundingBox().Intersects( zone_boundingbox ) )
 
 1463                                                 aFootprint, aLayer );
 
 1467                        aHoles.
Append( aFootprint->GetCourtyard( aLayer ) );
 
 1480        knockoutCourtyardClearance( footprint );
 
 1481        knockoutGraphicClearance( &footprint->Reference() );
 
 1482        knockoutGraphicClearance( &footprint->Value() );
 
 1484        std::set<PAD*> allowedNetTiePads;
 
 1488        if( footprint->IsNetTie() )
 
 1490            for( 
PAD* 
pad : footprint->Pads() )
 
 1499                    if( 
pad->IsOnLayer( aLayer ) )
 
 1500                        allowedNetTiePads.insert( 
pad );
 
 1502                    for( 
PAD* other : footprint->GetNetTiePads( 
pad ) )
 
 1504                        if( other->IsOnLayer( aLayer ) )
 
 1505                            allowedNetTiePads.insert( other );
 
 1511        for( 
BOARD_ITEM* item : footprint->GraphicalItems() )
 
 1516            BOX2I itemBBox = item->GetBoundingBox();
 
 1518            if( !zone_boundingbox.
Intersects( itemBBox ) )
 
 1521            bool skipItem = 
false;
 
 1523            if( item->IsOnLayer( aLayer ) )
 
 1525                std::shared_ptr<SHAPE> itemShape = item->GetEffectiveShape();
 
 1527                for( 
PAD* 
pad : allowedNetTiePads )
 
 1529                    if( 
pad->GetBoundingBox().Intersects( itemBBox )
 
 1530                            && 
pad->GetEffectiveShape( aLayer )->Collide( itemShape.get() ) )
 
 1539                knockoutGraphicClearance( item );
 
 1548        knockoutGraphicClearance( item );
 
 1553    auto knockoutZoneClearance =
 
 1554            [&]( 
ZONE* aKnockout )
 
 1557                if( !aKnockout->GetLayerSet().test( aLayer ) )
 
 1560                if( aKnockout->GetBoundingBox().Intersects( zone_boundingbox ) )
 
 1562                    if( aKnockout->GetIsRuleArea() )
 
 1565                        aKnockout->TransformSmoothedOutlineToPolygon( aHoles, 0, 
m_maxError,
 
 1571                                                                  aZone, aKnockout, aLayer ) );
 
 1574                                                                aZone, aKnockout, aLayer ) );
 
 1577                        aKnockout->TransformShapeToPolygon( poly, aLayer, gap + extra_margin,
 
 1590        if( !otherZone->GetBoundingBox().Intersects( zone_boundingbox ) )
 
 1597        if( otherZone->GetIsRuleArea() )
 
 1599            if( otherZone->GetDoNotAllowZoneFills() && !aZone->
IsTeardropArea() )
 
 1600                knockoutZoneClearance( otherZone );
 
 1602        else if( otherZone->HigherPriority( aZone ) )
 
 1604            if( !otherZone->SameNet( aZone ) )
 
 1605                knockoutZoneClearance( otherZone );
 
 1611        for( 
ZONE* otherZone : footprint->Zones() )
 
 1617            if( !otherZone->GetBoundingBox().Intersects( zone_boundingbox ) )
 
 1620            if( otherZone->GetIsRuleArea() )
 
 1622                if( otherZone->GetDoNotAllowZoneFills() && !aZone->
IsTeardropArea() )
 
 1623                    knockoutZoneClearance( otherZone );
 
 1625            else if( otherZone->HigherPriority( aZone ) )
 
 1627                if( !otherZone->SameNet( aZone ) )
 
 1628                    knockoutZoneClearance( otherZone );
 
 
 1646    auto knockoutZoneOutline =
 
 1647            [&]( 
ZONE* aKnockout )
 
 1650                if( !aKnockout->GetLayerSet().test( aLayer ) )
 
 1653                if( aKnockout->GetBoundingBox().Intersects( zoneBBox ) )
 
 1669        if( otherZone->SameNet( aZone )
 
 1673            if( !otherZone->IsTeardropArea() )
 
 1674                knockoutZoneOutline( otherZone );
 
 1680        for( 
ZONE* otherZone : footprint->Zones() )
 
 1682            if( otherZone->SameNet( aZone ) && otherZone->HigherPriority( aZone ) )
 
 1685                if( !otherZone->IsTeardropArea() )
 
 1686                    knockoutZoneOutline( otherZone );
 
 
 1704    std::map<int, std::vector<std::pair<int, VECTOR2I>>> insertion_points;
 
 1716        insertion_points[
result.m_outline1].push_back( { 
result.m_vertex1, pt1 } );
 
 1717        insertion_points[
result.m_outline1].push_back( { 
result.m_vertex1, pt2 } );
 
 1720    for( 
auto& [outline, vertices] : insertion_points )
 
 1724        if( vertices.empty() )
 
 1729        std::stable_sort( vertices.begin(), vertices.end(),
 
 1730                  []( 
const std::pair<int, VECTOR2I>& a, 
const std::pair<int, VECTOR2I>& b )
 
 1732                      return a.first < b.first;
 
 1735        std::vector<VECTOR2I> new_points;
 
 1736        new_points.reserve( line.
PointCount() + vertices.size() );
 
 1738        size_t vertex_idx = 0;
 
 1742            new_points.push_back( line.
CPoint( i ) );
 
 1745            while( vertex_idx < vertices.size() && vertices[vertex_idx].first == i )
 
 1747                new_points.push_back( vertices[vertex_idx].second );
 
 1754        for( 
const auto& pt : new_points )
 
 
 1760#define DUMP_POLYS_TO_COPPER_LAYER( a, b, c ) \ 
 1761    { if( m_debugZoneFiller && aDebugLayer == b ) \ 
 1763            m_board->SetLayerName( b, c ); \ 
 1764            SHAPE_POLY_SET d = a; \ 
 
 1803    std::vector<BOARD_ITEM*>     thermalConnectionPads;
 
 1804    std::vector<PAD*>            noConnectionPads;
 
 1805    std::deque<SHAPE_LINE_CHAIN> thermalSpokes;
 
 1808    aFillPolys = aSmoothedOutline;
 
 1845    static const bool USE_BBOX_CACHES = 
true;
 
 1872        const VECTOR2I& testPt = spoke.CPoint( 3 );
 
 1875        if( testAreas.
Contains( testPt, -1, 1, USE_BBOX_CACHES ) )
 
 1884        if( interval++ > 400 )
 
 1897            if( &other != &spoke
 
 1898                && other.PointInside( testPt, 1, USE_BBOX_CACHES )
 
 1899                && spoke.PointInside( other.CPoint( 3 ), 1, USE_BBOX_CACHES ) )
 
 1929    for( 
int ii = aFillPolys.
OutlineCount() - 1; ii >= 0; ii-- )
 
 1931        std::vector<SHAPE_LINE_CHAIN>& island = aFillPolys.
Polygon( ii );
 
 1932        BOX2I                          islandExtents;
 
 1934        for( 
const VECTOR2I& pt : island.front().CPoints() )
 
 1936            islandExtents.
Merge( pt );
 
 1957             || !
m_board->GetProject()->GetLocalSettings().m_PrototypeZoneFill ) )
 
 1992    for( 
BOARD_ITEM* item : thermalConnectionPads )
 
 
 2023    auto checkForCancel =
 
 2026                return aReporter && ( ticker++ % 50 ) == 0 && aReporter->IsCancelled();
 
 2029    auto knockoutGraphicItem =
 
 2032                if( aItem->IsKnockout() && aItem->IsOnLayer( aLayer )
 
 2033                        && aItem->GetBoundingBox().Intersects( zone_boundingbox ) )
 
 2035                    addKnockout( aItem, aLayer, 0, 
true, clearanceHoles );
 
 2044        knockoutGraphicItem( &footprint->Reference() );
 
 2045        knockoutGraphicItem( &footprint->Value() );
 
 2047        for( 
BOARD_ITEM* item : footprint->GraphicalItems() )
 
 2048            knockoutGraphicItem( item );
 
 2056        knockoutGraphicItem( item );
 
 2059    aFillPolys = aSmoothedOutline;
 
 2062    auto subtractKeepout =
 
 2063            [&]( 
ZONE* candidate )
 
 2065                if( !candidate->GetIsRuleArea() )
 
 2068                if( !candidate->HasKeepoutParametersSet() )
 
 2071                if( candidate->GetDoNotAllowZoneFills() && candidate->IsOnLayer( aLayer ) )
 
 2073                    if( candidate->GetBoundingBox().Intersects( zone_boundingbox ) )
 
 2075                        if( candidate->Outline()->ArcCount() == 0 )
 
 2094        subtractKeepout( keepout );
 
 2102        for( 
ZONE* keepout : footprint->Zones() )
 
 2103            subtractKeepout( keepout );
 
 
 2144        debugLayer = aLayer;
 
 2148    if( !aZone->
BuildSmoothedPoly( maxExtents, aLayer, boardOutline, &smoothedPoly ) )
 
 2156        if( 
fillCopperZone( aZone, aLayer, debugLayer, smoothedPoly, maxExtents, aFillPolys ) )
 
 
 2173                                      const std::vector<BOARD_ITEM*>& aSpokedPadsList,
 
 2174                                      std::deque<SHAPE_LINE_CHAIN>& aSpokesList )
 
 2193        if( !item->IsOnLayer( aLayer ) )
 
 2196        int       thermalReliefGap = 0;
 
 2200        bool      circular = 
false;
 
 2204            pad = 
static_cast<PAD*
>( item );
 
 2228            if( thermalReliefGap < 0 )
 
 2242            int spoke_max_allowed_w = std::min( 
pad->GetSize( aLayer ).x, 
pad->GetSize( aLayer ).y );
 
 2244            spoke_w = std::clamp( spoke_w, constraint.
Value().
Min(), constraint.
Value().
Max() );
 
 2247            spoke_w = std::min( spoke_w, spoke_max_allowed_w );
 
 2250            if( spoke_w < aZone->GetMinThickness() )
 
 2259        int spoke_half_w = spoke_w / 2;
 
 2262        BOX2I itemBB = item->GetBoundingBox();
 
 2268        bool customSpokes = 
false;
 
 2272            for( 
const std::shared_ptr<PCB_SHAPE>& primitive : 
pad->GetPrimitives( aLayer ) )
 
 2274                if( primitive->IsProxyItem() && primitive->GetShape() == 
SHAPE_T::SEGMENT )
 
 2276                    customSpokes = 
true;
 
 2287        auto buildSpokesFromOrigin =
 
 2294                    auto intersectLineBox =
 
 2297                                double dx = direction.x;
 
 2298                                double dy = direction.y;
 
 2302                                if( direction.x == 0 )
 
 2304                                else if( direction.y == 0 )
 
 2309                                double tx = std::min( half_size.
x / 
std::abs( dx ),
 
 2311                                return VECTOR2I( dx * tx, dy * tx );
 
 2323                    for( 
const EDA_ANGLE& spokeAngle : angles )
 
 2325                        VECTOR2D direction( spokeAngle.Cos(), spokeAngle.Sin() );
 
 2328                        VECTOR2I intersection = intersectLineBox( direction );
 
 2338                        aSpokesList.push_back( std::move( spoke ) );
 
 2347            pad->TransformShapeToPolygon( thermalPoly, aLayer, thermalReliefGap + 
epsilon,
 
 2351                thermalOutline = thermalPoly.
Outline( 0 );
 
 2355            auto trimToOutline = [&]( 
SEG& aSegment )
 
 2359                if( padOutline.
Intersect( aSegment, intersections ) )
 
 2361                    intersections.clear();
 
 2364                    if( thermalOutline.
Intersect( aSegment, intersections ) )
 
 2366                        aSegment.B = intersections.front().p;
 
 2373            for( 
const std::shared_ptr<PCB_SHAPE>& primitive : 
pad->GetPrimitives( aLayer ) )
 
 2375                if( primitive->IsProxyItem() && primitive->GetShape() == 
SHAPE_T::SEGMENT )
 
 2377                    SEG seg( primitive->GetStart(), primitive->GetEnd() );
 
 2382                    seg.
A += 
pad->ShapePos( aLayer );
 
 2383                    seg.
B += 
pad->ShapePos( aLayer );
 
 2397                    if( trimToOutline( seg ) )
 
 2399                        VECTOR2I direction = ( seg.
B - seg.
A ).Resize( spoke_half_w );
 
 2403                        SEG segL( seg.
A - direction - offset, seg.
B + direction - offset );
 
 2404                        SEG segR( seg.
A - direction + offset, seg.
B + direction + offset );
 
 2407                        if( trimToOutline( segL ) && trimToOutline( segR ) )
 
 2415                            spoke.
Append( seg.
A + offset );
 
 2416                            spoke.
Append( seg.
A - offset );
 
 2418                            spoke.
Append( segL.
B + direction );
 
 2419                            spoke.
Append( seg.
B + direction ); 
 
 2420                            spoke.
Append( segR.
B + direction );
 
 2423                            aSpokesList.push_back( std::move( spoke ) );
 
 2436                thermalSpokeAngle = 
pad->GetThermalSpokeAngle();
 
 2455                position = 
pad->ShapePos( aLayer );
 
 2456                orientation = 
pad->GetOrientation();
 
 2464                position = 
via->GetPosition();
 
 2470            spokesBox.
Inflate( thermalReliefGap + 
epsilon + zone_half_width );
 
 2477                buildSpokesFromOrigin( spokesBox, 
ANGLE_0 );
 
 2479                if( thermalSpokeAngle != 
ANGLE_0 )
 
 2482                    for( 
auto it = aSpokesList.rbegin(); it != aSpokesList.rbegin() + 4; ++it )
 
 2483                        it->Rotate( thermalSpokeAngle );
 
 2488                buildSpokesFromOrigin( spokesBox, thermalSpokeAngle );
 
 2491            auto spokeIter = aSpokesList.rbegin();
 
 2493            for( 
int ii = 0; ii < 4; ++ii, ++spokeIter )
 
 2495                spokeIter->Rotate( orientation );
 
 2496                spokeIter->Move( position );
 
 2501    for( 
size_t ii = 0; ii < aSpokesList.size(); ++ii )
 
 2502        aSpokesList[ii].GenerateBBoxCache();
 
 
 2521    int maxError = 
m_board->GetDesignSettings().m_MaxError;
 
 2537    hole_base.
Append( corner );
 
 2538    corner.
x += hole_size;
 
 2539    hole_base.
Append( corner );
 
 2540    corner.
y += hole_size;
 
 2541    hole_base.
Append( corner );
 
 2543    hole_base.
Append( corner );
 
 2563        #define SMOOTH_MIN_VAL_MM 0.02 
 2564        #define SMOOTH_SMALL_VAL_MM 0.04 
 2580            smooth_value = std::min( smooth_value, aZone->
GetHatchGap() / 2 );
 
 2583            maxError = std::max( maxError * 2, smooth_value / 20 );
 
 2585            switch( smooth_level )
 
 2597                hole_base = smooth_hole.
Fillet( smooth_value, maxError ).
Outline( 0 );
 
 2610    bool     zone_has_offset = 
false;
 
 2619    if( !zone_has_offset )
 
 2632    int x_offset = bbox.
GetX() - ( bbox.
GetX() ) % gridsize - gridsize;
 
 2633    int y_offset = bbox.
GetY() - ( bbox.
GetY() ) % gridsize - gridsize;
 
 2636    for( 
int xx = x_offset; xx <= bbox.
GetRight(); xx += gridsize )
 
 2638        for( 
int yy = y_offset; yy <= bbox.
GetBottom(); yy += gridsize )
 
 2649            hole.
Move( 
VECTOR2I( offset_opt.
x % gridsize, offset_opt.
y % gridsize ) );
 
 2662    deflated_thickness = std::max( deflated_thickness, maxError * 2 );
 
 2684        if( area < minimal_hole_area ) 
 
 
constexpr EDA_IU_SCALE pcbIUScale
 
@ ZLO_FORCE_NO_ZONE_CONNECTION
 
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
 
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
 
Container for design settings for a BOARD object.
 
std::shared_ptr< DRC_ENGINE > m_DRCEngine
 
int GetBiggestClearanceValue() const
 
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
 
virtual void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const
Convert the item shape to a closed polygon.
 
virtual void SetIsKnockout(bool aKnockout)
 
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
 
Information pertinent to a Pcbnew printed circuit board.
 
int GetCopperLayerCount() const
 
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
 
constexpr int GetSizeMax() const
 
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
 
constexpr coord_type GetY() const
 
constexpr size_type GetWidth() const
 
constexpr coord_type GetX() const
 
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
 
constexpr const Vec GetCenter() const
 
constexpr size_type GetHeight() const
 
constexpr coord_type GetRight() const
 
constexpr bool Intersects(const BOX2< Vec > &aRect) const
 
constexpr coord_type GetBottom() const
 
Represent a set of changes (additions, deletions or modifications) of a data model (e....
 
MINOPTMAX< int > & Value()
 
const MINOPTMAX< int > & GetValue() const
 
ZONE_CONNECTION m_ZoneConnection
 
DRC_CONSTRAINT EvalRules(DRC_CONSTRAINT_T aConstraintType, const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
 
DRC_CONSTRAINT EvalZoneConnection(const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
 
KICAD_T Type() const
Returns the type of object.
 
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
 
void DoNotShowCheckbox(wxString file, int line)
Shows the 'do not show again' checkbox.
 
bool SetOKCancelLabels(const ButtonLabel &ok, const ButtonLabel &cancel) override
 
LSET is a set of PCB_LAYER_IDs.
 
static LSET AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
 
static const LSET & InternalCuMask()
Return a complete set of internal copper layers which is all Cu layers except F_Cu and B_Cu.
 
A PADSTACK defines the characteristics of a single or multi-layer pad, in the IPC sense of the word.
 
UNCONNECTED_LAYER_MODE UnconnectedLayerMode() const
 
const BOX2I GetBoundingBox() const override
The bounding box is cached, so this will be efficient most of the time.
 
PAD_SHAPE GetShape(PCB_LAYER_ID aLayer) const
 
void SetOffset(PCB_LAYER_ID aLayer, const VECTOR2I &aOffset)
 
void SetPosition(const VECTOR2I &aPos) override
 
void SetOrientation(const EDA_ANGLE &aAngle)
Set the rotation angle of the pad.
 
bool TransformHoleToPolygon(SHAPE_POLY_SET &aBuffer, int aClearance, int aError, ERROR_LOC aErrorLoc=ERROR_INSIDE) const
Build the corner list of the polygonal drill shape in the board coordinate system.
 
void GetBoundingHull(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc=ERROR_INSIDE) const
 
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool aIgnoreLineWidth=false) const override
Convert the item shape to a closed polygon.
 
void TransformTextToPolySet(SHAPE_POLY_SET &aBuffer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc) const
Function TransformTextToPolySet Convert the text to a polygonSet describing the actual character stro...
 
void SetPosition(const VECTOR2I &aPoint) override
 
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
 
A progress reporter interface for use in multi-threaded environments.
 
RESULTS(int aOutline1, int aOutline2, int aVertex1, int aVertex2)
 
bool operator<(const RESULTS &aOther) const
 
VECTOR2I::extended_type ecoord
 
static SEG::ecoord Square(int a)
 
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
 
void Move(const VECTOR2I &aVector) override
 
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
 
int Intersect(const SEG &aSeg, INTERSECTIONS &aIp) const
Find all intersection points between our line chain and the segment aSeg.
 
int PointCount() const
Return the number of points (vertices) in this line chain.
 
void Clear()
Remove all points from the line chain.
 
double Area(bool aAbsolute=true) const
Return the area of this chain.
 
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
 
void Rotate(const EDA_ANGLE &aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Rotate all vertices by a given angle.
 
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
 
std::vector< INTERSECTION > INTERSECTIONS
 
Represent a set of closed polygons.
 
void Rotate(const EDA_ANGLE &aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Rotate all vertices by a given angle.
 
SHAPE_POLY_SET Chamfer(int aDistance)
Return a chamfered version of the polygon set.
 
void ClearArcs()
Removes all arc references from all the outlines and holes in the polyset.
 
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
 
void DeletePolygon(int aIdx)
Delete aIdx-th polygon from the set.
 
double Area()
Return the area of this poly set.
 
void Fracture()
Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the oute...
 
bool Collide(const SHAPE *aShape, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the shape aShape than aClearance,...
 
POLYGON & Polygon(int aIndex)
Return the aIndex-th subpolygon in the set.
 
void Inflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, bool aSimplify=false)
Perform outline inflation/deflation.
 
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
 
void Simplify()
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections)
 
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
 
int NewOutline()
Creates a new empty polygon in the set and returns its index.
 
void Deflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError)
 
void BooleanIntersection(const SHAPE_POLY_SET &b)
Perform boolean polyset intersection.
 
void BuildBBoxCaches() const
Construct BBoxCaches for Contains(), below.
 
int OutlineCount() const
Return the number of outlines in the set.
 
SHAPE_POLY_SET Fillet(int aRadius, int aErrorMax)
Return a filleted version of the polygon set.
 
bool Contains(const VECTOR2I &aP, int aSubpolyIndex=-1, int aAccuracy=0, bool aUseBBoxCaches=false) const
Return true if a given subpolygon contains the point aP.
 
SHAPE_POLY_SET CloneDropTriangulation() const
 
void BooleanSubtract(const SHAPE_POLY_SET &b)
Perform boolean polyset difference.
 
const BOX2I BBoxFromCaches() const
 
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
 
constexpr extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
 
constexpr VECTOR2< T > Perpendicular() const
Compute the perpendicular vector.
 
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
 
VERTEX * getPoint(VERTEX *aPt) const
 
std::set< RESULTS > GetResults() const
 
VERTEX_CONNECTOR(const BOX2I &aBBox, const SHAPE_POLY_SET &aPolys, int aDist)
 
std::set< RESULTS > m_results
 
std::deque< VERTEX > m_vertices
 
VERTEX * createList(const SHAPE_LINE_CHAIN &points, VERTEX *aTail=nullptr, void *aUserData=nullptr)
Create a list of vertices from a line chain.
 
void SetBoundingBox(const BOX2I &aBBox)
 
VERTEX_SET(int aSimplificationLevel)
 
uint32_t zOrder(const double aX, const double aY) const
Note that while the inputs are doubles, these are scaled by the size of the bounding box to fit into ...
 
void updateList()
After inserting or changing nodes, this function should be called to remove duplicate vertices and en...
 
void * GetUserData() const
 
bool isEar(bool aMatchUserData=false) const
Check whether the given vertex is in the middle of an ear.
 
void buildCopperItemClearances(const ZONE *aZone, PCB_LAYER_ID aLayer, const std::vector< PAD * > &aNoConnectionPads, SHAPE_POLY_SET &aHoles)
Removes clearance from the shape for copper items which share the zone's layer but are not connected ...
 
void connect_nearby_polys(SHAPE_POLY_SET &aPolys, double aDistance)
Create strands of zero-width between elements of SHAPE_POLY_SET that are within aDistance of each oth...
 
void buildThermalSpokes(const ZONE *box, PCB_LAYER_ID aLayer, const std::vector< BOARD_ITEM * > &aSpokedPadsList, std::deque< SHAPE_LINE_CHAIN > &aSpokes)
Function buildThermalSpokes Constructs a list of all thermal spokes for the given zone.
 
ZONE_FILLER(BOARD *aBoard, COMMIT *aCommit)
 
void subtractHigherPriorityZones(const ZONE *aZone, PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aRawFill)
Removes the outlines of higher-proirity zones with the same net.
 
void knockoutThermalReliefs(const ZONE *aZone, PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aFill, std::vector< BOARD_ITEM * > &aThermalConnectionPads, std::vector< PAD * > &aNoConnectionPads)
Removes thermal reliefs from the shape for any pads connected to the zone.
 
void addKnockout(BOARD_ITEM *aItem, PCB_LAYER_ID aLayer, int aGap, SHAPE_POLY_SET &aHoles)
Add a knockout for a pad or via.
 
SHAPE_POLY_SET m_boardOutline
 
bool addHatchFillTypeOnZone(const ZONE *aZone, PCB_LAYER_ID aLayer, PCB_LAYER_ID aDebugLayer, SHAPE_POLY_SET &aFillPolys)
for zones having the ZONE_FILL_MODE::ZONE_FILL_MODE::HATCH_PATTERN, create a grid pattern in filled a...
 
void SetProgressReporter(PROGRESS_REPORTER *aReporter)
 
PROGRESS_REPORTER * m_progressReporter
 
bool fillCopperZone(const ZONE *aZone, PCB_LAYER_ID aLayer, PCB_LAYER_ID aDebugLayer, const SHAPE_POLY_SET &aSmoothedOutline, const SHAPE_POLY_SET &aMaxExtents, SHAPE_POLY_SET &aFillPolys)
Function fillCopperZone Add non copper areas polygons (pads and tracks with clearance) to a filled co...
 
void addHoleKnockout(PAD *aPad, int aGap, SHAPE_POLY_SET &aHoles)
Add a knockout for a pad's hole.
 
bool fillNonCopperZone(const ZONE *candidate, PCB_LAYER_ID aLayer, const SHAPE_POLY_SET &aSmoothedOutline, SHAPE_POLY_SET &aFillPolys)
 
bool fillSingleZone(ZONE *aZone, PCB_LAYER_ID aLayer, SHAPE_POLY_SET &aFillPolys)
Build the filled solid areas polygons from zone outlines (stored in m_Poly) The solid areas can be mo...
 
bool Fill(const std::vector< ZONE * > &aZones, bool aCheck=false, wxWindow *aParent=nullptr)
Fills the given list of zones.
 
ZONE_SETTINGS handles zones parameters.
 
std::map< PCB_LAYER_ID, ZONE_LAYER_PROPERTIES > m_LayerProperties
 
Handle a list of polygons defining a copper zone.
 
void SetNeedRefill(bool aNeedRefill)
 
std::optional< int > GetLocalClearance() const override
 
ZONE_LAYER_PROPERTIES & LayerProperties(PCB_LAYER_ID aLayer)
 
const std::optional< VECTOR2I > & HatchingOffset(PCB_LAYER_ID aLayer) const
 
void CacheTriangulation(PCB_LAYER_ID aLayer=UNDEFINED_LAYER)
Create a list of triangles that "fill" the solid areas used for instance to draw these solid areas on...
 
const BOX2I GetBoundingBox() const override
 
SHAPE_POLY_SET * Outline()
 
void SetFillFlag(PCB_LAYER_ID aLayer, bool aFlag)
 
void SetFilledPolysList(PCB_LAYER_ID aLayer, const SHAPE_POLY_SET &aPolysList)
Set the list of filled polygons.
 
int GetMinThickness() const
 
bool HigherPriority(const ZONE *aOther) const
 
int GetHatchThickness() const
 
double GetHatchHoleMinArea() const
 
bool IsTeardropArea() const
 
EDA_ANGLE GetHatchOrientation() const
 
bool BuildSmoothedPoly(SHAPE_POLY_SET &aSmoothedPoly, PCB_LAYER_ID aLayer, SHAPE_POLY_SET *aBoardOutline, SHAPE_POLY_SET *aSmoothedPolyWithApron=nullptr) const
 
ZONE_FILL_MODE GetFillMode() const
 
double GetHatchSmoothingValue() const
 
int GetHatchSmoothingLevel() const
 
bool IsOnCopperLayer() const override
 
unsigned GetAssignedPriority() const
 
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aBuffer, const VECTOR2I &aCenter, int aRadius, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a circle to a polygon, using multiple straight lines.
 
void BuildConvexHull(std::vector< VECTOR2I > &aResult, const std::vector< VECTOR2I > &aPoly)
Calculate the convex hull of a list of points in counter-clockwise order.
 
CORNER_STRATEGY
define how inflate transform build inflated polygon
 
@ CHAMFER_ALL_CORNERS
All angles are chamfered.
 
@ ROUND_ALL_CORNERS
All angles are rounded.
 
@ EDGE_CLEARANCE_CONSTRAINT
 
@ PHYSICAL_HOLE_CLEARANCE_CONSTRAINT
 
@ THERMAL_SPOKE_WIDTH_CONSTRAINT
 
@ THERMAL_RELIEF_GAP_CONSTRAINT
 
@ HOLE_CLEARANCE_CONSTRAINT
 
@ PHYSICAL_CLEARANCE_CONSTRAINT
 
static constexpr EDA_ANGLE ANGLE_0
 
a few functions useful in geometry calculations.
 
bool m_DebugZoneFiller
A mode that dumps the various stages of a F_Cu fill into In1_Cu through In9_Cu.
 
@ ALWAYS_FLASHED
Always flashed for connectivity.
 
PCB_LAYER_ID
A quick note on layer IDs:
 
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
 
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
 
@ PTH
Plated through hole pad.
 
BARCODE class definition.
 
A storage class for 128-bit hash value.
 
A struct recording the isolated and single-pad islands within a zone.
 
std::optional< VECTOR2I > hatching_offset
 
wxString result
Test unit parsing edge cases and error handling.
 
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
 
BS::thread_pool< 0 > thread_pool
 
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
 
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
 
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
 
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
 
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
 
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
 
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
 
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
 
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
 
@ PCB_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
 
@ PCB_TARGET_T
class PCB_TARGET, a target (graphic item)
 
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
 
@ PCB_PAD_T
class PAD, a pad in a footprint
 
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
 
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
 
VECTOR2< int32_t > VECTOR2I
 
VECTOR2< double > VECTOR2D
 
#define SMOOTH_MIN_VAL_MM
 
int getHatchFillThermalClearance(const ZONE *aZone, BOARD_ITEM *aItem, PCB_LAYER_ID aLayer)
 
#define DUMP_POLYS_TO_COPPER_LAYER(a, b, c)
 
#define SMOOTH_SMALL_VAL_MM
 
ISLAND_REMOVAL_MODE
Whether or not to remove isolated islands from a zone.
 
ZONE_CONNECTION
How pads are covered by copper in zone.
 
@ THERMAL
Use thermal relief for pads.
 
@ NONE
Pads are not covered.
 
@ FULL
pads are covered by copper