keepout in footprint: fix some crashes and issues. Create a specific type (PCB_MODULE_ZONE_AREA_T) for zones in footprint. The new class (MODULE_ZONE_CONTAINER) is the same as ZONE_CONTAINER, but the type ID is PCB_MODULE_ZONE_AREA_T instead of PCB_ZONE_AREA_T.

This is mandatory because these zones must be handled differently in many functions.
This commit is contained in:
jean-pierre charras 2019-10-26 17:49:29 +02:00
parent 64a42ffa35
commit bc5dcf182f
16 changed files with 249 additions and 145 deletions

View File

@ -167,7 +167,7 @@ COMMIT& COMMIT::createModified( EDA_ITEM* aItem, EDA_ITEM* aCopy, int aExtraFlag
void COMMIT::makeEntry( EDA_ITEM* aItem, CHANGE_TYPE aType, EDA_ITEM* aCopy )
{
// Expect an item copy if it is going to be modified
assert( !!aCopy == ( ( aType & CHT_TYPE ) == CHT_MODIFY ) );
wxASSERT( !!aCopy == ( ( aType & CHT_TYPE ) == CHT_MODIFY ) );
if( m_changedItems.find( aItem ) != m_changedItems.end() )
{

View File

@ -92,6 +92,7 @@ enum KICAD_T
PCB_TEXT_T, ///< class TEXTE_PCB, text on a layer
PCB_MODULE_TEXT_T, ///< class TEXTE_MODULE, text in a footprint
PCB_MODULE_EDGE_T, ///< class EDGE_MODULE, a footprint edge
PCB_MODULE_ZONE_AREA_T, ///< class ZONE_CONTAINER, managed by a footprint
PCB_TRACE_T, ///< class TRACK, a track segment (segment on a copper layer)
PCB_VIA_T, ///< class VIA, a via (like a track segment on a copper layer)
PCB_MARKER_T, ///< class MARKER_PCB, a marker used to show something

View File

@ -64,7 +64,7 @@ COMMIT& BOARD_COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType )
{
EDA_ITEM* item = aItem->GetParent();
if( item && item->Type() == PCB_MODULE_T ) // means aItem belongs a footprint
if( item && item->Type() == PCB_MODULE_T ) // means aItem belongs a footprint
aItem = item;
}
@ -171,6 +171,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry, bool a
case PCB_PAD_T:
case PCB_MODULE_EDGE_T:
case PCB_MODULE_TEXT_T:
case PCB_MODULE_ZONE_AREA_T:
// This level can only handle module items when editing modules
if( !m_editModules )
break;
@ -330,9 +331,15 @@ EDA_ITEM* BOARD_COMMIT::parentObject( EDA_ITEM* aItem ) const
case PCB_PAD_T:
case PCB_MODULE_EDGE_T:
case PCB_MODULE_TEXT_T:
case PCB_MODULE_ZONE_AREA_T:
return aItem->GetParent();
default:
case PCB_ZONE_AREA_T:
wxASSERT( !dynamic_cast<MODULE*>( aItem->GetParent() ) );
return aItem;
default:
break;
}
return aItem;

View File

@ -1532,7 +1532,7 @@ std::list<ZONE_CONTAINER*> BOARD::GetZoneList( bool aIncludeZonesInFootprints )
{
for( MODULE* mod : m_modules )
{
for( ZONE_CONTAINER* zone : mod->Zones() )
for( MODULE_ZONE_CONTAINER* zone : mod->Zones() )
{
zones.push_back( zone );
}

View File

@ -110,7 +110,7 @@ MODULE::MODULE( const MODULE& aModule ) :
// Copy auxiliary data: Zones
for( auto item : aModule.Zones() )
Add( static_cast<ZONE_CONTAINER*>( item->Clone() ) );
Add( static_cast<MODULE_ZONE_CONTAINER*>( item->Clone() ) );
// Copy auxiliary data: Drawings
for( auto item : aModule.GraphicalItems() )
@ -156,10 +156,10 @@ MODULE::~MODULE()
m_pads.clear();
for( auto p : m_zones )
for( auto p : m_fp_zones )
delete p;
m_zones.clear();
m_fp_zones.clear();
for( auto d : m_drawings )
delete d;
@ -207,11 +207,11 @@ MODULE& MODULE::operator=( const MODULE& aOther )
}
// Copy auxiliary data: Zones
m_zones.clear();
m_fp_zones.clear();
for( auto item : aOther.Zones() )
{
Add( static_cast<ZONE_CONTAINER*>( item->Clone() ) );
Add( static_cast<MODULE_ZONE_CONTAINER*>( item->Clone() ) );
}
// Copy auxiliary data: Drawings
@ -278,11 +278,11 @@ void MODULE::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode )
m_pads.push_front( static_cast<D_PAD*>( aBoardItem ) );
break;
case PCB_ZONE_AREA_T:
case PCB_MODULE_ZONE_AREA_T:
if( aMode == ADD_APPEND )
m_zones.push_back( static_cast<ZONE_CONTAINER*>( aBoardItem ) );
m_fp_zones.push_back( static_cast<MODULE_ZONE_CONTAINER*>( aBoardItem ) );
else
m_zones.insert( m_zones.begin(), static_cast<ZONE_CONTAINER*>( aBoardItem ) );
m_fp_zones.insert( m_fp_zones.begin(), static_cast<MODULE_ZONE_CONTAINER*>( aBoardItem ) );
break;
default:
@ -337,12 +337,12 @@ void MODULE::Remove( BOARD_ITEM* aBoardItem )
break;
case PCB_ZONE_AREA_T:
for( auto it = m_zones.begin(); it != m_zones.end(); ++it )
case PCB_MODULE_ZONE_AREA_T:
for( auto it = m_fp_zones.begin(); it != m_fp_zones.end(); ++it )
{
if( *it == static_cast<ZONE_CONTAINER*>( aBoardItem ) )
if( *it == static_cast<MODULE_ZONE_CONTAINER*>( aBoardItem ) )
{
m_zones.erase( it );
m_fp_zones.erase( it );
break;
}
}
@ -365,7 +365,7 @@ 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 )
for( auto zone : m_fp_zones )
zone->Print( aFrame, aDC, aOffset );
BOARD* brd = GetBoard();
@ -424,7 +424,7 @@ EDA_RECT MODULE::GetFootprintRect() const
for( auto pad : m_pads )
area.Merge( pad->GetBoundingBox() );
for( auto zone : m_zones )
for( auto zone : m_fp_zones )
area.Merge( zone->GetBoundingBox() );
return area;
@ -632,7 +632,7 @@ bool MODULE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) co
return true;
}
for( auto zone : m_zones )
for( auto zone : m_fp_zones )
{
if( zone->HitTest( arect, false, 0 ) )
return true;
@ -790,8 +790,8 @@ 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 );
case PCB_MODULE_ZONE_AREA_T:
result = IterateForward<MODULE_ZONE_CONTAINER*>( m_fp_zones, inspector, testData, p );
++p;
break;
@ -872,8 +872,8 @@ 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 zone : m_fp_zones )
aFunction( static_cast<MODULE_ZONE_CONTAINER*>( zone ) );
for( auto drawing : m_drawings )
aFunction( static_cast<BOARD_ITEM*>( drawing ) );
@ -1080,7 +1080,7 @@ void MODULE::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
pad->Flip( m_Pos, false );
// Mirror zones to other side of board.
for( auto zone : m_zones )
for( auto zone : m_fp_zones )
zone->Flip( m_Pos, aFlipLeftRight );
// Mirror reference and value.
@ -1128,7 +1128,7 @@ void MODULE::SetPosition( const wxPoint& newpos )
pad->SetPosition( pad->GetPosition() + delta );
}
for( auto zone : m_zones )
for( auto zone : m_fp_zones )
zone->Move( delta );
for( auto item : m_drawings )
@ -1230,7 +1230,7 @@ void MODULE::SetOrientation( double newangle )
pad->SetDrawCoord();
}
for( auto zone : m_zones )
for( auto zone : m_fp_zones )
{
zone->Rotate( GetPosition(), angleChange );
}
@ -1261,7 +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;
MODULE_ZONE_CONTAINER* new_zone = NULL;
switch( aItem->Type() )
{
@ -1276,12 +1276,12 @@ BOARD_ITEM* MODULE::Duplicate( const BOARD_ITEM* aItem,
break;
}
case PCB_ZONE_AREA_T:
case PCB_MODULE_ZONE_AREA_T:
{
new_zone = new ZONE_CONTAINER( *static_cast<const ZONE_CONTAINER*>( aItem ) );
new_zone = new MODULE_ZONE_CONTAINER( *static_cast<const MODULE_ZONE_CONTAINER*>( aItem ) );
if( aAddToModule )
m_zones.push_back( new_zone );
m_fp_zones.push_back( new_zone );
new_item = new_zone;
break;

View File

@ -106,7 +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_VEC_FOR_SWIG( MODULE_ZONE_CONTAINERS, MODULE_ZONE_CONTAINER* )
DECL_DEQ_FOR_SWIG( MODULES, MODULE* )
class MODULE : public BOARD_ITEM_CONTAINER
@ -179,9 +179,9 @@ public:
return m_drawings;
}
const ZONE_CONTAINERS& Zones() const
const MODULE_ZONE_CONTAINERS& Zones() const
{
return m_zones;
return m_fp_zones;
}
const DRAWINGS& GraphicalItems() const
@ -669,9 +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
ZONE_CONTAINERS m_zones; // ZONE 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
MODULE_ZONE_CONTAINERS m_fp_zones; // MODULE_ZONE_CONTAINER 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.
@ -700,11 +700,11 @@ private:
int m_CntRot90; // Horizontal automatic placement cost ( 0..10 ).
int m_CntRot180; // Vertical automatic placement cost ( 0..10 ).
wxArrayString* m_initial_comments; ///< leading s-expression comments in the module,
///< lazily allocated only if needed for speed
wxArrayString* m_initial_comments; ///< leading s-expression comments in the module,
///< lazily allocated only if needed for speed
/// Used in DRC to test the courtyard area (a polygon which can be not basic
/// Note also a footprint can have courtyards on bot board sides
/// Note also a footprint can have courtyards on both board sides
SHAPE_POLY_SET m_poly_courtyard_front;
SHAPE_POLY_SET m_poly_courtyard_back;
};

View File

@ -42,8 +42,8 @@
#include <polygon_test_point_inside.h>
ZONE_CONTAINER::ZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent )
: BOARD_CONNECTED_ITEM( aParent, PCB_ZONE_AREA_T )
ZONE_CONTAINER::ZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent, bool aInModule )
: BOARD_CONNECTED_ITEM( aParent, aInModule ? PCB_MODULE_ZONE_AREA_T : PCB_ZONE_AREA_T )
{
m_CornerSelection = nullptr; // no corner is selected
m_IsFilled = false; // fill status : true when the zone is filled
@ -75,6 +75,55 @@ ZONE_CONTAINER::ZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent )
ZONE_CONTAINER::ZONE_CONTAINER( const ZONE_CONTAINER& aZone )
: BOARD_CONNECTED_ITEM( aZone.GetParent(), PCB_ZONE_AREA_T )
{
copyDataFromSrc( aZone );
}
ZONE_CONTAINER& ZONE_CONTAINER::operator=( const ZONE_CONTAINER& aOther )
{
BOARD_CONNECTED_ITEM::operator=( aOther );
// Replace the outlines for aOther outlines.
delete m_Poly;
m_Poly = new SHAPE_POLY_SET( *aOther.m_Poly );
m_CornerSelection = nullptr; // for corner moving, corner index to (null if no selection)
m_ZoneClearance = aOther.m_ZoneClearance; // clearance value
m_ZoneMinThickness = aOther.m_ZoneMinThickness;
m_FilledPolysUseThickness = aOther.m_FilledPolysUseThickness;
m_FillMode = aOther.m_FillMode; // filling mode (segments/polygons)
m_PadConnection = aOther.m_PadConnection;
m_ThermalReliefGap = aOther.m_ThermalReliefGap;
m_ThermalReliefCopperBridge = aOther.m_ThermalReliefCopperBridge;
SetHatchStyle( aOther.GetHatchStyle() );
SetHatchPitch( aOther.GetHatchPitch() );
m_HatchLines = aOther.m_HatchLines; // copy vector <SEG>
m_FilledPolysList.RemoveAllContours();
m_FilledPolysList.Append( aOther.m_FilledPolysList );
m_FillSegmList.clear();
m_FillSegmList = aOther.m_FillSegmList;
m_HatchFillTypeThickness = aOther.m_HatchFillTypeThickness;
m_HatchFillTypeGap = aOther.m_HatchFillTypeGap;
m_HatchFillTypeOrientation = aOther.m_HatchFillTypeOrientation;
m_HatchFillTypeSmoothingLevel = aOther.m_HatchFillTypeSmoothingLevel;
m_HatchFillTypeSmoothingValue = aOther.m_HatchFillTypeSmoothingValue;
SetLayerSet( aOther.GetLayerSet() );
return *this;
}
ZONE_CONTAINER::~ZONE_CONTAINER()
{
delete m_Poly;
delete m_CornerSelection;
}
void ZONE_CONTAINER::copyDataFromSrc( const ZONE_CONTAINER& aZone )
{
m_Poly = new SHAPE_POLY_SET( *aZone.m_Poly );
@ -122,49 +171,6 @@ ZONE_CONTAINER::ZONE_CONTAINER( const ZONE_CONTAINER& aZone )
}
ZONE_CONTAINER& ZONE_CONTAINER::operator=( const ZONE_CONTAINER& aOther )
{
BOARD_CONNECTED_ITEM::operator=( aOther );
// Replace the outlines for aOther outlines.
delete m_Poly;
m_Poly = new SHAPE_POLY_SET( *aOther.m_Poly );
m_CornerSelection = nullptr; // for corner moving, corner index to (null if no selection)
m_ZoneClearance = aOther.m_ZoneClearance; // clearance value
m_ZoneMinThickness = aOther.m_ZoneMinThickness;
m_FilledPolysUseThickness = aOther.m_FilledPolysUseThickness;
m_FillMode = aOther.m_FillMode; // filling mode (segments/polygons)
m_PadConnection = aOther.m_PadConnection;
m_ThermalReliefGap = aOther.m_ThermalReliefGap;
m_ThermalReliefCopperBridge = aOther.m_ThermalReliefCopperBridge;
SetHatchStyle( aOther.GetHatchStyle() );
SetHatchPitch( aOther.GetHatchPitch() );
m_HatchLines = aOther.m_HatchLines; // copy vector <SEG>
m_FilledPolysList.RemoveAllContours();
m_FilledPolysList.Append( aOther.m_FilledPolysList );
m_FillSegmList.clear();
m_FillSegmList = aOther.m_FillSegmList;
m_HatchFillTypeThickness = aOther.m_HatchFillTypeThickness;
m_HatchFillTypeGap = aOther.m_HatchFillTypeGap;
m_HatchFillTypeOrientation = aOther.m_HatchFillTypeOrientation;
m_HatchFillTypeSmoothingLevel = aOther.m_HatchFillTypeSmoothingLevel;
m_HatchFillTypeSmoothingValue = aOther.m_HatchFillTypeSmoothingValue;
SetLayerSet( aOther.GetLayerSet() );
return *this;
}
ZONE_CONTAINER::~ZONE_CONTAINER()
{
delete m_Poly;
delete m_CornerSelection;
}
EDA_ITEM* ZONE_CONTAINER::Clone() const
{
return new ZONE_CONTAINER( *this );
@ -1299,3 +1305,23 @@ void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon( SHAPE_POLY_SE
polybuffer.Fracture( SHAPE_POLY_SET::PM_FAST );
aCornerBuffer.Append( polybuffer );
}
MODULE_ZONE_CONTAINER::MODULE_ZONE_CONTAINER( const MODULE_ZONE_CONTAINER& aZone )
: ZONE_CONTAINER( aZone.GetParent(), true )
{
copyDataFromSrc( aZone );
}
MODULE_ZONE_CONTAINER& MODULE_ZONE_CONTAINER::operator=( const MODULE_ZONE_CONTAINER& aOther )
{
ZONE_CONTAINER::operator=( aOther );
return *this;
}
EDA_ITEM* MODULE_ZONE_CONTAINER::Clone() const
{
return new MODULE_ZONE_CONTAINER( *this );
}

View File

@ -51,19 +51,28 @@ typedef std::vector<SEG> ZONE_SEGMENT_FILL;
/**
* Class ZONE_CONTAINER
* handles a list of polygons defining a copper zone.
* A zone is described by a main polygon, a time stamp, a layer, and a net name.
* A zone is described by a main polygon, a time stamp, a layer or a lyer set, and a net name.
* Other polygons inside the main polygon are holes in the zone.
*
* a item ZONE_CONTAINER is living in a board
* a variant MODULE_ZONE_CONTAINER is living in a footprint
*/
class ZONE_CONTAINER : public BOARD_CONNECTED_ITEM
{
public:
/**
* Zone hatch styles
*/
/// Zone hatch styles
typedef enum HATCH_STYLE { NO_HATCH, DIAGONAL_FULL, DIAGONAL_EDGE } HATCH_STYLE;
ZONE_CONTAINER( BOARD_ITEM_CONTAINER* parent );
/**
* The ctor to build ZONE_CONTAINER, but comaptible with MODULE_ZONE_CONTAINER
* requirement.
* if aInModule is true, a MODULE_ZONE_CONTAINER is actually built
* (same item, but with a specific type id:
* The type is PCB_ZONE_AREA_T for a ZONE_CONTAINER
* The type is PCB_MODULE_ZONE_AREA_T for a MODULE_ZONE_CONTAINER
*/
ZONE_CONTAINER( BOARD_ITEM_CONTAINER* parent, bool aInModule = false );
ZONE_CONTAINER( const ZONE_CONTAINER& aZone );
ZONE_CONTAINER& operator=( const ZONE_CONTAINER &aOther );
@ -699,7 +708,11 @@ public:
virtual void SwapData( BOARD_ITEM* aImage ) override;
private:
protected:
/** Copy aZone data to me
*/
void copyDataFromSrc( const ZONE_CONTAINER& aZone );
SHAPE_POLY_SET* m_Poly; ///< Outline of the zone.
int m_cornerSmoothingType;
@ -802,4 +815,26 @@ private:
};
/**
* MODULE_ZONE_CONTAINER is the same item as ZONE_CONTAINER, but with a specific type id
* ZONE_CONTAINER is living in a board
* MODULE_ZONE_CONTAINER is living in a footprint
* althougt the are similar, these items need a specific type to be easily managed
* in many functions using the type id in switches
*/
class MODULE_ZONE_CONTAINER : public ZONE_CONTAINER
{
public:
MODULE_ZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent ) :
ZONE_CONTAINER( aParent, true )
{
}
MODULE_ZONE_CONTAINER( const MODULE_ZONE_CONTAINER& aZone );
MODULE_ZONE_CONTAINER& operator=( const MODULE_ZONE_CONTAINER &aOther );
// ~MODULE_ZONE_CONTAINER();
EDA_ITEM* Clone() const override;
};
#endif // CLASS_ZONE_H_

View File

@ -107,12 +107,23 @@ 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, PCB_ZONE_AREA_T, EOT };
const KICAD_T GENERAL_COLLECTOR::ModulesAndTheirItems[] = {
PCB_MODULE_T,
PCB_MODULE_TEXT_T,
PCB_MODULE_EDGE_T,
PCB_PAD_T,
PCB_MODULE_ZONE_AREA_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::ModuleItems[] = {
PCB_MODULE_TEXT_T,
PCB_MODULE_EDGE_T,
PCB_PAD_T,
PCB_MODULE_ZONE_AREA_T,
EOT
};
const KICAD_T GENERAL_COLLECTOR::Tracks[] = {
@ -132,6 +143,7 @@ const KICAD_T GENERAL_COLLECTOR::LockableItems[] = {
const KICAD_T GENERAL_COLLECTOR::Zones[] = {
PCB_ZONE_AREA_T,
PCB_MODULE_ZONE_AREA_T,
EOT
};

View File

@ -385,39 +385,40 @@ 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;
case PCB_MODULE_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:
wxASSERT( 0 );
break;
}
}

View File

@ -443,6 +443,7 @@ void PCB_IO::Format( BOARD_ITEM* aItem, int aNestLevel ) const
format( static_cast<TRACK*>( aItem ), aNestLevel );
break;
case PCB_MODULE_ZONE_AREA_T:
case PCB_ZONE_AREA_T:
format( static_cast<ZONE_CONTAINER*>( aItem ), aNestLevel );
break;

View File

@ -354,6 +354,10 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
draw( static_cast<const ZONE_CONTAINER*>( item ), aLayer );
break;
case PCB_MODULE_ZONE_AREA_T:
draw( static_cast<const ZONE_CONTAINER*>( item ), aLayer );
break;
case PCB_DIMENSION_T:
draw( static_cast<const DIMENSION*>( item ), aLayer );
break;

View File

@ -3416,8 +3416,14 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent )
// bigger scope since each filled_polygon is concatenated in here
SHAPE_POLY_SET pts;
bool inModule = false;
std::unique_ptr<ZONE_CONTAINER> zone( new ZONE_CONTAINER( aParent ) );
if( dynamic_cast<MODULE*>( aParent ) ) // The zone belongs a footprint
inModule = true;
std::unique_ptr<ZONE_CONTAINER> zone( inModule ?
new MODULE_ZONE_CONTAINER( aParent ) :
new ZONE_CONTAINER( aParent ) );
zone->SetPriority( 0 );

View File

@ -90,8 +90,8 @@ private:
SELECTION_TOOL* selTool = getToolManager()->GetTool<SELECTION_TOOL>();
// enable zone actions that act on a single zone
bool singleZoneActionsEnabled = ( SELECTION_CONDITIONS::Count( 1 )
&& SELECTION_CONDITIONS::OnlyType( PCB_ZONE_AREA_T )
bool singleZoneActionsEnabled = ( SELECTION_CONDITIONS::Count( 1 ) &&
SELECTION_CONDITIONS::OnlyTypes( GENERAL_COLLECTOR::Zones )
)( selTool->GetSelection() );
Enable( getMenuId( PCB_ACTIONS::zoneDuplicate ), singleZoneActionsEnabled );
@ -353,7 +353,7 @@ int PCB_EDITOR_CONTROL::ExportSpecctraDSN( const TOOL_EVENT& aEvent )
fn = fullFileName;
fullFileName = EDA_FILE_SELECTOR( _( "Specctra DSN File" ), fn.GetPath(), fn.GetFullName(),
SpecctraDsnFileExtension, SpecctraDsnFileWildcard(),
SpecctraDsnFileExtension, SpecctraDsnFileWildcard(),
frame(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT, false );
if( !fullFileName.IsEmpty() )
@ -361,7 +361,7 @@ int PCB_EDITOR_CONTROL::ExportSpecctraDSN( const TOOL_EVENT& aEvent )
m_frame->SetLastPath( LAST_PATH_SPECCTRADSN, fullFileName );
getEditFrame<PCB_EDIT_FRAME>()->ExportSpecctraFile( fullFileName );
}
return 0;
}
@ -369,7 +369,7 @@ int PCB_EDITOR_CONTROL::ExportSpecctraDSN( const TOOL_EVENT& aEvent )
int PCB_EDITOR_CONTROL::GenerateFabFiles( const TOOL_EVENT& aEvent )
{
wxCommandEvent dummy;
if( aEvent.IsAction( &PCB_ACTIONS::generateGerbers ) )
m_frame->ToPlotter( ID_GEN_PLOT_GERBER );
else if( aEvent.IsAction( &PCB_ACTIONS::generateReportFile ) )
@ -380,7 +380,7 @@ int PCB_EDITOR_CONTROL::GenerateFabFiles( const TOOL_EVENT& aEvent )
m_frame->RecreateBOMFileFromBoard( dummy );
else
wxFAIL_MSG( "GenerateFabFiles(): unexpected request" );
return 0;
}

View File

@ -183,6 +183,7 @@ public:
break;
}
case PCB_MODULE_ZONE_AREA_T:
case PCB_ZONE_AREA_T:
{
auto zone = static_cast<const ZONE_CONTAINER*>( aItem );
@ -539,6 +540,7 @@ void POINT_EDITOR::updateItem() const
break;
}
case PCB_MODULE_ZONE_AREA_T:
case PCB_ZONE_AREA_T:
{
ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( item );
@ -622,7 +624,7 @@ void POINT_EDITOR::finishItem()
if( !item )
return;
if( item->Type() == PCB_ZONE_AREA_T )
if( item->Type() == PCB_ZONE_AREA_T || item->Type() == PCB_MODULE_ZONE_AREA_T )
{
auto zone = static_cast<ZONE_CONTAINER*>( item );
@ -723,6 +725,7 @@ void POINT_EDITOR::updatePoints()
break;
}
case PCB_MODULE_ZONE_AREA_T:
case PCB_ZONE_AREA_T:
{
ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( item );
@ -791,7 +794,9 @@ void POINT_EDITOR::setAltConstraint( bool aEnabled )
{
EDIT_LINE* line = dynamic_cast<EDIT_LINE*>( m_editedPoint );
if( line && m_editPoints->GetParent()->Type() == PCB_ZONE_AREA_T )
if( line &&
( m_editPoints->GetParent()->Type() == PCB_ZONE_AREA_T
|| m_editPoints->GetParent()->Type() == PCB_MODULE_ZONE_AREA_T ) )
{
m_altConstraint.reset( (EDIT_CONSTRAINT<EDIT_POINT>*)( new EC_CONVERGING( *line, *m_editPoints ) ) );
}
@ -866,7 +871,7 @@ bool POINT_EDITOR::canAddCorner( const EDA_ITEM& aItem )
const auto type = aItem.Type();
// Works only for zones and line segments
return type == PCB_ZONE_AREA_T ||
return type == PCB_ZONE_AREA_T || type == PCB_MODULE_ZONE_AREA_T ||
( ( type == PCB_LINE_T || type == PCB_MODULE_EDGE_T ) &&
( static_cast<const DRAWSEGMENT&>( aItem ).GetShape() == S_SEGMENT ||
static_cast<const DRAWSEGMENT&>( aItem ).GetShape() == S_POLYGON ) );
@ -907,14 +912,14 @@ bool POINT_EDITOR::removeCornerCondition( const SELECTION& )
EDA_ITEM* item = m_editPoints->GetParent();
if( !item || !( item->Type() == PCB_ZONE_AREA_T ||
if( !item || !( item->Type() == PCB_ZONE_AREA_T || item->Type() == PCB_MODULE_ZONE_AREA_T ||
( ( item->Type() == PCB_MODULE_EDGE_T || item->Type() == PCB_LINE_T ) &&
static_cast<DRAWSEGMENT*>( item )->GetShape() == S_POLYGON ) ) )
return false;
SHAPE_POLY_SET *polyset;
if( item->Type() == PCB_ZONE_AREA_T )
if( item->Type() == PCB_ZONE_AREA_T || item->Type() == PCB_MODULE_ZONE_AREA_T )
polyset = static_cast<ZONE_CONTAINER*>( item )->Outline();
else
polyset = &static_cast<DRAWSEGMENT*>( item )->GetPolyShape();
@ -957,7 +962,7 @@ int POINT_EDITOR::addCorner( const TOOL_EVENT& aEvent )
DRAWSEGMENT* graphicItem = dynamic_cast<DRAWSEGMENT*>( item );
BOARD_COMMIT commit( frame );
if( item->Type() == PCB_ZONE_AREA_T ||
if( item->Type() == PCB_ZONE_AREA_T || item->Type() == PCB_MODULE_ZONE_AREA_T ||
( graphicItem && graphicItem->GetShape() == S_POLYGON ) )
{
unsigned int nearestIdx = 0;
@ -966,7 +971,7 @@ int POINT_EDITOR::addCorner( const TOOL_EVENT& aEvent )
unsigned int firstPointInContour = 0;
SHAPE_POLY_SET* zoneOutline;
if( item->Type() == PCB_ZONE_AREA_T )
if( item->Type() == PCB_ZONE_AREA_T || item->Type() == PCB_MODULE_ZONE_AREA_T )
{
ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( item );
zoneOutline = zone->Outline();
@ -1022,7 +1027,7 @@ int POINT_EDITOR::addCorner( const TOOL_EVENT& aEvent )
zoneOutline->InsertVertex( nextNearestIdx, nearestPoint );
// We re-hatch the filled zones but not polygons
if( item->Type() == PCB_ZONE_AREA_T )
if( item->Type() == PCB_ZONE_AREA_T || item->Type() == PCB_MODULE_ZONE_AREA_T )
static_cast<ZONE_CONTAINER*>( item )->Hatch();
@ -1078,7 +1083,7 @@ int POINT_EDITOR::removeCorner( const TOOL_EVENT& aEvent )
SHAPE_POLY_SET* polygon = nullptr;
if( item->Type() == PCB_ZONE_AREA_T)
if( item->Type() == PCB_ZONE_AREA_T || item->Type() == PCB_MODULE_ZONE_AREA_T )
{
auto zone = static_cast<ZONE_CONTAINER*>( item );
polygon = zone->Outline();
@ -1132,7 +1137,7 @@ int POINT_EDITOR::removeCorner( const TOOL_EVENT& aEvent )
commit.Push( _( "Remove a zone/polygon corner" ) );
// Refresh zone hatching
if( item->Type() == PCB_ZONE_AREA_T)
if( item->Type() == PCB_ZONE_AREA_T || item->Type() == PCB_MODULE_ZONE_AREA_T )
static_cast<ZONE_CONTAINER*>( item )->Hatch();
updatePoints();

View File

@ -51,7 +51,7 @@ ZONE_CREATE_HELPER::~ZONE_CREATE_HELPER()
std::unique_ptr<ZONE_CONTAINER> ZONE_CREATE_HELPER::createNewZone( bool aKeepout )
{
auto& frame = *m_tool.getEditFrame<PCB_BASE_EDIT_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();
@ -86,7 +86,13 @@ std::unique_ptr<ZONE_CONTAINER> ZONE_CREATE_HELPER::createNewZone( bool aKeepout
controls->WarpCursor( controls->GetCursorPosition(), true );
}
auto newZone = std::make_unique<ZONE_CONTAINER>( parent );
// The new zone is a ZONE_CONTAINER if created in the board editor
// and a MODULE_ZONE_CONTAINER if created in the footprint editor
wxASSERT( !m_tool.m_editModules || ( parent->Type() == PCB_MODULE_T ) );
auto newZone = m_tool.m_editModules ?
std::make_unique<MODULE_ZONE_CONTAINER>( parent ) :
std::make_unique<ZONE_CONTAINER>( parent );
// Apply the selected settings
zoneInfo.ExportSetting( *newZone );