Add keepout in footprints: Starting point.

This commit is contained in:
Ross Schlaikjer 2019-10-19 16:45:08 +02:00 committed by jean-pierre charras
parent e533ea4ae6
commit 64a42ffa35
23 changed files with 302 additions and 62 deletions

View File

@ -450,6 +450,25 @@ public:
return SEARCH_CONTINUE;
}
/**
* @copydoc SEARCH_RESULT IterateForward( EDA_ITEM*, INSPECTOR, void*, const KICAD_T )
*
* This changes first parameter to avoid the DList and use std::vector instead
*/
template <class T>
static SEARCH_RESULT IterateForward(
std::vector<T>& aList, INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] )
{
for( auto it : aList )
{
if( static_cast<EDA_ITEM*>( it )->Visit( inspector, testData, scanTypes )
== SEARCH_QUIT )
return SEARCH_QUIT;
}
return SEARCH_CONTINUE;
}
/**
* Function GetClass
* returns the class name.

View File

@ -123,11 +123,11 @@ public:
///> Adds a change of the item aItem of type aChangeType to the change list.
COMMIT& Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType );
virtual COMMIT& Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType );
COMMIT& Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType );
virtual COMMIT& Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType );
COMMIT& Stage( const PICKED_ITEMS_LIST& aItems, UNDO_REDO_T aModFlag = UR_UNSPECIFIED );
virtual COMMIT& Stage( const PICKED_ITEMS_LIST& aItems, UNDO_REDO_T aModFlag = UR_UNSPECIFIED );
///> Executes the changes.
virtual void Push( const wxString& aMessage = wxT( "A commit" ),

View File

@ -56,6 +56,30 @@ BOARD_COMMIT::~BOARD_COMMIT()
{
}
COMMIT& BOARD_COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType )
{
// if aItem belongs a footprint, the full footprint will be saved
// because undo/redo does not handle "sub items" modifications
if( aItem && aItem->Type() != PCB_MODULE_T && aChangeType == CHT_MODIFY )
{
EDA_ITEM* item = aItem->GetParent();
if( item && item->Type() == PCB_MODULE_T ) // means aItem belongs a footprint
aItem = item;
}
return COMMIT::Stage( aItem, aChangeType );
}
COMMIT& BOARD_COMMIT::Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType )
{
return COMMIT::Stage( container, aChangeType );
}
COMMIT& BOARD_COMMIT::Stage( const PICKED_ITEMS_LIST& aItems, UNDO_REDO_T aModFlag )
{
return COMMIT::Stage( aItems, aModFlag );
}
void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry, bool aSetDirtyBit )
{

View File

@ -46,6 +46,10 @@ public:
bool aCreateUndoEntry = true, bool aSetDirtyBit = true ) override;
virtual void Revert() override;
COMMIT& Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType ) override;
COMMIT& Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType ) override;
COMMIT& Stage(
const PICKED_ITEMS_LIST& aItems, UNDO_REDO_T aModFlag = UR_UNSPECIFIED ) override;
private:
TOOL_MANAGER* m_toolMgr;

View File

@ -28,6 +28,7 @@
#define BOARD_ITEM_CONTAINER_H
#include <class_board_item.h>
#include <zone_settings.h>
enum ADD_MODE { ADD_INSERT, ADD_APPEND };
@ -63,6 +64,26 @@ public:
Remove( aItem );
delete aItem;
}
/**
* @brief Fetch the zone settings for this container
*/
const ZONE_SETTINGS& GetZoneSettings() const
{
return m_zoneSettings;
}
/**
* @brief Set the zone settings for this container
* @param aSettings new Zone settings for this container
*/
void SetZoneSettings( const ZONE_SETTINGS& aSettings )
{
m_zoneSettings = aSettings;
}
private:
ZONE_SETTINGS m_zoneSettings;
};
#endif /* BOARD_ITEM_CONTAINER_H */

View File

@ -1519,6 +1519,29 @@ MODULE* BOARD::GetFootprint( const wxPoint& aPosition, PCB_LAYER_ID aActiveLayer
return NULL;
}
std::list<ZONE_CONTAINER*> BOARD::GetZoneList( bool aIncludeZonesInFootprints )
{
std::list<ZONE_CONTAINER*> zones;
for( int ii = 0; ii < GetAreaCount(); ii++ )
{
zones.push_back( GetArea( ii ) );
}
if( aIncludeZonesInFootprints )
{
for( MODULE* mod : m_modules )
{
for( ZONE_CONTAINER* zone : mod->Zones() )
{
zones.push_back( zone );
}
}
}
return zones;
}
ZONE_CONTAINER* BOARD::AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode,
PCB_LAYER_ID aLayer, wxPoint aStartPointPosition, int aHatch )

View File

@ -192,7 +192,6 @@ private:
std::shared_ptr<CONNECTIVITY_DATA> m_connectivity;
BOARD_DESIGN_SETTINGS m_designSettings;
ZONE_SETTINGS m_zoneSettings;
PCB_GENERAL_SETTINGS* m_generalSettings; ///< reference only; I have no ownership
PAGE_INFO m_paper;
TITLE_BLOCK m_titles; ///< text in lower right of screen and plots
@ -561,9 +560,6 @@ public:
TITLE_BLOCK& GetTitleBlock() { return m_titles; }
void SetTitleBlock( const TITLE_BLOCK& aTitleBlock ) { m_titles = aTitleBlock; }
const ZONE_SETTINGS& GetZoneSettings() const { return m_zoneSettings; }
void SetZoneSettings( const ZONE_SETTINGS& aSettings ) { m_zoneSettings = aSettings; }
wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override;
/**
@ -948,6 +944,12 @@ public:
return -1;
}
/**
* Function GetZoneList
* @return a std::list of pointers to all board zones (possibly including zones in footprints)
*/
std::list<ZONE_CONTAINER*> GetZoneList( bool aIncludeZonesInFootprints = false );
/**
* Function GetAreaCount
* @return int - The number of Areas or ZONE_CONTAINER.

View File

@ -108,6 +108,10 @@ MODULE::MODULE( const MODULE& aModule ) :
Add( new D_PAD( *pad ) );
}
// Copy auxiliary data: Zones
for( auto item : aModule.Zones() )
Add( static_cast<ZONE_CONTAINER*>( item->Clone() ) );
// Copy auxiliary data: Drawings
for( auto item : aModule.GraphicalItems() )
{
@ -152,6 +156,11 @@ MODULE::~MODULE()
m_pads.clear();
for( auto p : m_zones )
delete p;
m_zones.clear();
for( auto d : m_drawings )
delete d;
@ -197,6 +206,14 @@ MODULE& MODULE::operator=( const MODULE& aOther )
Add( new D_PAD( *pad ) );
}
// Copy auxiliary data: Zones
m_zones.clear();
for( auto item : aOther.Zones() )
{
Add( static_cast<ZONE_CONTAINER*>( item->Clone() ) );
}
// Copy auxiliary data: Drawings
m_drawings.clear();
@ -261,6 +278,13 @@ void MODULE::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode )
m_pads.push_front( static_cast<D_PAD*>( aBoardItem ) );
break;
case PCB_ZONE_AREA_T:
if( aMode == ADD_APPEND )
m_zones.push_back( static_cast<ZONE_CONTAINER*>( aBoardItem ) );
else
m_zones.insert( m_zones.begin(), static_cast<ZONE_CONTAINER*>( aBoardItem ) );
break;
default:
{
wxString msg;
@ -313,6 +337,18 @@ void MODULE::Remove( BOARD_ITEM* aBoardItem )
break;
case PCB_ZONE_AREA_T:
for( auto it = m_zones.begin(); it != m_zones.end(); ++it )
{
if( *it == static_cast<ZONE_CONTAINER*>( aBoardItem ) )
{
m_zones.erase( it );
break;
}
}
break;
default:
{
wxString msg;
@ -329,6 +365,9 @@ void MODULE::Print( PCB_BASE_FRAME* aFrame, wxDC* aDC, const wxPoint& aOffset )
for( auto pad : m_pads )
pad->Print( aFrame, aDC, aOffset );
for( auto zone : m_zones )
zone->Print( aFrame, aDC, aOffset );
BOARD* brd = GetBoard();
// Draw graphic items
@ -385,6 +424,9 @@ EDA_RECT MODULE::GetFootprintRect() const
for( auto pad : m_pads )
area.Merge( pad->GetBoundingBox() );
for( auto zone : m_zones )
area.Merge( zone->GetBoundingBox() );
return area;
}
@ -590,6 +632,12 @@ bool MODULE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) co
return true;
}
for( auto zone : m_zones )
{
if( zone->HitTest( arect, false, 0 ) )
return true;
}
for( auto item : m_drawings )
{
if( item->HitTest( arect, false, 0 ) )
@ -742,6 +790,11 @@ SEARCH_RESULT MODULE::Visit( INSPECTOR inspector, void* testData, const KICAD_T
++p;
break;
case PCB_ZONE_AREA_T:
result = IterateForward<ZONE_CONTAINER*>( m_zones, inspector, testData, p );
++p;
break;
case PCB_MODULE_TEXT_T:
result = inspector( m_Reference, testData );
@ -819,6 +872,9 @@ void MODULE::RunOnChildren( const std::function<void (BOARD_ITEM*)>& aFunction )
for( auto pad : m_pads )
aFunction( static_cast<BOARD_ITEM*>( pad ) );
for( auto zone : m_zones )
aFunction( static_cast<ZONE_CONTAINER*>( zone ) );
for( auto drawing : m_drawings )
aFunction( static_cast<BOARD_ITEM*>( drawing ) );
@ -1023,6 +1079,10 @@ void MODULE::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
for( auto pad : m_pads )
pad->Flip( m_Pos, false );
// Mirror zones to other side of board.
for( auto zone : m_zones )
zone->Flip( m_Pos, aFlipLeftRight );
// Mirror reference and value.
m_Reference->Flip( m_Pos, false );
m_Value->Flip( m_Pos, false );
@ -1068,6 +1128,9 @@ void MODULE::SetPosition( const wxPoint& newpos )
pad->SetPosition( pad->GetPosition() + delta );
}
for( auto zone : m_zones )
zone->Move( delta );
for( auto item : m_drawings )
{
switch( item->Type() )
@ -1167,6 +1230,11 @@ void MODULE::SetOrientation( double newangle )
pad->SetDrawCoord();
}
for( auto zone : m_zones )
{
zone->Rotate( GetPosition(), angleChange );
}
// Update of the reference and value.
m_Reference->SetDrawCoord();
m_Value->SetDrawCoord();
@ -1193,6 +1261,7 @@ BOARD_ITEM* MODULE::Duplicate( const BOARD_ITEM* aItem,
{
BOARD_ITEM* new_item = NULL;
D_PAD* new_pad = NULL;
ZONE_CONTAINER* new_zone = NULL;
switch( aItem->Type() )
{
@ -1207,6 +1276,17 @@ BOARD_ITEM* MODULE::Duplicate( const BOARD_ITEM* aItem,
break;
}
case PCB_ZONE_AREA_T:
{
new_zone = new ZONE_CONTAINER( *static_cast<const ZONE_CONTAINER*>( aItem ) );
if( aAddToModule )
m_zones.push_back( new_zone );
new_item = new_zone;
break;
}
case PCB_MODULE_TEXT_T:
{
const TEXTE_MODULE* old_text = static_cast<const TEXTE_MODULE*>( aItem );

View File

@ -41,8 +41,9 @@
#include <lib_id.h>
#include <list>
#include <class_text_mod.h>
#include "zones.h"
#include <class_text_mod.h>
#include <class_zone.h>
#include <core/iterators.h>
@ -105,6 +106,7 @@ class MODULE_3D_SETTINGS
DECL_DEQ_FOR_SWIG( PADS, D_PAD* )
DECL_DEQ_FOR_SWIG( DRAWINGS, BOARD_ITEM* )
DECL_VEC_FOR_SWIG( ZONE_CONTAINERS, ZONE_CONTAINER* )
DECL_DEQ_FOR_SWIG( MODULES, MODULE* )
class MODULE : public BOARD_ITEM_CONTAINER
@ -177,6 +179,11 @@ public:
return m_drawings;
}
const ZONE_CONTAINERS& Zones() const
{
return m_zones;
}
const DRAWINGS& GraphicalItems() const
{
return m_drawings;
@ -662,8 +669,9 @@ public:
#endif
private:
DRAWINGS m_drawings; // BOARD_ITEMs for drawings on the board, owned by pointer.
PADS m_pads; // D_PAD items, owned by pointer
DRAWINGS m_drawings; // BOARD_ITEMs for drawings on the board, owned by pointer.
PADS m_pads; // D_PAD items, owned by pointer
ZONE_CONTAINERS m_zones; // ZONE items, owned by pointer
std::list<MODULE_3D_SETTINGS> m_3D_Drawings; // Linked list of 3D models.
double m_Orient; // Orientation in tenths of a degree, 900=90.0 degrees.

View File

@ -42,8 +42,8 @@
#include <polygon_test_point_inside.h>
ZONE_CONTAINER::ZONE_CONTAINER( BOARD* aBoard ) :
BOARD_CONNECTED_ITEM( aBoard, PCB_ZONE_AREA_T )
ZONE_CONTAINER::ZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent )
: BOARD_CONNECTED_ITEM( aParent, PCB_ZONE_AREA_T )
{
m_CornerSelection = nullptr; // no corner is selected
m_IsFilled = false; // fill status : true when the zone is filled
@ -67,14 +67,14 @@ ZONE_CONTAINER::ZONE_CONTAINER( BOARD* aBoard ) :
SetLocalFlags( 0 ); // flags tempoarry used in zone calculations
m_Poly = new SHAPE_POLY_SET(); // Outlines
m_FilledPolysUseThickness = true; // set the "old" way to build filled polygon areas (before 6.0.x)
aBoard->GetZoneSettings().ExportSetting( *this );
aParent->GetZoneSettings().ExportSetting( *this );
m_needRefill = false; // True only after some edition.
}
ZONE_CONTAINER::ZONE_CONTAINER( const ZONE_CONTAINER& aZone ) :
BOARD_CONNECTED_ITEM( aZone )
ZONE_CONTAINER::ZONE_CONTAINER( const ZONE_CONTAINER& aZone )
: BOARD_CONNECTED_ITEM( aZone.GetParent(), PCB_ZONE_AREA_T )
{
m_Poly = new SHAPE_POLY_SET( *aZone.m_Poly );

View File

@ -63,7 +63,7 @@ public:
*/
typedef enum HATCH_STYLE { NO_HATCH, DIAGONAL_FULL, DIAGONAL_EDGE } HATCH_STYLE;
ZONE_CONTAINER( BOARD* parent );
ZONE_CONTAINER( BOARD_ITEM_CONTAINER* parent );
ZONE_CONTAINER( const ZONE_CONTAINER& aZone );
ZONE_CONTAINER& operator=( const ZONE_CONTAINER &aOther );

View File

@ -107,21 +107,12 @@ const KICAD_T GENERAL_COLLECTOR::PadsOrTracks[] = {
};
const KICAD_T GENERAL_COLLECTOR::ModulesAndTheirItems[] = {
PCB_MODULE_TEXT_T,
PCB_MODULE_EDGE_T,
PCB_PAD_T,
PCB_MODULE_T,
EOT
};
const KICAD_T GENERAL_COLLECTOR::ModulesAndTheirItems[] = { PCB_MODULE_TEXT_T, PCB_MODULE_EDGE_T,
PCB_PAD_T, PCB_MODULE_T, PCB_ZONE_AREA_T, EOT };
const KICAD_T GENERAL_COLLECTOR::ModuleItems[] = {
PCB_MODULE_TEXT_T,
PCB_MODULE_EDGE_T,
PCB_PAD_T,
EOT
};
const KICAD_T GENERAL_COLLECTOR::ModuleItems[] = { PCB_MODULE_TEXT_T, PCB_MODULE_EDGE_T, PCB_PAD_T,
PCB_ZONE_AREA_T, EOT };
const KICAD_T GENERAL_COLLECTOR::Tracks[] = {

View File

@ -385,6 +385,38 @@ void FOOTPRINT_EDIT_FRAME::OnEditItemRequest( BOARD_ITEM* aItem )
InstallGraphicItemPropertiesDialog( aItem );
break;
case PCB_ZONE_AREA_T:
{
ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( aItem );
bool success = false;
if( zone )
{
ZONE_SETTINGS zoneSettings;
zoneSettings << *zone;
if( zone->GetIsKeepout() )
{
success = InvokeKeepoutAreaEditor( this, &zoneSettings );
}
else if( zone->IsOnCopperLayer() )
{
success = InvokeCopperZonesEditor( this, &zoneSettings );
}
else
{
success = InvokeNonCopperZonesEditor( this, &zoneSettings );
}
if( success )
{
BOARD_COMMIT commit( this );
commit.Modify( zone );
commit.Push( _( "Edit Zone" ) );
zoneSettings.ExportSetting( *zone );
}
}
}
break;
default:
break;
}

View File

@ -1140,6 +1140,10 @@ void PCB_IO::format( MODULE* aModule, int aNestLevel ) const
for( auto pad : aModule->Pads() )
format( pad, aNestLevel+1 );
// Save zones.
for( auto zone : aModule->Zones() )
format( zone, aNestLevel + 1 );
// Save 3D info.
auto bs3D = aModule->Models().begin();
auto es3D = aModule->Models().end();

View File

@ -62,7 +62,8 @@ class TEXTE_PCB;
//#define SEXPR_BOARD_FILE_VERSION 20190421 // curves in custom pads
//#define SEXPR_BOARD_FILE_VERSION 20190516 // Remove segment count from zones
//#define SEXPR_BOARD_FILE_VERSION 20190605 // Add layer defaults
#define SEXPR_BOARD_FILE_VERSION 20190905 // Add board physical stackup info in setup section
//#define SEXPR_BOARD_FILE_VERSION 20190905 // Add board physical stackup info in setup section
#define SEXPR_BOARD_FILE_VERSION 20190907 // Keepout areas in footprints
#define CTL_STD_LAYER_NAMES (1 << 0) ///< Use English Standard layer names
#define CTL_OMIT_NETS (1 << 1) ///< Omit pads net names (useless in library)

View File

@ -228,15 +228,16 @@ void FOOTPRINT_EDIT_FRAME::ReCreateMenuBar()
placeMenu->AddItem( PCB_ACTIONS::placePad, haveFootprintCondition );
placeMenu->AddSeparator();
placeMenu->AddItem( PCB_ACTIONS::placeText, haveFootprintCondition );
placeMenu->AddItem( PCB_ACTIONS::drawArc, haveFootprintCondition );
placeMenu->AddItem( PCB_ACTIONS::drawCircle, haveFootprintCondition );
placeMenu->AddItem( PCB_ACTIONS::drawLine, haveFootprintCondition );
placeMenu->AddItem( PCB_ACTIONS::placeText, haveFootprintCondition );
placeMenu->AddItem( PCB_ACTIONS::drawArc, haveFootprintCondition );
placeMenu->AddItem( PCB_ACTIONS::drawCircle, haveFootprintCondition );
placeMenu->AddItem( PCB_ACTIONS::drawLine, haveFootprintCondition );
placeMenu->AddItem( PCB_ACTIONS::drawPolygon, haveFootprintCondition );
placeMenu->AddItem( PCB_ACTIONS::drawZoneKeepout, haveFootprintCondition );
placeMenu->AddSeparator();
placeMenu->AddItem( PCB_ACTIONS::setAnchor, haveFootprintCondition );
placeMenu->AddItem( ACTIONS::gridSetOrigin, haveFootprintCondition );
placeMenu->AddItem( PCB_ACTIONS::setAnchor, haveFootprintCondition );
placeMenu->AddItem( ACTIONS::gridSetOrigin, haveFootprintCondition );
placeMenu->Resolve();

View File

@ -74,6 +74,7 @@ void PCB_PARSER::init()
}
m_layerMasks[ "*.Cu" ] = LSET::AllCuMask();
m_layerMasks["*In.Cu"] = LSET::InternalCuMask();
m_layerMasks[ "F&B.Cu" ] = LSET( 2, F_Cu, B_Cu );
m_layerMasks[ "*.Adhes" ] = LSET( 2, B_Adhes, F_Adhes );
m_layerMasks[ "*.Paste" ] = LSET( 2, B_Paste, F_Paste );
@ -590,7 +591,7 @@ BOARD* PCB_PARSER::parseBOARD_unchecked()
break;
case T_zone:
m_board->Add( parseZONE_CONTAINER(), ADD_APPEND );
m_board->Add( parseZONE_CONTAINER( m_board ), ADD_APPEND );
break;
case T_target:
@ -2511,12 +2512,21 @@ MODULE* PCB_PARSER::parseMODULE_unchecked( wxArrayString* aInitialComments )
module->Add3DModel( parse3DModel() );
break;
case T_zone:
{
ZONE_CONTAINER* zone = parseZONE_CONTAINER( module.get() );
module->Add( zone, ADD_APPEND );
}
break;
default:
Expecting( "locked, placed, tedit, tstamp, at, descr, tags, path, "
"autoplace_cost90, autoplace_cost180, solder_mask_margin, "
"solder_paste_margin, solder_paste_ratio, clearance, "
"zone_connect, thermal_width, thermal_gap, attr, fp_text, "
"fp_arc, fp_circle, fp_curve, fp_line, fp_poly, pad, or model" );
Expecting(
"locked, placed, tedit, tstamp, at, descr, tags, path, "
"autoplace_cost90, autoplace_cost180, solder_mask_margin, "
"solder_paste_margin, solder_paste_ratio, clearance, "
"zone_connect, thermal_width, thermal_gap, attr, fp_text, "
"fp_arc, fp_circle, fp_curve, fp_line, fp_poly, pad, "
"zone, or model" );
}
}
@ -3390,7 +3400,7 @@ VIA* PCB_PARSER::parseVIA()
}
ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER()
ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent )
{
wxCHECK_MSG( CurTok() == T_zone, NULL,
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) +
@ -3407,7 +3417,7 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER()
// bigger scope since each filled_polygon is concatenated in here
SHAPE_POLY_SET pts;
std::unique_ptr< ZONE_CONTAINER > zone( new ZONE_CONTAINER( m_board ) );
std::unique_ptr<ZONE_CONTAINER> zone( new ZONE_CONTAINER( aParent ) );
zone->SetPriority( 0 );

View File

@ -41,6 +41,7 @@
class BOARD;
class BOARD_ITEM;
class BOARD_ITEM_CONTAINER;
class D_PAD;
class BOARD_DESIGN_SETTINGS;
class DIMENSION;
@ -156,7 +157,7 @@ class PCB_PARSER : public PCB_LEXER
bool parseD_PAD_option( D_PAD* aPad );
TRACK* parseTRACK();
VIA* parseVIA();
ZONE_CONTAINER* parseZONE_CONTAINER();
ZONE_CONTAINER* parseZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent );
PCB_TARGET* parsePCB_TARGET();
BOARD* parseBOARD();

View File

@ -53,7 +53,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateHToolbar()
#ifdef KICAD_SCRIPTING
m_mainToolBar->Add( PCB_ACTIONS::createFootprint );
#endif
if( IsCurrentFPFromBoard() )
m_mainToolBar->Add( PCB_ACTIONS::saveToBoard );
else
@ -129,18 +129,19 @@ void FOOTPRINT_EDIT_FRAME::ReCreateVToolbar()
m_drawToolBar->Add( ACTIONS::selectionTool, ACTION_TOOLBAR::TOGGLE );
KiScaledSeparator( m_drawToolBar, this );
m_drawToolBar->Add( PCB_ACTIONS::placePad, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( PCB_ACTIONS::drawLine, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( PCB_ACTIONS::drawCircle, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( PCB_ACTIONS::drawArc, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( PCB_ACTIONS::drawPolygon, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( PCB_ACTIONS::placeText, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( ACTIONS::deleteTool, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( PCB_ACTIONS::placePad, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( PCB_ACTIONS::drawLine, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( PCB_ACTIONS::drawCircle, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( PCB_ACTIONS::drawArc, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( PCB_ACTIONS::drawPolygon, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( PCB_ACTIONS::drawZoneKeepout, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( PCB_ACTIONS::placeText, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( ACTIONS::deleteTool, ACTION_TOOLBAR::TOGGLE );
KiScaledSeparator( m_drawToolBar, this );
m_drawToolBar->Add( PCB_ACTIONS::setAnchor, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( PCB_ACTIONS::gridSetOrigin, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( ACTIONS::measureTool, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( PCB_ACTIONS::setAnchor, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( PCB_ACTIONS::gridSetOrigin, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Add( ACTIONS::measureTool, ACTION_TOOLBAR::TOGGLE );
m_drawToolBar->Realize();
}
@ -205,6 +206,7 @@ void FOOTPRINT_EDIT_FRAME::SyncToolbars()
TOGGLE_TOOL( m_drawToolBar, PCB_ACTIONS::drawCircle );
TOGGLE_TOOL( m_drawToolBar, PCB_ACTIONS::drawArc );
TOGGLE_TOOL( m_drawToolBar, PCB_ACTIONS::drawPolygon );
TOGGLE_TOOL( m_drawToolBar, PCB_ACTIONS::drawZoneKeepout );
TOGGLE_TOOL( m_drawToolBar, PCB_ACTIONS::placeText );
TOGGLE_TOOL( m_drawToolBar, ACTIONS::deleteTool );
TOGGLE_TOOL( m_drawToolBar, PCB_ACTIONS::setAnchor );

View File

@ -882,10 +882,12 @@ void DRC::testZones()
void DRC::testKeepoutAreas()
{
// Get a list of all zones to inspect, from both board and footprints
std::list<ZONE_CONTAINER*> areasToInspect = m_pcb->GetZoneList( true );
// Test keepout areas for vias, tracks and pads inside keepout areas
for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
for( ZONE_CONTAINER* area : areasToInspect )
{
ZONE_CONTAINER* area = m_pcb->GetArea( ii );
if( !area->GetIsKeepout() )
continue;

View File

@ -1461,6 +1461,14 @@ bool SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibilityOn
switch( aItem->Type() )
{
case PCB_ZONE_AREA_T:
{
// Check to see if this keepout is part of a footprint
// If it is, and we are not editing the footprint, it should not be selectable
const bool zoneInFootprint =
aItem->GetParent() != nullptr && aItem->GetParent()->Type() == PCB_MODULE_T;
if( zoneInFootprint && !m_editModules && !checkVisibilityOnly )
return false;
// Keepout zones can exist on multiple layers!
{
auto* zone = static_cast<const ZONE_CONTAINER*>( aItem );
@ -1481,6 +1489,7 @@ bool SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibilityOn
return false;
}
}
}
break;
case PCB_TRACE_T:
@ -1543,6 +1552,12 @@ bool SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibilityOn
return true;
}
for( auto zone : module->Zones() )
{
if( Selectable( zone, true ) )
return true;
}
return false;
}

View File

@ -51,8 +51,9 @@ ZONE_CREATE_HELPER::~ZONE_CREATE_HELPER()
std::unique_ptr<ZONE_CONTAINER> ZONE_CREATE_HELPER::createNewZone( bool aKeepout )
{
auto& frame = *m_tool.getEditFrame<PCB_BASE_FRAME>();
auto& frame = *m_tool.getEditFrame<PCB_BASE_EDIT_FRAME>();
auto& board = *m_tool.getModel<BOARD>();
BOARD_ITEM_CONTAINER* parent = m_tool.m_frame->GetModel();
KIGFX::VIEW_CONTROLS* controls = m_tool.GetManager()->GetViewControls();
// Get the current default settings for zones
@ -85,7 +86,7 @@ std::unique_ptr<ZONE_CONTAINER> ZONE_CREATE_HELPER::createNewZone( bool aKeepout
controls->WarpCursor( controls->GetCursorPosition(), true );
}
auto newZone = std::make_unique<ZONE_CONTAINER>( &board );
auto newZone = std::make_unique<ZONE_CONTAINER>( parent );
// Apply the selected settings
zoneInfo.ExportSetting( *newZone );

View File

@ -621,9 +621,8 @@ void ZONE_FILLER::buildCopperItemClearances( const ZONE_CONTAINER* aZone, SHAPE_
// Add zones outlines having an higher priority and keepout
//
for( int ii = 0; ii < m_board->GetAreaCount(); ii++ )
for( ZONE_CONTAINER* zone : m_board->GetZoneList( true ) )
{
ZONE_CONTAINER* zone = m_board->GetArea( ii );
// If the zones share no common layers
if( !aZone->CommonLayerExists( zone->GetLayerSet() ) )