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 ) void COMMIT::makeEntry( EDA_ITEM* aItem, CHANGE_TYPE aType, EDA_ITEM* aCopy )
{ {
// Expect an item copy if it is going to be modified // 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() ) 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_TEXT_T, ///< class TEXTE_PCB, text on a layer
PCB_MODULE_TEXT_T, ///< class TEXTE_MODULE, text in a footprint PCB_MODULE_TEXT_T, ///< class TEXTE_MODULE, text in a footprint
PCB_MODULE_EDGE_T, ///< class EDGE_MODULE, a footprint edge 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_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_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 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(); 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; aItem = item;
} }
@ -171,6 +171,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry, bool a
case PCB_PAD_T: case PCB_PAD_T:
case PCB_MODULE_EDGE_T: case PCB_MODULE_EDGE_T:
case PCB_MODULE_TEXT_T: case PCB_MODULE_TEXT_T:
case PCB_MODULE_ZONE_AREA_T:
// This level can only handle module items when editing modules // This level can only handle module items when editing modules
if( !m_editModules ) if( !m_editModules )
break; break;
@ -330,9 +331,15 @@ EDA_ITEM* BOARD_COMMIT::parentObject( EDA_ITEM* aItem ) const
case PCB_PAD_T: case PCB_PAD_T:
case PCB_MODULE_EDGE_T: case PCB_MODULE_EDGE_T:
case PCB_MODULE_TEXT_T: case PCB_MODULE_TEXT_T:
case PCB_MODULE_ZONE_AREA_T:
return aItem->GetParent(); return aItem->GetParent();
default:
case PCB_ZONE_AREA_T:
wxASSERT( !dynamic_cast<MODULE*>( aItem->GetParent() ) );
return aItem; return aItem;
default:
break;
} }
return aItem; return aItem;

View File

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

View File

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

View File

@ -106,7 +106,7 @@ class MODULE_3D_SETTINGS
DECL_DEQ_FOR_SWIG( PADS, D_PAD* ) DECL_DEQ_FOR_SWIG( PADS, D_PAD* )
DECL_DEQ_FOR_SWIG( DRAWINGS, BOARD_ITEM* ) 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* ) DECL_DEQ_FOR_SWIG( MODULES, MODULE* )
class MODULE : public BOARD_ITEM_CONTAINER class MODULE : public BOARD_ITEM_CONTAINER
@ -179,9 +179,9 @@ public:
return m_drawings; 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 const DRAWINGS& GraphicalItems() const
@ -669,9 +669,9 @@ public:
#endif #endif
private: private:
DRAWINGS m_drawings; // BOARD_ITEMs for drawings on the board, 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 PADS m_pads; // D_PAD items, owned by pointer
ZONE_CONTAINERS m_zones; // ZONE 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. 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. 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_CntRot90; // Horizontal automatic placement cost ( 0..10 ).
int m_CntRot180; // Vertical 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, wxArrayString* m_initial_comments; ///< leading s-expression comments in the module,
///< lazily allocated only if needed for speed ///< lazily allocated only if needed for speed
/// Used in DRC to test the courtyard area (a polygon which can be not basic /// 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_front;
SHAPE_POLY_SET m_poly_courtyard_back; SHAPE_POLY_SET m_poly_courtyard_back;
}; };

View File

@ -42,8 +42,8 @@
#include <polygon_test_point_inside.h> #include <polygon_test_point_inside.h>
ZONE_CONTAINER::ZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent ) ZONE_CONTAINER::ZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent, bool aInModule )
: BOARD_CONNECTED_ITEM( aParent, PCB_ZONE_AREA_T ) : BOARD_CONNECTED_ITEM( aParent, aInModule ? PCB_MODULE_ZONE_AREA_T : PCB_ZONE_AREA_T )
{ {
m_CornerSelection = nullptr; // no corner is selected m_CornerSelection = nullptr; // no corner is selected
m_IsFilled = false; // fill status : true when the zone is filled 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 ) ZONE_CONTAINER::ZONE_CONTAINER( const ZONE_CONTAINER& aZone )
: BOARD_CONNECTED_ITEM( aZone.GetParent(), PCB_ZONE_AREA_T ) : 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 ); 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 EDA_ITEM* ZONE_CONTAINER::Clone() const
{ {
return new ZONE_CONTAINER( *this ); return new ZONE_CONTAINER( *this );
@ -1299,3 +1305,23 @@ void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon( SHAPE_POLY_SE
polybuffer.Fracture( SHAPE_POLY_SET::PM_FAST ); polybuffer.Fracture( SHAPE_POLY_SET::PM_FAST );
aCornerBuffer.Append( polybuffer ); 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 * Class ZONE_CONTAINER
* handles a list of polygons defining a copper zone. * 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. * 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 class ZONE_CONTAINER : public BOARD_CONNECTED_ITEM
{ {
public: public:
/** /// Zone hatch styles
* Zone hatch styles
*/
typedef enum HATCH_STYLE { NO_HATCH, DIAGONAL_FULL, DIAGONAL_EDGE } HATCH_STYLE; 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( const ZONE_CONTAINER& aZone );
ZONE_CONTAINER& operator=( const ZONE_CONTAINER &aOther ); ZONE_CONTAINER& operator=( const ZONE_CONTAINER &aOther );
@ -699,7 +708,11 @@ public:
virtual void SwapData( BOARD_ITEM* aImage ) override; 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. SHAPE_POLY_SET* m_Poly; ///< Outline of the zone.
int m_cornerSmoothingType; 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_ #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, const KICAD_T GENERAL_COLLECTOR::ModulesAndTheirItems[] = {
PCB_PAD_T, PCB_MODULE_T, PCB_ZONE_AREA_T, EOT }; 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, const KICAD_T GENERAL_COLLECTOR::ModuleItems[] = {
PCB_ZONE_AREA_T, EOT }; PCB_MODULE_TEXT_T,
PCB_MODULE_EDGE_T,
PCB_PAD_T,
PCB_MODULE_ZONE_AREA_T,
EOT
};
const KICAD_T GENERAL_COLLECTOR::Tracks[] = { const KICAD_T GENERAL_COLLECTOR::Tracks[] = {
@ -132,6 +143,7 @@ const KICAD_T GENERAL_COLLECTOR::LockableItems[] = {
const KICAD_T GENERAL_COLLECTOR::Zones[] = { const KICAD_T GENERAL_COLLECTOR::Zones[] = {
PCB_ZONE_AREA_T, PCB_ZONE_AREA_T,
PCB_MODULE_ZONE_AREA_T,
EOT EOT
}; };

View File

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

View File

@ -443,6 +443,7 @@ void PCB_IO::Format( BOARD_ITEM* aItem, int aNestLevel ) const
format( static_cast<TRACK*>( aItem ), aNestLevel ); format( static_cast<TRACK*>( aItem ), aNestLevel );
break; break;
case PCB_MODULE_ZONE_AREA_T:
case PCB_ZONE_AREA_T: case PCB_ZONE_AREA_T:
format( static_cast<ZONE_CONTAINER*>( aItem ), aNestLevel ); format( static_cast<ZONE_CONTAINER*>( aItem ), aNestLevel );
break; 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 ); draw( static_cast<const ZONE_CONTAINER*>( item ), aLayer );
break; break;
case PCB_MODULE_ZONE_AREA_T:
draw( static_cast<const ZONE_CONTAINER*>( item ), aLayer );
break;
case PCB_DIMENSION_T: case PCB_DIMENSION_T:
draw( static_cast<const DIMENSION*>( item ), aLayer ); draw( static_cast<const DIMENSION*>( item ), aLayer );
break; 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 // bigger scope since each filled_polygon is concatenated in here
SHAPE_POLY_SET pts; 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 ); zone->SetPriority( 0 );

View File

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

View File

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

View File

@ -51,7 +51,7 @@ ZONE_CREATE_HELPER::~ZONE_CREATE_HELPER()
std::unique_ptr<ZONE_CONTAINER> ZONE_CREATE_HELPER::createNewZone( bool aKeepout ) 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>(); auto& board = *m_tool.getModel<BOARD>();
BOARD_ITEM_CONTAINER* parent = m_tool.m_frame->GetModel(); BOARD_ITEM_CONTAINER* parent = m_tool.m_frame->GetModel();
KIGFX::VIEW_CONTROLS* controls = m_tool.GetManager()->GetViewControls(); 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 ); 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 // Apply the selected settings
zoneInfo.ExportSetting( *newZone ); zoneInfo.ExportSetting( *newZone );