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 );
|
ZONE_CONTAINER* new_area = new ZONE_CONTAINER( this );
|
||||||
|
|
||||||
new_area->SetNetCode( netcode );
|
new_area->SetNetCode( aNetcode );
|
||||||
new_area->SetLayer( layer );
|
new_area->SetLayer( aLayer );
|
||||||
new_area->SetTimeStamp( GetNewTimeStamp() );
|
new_area->SetTimeStamp( GetNewTimeStamp() );
|
||||||
|
|
||||||
if( iarea < (int) ( m_ZoneDescriptorList.size() - 1 ) )
|
if( aAreaIdx < (int) ( m_ZoneDescriptorList.size() - 1 ) )
|
||||||
m_ZoneDescriptorList.insert( m_ZoneDescriptorList.begin() + iarea + 1, new_area );
|
m_ZoneDescriptorList.insert( m_ZoneDescriptorList.begin() + aAreaIdx + 1, new_area );
|
||||||
else
|
else
|
||||||
m_ZoneDescriptorList.push_back( new_area );
|
m_ZoneDescriptorList.push_back( new_area );
|
||||||
|
|
||||||
new_area->SetHatchStyle( (ZONE_CONTAINER::HATCH_STYLE) hatch );
|
new_area->SetHatchStyle( (ZONE_CONTAINER::HATCH_STYLE) aHatch );
|
||||||
new_area->AppendCorner( wxPoint( x, y ) );
|
|
||||||
|
// Add the first corner to the new zone
|
||||||
|
new_area->AppendCorner( wxPoint( aCornerX, aCornerY ), -1 );
|
||||||
|
|
||||||
return new_area;
|
return new_area;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1070,11 +1070,17 @@ public:
|
||||||
PCB_LAYER_ID aLayer, wxPoint aStartPointPosition, int aHatch );
|
PCB_LAYER_ID aLayer, wxPoint aStartPointPosition, int aHatch );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function InsertArea
|
* Add a copper area to net, inserting after m_ZoneDescriptorList[aAreaIdx]
|
||||||
* add empty copper area to net, inserting after m_ZoneDescriptorList[iarea]
|
* @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
|
* @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
|
* 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 ZONE_CONTAINER::GetSelectMenuText() const
|
||||||
{
|
{
|
||||||
wxString text;
|
wxString text;
|
||||||
|
|
|
@ -537,18 +537,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function AppendCorner
|
* Add a new corner to the zone outline (to the main outline or a hole)
|
||||||
* @param position is the position of the new corner.
|
* @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
|
* @param aAllowDuplication is a flag to indicate whether it is allowed to add this corner
|
||||||
* even if it is duplicated.
|
* 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 )
|
bool AppendCorner( wxPoint aPosition, int aHoleIdx, bool aAllowDuplication = false );
|
||||||
{
|
|
||||||
if( m_Poly->OutlineCount() == 0 )
|
|
||||||
m_Poly->NewOutline();
|
|
||||||
|
|
||||||
m_Poly->Append( position.x, position.y, -1, -1, aAllowDuplication );
|
|
||||||
}
|
|
||||||
|
|
||||||
HATCH_STYLE GetHatchStyle() const
|
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_CONTAINER::HATCH_STYLE outline_hatch = ZONE_CONTAINER::DIAGONAL_EDGE;
|
||||||
|
|
||||||
zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y1 ) ) );
|
const int outlineIdx = -1; // this is the id of the copper zone main outline
|
||||||
zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y1 ) ) );
|
zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y1 ) ), outlineIdx );
|
||||||
zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y2 ) ) );
|
zone->AppendCorner( wxPoint( kicad_x( r.x2 ), kicad_y( r.y1 ) ), outlineIdx );
|
||||||
zone->AppendCorner( wxPoint( kicad_x( r.x1 ), kicad_y( r.y2 ) ) );
|
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:
|
// this is not my fault:
|
||||||
zone->SetHatch( outline_hatch, Mils2iu( zone->GetDefaultHatchPitchMils() ), true );
|
zone->SetHatch( outline_hatch, Mils2iu( zone->GetDefaultHatchPitchMils() ), true );
|
||||||
|
@ -1812,7 +1813,7 @@ void EAGLE_PLUGIN::loadSignals( wxXmlNode* aSignals )
|
||||||
EVERTEX v( vertex );
|
EVERTEX v( vertex );
|
||||||
|
|
||||||
// Append the corner
|
// 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();
|
vertex = vertex->GetNext();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2475,7 +2475,8 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
|
||||||
unique_ptr<ZONE_CONTAINER> zc( new ZONE_CONTAINER( m_board ) );
|
unique_ptr<ZONE_CONTAINER> zc( new ZONE_CONTAINER( m_board ) );
|
||||||
|
|
||||||
ZONE_CONTAINER::HATCH_STYLE outline_hatch = ZONE_CONTAINER::NO_HATCH;
|
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 buf[1024];
|
||||||
char* line;
|
char* line;
|
||||||
char* saveptr;
|
char* saveptr;
|
||||||
|
@ -2484,18 +2485,27 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
|
||||||
{
|
{
|
||||||
const char* data;
|
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"
|
// e.g. "ZCorner 25650 49500 0"
|
||||||
BIU x = biuParse( line + SZ( "ZCorner" ), &data );
|
BIU x = biuParse( line + SZ( "ZCorner" ), &data );
|
||||||
BIU y = biuParse( data, &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();
|
zc->NewHole();
|
||||||
else
|
holeIndex++;
|
||||||
zc->AppendCorner( wxPoint( x, y ) );
|
}
|
||||||
|
|
||||||
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
|
else if( TESTLINE( "ZInfo" ) ) // general info found
|
||||||
|
@ -2655,7 +2665,7 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
|
||||||
|
|
||||||
else if( TESTLINE( "$POLYSCORNERS" ) )
|
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;
|
SHAPE_POLY_SET polysList;
|
||||||
|
|
||||||
bool makeNewOutline = true;
|
bool makeNewOutline = true;
|
||||||
|
|
|
@ -182,7 +182,7 @@ void PCB_POLYGON::AddToBoard()
|
||||||
for( i = 0; i < (int) m_outline.GetCount(); i++ )
|
for( i = 0; i < (int) m_outline.GetCount(); i++ )
|
||||||
{
|
{
|
||||||
zone->AppendCorner( wxPoint( KiROUND( m_outline[i]->x ),
|
zone->AppendCorner( wxPoint( KiROUND( m_outline[i]->x ),
|
||||||
KiROUND( m_outline[i]->y ) ) );
|
KiROUND( m_outline[i]->y ) ), -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
zone->SetZoneClearance( m_width );
|
zone->SetZoneClearance( m_width );
|
||||||
|
@ -206,7 +206,6 @@ void PCB_POLYGON::AddToBoard()
|
||||||
}
|
}
|
||||||
|
|
||||||
//if( m_filled )
|
//if( m_filled )
|
||||||
// cvpcb is not linked
|
|
||||||
// zone->BuildFilledPolysListData( m_board );
|
// zone->BuildFilledPolysListData( m_board );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -669,8 +669,9 @@ int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC )
|
||||||
zone->SetLayer( zoneInfo.m_CurrentZone_Layer );
|
zone->SetLayer( zoneInfo.m_CurrentZone_Layer );
|
||||||
|
|
||||||
// A duplicated corner is needed; null segments are removed when the zone is finished.
|
// A duplicated corner is needed; null segments are removed when the zone is finished.
|
||||||
zone->AppendCorner( GetCrossHairPosition() );
|
zone->AppendCorner( GetCrossHairPosition(), -1 );
|
||||||
zone->AppendCorner( GetCrossHairPosition(), true );
|
// Add the duplicate corner:
|
||||||
|
zone->AppendCorner( GetCrossHairPosition(), -1, true );
|
||||||
|
|
||||||
if( g_Drc_On && (m_drc->Drc( zone, 0 ) == BAD_DRC) && zone->IsOnCopperLayer() )
|
if( g_Drc_On && (m_drc->Drc( zone, 0 ) == BAD_DRC) && zone->IsOnCopperLayer() )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue