Commit 5a96588e authored by jean-pierre charras's avatar jean-pierre charras

Fix bug 910364: When a footprint saved in a .mod file is not on front layer...

Fix bug 910364: When a footprint saved in a .mod file is not on front layer and/or not with orientation 0 degree, the Module editor load it incorrectly.
note:  the Module editor save it with default orientation and layer, but the archive function does not, so some footprints can be not editable.
TODO: modify the Archive Function to use the default layer / orientation.
parent b774d96f
This diff is collapsed.
This diff is collapsed.
...@@ -326,9 +326,12 @@ void SCH_PRINTOUT::DrawPage( SCH_SCREEN* aScreen ) ...@@ -326,9 +326,12 @@ void SCH_PRINTOUT::DrawPage( SCH_SCREEN* aScreen )
old_org = aScreen->m_DrawOrg; old_org = aScreen->m_DrawOrg;
oldClipBox = *panel->GetClipBox(); oldClipBox = *panel->GetClipBox();
/* Change scale factor, offsets, and clip box to print the whole page. */ // Change clip box to print the whole page.
panel->SetClipBox( EDA_RECT( wxPoint( 0, 0 ), wxSize( 0x7FFFFF0, 0x7FFFFF0 ) ) ); #define MAX_VALUE (INT_MAX/2) // MAX_VALUE is the max we can use in an integer
// and that allows calculations without overflow
panel->SetClipBox( EDA_RECT( wxPoint( 0, 0 ), wxSize( MAX_VALUE, MAX_VALUE ) ) );
// Change scale factor and offset to print the whole page.
bool printReference = parent->GetPrintSheetReference(); bool printReference = parent->GetPrintSheetReference();
if( printReference ) if( printReference )
......
...@@ -91,9 +91,13 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule ) ...@@ -91,9 +91,13 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule )
GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) ); GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) );
PlaceModule( aModule, NULL ); PlaceModule( aModule, NULL );
// Put it on FRONT layer,
// because this is the default in ModEdit, and in libs
if( aModule->GetLayer() != LAYER_N_FRONT ) if( aModule->GetLayer() != LAYER_N_FRONT )
aModule->Flip( aModule->m_Pos ); aModule->Flip( aModule->m_Pos );
// Put it in orientation 0,
// because this is the default orientation in ModEdit, and in libs
Rotate_Module( NULL, aModule, 0, false ); Rotate_Module( NULL, aModule, 0, false );
GetScreen()->ClrModify(); GetScreen()->ClrModify();
Zoom_Automatique( false ); Zoom_Automatique( false );
...@@ -189,15 +193,15 @@ MODULE* PCB_BASE_FRAME::Load_Module_From_Library( const wxString& library, wxDC* ...@@ -189,15 +193,15 @@ MODULE* PCB_BASE_FRAME::Load_Module_From_Library( const wxString& library, wxDC*
module->SetTimeStamp( GetNewTimeStamp() ); module->SetTimeStamp( GetNewTimeStamp() );
GetBoard()->m_Status_Pcb = 0; GetBoard()->m_Status_Pcb = 0;
module->SetPosition( curspos ); module->SetPosition( curspos );
// Put it on FRONT layer,
// (Can be stored on BACK layer if the lib is an archive built from a board)
if( module->GetLayer() != LAYER_N_FRONT )
module->Flip( module->m_Pos );
// Put in in orientation 0,
// even if it is not saved with with orientation 0 in lib
// (Can happen if the lib is an archive built from a board)
Rotate_Module( NULL, module, 0, false );
/* TODO: call RecalculateAllTracksNetcode() only if some pads pads have
* a netname.
* If all pads are not connected (usually the case in module libraries,
* rebuild only the pad and list of nets ( faster)
*/
// GetBoard()->m_Pcb->m_NetInfo.BuildListOfNets();
RecalculateAllTracksNetcode(); RecalculateAllTracksNetcode();
if( DC ) if( DC )
......
...@@ -22,6 +22,16 @@ using namespace std; ...@@ -22,6 +22,16 @@ using namespace std;
static bool CmpZoneSubnetValue( const BOARD_CONNECTED_ITEM* a, const BOARD_CONNECTED_ITEM* b ); static bool CmpZoneSubnetValue( const BOARD_CONNECTED_ITEM* a, const BOARD_CONNECTED_ITEM* b );
void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode ); void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode );
// This helper function sort a list of zones by netcode,
// and for a given netcode by zone size
// zone size = size of the m_FilledPolysList buffer
bool sort_areas( const ZONE_CONTAINER* ref, const ZONE_CONTAINER* tst )
{
if( ref->GetNet() == tst->GetNet() )
return ref->m_FilledPolysList.size() < tst->m_FilledPolysList.size();
else
return ref->GetNet() < tst->GetNet();
}
/** /**
* Function Test_Connection_To_Copper_Areas * Function Test_Connection_To_Copper_Areas
...@@ -34,7 +44,6 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode ) ...@@ -34,7 +44,6 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode )
// It is static to avoid multiple memory realloc. // It is static to avoid multiple memory realloc.
static std::vector <BOARD_CONNECTED_ITEM*> Candidates; static std::vector <BOARD_CONNECTED_ITEM*> Candidates;
// clear .m_ZoneSubnet parameter for pads // clear .m_ZoneSubnet parameter for pads
for( MODULE* module = m_Modules; module; module = module->Next() ) for( MODULE* module = m_Modules; module; module = module->Next() )
{ {
...@@ -52,30 +61,49 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode ) ...@@ -52,30 +61,49 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode )
// examine all zones, net by net: // examine all zones, net by net:
int subnet = 0; int subnet = 0;
// Build zones candidates list
std::vector<ZONE_CONTAINER*> zones_candidates;
for( int index = 0; index < GetAreaCount(); index++ ) for( int index = 0; index < GetAreaCount(); index++ )
{ {
ZONE_CONTAINER* curr_zone = GetArea( index ); ZONE_CONTAINER* curr_zone = GetArea( index );
if( !curr_zone->IsOnCopperLayer() ) if( !curr_zone->IsOnCopperLayer() )
continue; continue;
if( (aNetcode >= 0) && ( aNetcode != curr_zone->GetNet() ) )
int netcode = curr_zone->GetNet();
if( (aNetcode >= 0) && !( aNetcode == netcode ) )
continue; continue;
if( curr_zone->m_FilledPolysList.size() == 0 ) if( curr_zone->m_FilledPolysList.size() == 0 )
continue; continue;
zones_candidates.push_back(curr_zone);
}
// sort them by netcode then vertices count.
// For a given net, examine the smaller zones first slightly speed up calculation
// (25% faster)
// this is only noticeable with very large boards and depends on board zones topology
// This is due to the fact some items are connected bt small zones ares,
// before examining large zones areas and these items are not tested after a connection is found
sort(zones_candidates.begin(), zones_candidates.end(), sort_areas );
int oldnetcode = -1;
for( unsigned idx = 0; idx < zones_candidates.size(); idx++ )
{
ZONE_CONTAINER* curr_zone = zones_candidates[idx];
// Build a list of candidates connected to the net: int netcode = curr_zone->GetNet();
Candidates.clear();
// Build a list of candidates connected to the net:
// At this point, layers are not considered, because areas on different layers can // At this point, layers are not considered, because areas on different layers can
// be connected by a via or a pad. // be connected by a via or a pad.
// (because zones are sorted by netcode, there is made only once per net)
// Build the list of pads candidates connected to the net:
NETINFO_ITEM* net = FindNet( netcode ); NETINFO_ITEM* net = FindNet( netcode );
wxASSERT( net ); wxASSERT( net );
if( net == NULL ) if( net == NULL )
continue; continue;
if( oldnetcode != netcode )
{
oldnetcode = netcode;
Candidates.clear();
// Build the list of pads candidates connected to the net:
Candidates.reserve( net->m_PadInNetList.size() ); Candidates.reserve( net->m_PadInNetList.size() );
for( unsigned ii = 0; ii < net->m_PadInNetList.size(); ii++ ) for( unsigned ii = 0; ii < net->m_PadInNetList.size(); ii++ )
Candidates.push_back( net->m_PadInNetList[ii] ); Candidates.push_back( net->m_PadInNetList[ii] );
...@@ -88,10 +116,10 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode ) ...@@ -88,10 +116,10 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode )
break; break;
Candidates.push_back( track ); Candidates.push_back( track );
} }
}
// test if a candidate is inside a filled area of this zone // test if a candidate is inside a filled area of this zone
unsigned indexstart = 0, indexend; unsigned indexstart = 0, indexend;
for( indexend = 0; indexend < curr_zone->m_FilledPolysList.size(); indexend++ ) for( indexend = 0; indexend < curr_zone->m_FilledPolysList.size(); indexend++ )
{ {
// end of a filled sub-area found // end of a filled sub-area found
...@@ -104,6 +132,9 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode ) ...@@ -104,6 +132,9 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode )
{ // test if this area is connected to a board item: { // test if this area is connected to a board item:
BOARD_CONNECTED_ITEM* item = Candidates[ic]; BOARD_CONNECTED_ITEM* item = Candidates[ic];
if( item->GetZoneSubNet() == subnet ) // Already merged
continue;
if( !item->IsOnLayer( curr_zone->GetLayer() ) ) if( !item->IsOnLayer( curr_zone->GetLayer() ) )
continue; continue;
...@@ -138,17 +169,19 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode ) ...@@ -138,17 +169,19 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode )
if( !connected && (pos1 != pos2 ) ) if( !connected && (pos1 != pos2 ) )
{ {
if( bbox.Contains( pos2 ) ) if( bbox.Contains( pos2 ) )
if( TestPointInsidePolygon( curr_zone->m_FilledPolysList, indexstart, {
indexend, pos2.x, pos2.y ) ) if( TestPointInsidePolygon( curr_zone->m_FilledPolysList,
indexstart, indexend,
pos2.x, pos2.y ) )
connected = true; connected = true;
} }
}
if( connected ) if( connected )
{ // Set ZoneSubnet to the current subnet value. { // Set ZoneSubnet to the current subnet value.
// If the previous subnet is not 0, merge all items with old subnet // If the previous subnet is not 0, merge all items with old subnet
// to the new one // to the new one
int old_subnet = 0; int old_subnet = item->GetZoneSubNet();
old_subnet = item->GetZoneSubNet();
item->SetZoneSubNet( subnet ); item->SetZoneSubNet( subnet );
// Merge previous subnet with the current // Merge previous subnet with the current
...@@ -170,8 +203,8 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode ) ...@@ -170,8 +203,8 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode )
// (if exists). End read one area in // (if exists). End read one area in
// curr_zone->m_FilledPolysList // curr_zone->m_FilledPolysList
} }
} // End read all segments in zone. } // End read all segments in zone
} // End read all zones in board } // End read all zones candidates
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment