fixed: 2 bugs that crashes pcbnew (see changelog)
This commit is contained in:
parent
cdbd1b294e
commit
17dc3090c4
|
@ -5,6 +5,20 @@ Started 2007-June-11
|
||||||
Please add newer entries at the top, list the date and your name with
|
Please add newer entries at the top, list the date and your name with
|
||||||
email address.
|
email address.
|
||||||
|
|
||||||
|
|
||||||
|
2009-mar-16 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
|
||||||
|
================================================================================
|
||||||
|
++pcbnew:
|
||||||
|
Fixed:
|
||||||
|
bug that crashes pcbnew when removing all footprints
|
||||||
|
(in connection calculations, pointers to pads not reset)
|
||||||
|
|
||||||
|
bug that crashes pcbnew when filling a zone
|
||||||
|
if a module has a trapezoidal pad
|
||||||
|
(trapezoidal pads are not yet implemented in zone filling,
|
||||||
|
they are now calculated as rect shape (todo: a better handling) )
|
||||||
|
|
||||||
|
|
||||||
2009-mar-12 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
|
2009-mar-12 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
|
||||||
================================================================================
|
================================================================================
|
||||||
++eeschema:
|
++eeschema:
|
||||||
|
|
|
@ -69,14 +69,14 @@ static int Merge_Two_SubNets( TRACK* pt_start_conn, TRACK* pt_end_conn, int old_
|
||||||
{
|
{
|
||||||
pt_pad = (D_PAD*) (pt_conn->start);
|
pt_pad = (D_PAD*) (pt_conn->start);
|
||||||
if( pt_pad->GetSubNet() == old_val )
|
if( pt_pad->GetSubNet() == old_val )
|
||||||
pt_pad->SetSubNet(pt_conn->GetSubNet());
|
pt_pad->SetSubNet( pt_conn->GetSubNet() );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pt_conn->end && (pt_conn->end->Type() == TYPE_PAD) )
|
if( pt_conn->end && (pt_conn->end->Type() == TYPE_PAD) )
|
||||||
{
|
{
|
||||||
pt_pad = (D_PAD*) (pt_conn->end);
|
pt_pad = (D_PAD*) (pt_conn->end);
|
||||||
if( pt_pad->GetSubNet() == old_val )
|
if( pt_pad->GetSubNet() == old_val )
|
||||||
pt_pad->SetSubNet(pt_conn->GetSubNet());
|
pt_pad->SetSubNet( pt_conn->GetSubNet() );
|
||||||
}
|
}
|
||||||
if( pt_conn == pt_end_conn )
|
if( pt_conn == pt_end_conn )
|
||||||
break;
|
break;
|
||||||
|
@ -115,11 +115,11 @@ static void Propagate_SubNet( TRACK* pt_start_conn, TRACK* pt_end_conn )
|
||||||
pt_conn->SetSubNet( 0 );
|
pt_conn->SetSubNet( 0 );
|
||||||
PtStruct = pt_conn->start;
|
PtStruct = pt_conn->start;
|
||||||
if( PtStruct && (PtStruct->Type() == TYPE_PAD) )
|
if( PtStruct && (PtStruct->Type() == TYPE_PAD) )
|
||||||
( (D_PAD*) PtStruct )->SetSubNet( 0);
|
( (D_PAD*) PtStruct )->SetSubNet( 0 );
|
||||||
|
|
||||||
PtStruct = pt_conn->end;
|
PtStruct = pt_conn->end;
|
||||||
if( PtStruct && (PtStruct->Type() == TYPE_PAD) )
|
if( PtStruct && (PtStruct->Type() == TYPE_PAD) )
|
||||||
( (D_PAD*) PtStruct )->SetSubNet( 0);
|
( (D_PAD*) PtStruct )->SetSubNet( 0 );
|
||||||
|
|
||||||
if( pt_conn == pt_end_conn )
|
if( pt_conn == pt_end_conn )
|
||||||
break;
|
break;
|
||||||
|
@ -141,17 +141,17 @@ static void Propagate_SubNet( TRACK* pt_start_conn, TRACK* pt_end_conn )
|
||||||
pt_pad = (D_PAD*) PtStruct;
|
pt_pad = (D_PAD*) PtStruct;
|
||||||
if( pt_conn->GetSubNet() ) /* the track segment is already a cluster member */
|
if( pt_conn->GetSubNet() ) /* the track segment is already a cluster member */
|
||||||
{
|
{
|
||||||
if( pt_pad->GetSubNet() > 0 ) /* The pad is already a cluster member, so we can merge the 2 clusters */
|
if( pt_pad->GetSubNet() > 0 ) /* The pad is already a cluster member, so we can merge the 2 clusters */
|
||||||
{
|
{
|
||||||
Merge_Two_SubNets( pt_start_conn, pt_end_conn,
|
Merge_Two_SubNets( pt_start_conn, pt_end_conn,
|
||||||
pt_pad->GetSubNet(), pt_conn->GetSubNet() );
|
pt_pad->GetSubNet(), pt_conn->GetSubNet() );
|
||||||
}
|
}
|
||||||
else /* The pad is not yet attached to a cluster , so we can add this pad to the cluster */
|
else /* The pad is not yet attached to a cluster , so we can add this pad to the cluster */
|
||||||
pt_pad->SetSubNet( pt_conn->GetSubNet() );
|
pt_pad->SetSubNet( pt_conn->GetSubNet() );
|
||||||
}
|
}
|
||||||
else /* the track segment is not attached to a cluster */
|
else /* the track segment is not attached to a cluster */
|
||||||
{
|
{
|
||||||
if( pt_pad->GetSubNet() > 0 ) /* it is connected to a pad in a cluster, merge this track */
|
if( pt_pad->GetSubNet() > 0 ) /* it is connected to a pad in a cluster, merge this track */
|
||||||
{
|
{
|
||||||
pt_conn->SetSubNet( pt_pad->GetSubNet() );
|
pt_conn->SetSubNet( pt_pad->GetSubNet() );
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@ static void Propagate_SubNet( TRACK* pt_start_conn, TRACK* pt_end_conn )
|
||||||
if( pt_pad->GetSubNet() > 0 )
|
if( pt_pad->GetSubNet() > 0 )
|
||||||
{
|
{
|
||||||
Merge_Two_SubNets( pt_start_conn, pt_end_conn,
|
Merge_Two_SubNets( pt_start_conn, pt_end_conn,
|
||||||
pt_pad->GetSubNet(), pt_conn->GetSubNet() );
|
pt_pad->GetSubNet(), pt_conn->GetSubNet() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pt_pad->SetSubNet( pt_conn->GetSubNet() );
|
pt_pad->SetSubNet( pt_conn->GetSubNet() );
|
||||||
|
@ -207,7 +207,7 @@ static void Propagate_SubNet( TRACK* pt_start_conn, TRACK* pt_end_conn )
|
||||||
if( pt_autre_piste->GetSubNet() ) /* The other track is already a cluster member, so we can merge the 2 clusters */
|
if( pt_autre_piste->GetSubNet() ) /* The other track is already a cluster member, so we can merge the 2 clusters */
|
||||||
{
|
{
|
||||||
Merge_Two_SubNets( pt_start_conn, pt_end_conn,
|
Merge_Two_SubNets( pt_start_conn, pt_end_conn,
|
||||||
pt_autre_piste->GetSubNet(), pt_conn->GetSubNet() );
|
pt_autre_piste->GetSubNet(), pt_conn->GetSubNet() );
|
||||||
}
|
}
|
||||||
else /* The other track is not yet attached to a cluster , so we can add this other track to the cluster */
|
else /* The other track is not yet attached to a cluster , so we can add this other track to the cluster */
|
||||||
{
|
{
|
||||||
|
@ -239,7 +239,7 @@ static void Propagate_SubNet( TRACK* pt_start_conn, TRACK* pt_end_conn )
|
||||||
if( pt_autre_piste->GetSubNet() )
|
if( pt_autre_piste->GetSubNet() )
|
||||||
{
|
{
|
||||||
Merge_Two_SubNets( pt_start_conn, pt_end_conn,
|
Merge_Two_SubNets( pt_start_conn, pt_end_conn,
|
||||||
pt_autre_piste->GetSubNet(), pt_conn->GetSubNet() );
|
pt_autre_piste->GetSubNet(), pt_conn->GetSubNet() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pt_autre_piste->SetSubNet( pt_conn->GetSubNet() );
|
pt_autre_piste->SetSubNet( pt_conn->GetSubNet() );
|
||||||
|
@ -291,7 +291,7 @@ void WinEDA_BasePcbFrame::test_connexions( wxDC* DC )
|
||||||
for( TRACK* track = m_Pcb->m_Track; track; )
|
for( TRACK* track = m_Pcb->m_Track; track; )
|
||||||
{
|
{
|
||||||
// this is the current net because pt_start_conn is the first segment of the net
|
// this is the current net because pt_start_conn is the first segment of the net
|
||||||
int current_net_code = track->GetNet();
|
int current_net_code = track->GetNet();
|
||||||
|
|
||||||
// this is the last segment of the current net
|
// this is the last segment of the current net
|
||||||
TRACK* pt_end_conn = track->GetEndNetCode( current_net_code );
|
TRACK* pt_end_conn = track->GetEndNetCode( current_net_code );
|
||||||
|
@ -317,7 +317,7 @@ void WinEDA_BasePcbFrame::test_1_net_connexion( wxDC* DC, int net_code )
|
||||||
* @param net_code = net code to test
|
* @param net_code = net code to test
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
wxString msg;
|
wxString msg;
|
||||||
|
|
||||||
if( net_code == 0 )
|
if( net_code == 0 )
|
||||||
return;
|
return;
|
||||||
|
@ -325,11 +325,11 @@ void WinEDA_BasePcbFrame::test_1_net_connexion( wxDC* DC, int net_code )
|
||||||
if( (m_Pcb->m_Status_Pcb & LISTE_CHEVELU_OK) == 0 )
|
if( (m_Pcb->m_Status_Pcb & LISTE_CHEVELU_OK) == 0 )
|
||||||
Compile_Ratsnest( DC, TRUE );
|
Compile_Ratsnest( DC, TRUE );
|
||||||
|
|
||||||
for( unsigned i=0; i<m_Pcb->m_Pads.size(); ++i )
|
for( unsigned i = 0; i<m_Pcb->m_Pads.size(); ++i )
|
||||||
{
|
{
|
||||||
D_PAD* pad = m_Pcb->m_Pads[i];
|
D_PAD* pad = m_Pcb->m_Pads[i];
|
||||||
|
|
||||||
int pad_net_code = pad->GetNet();
|
int pad_net_code = pad->GetNet();
|
||||||
|
|
||||||
if( pad_net_code < net_code )
|
if( pad_net_code < net_code )
|
||||||
continue;
|
continue;
|
||||||
|
@ -345,8 +345,8 @@ void WinEDA_BasePcbFrame::test_1_net_connexion( wxDC* DC, int net_code )
|
||||||
/* Search for the first and the last segment relative to the given net code */
|
/* Search for the first and the last segment relative to the given net code */
|
||||||
if( m_Pcb->m_Track )
|
if( m_Pcb->m_Track )
|
||||||
{
|
{
|
||||||
TRACK* pt_start_conn;
|
TRACK* pt_start_conn;
|
||||||
TRACK* pt_end_conn = NULL;
|
TRACK* pt_end_conn = NULL;
|
||||||
pt_start_conn = m_Pcb->m_Track.GetFirst()->GetStartNetCode( net_code );
|
pt_start_conn = m_Pcb->m_Track.GetFirst()->GetStartNetCode( net_code );
|
||||||
|
|
||||||
if( pt_start_conn )
|
if( pt_start_conn )
|
||||||
|
@ -475,7 +475,7 @@ static D_PAD* SuperFast_Locate_Pad_Connecte( BOARD* aPcb, LISTE_PAD* pt_liste,
|
||||||
|
|
||||||
int nb_pad = aPcb->m_Pads.size();
|
int nb_pad = aPcb->m_Pads.size();
|
||||||
LISTE_PAD* ptr_pad = pt_liste;
|
LISTE_PAD* ptr_pad = pt_liste;
|
||||||
LISTE_PAD* lim = pt_liste + nb_pad - 1;
|
LISTE_PAD* lim = pt_liste + nb_pad - 1;
|
||||||
|
|
||||||
ptr_pad = pt_liste;
|
ptr_pad = pt_liste;
|
||||||
while( nb_pad )
|
while( nb_pad )
|
||||||
|
@ -539,7 +539,6 @@ static D_PAD* SuperFast_Locate_Pad_Connecte( BOARD* aPcb, LISTE_PAD* pt_liste,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function SortPadsByXCoord
|
* Function SortPadsByXCoord
|
||||||
* is used to Sort a pad list by x coordinate value.
|
* is used to Sort a pad list by x coordinate value.
|
||||||
|
@ -553,7 +552,6 @@ static int SortPadsByXCoord( const void* pt_ref, const void* pt_comp )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
void CreateSortedPadListByXCoord( BOARD* aBoard, std::vector<D_PAD*>* aVector )
|
void CreateSortedPadListByXCoord( BOARD* aBoard, std::vector<D_PAD*>* aVector )
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -575,17 +573,29 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche )
|
||||||
* We search a connection between a track segment and a pad: if found : this segment netcode is set to the pad netcode
|
* We search a connection between a track segment and a pad: if found : this segment netcode is set to the pad netcode
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
TRACK* pt_piste;
|
TRACK* pt_piste;
|
||||||
TRACK* pt_next;
|
TRACK* pt_next;
|
||||||
int a_color;
|
int a_color;
|
||||||
char new_passe_request = 1, flag;
|
char new_passe_request = 1, flag;
|
||||||
std::vector<D_PAD*> sortedPads;
|
|
||||||
BOARD_ITEM* PtStruct;
|
std::vector<D_PAD*> sortedPads;
|
||||||
int masque_layer;
|
BOARD_ITEM* PtStruct;
|
||||||
wxString msg;
|
int masque_layer;
|
||||||
|
wxString msg;
|
||||||
|
|
||||||
|
if( m_Pcb->m_Pads.size() == 0 ) // If no pad, reset pointers and netcode, and do nothing else
|
||||||
|
{
|
||||||
|
pt_piste = m_Pcb->m_Track;
|
||||||
|
for( ; pt_piste != NULL; pt_piste = pt_piste->Next() )
|
||||||
|
{
|
||||||
|
pt_piste->start = NULL;
|
||||||
|
pt_piste->SetState( BEGIN_ONPAD | END_ONPAD, OFF );
|
||||||
|
pt_piste->SetNet( 0 );
|
||||||
|
pt_piste->end = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if( m_Pcb->m_Pads.size() == 0 )
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
a_color = CYAN;
|
a_color = CYAN;
|
||||||
|
|
||||||
|
@ -795,10 +805,10 @@ void WinEDA_BasePcbFrame::reattribution_reference_piste( int affiche )
|
||||||
*/
|
*/
|
||||||
static int Sort_By_NetCode( const void* left, const void* right )
|
static int Sort_By_NetCode( const void* left, const void* right )
|
||||||
{
|
{
|
||||||
TRACK* pt_ref = *(TRACK**) left;
|
TRACK* pt_ref = *(TRACK**) left;
|
||||||
TRACK* pt_compare = *(TRACK**) right;
|
TRACK* pt_compare = *(TRACK**) right;
|
||||||
|
|
||||||
int ret = pt_ref->GetNet() - pt_compare->GetNet();
|
int ret = pt_ref->GetNet() - pt_compare->GetNet();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -815,11 +825,11 @@ static void RebuildTrackChain( BOARD* pcb )
|
||||||
if( pcb->m_Track == NULL )
|
if( pcb->m_Track == NULL )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int nbsegm = pcb->m_Track.GetCount();
|
int nbsegm = pcb->m_Track.GetCount();
|
||||||
|
|
||||||
TRACK** array = (TRACK**) MyZMalloc( nbsegm * sizeof(TRACK*) );
|
TRACK** array = (TRACK**) MyZMalloc( nbsegm * sizeof(TRACK*) );
|
||||||
|
|
||||||
for( int i=0; i<nbsegm; ++i )
|
for( int i = 0; i<nbsegm; ++i )
|
||||||
{
|
{
|
||||||
array[i] = pcb->m_Track.PopFront();
|
array[i] = pcb->m_Track.PopFront();
|
||||||
wxASSERT( array[i] );
|
wxASSERT( array[i] );
|
||||||
|
@ -831,7 +841,7 @@ static void RebuildTrackChain( BOARD* pcb )
|
||||||
qsort( array, nbsegm, sizeof(TRACK*), Sort_By_NetCode );
|
qsort( array, nbsegm, sizeof(TRACK*), Sort_By_NetCode );
|
||||||
|
|
||||||
// add them back to the list
|
// add them back to the list
|
||||||
for( int i=0; i<nbsegm; ++i )
|
for( int i = 0; i<nbsegm; ++i )
|
||||||
{
|
{
|
||||||
pcb->m_Track.PushBack( array[i] );
|
pcb->m_Track.PushBack( array[i] );
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,11 +34,14 @@ void WinEDA_PcbGlobalDeleteFrame::AcceptPcbDelete( wxCommandEvent& event )
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
{
|
{
|
||||||
int track_mask;
|
int track_mask;
|
||||||
bool redraw = FALSE;
|
bool redraw = false;
|
||||||
|
bool gen_rastnest = false;
|
||||||
wxClientDC dc( m_Parent->DrawPanel );
|
wxClientDC dc( m_Parent->DrawPanel );
|
||||||
|
|
||||||
m_Parent->DrawPanel->PrepareGraphicContext( &dc );
|
m_Parent->DrawPanel->PrepareGraphicContext( &dc );
|
||||||
|
|
||||||
|
m_Parent->SetCurItem( NULL );
|
||||||
|
|
||||||
if( m_DelAlls->GetValue() )
|
if( m_DelAlls->GetValue() )
|
||||||
{
|
{
|
||||||
m_Parent->Clear_Pcb( TRUE );
|
m_Parent->Clear_Pcb( TRUE );
|
||||||
|
@ -49,6 +52,7 @@ void WinEDA_PcbGlobalDeleteFrame::AcceptPcbDelete( wxCommandEvent& event )
|
||||||
if( m_DelZones->GetValue() )
|
if( m_DelZones->GetValue() )
|
||||||
{
|
{
|
||||||
m_Parent->Erase_Zones( TRUE );
|
m_Parent->Erase_Zones( TRUE );
|
||||||
|
gen_rastnest = true;
|
||||||
redraw = TRUE;
|
redraw = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,12 +77,12 @@ void WinEDA_PcbGlobalDeleteFrame::AcceptPcbDelete( wxCommandEvent& event )
|
||||||
if( m_DelModules->GetValue() )
|
if( m_DelModules->GetValue() )
|
||||||
{
|
{
|
||||||
m_Parent->Erase_Modules( TRUE );
|
m_Parent->Erase_Modules( TRUE );
|
||||||
|
gen_rastnest = true;
|
||||||
redraw = TRUE;
|
redraw = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_DelTracks->GetValue() )
|
if( m_DelTracks->GetValue() )
|
||||||
{
|
{
|
||||||
{
|
|
||||||
track_mask = 0;
|
track_mask = 0;
|
||||||
if( !m_TrackFilterLocked->GetValue() )
|
if( !m_TrackFilterLocked->GetValue() )
|
||||||
track_mask |= SEGM_FIXE;
|
track_mask |= SEGM_FIXE;
|
||||||
|
@ -87,7 +91,7 @@ void WinEDA_PcbGlobalDeleteFrame::AcceptPcbDelete( wxCommandEvent& event )
|
||||||
|
|
||||||
m_Parent->Erase_Pistes( &dc, track_mask, TRUE );
|
m_Parent->Erase_Pistes( &dc, track_mask, TRUE );
|
||||||
redraw = TRUE;
|
redraw = TRUE;
|
||||||
}
|
gen_rastnest = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_DelMarkers->GetValue() )
|
if( m_DelMarkers->GetValue() )
|
||||||
|
@ -95,11 +99,14 @@ void WinEDA_PcbGlobalDeleteFrame::AcceptPcbDelete( wxCommandEvent& event )
|
||||||
m_Parent->Erase_Marqueurs();
|
m_Parent->Erase_Marqueurs();
|
||||||
redraw = TRUE;
|
redraw = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( gen_rastnest )
|
||||||
|
m_Parent->Compile_Ratsnest( &dc, true );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( redraw )
|
if( redraw )
|
||||||
{
|
{
|
||||||
m_Parent->SetCurItem( NULL );
|
|
||||||
m_Parent->DrawPanel->Refresh();
|
m_Parent->DrawPanel->Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,6 +285,7 @@ void WinEDA_PcbFrame::Erase_Modules( bool query )
|
||||||
GetBoard()->m_NbNodes = 0;
|
GetBoard()->m_NbNodes = 0;
|
||||||
GetBoard()->m_NbLinks = 0;
|
GetBoard()->m_NbLinks = 0;
|
||||||
GetBoard()->m_NbNoconnect = 0;
|
GetBoard()->m_NbNoconnect = 0;
|
||||||
|
m_Pcb->m_Pads.clear(); // empty the pad list pointers
|
||||||
|
|
||||||
GetScreen()->SetModify();
|
GetScreen()->SetModify();
|
||||||
}
|
}
|
||||||
|
|
|
@ -446,6 +446,11 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
|
||||||
m_Pcb->m_NbNoconnect = 0;
|
m_Pcb->m_NbNoconnect = 0;
|
||||||
m_Pcb->m_NbLinks = 0;
|
m_Pcb->m_NbLinks = 0;
|
||||||
|
|
||||||
|
if( m_Pcb->m_Ratsnest )
|
||||||
|
MyFree( m_Pcb->m_Ratsnest );
|
||||||
|
m_Pcb->m_Ratsnest = NULL;
|
||||||
|
|
||||||
|
|
||||||
if( m_Pcb->m_Pads.size() == 0 )
|
if( m_Pcb->m_Pads.size() == 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -464,13 +469,9 @@ void WinEDA_BasePcbFrame::Build_Board_Ratsnest( wxDC* DC )
|
||||||
|
|
||||||
/* Allocate memory for buffer ratsnest: there are nb_nodes - 1 ratsnest
|
/* Allocate memory for buffer ratsnest: there are nb_nodes - 1 ratsnest
|
||||||
* maximum ( 1 node = 1 active pad ).
|
* maximum ( 1 node = 1 active pad ).
|
||||||
* Meory is allocated for nb_nodes ratsnests... (+ a bit more, just in case)
|
* Memory is allocated for nb_nodes ratsnests... (+ a bit more, just in case)
|
||||||
* The real ratsnests count nb_links < nb_nodes
|
* The real ratsnests count nb_links < nb_nodes
|
||||||
*/
|
*/
|
||||||
if( m_Pcb->m_Ratsnest )
|
|
||||||
MyFree( m_Pcb->m_Ratsnest );
|
|
||||||
m_Pcb->m_Ratsnest = NULL;
|
|
||||||
|
|
||||||
if( m_Pcb->m_NbNodes == 0 )
|
if( m_Pcb->m_NbNodes == 0 )
|
||||||
return; /* pas de connexions utiles */
|
return; /* pas de connexions utiles */
|
||||||
|
|
||||||
|
|
|
@ -110,6 +110,8 @@ double s_Correction; /* mult coeff used to enlarge rounded and oval pads (an
|
||||||
*/
|
*/
|
||||||
void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
{
|
{
|
||||||
|
bool have_poly_to_substract = false;
|
||||||
|
|
||||||
// Set the number of segments in arc approximations
|
// Set the number of segments in arc approximations
|
||||||
if( m_ArcToSegmentsCount == 32 )
|
if( m_ArcToSegmentsCount == 32 )
|
||||||
s_CircleToSegmentsCount = 32;
|
s_CircleToSegmentsCount = 32;
|
||||||
|
@ -149,6 +151,9 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
CopyPolygonsFromBoolengineToFilledPolysList( booleng );
|
CopyPolygonsFromBoolengineToFilledPolysList( booleng );
|
||||||
delete booleng;
|
delete booleng;
|
||||||
|
|
||||||
|
if ( m_FilledPolysList.size() == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
/* Second, Add the main (corrected) polygon (i.e. the filled area using only one outline)
|
/* Second, Add the main (corrected) polygon (i.e. the filled area using only one outline)
|
||||||
* in GroupA in Bool_Engine to do a BOOL_A_SUB_B operation
|
* in GroupA in Bool_Engine to do a BOOL_A_SUB_B operation
|
||||||
* All areas to remove will be put in GroupB in Bool_Engine
|
* All areas to remove will be put in GroupB in Bool_Engine
|
||||||
|
@ -178,6 +183,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
* First : Add pads. Note: pads having the same net as zone are left in zone.
|
* First : Add pads. Note: pads having the same net as zone are left in zone.
|
||||||
* Thermal shapes will be created later if necessary
|
* Thermal shapes will be created later if necessary
|
||||||
*/
|
*/
|
||||||
|
have_poly_to_substract = false;
|
||||||
for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
|
for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
|
||||||
{
|
{
|
||||||
for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() )
|
for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() )
|
||||||
|
@ -189,7 +195,10 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
{
|
{
|
||||||
item_boundingbox = pad->GetBoundingBox();
|
item_boundingbox = pad->GetBoundingBox();
|
||||||
if( item_boundingbox.Intersects( zone_boundingbox ) )
|
if( item_boundingbox.Intersects( zone_boundingbox ) )
|
||||||
|
{
|
||||||
AddPadWithClearancePolygon( booleng, *pad, clearance );
|
AddPadWithClearancePolygon( booleng, *pad, clearance );
|
||||||
|
have_poly_to_substract = true;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,7 +206,11 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
{
|
{
|
||||||
item_boundingbox = pad->GetBoundingBox();
|
item_boundingbox = pad->GetBoundingBox();
|
||||||
if( item_boundingbox.Intersects( zone_boundingbox ) )
|
if( item_boundingbox.Intersects( zone_boundingbox ) )
|
||||||
|
{
|
||||||
AddPadWithClearancePolygon( booleng, *pad, clearance );
|
AddPadWithClearancePolygon( booleng, *pad, clearance );
|
||||||
|
have_poly_to_substract = true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,8 +227,11 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
continue;
|
continue;
|
||||||
item_boundingbox = track->GetBoundingBox();
|
item_boundingbox = track->GetBoundingBox();
|
||||||
if( item_boundingbox.Intersects( zone_boundingbox ) )
|
if( item_boundingbox.Intersects( zone_boundingbox ) )
|
||||||
|
{
|
||||||
AddTrackWithClearancePolygon( booleng, *track, clearance );
|
AddTrackWithClearancePolygon( booleng, *track, clearance );
|
||||||
}
|
have_poly_to_substract = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Draw graphic items (copper texts) and board edges
|
// Draw graphic items (copper texts) and board edges
|
||||||
// zone clearance is used here regardless of the g_DesignSettings.m_TrackClearence value
|
// zone clearance is used here regardless of the g_DesignSettings.m_TrackClearence value
|
||||||
|
@ -234,6 +250,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
AddRingPolygon( booleng, ( (DRAWSEGMENT*) item )->m_Start, // Circle centre
|
AddRingPolygon( booleng, ( (DRAWSEGMENT*) item )->m_Start, // Circle centre
|
||||||
( (DRAWSEGMENT*) item )->m_End, 3600,
|
( (DRAWSEGMENT*) item )->m_End, 3600,
|
||||||
( (DRAWSEGMENT*) item )->m_Width + (2 * m_ZoneClearance) );
|
( (DRAWSEGMENT*) item )->m_Width + (2 * m_ZoneClearance) );
|
||||||
|
have_poly_to_substract = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_ARC:
|
case S_ARC:
|
||||||
|
@ -241,6 +258,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
( (DRAWSEGMENT*) item )->m_End,
|
( (DRAWSEGMENT*) item )->m_End,
|
||||||
( (DRAWSEGMENT*) item )->m_Angle,
|
( (DRAWSEGMENT*) item )->m_Angle,
|
||||||
( (DRAWSEGMENT*) item )->m_Width + (2 * m_ZoneClearance) );
|
( (DRAWSEGMENT*) item )->m_Width + (2 * m_ZoneClearance) );
|
||||||
|
have_poly_to_substract = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -250,6 +268,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
( (DRAWSEGMENT*) item )->m_End,
|
( (DRAWSEGMENT*) item )->m_End,
|
||||||
( (DRAWSEGMENT*) item )->m_Width +
|
( (DRAWSEGMENT*) item )->m_Width +
|
||||||
(2 * m_ZoneClearance) );
|
(2 * m_ZoneClearance) );
|
||||||
|
have_poly_to_substract = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,6 +278,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
if( ( (TEXTE_PCB*) item )->GetLength() == 0 )
|
if( ( (TEXTE_PCB*) item )->GetLength() == 0 )
|
||||||
break;
|
break;
|
||||||
AddTextBoxWithClearancePolygon( booleng, (TEXTE_PCB*) item, m_ZoneClearance );
|
AddTextBoxWithClearancePolygon( booleng, (TEXTE_PCB*) item, m_ZoneClearance );
|
||||||
|
have_poly_to_substract = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -267,23 +287,32 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calculates copper areas */
|
/* calculates copper areas */
|
||||||
booleng->Do_Operation( BOOL_A_SUB_B );
|
if ( have_poly_to_substract )
|
||||||
|
{
|
||||||
|
booleng->Do_Operation( BOOL_A_SUB_B );
|
||||||
|
|
||||||
/* put these areas in m_FilledPolysList */
|
/* put these areas in m_FilledPolysList */
|
||||||
m_FilledPolysList.clear();
|
m_FilledPolysList.clear();
|
||||||
CopyPolygonsFromBoolengineToFilledPolysList( booleng );
|
CopyPolygonsFromBoolengineToFilledPolysList( booleng );
|
||||||
|
}
|
||||||
delete booleng;
|
delete booleng;
|
||||||
|
|
||||||
// Remove insulated islands:
|
// Remove insulated islands:
|
||||||
if( GetNet() > 0 )
|
if( GetNet() > 0 )
|
||||||
Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb );
|
Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb );
|
||||||
|
|
||||||
|
// remove thermal gaps if required:
|
||||||
|
if( m_PadOption != THERMAL_PAD || aPcb->m_Modules == NULL )
|
||||||
|
return;
|
||||||
|
|
||||||
// Remove thermal symbols
|
// Remove thermal symbols
|
||||||
|
have_poly_to_substract = false;
|
||||||
|
|
||||||
if( m_PadOption == THERMAL_PAD )
|
if( m_PadOption == THERMAL_PAD )
|
||||||
{
|
{
|
||||||
booleng = new Bool_Engine();
|
booleng = new Bool_Engine();
|
||||||
ArmBoolEng( booleng, true );
|
ArmBoolEng( booleng, true );
|
||||||
bool have_poly_to_substract = false;
|
have_poly_to_substract = false;
|
||||||
|
|
||||||
for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
|
for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
|
||||||
{
|
{
|
||||||
|
@ -320,15 +349,13 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
CopyPolygonsFromBoolengineToFilledPolysList( booleng );
|
CopyPolygonsFromBoolengineToFilledPolysList( booleng );
|
||||||
}
|
}
|
||||||
delete booleng;
|
delete booleng;
|
||||||
|
|
||||||
|
// Remove insulated islands:
|
||||||
|
if( GetNet() > 0 )
|
||||||
|
Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove insulated islands:
|
|
||||||
if( GetNet() > 0 )
|
|
||||||
Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb );
|
|
||||||
|
|
||||||
if( m_PadOption != THERMAL_PAD )
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Now we remove all unused thermal stubs.
|
// Now we remove all unused thermal stubs.
|
||||||
//define REMOVE_UNUSED_THERMAL_STUBS // Can be commented to skip unused thermal stubs calculations
|
//define REMOVE_UNUSED_THERMAL_STUBS // Can be commented to skip unused thermal stubs calculations
|
||||||
//#ifdef REMOVE_UNUSED_THERMAL_STUBS
|
//#ifdef REMOVE_UNUSED_THERMAL_STUBS
|
||||||
|
@ -348,6 +375,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
/*
|
/*
|
||||||
* Test and add polygons to remove thermal stubs.
|
* Test and add polygons to remove thermal stubs.
|
||||||
*/
|
*/
|
||||||
|
have_poly_to_substract = false;
|
||||||
for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
|
for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
|
||||||
{
|
{
|
||||||
for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() )
|
for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() )
|
||||||
|
@ -446,6 +474,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
RotatePoint( &cpos, fAngle ); // Rotate according to module orientation
|
RotatePoint( &cpos, fAngle ); // Rotate according to module orientation
|
||||||
cpos += pad->ReturnShapePos(); // Shift origin to position
|
cpos += pad->ReturnShapePos(); // Shift origin to position
|
||||||
booleng->AddPoint( cpos.x, cpos.y );
|
booleng->AddPoint( cpos.x, cpos.y );
|
||||||
|
have_poly_to_substract = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
booleng->EndPolygonAdd();
|
booleng->EndPolygonAdd();
|
||||||
|
@ -456,16 +485,19 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compute copper areas */
|
/* compute copper areas */
|
||||||
booleng->Do_Operation( BOOL_A_SUB_B );
|
if ( have_poly_to_substract )
|
||||||
|
{
|
||||||
|
booleng->Do_Operation( BOOL_A_SUB_B );
|
||||||
|
|
||||||
|
/* put these areas in m_FilledPolysList */
|
||||||
|
m_FilledPolysList.clear();
|
||||||
|
CopyPolygonsFromBoolengineToFilledPolysList( booleng );
|
||||||
|
// Remove insulated islands, if any:
|
||||||
|
if( GetNet() > 0 )
|
||||||
|
Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb );
|
||||||
|
}
|
||||||
|
|
||||||
/* put these areas in m_FilledPolysList */
|
|
||||||
m_FilledPolysList.clear();
|
|
||||||
CopyPolygonsFromBoolengineToFilledPolysList( booleng );
|
|
||||||
delete booleng;
|
delete booleng;
|
||||||
|
|
||||||
// Remove insulated islands, if any:
|
|
||||||
if( GetNet() > 0 )
|
|
||||||
Test_For_Copper_Island_And_Remove_Insulated_Islands( aPcb );
|
|
||||||
//#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -569,7 +601,12 @@ void AddPadWithClearancePolygon( Bool_Engine* aBooleng,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case PAD_RECT: // Easy implementation for rectangular cutouts with rounded corners
|
case PAD_TRAPEZOID:
|
||||||
|
default: /* @todo: the others shapes must be calculated: see trapezoidal shape
|
||||||
|
* but before this is made, the rect shape is used insteed.
|
||||||
|
* A polygon *must* be created because we have started a polygon in kbool engine
|
||||||
|
*/
|
||||||
|
case PAD_RECT: // Easy implementation for rectangular cutouts with rounded corners // Easy implementation for rectangular cutouts with rounded corners
|
||||||
angle = aPad.m_Orient;
|
angle = aPad.m_Orient;
|
||||||
int rounding_radius = (int) ( aClearanceValue * s_Correction ); // Corner rounding radius
|
int rounding_radius = (int) ( aClearanceValue * s_Correction ); // Corner rounding radius
|
||||||
int angle_pg; // Polygon increment angle
|
int angle_pg; // Polygon increment angle
|
||||||
|
|
Loading…
Reference in New Issue