pcbnew crash while opening old .brd file
Fixes: lp:1698697 https://bugs.launchpad.net/kicad/+bug/1698697 The incorrect method ZONE_CONTAINER::AppendCorner() is also fixed: It was expecting the corner must be added to the main outline, but this is a false expectation: it can be added to a hole inside the zone outline.
This commit is contained in:
parent
d6a56e5d3d
commit
6a63d4fbff
|
@ -2348,21 +2348,24 @@ void BOARD::RemoveArea( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_to
|
|||
}
|
||||
|
||||
|
||||
ZONE_CONTAINER* BOARD::InsertArea( int netcode, int iarea, PCB_LAYER_ID layer, int x, int y, int hatch )
|
||||
ZONE_CONTAINER* BOARD::InsertArea( int aNetcode, int aAreaIdx, PCB_LAYER_ID aLayer,
|
||||
int aCornerX, int aCornerY, int aHatch )
|
||||
{
|
||||
ZONE_CONTAINER* new_area = new ZONE_CONTAINER( this );
|
||||
|
||||
new_area->SetNetCode( netcode );
|
||||
new_area->SetLayer( layer );
|
||||
new_area->SetNetCode( aNetcode );
|
||||
new_area->SetLayer( aLayer );
|
||||
new_area->SetTimeStamp( GetNewTimeStamp() );
|
||||
|
||||
if( iarea < (int) ( m_ZoneDescriptorList.size() - 1 ) )
|
||||
m_ZoneDescriptorList.insert( m_ZoneDescriptorList.begin() + iarea + 1, new_area );
|
||||
if( aAreaIdx < (int) ( m_ZoneDescriptorList.size() - 1 ) )
|
||||
m_ZoneDescriptorList.insert( m_ZoneDescriptorList.begin() + aAreaIdx + 1, new_area );
|
||||
else
|
||||
m_ZoneDescriptorList.push_back( new_area );
|
||||
|
||||
new_area->SetHatchStyle( (ZONE_CONTAINER::HATCH_STYLE) hatch );
|
||||
new_area->AppendCorner( wxPoint( x, y ) );
|
||||
new_area->SetHatchStyle( (ZONE_CONTAINER::HATCH_STYLE) aHatch );
|
||||
|
||||
// Add the first corner to the new zone
|
||||
new_area->AppendCorner( wxPoint( aCornerX, aCornerY ), -1 );
|
||||
|
||||
return new_area;
|
||||
}
|
||||
|
|
|
@ -1070,11 +1070,17 @@ public:
|
|||
PCB_LAYER_ID aLayer, wxPoint aStartPointPosition, int aHatch );
|
||||
|
||||
/**
|
||||
* Function InsertArea
|
||||
* add empty copper area to net, inserting after m_ZoneDescriptorList[iarea]
|
||||
* Add a copper area to net, inserting after m_ZoneDescriptorList[aAreaIdx]
|
||||
* @param aNetcode is the netcode of the new copper zone
|
||||
* @param aAreaIdx is the netcode of the new copper zone
|
||||
* @param aLayer is the copper layer id of the new copper zone
|
||||
* @param aCornerX,aCornerY is the coordinate of the first corner
|
||||
* (a zone cannot have a empty outline)
|
||||
* @param aHatch is the hatch option
|
||||
* @return pointer to the new area
|
||||
*/
|
||||
ZONE_CONTAINER* InsertArea( int netcode, int iarea, PCB_LAYER_ID layer, int x, int y, int hatch );
|
||||
ZONE_CONTAINER* InsertArea( int aNetcode, int aAreaIdx, PCB_LAYER_ID aLayer,
|
||||
int aCornerX, int aCornerY, int aHatch );
|
||||
|
||||
/**
|
||||
* Function NormalizeAreaPolygon
|
||||
|
|
|
@ -843,6 +843,24 @@ void ZONE_CONTAINER::AddPolygon( std::vector< wxPoint >& aPolygon )
|
|||
}
|
||||
|
||||
|
||||
bool ZONE_CONTAINER::AppendCorner( wxPoint aPosition, int aHoleIdx, bool aAllowDuplication )
|
||||
{
|
||||
// Ensure the main outline exists:
|
||||
if( m_Poly->OutlineCount() == 0 )
|
||||
m_Poly->NewOutline();
|
||||
|
||||
// If aHoleIdx >= 0, the corner musty be added to the hole, index aHoleIdx.
|
||||
// (remember: the index of the first hole is 0)
|
||||
// Return error if if does dot exist.
|
||||
if( aHoleIdx >= m_Poly->HoleCount( 0 ) )
|
||||
return false;
|
||||
|
||||
m_Poly->Append( aPosition.x, aPosition.y, -1, aHoleIdx, aAllowDuplication );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
wxString ZONE_CONTAINER::GetSelectMenuText() const
|
||||
{
|
||||
wxString text;
|
||||
|
|
|
@ -537,18 +537,14 @@ public:
|
|||
}
|
||||
|
||||
/**
|
||||
* Function AppendCorner
|
||||
* @param position is the position of the new corner.
|
||||
* Add a new corner to the zone outline (to the main outline or a hole)
|
||||
* @param aPosition is the position of the new corner.
|
||||
* @param aHoleIdx is the index of the hole (-1 for the main outline, >= 0 for hole).
|
||||
* @param aAllowDuplication is a flag to indicate whether it is allowed to add this corner
|
||||
* even if it is duplicated.
|
||||
* @return true if the corner was added, false if error (aHoleIdx > hole count -1)
|
||||
*/
|
||||
void AppendCorner( wxPoint position, bool aAllowDuplication = false )
|
||||
{
|
||||
if( m_Poly->OutlineCount() == 0 )
|
||||
m_Poly->NewOutline();
|
||||
|
||||
m_Poly->Append( position.x, position.y, -1, -1, aAllowDuplication );
|
||||
}
|
||||
bool AppendCorner( wxPoint aPosition, int aHoleIdx, bool aAllowDuplication = false );
|
||||
|
||||
HATCH_STYLE GetHatchStyle() const
|
||||
{
|
||||
|
|
|
@ -621,10 +621,11 @@ void EAGLE_PLUGIN::loadPlain( wxXmlNode* aGraphics )
|
|||
|
||||
ZONE_CONTAINER::HATCH_STYLE outline_hatch = ZONE_CONTAINER::DIAGONAL_EDGE;
|
||||
|
||||
zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y1 ) ) );
|
||||
zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y1 ) ) );
|
||||
zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y2 ) ) );
|
||||
zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y2 ) ) );
|
||||
const int outlineIdx = -1; // this is the id of the copper zone main outline
|
||||
zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y1 ) ), outlineIdx );
|
||||
zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y1 ) ), outlineIdx );
|
||||
zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y2 ) ), outlineIdx );
|
||||
zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y2 ) ), outlineIdx );
|
||||
|
||||
// this is not my fault:
|
||||
zone->SetHatch( outline_hatch, Mils2iu( zone->GetDefaultHatchPitchMils() ), true );
|
||||
|
@ -1812,7 +1813,7 @@ void EAGLE_PLUGIN::loadSignals( wxXmlNode* aSignals )
|
|||
EVERTEX v( vertex );
|
||||
|
||||
// Append the corner
|
||||
zone->AppendCorner( wxPoint( kicad_x( v.x ), kicad_y( v.y ) ) );
|
||||
zone->AppendCorner( wxPoint( kicad_x( v.x ), kicad_y( v.y ) ), -1 );
|
||||
|
||||
vertex = vertex->GetNext();
|
||||
}
|
||||
|
|
|
@ -2475,7 +2475,8 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
|
|||
unique_ptr<ZONE_CONTAINER> zc( new ZONE_CONTAINER( m_board ) );
|
||||
|
||||
ZONE_CONTAINER::HATCH_STYLE outline_hatch = ZONE_CONTAINER::NO_HATCH;
|
||||
bool sawCorner = false;
|
||||
bool endContour = false;
|
||||
int holeIndex = -1; // -1 is the main outline; holeIndex >= 0 = hole index
|
||||
char buf[1024];
|
||||
char* line;
|
||||
char* saveptr;
|
||||
|
@ -2484,18 +2485,27 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
|
|||
{
|
||||
const char* data;
|
||||
|
||||
if( TESTLINE( "ZCorner" ) ) // new corner found
|
||||
if( TESTLINE( "ZCorner" ) ) // new corner of the zone outlines found
|
||||
{
|
||||
// e.g. "ZCorner 25650 49500 0"
|
||||
BIU x = biuParse( line + SZ( "ZCorner" ), &data );
|
||||
BIU y = biuParse( data, &data );
|
||||
|
||||
if( !sawCorner )
|
||||
if( endContour )
|
||||
{
|
||||
// the previous corner was the last corner of a contour.
|
||||
// so this corner is the first of a new hole
|
||||
endContour = false;
|
||||
zc->NewHole();
|
||||
else
|
||||
zc->AppendCorner( wxPoint( x, y ) );
|
||||
holeIndex++;
|
||||
}
|
||||
|
||||
sawCorner = true;
|
||||
zc->AppendCorner( wxPoint( x, y ), holeIndex );
|
||||
|
||||
// Is this corner the end of current contour?
|
||||
// the next corner (if any) will be stored in a new contour (a hole)
|
||||
// intParse( data )returns 0 = usual corner, 1 = last corner of the current contour:
|
||||
endContour = intParse( data );
|
||||
}
|
||||
|
||||
else if( TESTLINE( "ZInfo" ) ) // general info found
|
||||
|
@ -2655,7 +2665,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
|
|||
|
||||
else if( TESTLINE( "$POLYSCORNERS" ) )
|
||||
{
|
||||
// Read the PolysList (polygons used for fill areas in the zone)
|
||||
// Read the PolysList (polygons that are the solid areas in the filled zone)
|
||||
SHAPE_POLY_SET polysList;
|
||||
|
||||
bool makeNewOutline = true;
|
||||
|
|
|
@ -182,7 +182,7 @@ void PCB_POLYGON::AddToBoard()
|
|||
for( i = 0; i < (int) m_outline.GetCount(); i++ )
|
||||
{
|
||||
zone->AppendCorner( wxPoint( KiROUND( m_outline[i]->x ),
|
||||
KiROUND( m_outline[i]->y ) ) );
|
||||
KiROUND( m_outline[i]->y ) ), -1 );
|
||||
}
|
||||
|
||||
zone->SetZoneClearance( m_width );
|
||||
|
@ -206,7 +206,6 @@ void PCB_POLYGON::AddToBoard()
|
|||
}
|
||||
|
||||
//if( m_filled )
|
||||
// cvpcb is not linked
|
||||
// zone->BuildFilledPolysListData( m_board );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -669,8 +669,9 @@ int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC )
|
|||
zone->SetLayer( zoneInfo.m_CurrentZone_Layer );
|
||||
|
||||
// A duplicated corner is needed; null segments are removed when the zone is finished.
|
||||
zone->AppendCorner( GetCrossHairPosition() );
|
||||
zone->AppendCorner( GetCrossHairPosition(), true );
|
||||
zone->AppendCorner( GetCrossHairPosition(), -1 );
|
||||
// Add the duplicate corner:
|
||||
zone->AppendCorner( GetCrossHairPosition(), -1, true );
|
||||
|
||||
if( g_Drc_On && (m_drc->Drc( zone, 0 ) == BAD_DRC) && zone->IsOnCopperLayer() )
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue