mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 02:03:12 +02:00
Better algorithm for knocking out footprints.
(Though anything would have been as the previous one didn't work at all.)
This commit is contained in:
parent
78fc95fd6d
commit
7db3ccd98a
@ -149,23 +149,24 @@ void BOARD_COMMIT::propagateDamage( BOARD_ITEM* aItem, std::vector<ZONE*>* aStal
|
||||
else
|
||||
layers &= LSET::AllCuMask();
|
||||
|
||||
if( layers.empty() )
|
||||
return;
|
||||
|
||||
for( ZONE* zone : board->Zones() )
|
||||
if( layers.any() )
|
||||
{
|
||||
if( zone->GetIsRuleArea() )
|
||||
continue;
|
||||
|
||||
if( ( zone->GetLayerSet() & layers ).any()
|
||||
&& zone->GetBoundingBox().Intersects( bbox ) )
|
||||
for( ZONE* zone : board->Zones() )
|
||||
{
|
||||
aStaleZones->push_back( zone );
|
||||
if( zone->GetIsRuleArea() )
|
||||
continue;
|
||||
|
||||
if( ( zone->GetLayerSet() & layers ).any()
|
||||
&& zone->GetBoundingBox().Intersects( bbox ) )
|
||||
{
|
||||
aStaleZones->push_back( zone );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( aStaleHatchedShapes && ( aItem->Type() == PCB_TEXT_T
|
||||
if( aStaleHatchedShapes && ( aItem->Type() == PCB_FIELD_T
|
||||
|| aItem->Type() == PCB_TEXT_T
|
||||
|| aItem->Type() == PCB_TEXTBOX_T
|
||||
|| aItem->Type() == PCB_SHAPE_T ) )
|
||||
{
|
||||
|
@ -1513,7 +1513,6 @@ SHAPE_POLY_SET FOOTPRINT::GetBoundingHull() const
|
||||
}
|
||||
|
||||
SHAPE_POLY_SET rawPolys;
|
||||
SHAPE_POLY_SET hull;
|
||||
|
||||
for( BOARD_ITEM* item : m_drawings )
|
||||
{
|
||||
@ -1588,6 +1587,58 @@ SHAPE_POLY_SET FOOTPRINT::GetBoundingHull() const
|
||||
}
|
||||
|
||||
|
||||
SHAPE_POLY_SET FOOTPRINT::GetBoundingHull( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
const BOARD* board = GetBoard();
|
||||
bool isFPEdit = board && board->IsFootprintHolder();
|
||||
|
||||
SHAPE_POLY_SET rawPolys;
|
||||
SHAPE_POLY_SET hull;
|
||||
|
||||
for( BOARD_ITEM* item : m_drawings )
|
||||
{
|
||||
if( !isFPEdit && m_privateLayers.test( item->GetLayer() ) )
|
||||
continue;
|
||||
|
||||
if( item->IsOnLayer( aLayer ) )
|
||||
{
|
||||
if( item->Type() != PCB_FIELD_T && item->Type() != PCB_REFERENCE_IMAGE_T )
|
||||
{
|
||||
item->TransformShapeToPolygon( rawPolys, UNDEFINED_LAYER, 0, ARC_LOW_DEF,
|
||||
ERROR_OUTSIDE );
|
||||
}
|
||||
|
||||
// We intentionally exclude footprint fields from the bounding hull.
|
||||
}
|
||||
}
|
||||
|
||||
for( PAD* pad : m_pads )
|
||||
{
|
||||
if( pad->IsOnLayer( aLayer ) )
|
||||
pad->TransformShapeToPolygon( rawPolys, aLayer, 0, ARC_LOW_DEF, ERROR_OUTSIDE );
|
||||
}
|
||||
|
||||
for( ZONE* zone : m_zones )
|
||||
{
|
||||
if( const std::shared_ptr<SHAPE_POLY_SET>& layerPoly = zone->GetFilledPolysList( aLayer ) )
|
||||
{
|
||||
for( int ii = 0; ii < layerPoly->OutlineCount(); ii++ )
|
||||
rawPolys.AddOutline( layerPoly->COutline( ii ) );
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<VECTOR2I> convex_hull;
|
||||
BuildConvexHull( convex_hull, rawPolys );
|
||||
|
||||
hull.NewOutline();
|
||||
|
||||
for( const VECTOR2I& pt : convex_hull )
|
||||
hull.Append( pt );
|
||||
|
||||
return hull;
|
||||
}
|
||||
|
||||
|
||||
void FOOTPRINT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
|
||||
{
|
||||
wxString msg, msg2;
|
||||
|
@ -187,6 +187,7 @@ public:
|
||||
* This operation is slower but more accurate than calculating a bounding box.
|
||||
*/
|
||||
SHAPE_POLY_SET GetBoundingHull() const;
|
||||
SHAPE_POLY_SET GetBoundingHull( PCB_LAYER_ID aLayer ) const;
|
||||
|
||||
bool TextOnly() const;
|
||||
|
||||
|
@ -304,44 +304,58 @@ void PCB_SHAPE::updateHatching() const
|
||||
{
|
||||
EDA_SHAPE::updateHatching();
|
||||
|
||||
static std::initializer_list<KICAD_T> knockoutTypes = { PCB_TEXT_T, PCB_TEXTBOX_T,
|
||||
PCB_SHAPE_T };
|
||||
|
||||
if( !m_hatching.IsEmpty() )
|
||||
{
|
||||
PCB_LAYER_ID layer = GetLayer();
|
||||
BOX2I bbox = GetBoundingBox();
|
||||
SHAPE_POLY_SET holes;
|
||||
int maxError = ARC_LOW_DEF;
|
||||
|
||||
auto knockoutItem =
|
||||
[&]( BOARD_ITEM* item )
|
||||
{
|
||||
int margin = GetHatchLineSpacing() / 2;
|
||||
|
||||
if( item->Type() == PCB_TEXTBOX_T )
|
||||
margin = 0;
|
||||
|
||||
item->TransformShapeToPolygon( holes, layer, margin, maxError, ERROR_OUTSIDE );
|
||||
};
|
||||
|
||||
for( BOARD_ITEM* item : GetBoard()->Drawings() )
|
||||
{
|
||||
if( item == this )
|
||||
continue;
|
||||
|
||||
if( item->IsType( knockoutTypes )
|
||||
&& item->GetLayer() == layer
|
||||
&& item->GetBoundingBox().Intersects( bbox ) )
|
||||
if( item->Type() == PCB_FIELD_T
|
||||
|| item->Type() == PCB_TEXT_T
|
||||
|| item->Type() == PCB_TEXTBOX_T
|
||||
|| item->Type() == PCB_SHAPE_T )
|
||||
{
|
||||
item->TransformShapeToPolygon( holes, layer, 0, ARC_LOW_DEF, ERROR_OUTSIDE, true );
|
||||
if( item->GetLayer() == layer && item->GetBoundingBox().Intersects( bbox ) )
|
||||
knockoutItem( item );
|
||||
}
|
||||
|
||||
if( item->Type() == PCB_FOOTPRINT_T )
|
||||
{
|
||||
static_cast<FOOTPRINT*>( item )->RunOnDescendants(
|
||||
[&]( BOARD_ITEM* descendant )
|
||||
}
|
||||
|
||||
for( FOOTPRINT* footprint : GetBoard()->Footprints() )
|
||||
{
|
||||
int margin = GetHatchLineSpacing() / 2;
|
||||
SHAPE_POLY_SET hull = footprint->GetBoundingHull( layer );
|
||||
|
||||
hull.Inflate( margin, CORNER_STRATEGY::CHAMFER_ACUTE_CORNERS, maxError );
|
||||
holes.Append( hull );
|
||||
|
||||
footprint->RunOnDescendants(
|
||||
[&]( BOARD_ITEM* item )
|
||||
{
|
||||
if( item->Type() == PCB_FIELD_T
|
||||
&& item->GetLayer() == layer
|
||||
&& item->GetBoundingBox().Intersects( bbox ) )
|
||||
{
|
||||
if( descendant == this )
|
||||
return;
|
||||
|
||||
if( descendant->IsType( knockoutTypes )
|
||||
&& descendant->GetLayer() == layer
|
||||
&& descendant->GetBoundingBox().Intersects( bbox ) )
|
||||
{
|
||||
descendant->TransformShapeToPolygon( holes, layer, 0, ARC_LOW_DEF,
|
||||
ERROR_OUTSIDE, true );
|
||||
}
|
||||
} );
|
||||
}
|
||||
knockoutItem( item );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
m_hatching.BooleanSubtract( holes );
|
||||
|
@ -31,6 +31,7 @@ using namespace std::placeholders;
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <pcb_track.h>
|
||||
#include <pcb_group.h>
|
||||
#include <pcb_shape.h>
|
||||
#include <pcb_generator.h>
|
||||
#include <pcb_target.h>
|
||||
#include <footprint.h>
|
||||
@ -612,6 +613,33 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
|
||||
}
|
||||
}
|
||||
|
||||
auto checkHatching =
|
||||
[&]( BOARD_ITEM* item )
|
||||
{
|
||||
if( item->Type() == PCB_SHAPE_T )
|
||||
{
|
||||
PCB_SHAPE* shape = static_cast<PCB_SHAPE*>( item );
|
||||
|
||||
if( shape->IsHatchedFill() )
|
||||
{
|
||||
shape->SetHatchingDirty();
|
||||
view->Update( shape );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for( BOARD_ITEM* item : GetBoard()->Drawings() )
|
||||
checkHatching( item );
|
||||
|
||||
for( FOOTPRINT* footprint : GetBoard()->Footprints() )
|
||||
{
|
||||
footprint->RunOnDescendants(
|
||||
[&]( BOARD_ITEM* item )
|
||||
{
|
||||
checkHatching( item );
|
||||
} );
|
||||
}
|
||||
|
||||
if( added_items.size() > 0 || deleted_items.size() > 0 || changed_items.size() > 0 )
|
||||
GetBoard()->OnItemsCompositeUpdate( added_items, deleted_items, changed_items );
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user