Commit d47823c1 authored by dickelbeck's avatar dickelbeck

specctra session work

parent 40e2fed3
...@@ -5,6 +5,21 @@ Started 2007-June-11 ...@@ -5,6 +5,21 @@ 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.
2008-Feb-7 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+pcbnew
added "const" to SEGVIA::GetDrillValue() const;
added GetDrillValue() to DRC instead of accessing SEGVIA::m_Drill directly.
changed specctra_export so it aborts if all reference designators are not
unique. Unless they are unique we cannot import the routed session. A
good example is the xylinx board which now fails to export.
first rough work on SEGVIA::makeVIA() but needs much more work. Simple
session files with vias at least import. Now encode drill diameter in
padstack name for later session import.
updated todo.txt file.
2008-Feb-7 UPDATE Dick Hollenbeck <dick@softplc.com> 2008-Feb-7 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================ ================================================================================
+pcbnew +pcbnew
......
...@@ -62,7 +62,7 @@ wxString TRACK::ShowWidth() ...@@ -62,7 +62,7 @@ wxString TRACK::ShowWidth()
/***************************/ /***************************/
{ {
wxString msg; wxString msg;
valeur_param( m_Width, msg ); valeur_param( m_Width, msg );
return msg; return msg;
...@@ -125,16 +125,18 @@ TRACK* TRACK::Copy() const ...@@ -125,16 +125,18 @@ TRACK* TRACK::Copy() const
* calculate the drill value for vias (m-Drill if > 0, or default drill value for the board * calculate the drill value for vias (m-Drill if > 0, or default drill value for the board
* @return real drill_value * @return real drill_value
*/ */
int TRACK::GetDrillValue(void) int TRACK::GetDrillValue() const
{ {
if ( Type() != TYPEVIA ) return 0; if ( Type() != TYPEVIA )
return 0;
if ( m_Drill >= 0 )
return m_Drill;
if ( m_Drill >= 0 ) return m_Drill; if ( m_Shape == VIA_MICROVIA )
return g_DesignSettings.m_MicroViaDrill;
if ( m_Shape == VIA_MICROVIA )
return g_DesignSettings.m_MicroViaDrill;
return g_DesignSettings.m_ViaDrill; return g_DesignSettings.m_ViaDrill;
} }
...@@ -441,7 +443,7 @@ TRACK* TRACK::GetBestInsertPoint( BOARD* Pcb ) ...@@ -441,7 +443,7 @@ TRACK* TRACK::GetBestInsertPoint( BOARD* Pcb )
/* Traitement du debut de liste */ /* Traitement du debut de liste */
if( track == NULL ) if( track == NULL )
return NULL; /* No tracks ! */ return NULL; /* No tracks ! */
if( GetNet() < track->GetNet() ) /* no net code or net code = 0 (track not connected) */ if( GetNet() < track->GetNet() ) /* no net code or net code = 0 (track not connected) */
return NULL; return NULL;
...@@ -449,7 +451,7 @@ TRACK* TRACK::GetBestInsertPoint( BOARD* Pcb ) ...@@ -449,7 +451,7 @@ TRACK* TRACK::GetBestInsertPoint( BOARD* Pcb )
{ {
if( NextTrack->GetNet() > this->GetNet() ) if( NextTrack->GetNet() > this->GetNet() )
break; break;
track = NextTrack; track = NextTrack;
} }
...@@ -614,7 +616,7 @@ void TRACK::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode ) ...@@ -614,7 +616,7 @@ void TRACK::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode )
if( rayon > (4 * zoom) ) if( rayon > (4 * zoom) )
{ {
int drill_rayon = GetDrillValue() / 2; int drill_rayon = GetDrillValue() / 2;
int inner_rayon = rayon - (2 * zoom); int inner_rayon = rayon - (2 * zoom);
GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y,
inner_rayon, color ); inner_rayon, color );
...@@ -622,7 +624,7 @@ void TRACK::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode ) ...@@ -622,7 +624,7 @@ void TRACK::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode )
if( DisplayOpt.m_DisplayViaMode != VIA_HOLE_NOT_SHOW ) if( DisplayOpt.m_DisplayViaMode != VIA_HOLE_NOT_SHOW )
{ {
if( (DisplayOpt.m_DisplayViaMode == ALL_VIA_HOLE_SHOW) || // Display all drill holes requested if( (DisplayOpt.m_DisplayViaMode == ALL_VIA_HOLE_SHOW) || // Display all drill holes requested
( (drill_rayon > 0 ) && ! IsDrillDefault() ) ) // Or Display non default holes requested ( (drill_rayon > 0 ) && ! IsDrillDefault() ) ) // Or Display non default holes requested
{ {
if( drill_rayon < inner_rayon ) // We can show the via hole if( drill_rayon < inner_rayon ) // We can show the via hole
{ {
...@@ -635,53 +637,53 @@ void TRACK::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode ) ...@@ -635,53 +637,53 @@ void TRACK::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode )
if( DisplayOpt.DisplayTrackIsol ) if( DisplayOpt.DisplayTrackIsol )
GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y, GRCircle( &panel->m_ClipBox, DC, m_Start.x, m_Start.y,
rayon + g_DesignSettings.m_TrackClearence, color ); rayon + g_DesignSettings.m_TrackClearence, color );
// for Micro Vias, draw a partial cross : // for Micro Vias, draw a partial cross :
// X on component layer, or + on copper layer // X on component layer, or + on copper layer
// (so we can see 2 superimposed microvias ): // (so we can see 2 superimposed microvias ):
if ( Shape() == VIA_MICROVIA ) if ( Shape() == VIA_MICROVIA )
{ {
int ax, ay, bx, by; int ax, ay, bx, by;
if ( IsOnLayer(COPPER_LAYER_N) ) if ( IsOnLayer(COPPER_LAYER_N) )
{ {
ax = rayon; ay = 0; ax = rayon; ay = 0;
bx = drill_rayon; by = 0; bx = drill_rayon; by = 0;
} }
else else
{ {
ax = ay = (rayon * 707) / 1000; ax = ay = (rayon * 707) / 1000;
bx = by = (drill_rayon * 707) / 1000; bx = by = (drill_rayon * 707) / 1000;
} }
/* lines | or \ */ /* lines | or \ */
GRLine( &panel->m_ClipBox, DC, m_Start.x - ax , m_Start.y - ay, GRLine( &panel->m_ClipBox, DC, m_Start.x - ax , m_Start.y - ay,
m_Start.x - bx , m_Start.y - by, 0, color ); m_Start.x - bx , m_Start.y - by, 0, color );
GRLine( &panel->m_ClipBox, DC, m_Start.x + bx , m_Start.y + by, GRLine( &panel->m_ClipBox, DC, m_Start.x + bx , m_Start.y + by,
m_Start.x + ax , m_Start.y + ay, 0, color ); m_Start.x + ax , m_Start.y + ay, 0, color );
/* lines - or / */ /* lines - or / */
GRLine( &panel->m_ClipBox, DC, m_Start.x + ay, m_Start.y - ax , GRLine( &panel->m_ClipBox, DC, m_Start.x + ay, m_Start.y - ax ,
m_Start.x + by, m_Start.y - bx, 0, color ); m_Start.x + by, m_Start.y - bx, 0, color );
GRLine( &panel->m_ClipBox, DC, m_Start.x - by, m_Start.y + bx , GRLine( &panel->m_ClipBox, DC, m_Start.x - by, m_Start.y + bx ,
m_Start.x - ay, m_Start.y + ax, 0, color ); m_Start.x - ay, m_Start.y + ax, 0, color );
} }
// for Buried Vias, draw a partial line : // for Buried Vias, draw a partial line :
// orient depending on layer pair // orient depending on layer pair
// (so we can see superimposed buried vias ): // (so we can see superimposed buried vias ):
if ( Shape() == VIA_BLIND_BURIED ) if ( Shape() == VIA_BLIND_BURIED )
{ {
int ax = 0, ay = rayon, bx = 0, by = drill_rayon; int ax = 0, ay = rayon, bx = 0, by = drill_rayon;
int layer_top, layer_bottom ; int layer_top, layer_bottom ;
((SEGVIA*)this)->ReturnLayerPair(&layer_top, &layer_bottom); ((SEGVIA*)this)->ReturnLayerPair(&layer_top, &layer_bottom);
/* lines for the top layer */ /* lines for the top layer */
RotatePoint( &ax, &ay, layer_top * 3600 / g_DesignSettings.m_CopperLayerCount); RotatePoint( &ax, &ay, layer_top * 3600 / g_DesignSettings.m_CopperLayerCount);
RotatePoint( &bx, &by, layer_top * 3600 / g_DesignSettings.m_CopperLayerCount); RotatePoint( &bx, &by, layer_top * 3600 / g_DesignSettings.m_CopperLayerCount);
GRLine( &panel->m_ClipBox, DC, m_Start.x - ax , m_Start.y - ay, GRLine( &panel->m_ClipBox, DC, m_Start.x - ax , m_Start.y - ay,
m_Start.x - bx , m_Start.y - by, 0, color ); m_Start.x - bx , m_Start.y - by, 0, color );
/* lines for the bottom layer */ /* lines for the bottom layer */
ax = 0; ay = rayon; bx = 0; by = drill_rayon; ax = 0; ay = rayon; bx = 0; by = drill_rayon;
RotatePoint( &ax, &ay, layer_bottom * 3600 / g_DesignSettings.m_CopperLayerCount); RotatePoint( &ax, &ay, layer_bottom * 3600 / g_DesignSettings.m_CopperLayerCount);
RotatePoint( &bx, &by, layer_bottom * 3600 / g_DesignSettings.m_CopperLayerCount); RotatePoint( &bx, &by, layer_bottom * 3600 / g_DesignSettings.m_CopperLayerCount);
GRLine( &panel->m_ClipBox, DC, m_Start.x - ax , m_Start.y - ay, GRLine( &panel->m_ClipBox, DC, m_Start.x - ax , m_Start.y - ay,
m_Start.x - bx , m_Start.y - by, 0, color ); m_Start.x - bx , m_Start.y - by, 0, color );
} }
} }
return; return;
} }
...@@ -909,11 +911,11 @@ bool TRACK::HitTest( const wxPoint& ref_pos ) ...@@ -909,11 +911,11 @@ bool TRACK::HitTest( const wxPoint& ref_pos )
*/ */
bool TRACK::HitTest( EDA_Rect& refArea ) bool TRACK::HitTest( EDA_Rect& refArea )
{ {
if( refArea.Inside( m_Start ) ) if( refArea.Inside( m_Start ) )
return true; return true;
if( refArea.Inside( m_End ) ) if( refArea.Inside( m_End ) )
return true; return true;
return false; return false;
} }
......
...@@ -25,7 +25,7 @@ public: ...@@ -25,7 +25,7 @@ public:
int m_Shape; // vias: shape and type, Track = shape.. int m_Shape; // vias: shape and type, Track = shape..
protected: protected:
int m_Drill; // for vias: via drill (- 1 for default value) int m_Drill; // for vias: via drill (- 1 for default value)
public: public:
BOARD_ITEM* start; // pointers to a connected item (pad or track) BOARD_ITEM* start; // pointers to a connected item (pad or track)
...@@ -148,32 +148,32 @@ public: ...@@ -148,32 +148,32 @@ public:
/* divers */ /* divers */
int Shape() const { return m_Shape & 0xFF; } int Shape() const { return m_Shape & 0xFF; }
/** /**
* Function SetDrillValue * Function SetDrillValue
* Set the drill value for vias * Set the drill value for vias
* @param drill_value = new drill value * @param drill_value = new drill value
*/ */
void SetDrillValue(int drill_value) { m_Drill = drill_value; } void SetDrillValue(int drill_value) { m_Drill = drill_value; }
/** /**
* Function SetDrillDefault * Function SetDrillDefault
* Set the drill value for vias at default value (-1) * Set the drill value for vias at default value (-1)
*/ */
void SetDrillDefault(void) { m_Drill = -1; } void SetDrillDefault(void) { m_Drill = -1; }
/** /**
* Function IsDrillDefault * Function IsDrillDefault
* @return true if the drill value is default value (-1) * @return true if the drill value is default value (-1)
*/ */
bool IsDrillDefault(void) { return m_Drill < 0; } bool IsDrillDefault(void) { return m_Drill < 0; }
/** /**
* Function GetDrillValue * Function GetDrillValue
* calculate the drill value for vias (m-Drill if > 0, or default drill value for the board * calculate the drill value for vias (m-Drill if > 0, or default drill value for the board
* @return real drill_value * @return real drill_value
*/ */
int GetDrillValue(void); int GetDrillValue() const;
/** /**
* Function ReturnMaskLayer * Function ReturnMaskLayer
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
/****************************/ /****************************/
/* DRC control */ /* DRC control */
/****************************/ /****************************/
...@@ -58,22 +58,22 @@ void DRC::ShowDialog() ...@@ -58,22 +58,22 @@ void DRC::ShowDialog()
{ {
m_ui = new DrcDialog( this, m_mainWindow ); m_ui = new DrcDialog( this, m_mainWindow );
updatePointers(); updatePointers();
// copy data retained in this DRC object into the m_ui DrcPanel: // copy data retained in this DRC object into the m_ui DrcPanel:
PutValueInLocalUnits( *m_ui->m_SetClearance, g_DesignSettings.m_TrackClearence, PutValueInLocalUnits( *m_ui->m_SetClearance, g_DesignSettings.m_TrackClearence,
m_mainWindow->m_InternalUnits );; m_mainWindow->m_InternalUnits );;
m_ui->m_Pad2PadTestCtrl->SetValue( m_doPad2PadTest ); m_ui->m_Pad2PadTestCtrl->SetValue( m_doPad2PadTest );
m_ui->m_ZonesTestCtrl->SetValue( m_doZonesTest ); m_ui->m_ZonesTestCtrl->SetValue( m_doZonesTest );
m_ui->m_UnconnectedTestCtrl->SetValue( m_doUnconnectedTest ); m_ui->m_UnconnectedTestCtrl->SetValue( m_doUnconnectedTest );
m_ui->m_CreateRptCtrl->SetValue( m_doCreateRptFile ); m_ui->m_CreateRptCtrl->SetValue( m_doCreateRptFile );
m_ui->m_RptFilenameCtrl->SetValue( m_rptFilename ); m_ui->m_RptFilenameCtrl->SetValue( m_rptFilename );
} }
else else
updatePointers(); updatePointers();
m_ui->Show(true); m_ui->Show(true);
} }
...@@ -84,14 +84,14 @@ void DRC::DestroyDialog( int aReason ) ...@@ -84,14 +84,14 @@ void DRC::DestroyDialog( int aReason )
{ {
if( aReason == wxID_OK ) if( aReason == wxID_OK )
{ {
// if user clicked OK, save his choices in this DRC object. // if user clicked OK, save his choices in this DRC object.
m_doCreateRptFile = m_ui->m_CreateRptCtrl->GetValue(); m_doCreateRptFile = m_ui->m_CreateRptCtrl->GetValue();
m_doPad2PadTest = m_ui->m_Pad2PadTestCtrl->GetValue(); m_doPad2PadTest = m_ui->m_Pad2PadTestCtrl->GetValue();
m_doZonesTest = m_ui->m_ZonesTestCtrl->GetValue(); m_doZonesTest = m_ui->m_ZonesTestCtrl->GetValue();
m_doUnconnectedTest = m_ui->m_UnconnectedTestCtrl->GetValue(); m_doUnconnectedTest = m_ui->m_UnconnectedTestCtrl->GetValue();
m_rptFilename = m_ui->m_RptFilenameCtrl->GetValue(); m_rptFilename = m_ui->m_RptFilenameCtrl->GetValue();
} }
m_ui->Destroy(); m_ui->Destroy();
m_ui = 0; m_ui = 0;
} }
...@@ -105,25 +105,25 @@ DRC::DRC( WinEDA_PcbFrame* aPcbWindow ) ...@@ -105,25 +105,25 @@ DRC::DRC( WinEDA_PcbFrame* aPcbWindow )
m_pcb = aPcbWindow->m_Pcb; m_pcb = aPcbWindow->m_Pcb;
m_ui = 0; m_ui = 0;
// establish initial values for everything: // establish initial values for everything:
m_doPad2PadTest = true; m_doPad2PadTest = true;
m_doUnconnectedTest = true; m_doUnconnectedTest = true;
m_doZonesTest = false; m_doZonesTest = false;
m_doCreateRptFile = false; m_doCreateRptFile = false;
// m_rptFilename set to empty by its constructor // m_rptFilename set to empty by its constructor
m_currentMarker = 0; m_currentMarker = 0;
m_spotcx = 0; m_spotcx = 0;
m_spotcy = 0; m_spotcy = 0;
m_finx = 0; m_finx = 0;
m_finy = 0; m_finy = 0;
m_segmAngle = 0; m_segmAngle = 0;
m_segmLength = 0; m_segmLength = 0;
m_xcliplo = 0; m_xcliplo = 0;
m_ycliplo = 0; m_ycliplo = 0;
m_xcliphi = 0; m_xcliphi = 0;
...@@ -134,7 +134,7 @@ DRC::DRC( WinEDA_PcbFrame* aPcbWindow ) ...@@ -134,7 +134,7 @@ DRC::DRC( WinEDA_PcbFrame* aPcbWindow )
DRC::~DRC() DRC::~DRC()
{ {
// maybe someday look at pointainer.h <- google for "pointainer.h" // maybe someday look at pointainer.h <- google for "pointainer.h"
for( unsigned i=0; i<m_unconnected.size(); ++i ) for( unsigned i=0; i<m_unconnected.size(); ++i )
delete m_unconnected[i]; delete m_unconnected[i];
} }
...@@ -144,15 +144,15 @@ int DRC::Drc( TRACK* aRefSegm, TRACK* aList ) ...@@ -144,15 +144,15 @@ int DRC::Drc( TRACK* aRefSegm, TRACK* aList )
/*********************************************/ /*********************************************/
{ {
updatePointers(); updatePointers();
if( !doTrackDrc( aRefSegm, aList ) ) if( !doTrackDrc( aRefSegm, aList ) )
{ {
wxASSERT( m_currentMarker ); wxASSERT( m_currentMarker );
m_currentMarker->Display_Infos( m_mainWindow ); m_currentMarker->Display_Infos( m_mainWindow );
return BAD_DRC; return BAD_DRC;
} }
return OK_DRC; return OK_DRC;
} }
...@@ -172,14 +172,14 @@ int DRC::Drc( ZONE_CONTAINER * aArea, int CornerIndex ) ...@@ -172,14 +172,14 @@ int DRC::Drc( ZONE_CONTAINER * aArea, int CornerIndex )
*/ */
{ {
updatePointers(); updatePointers();
if( ! doEdgeZoneDrc( aArea, CornerIndex ) ) if( ! doEdgeZoneDrc( aArea, CornerIndex ) )
{ {
wxASSERT( m_currentMarker ); wxASSERT( m_currentMarker );
m_currentMarker->Display_Infos( m_mainWindow ); m_currentMarker->Display_Infos( m_mainWindow );
return BAD_DRC; return BAD_DRC;
} }
return OK_DRC; return OK_DRC;
} }
...@@ -188,7 +188,7 @@ int DRC::Drc( ZONE_CONTAINER * aArea, int CornerIndex ) ...@@ -188,7 +188,7 @@ int DRC::Drc( ZONE_CONTAINER * aArea, int CornerIndex )
void DRC::RunTests() void DRC::RunTests()
{ {
// someone should have cleared the two lists before calling this. // someone should have cleared the two lists before calling this.
// test pad to pad clearances, nothing to do with tracks, vias or zones. // test pad to pad clearances, nothing to do with tracks, vias or zones.
if( m_doPad2PadTest ) if( m_doPad2PadTest )
testPad2Pad(); testPad2Pad();
...@@ -196,13 +196,13 @@ void DRC::RunTests() ...@@ -196,13 +196,13 @@ void DRC::RunTests()
// test track and via clearances to other tracks, pads, and vias // test track and via clearances to other tracks, pads, and vias
testTracks(); testTracks();
// test zone clearances to other zones, pads, tracks, and vias // test zone clearances to other zones, pads, tracks, and vias
testZones(m_doZonesTest); testZones(m_doZonesTest);
// find and gather unconnected pads. // find and gather unconnected pads.
if( m_doUnconnectedTest ) if( m_doUnconnectedTest )
testUnconnected(); testUnconnected();
// update the m_ui listboxes // update the m_ui listboxes
updatePointers(); updatePointers();
} }
...@@ -214,7 +214,7 @@ void DRC::ListUnconnectedPads() ...@@ -214,7 +214,7 @@ void DRC::ListUnconnectedPads()
/***************************************************************/ /***************************************************************/
{ {
testUnconnected(); testUnconnected();
// update the m_ui listboxes // update the m_ui listboxes
updatePointers(); updatePointers();
} }
...@@ -225,15 +225,15 @@ void DRC::updatePointers() ...@@ -225,15 +225,15 @@ void DRC::updatePointers()
// update my pointers, m_mainWindow is the only unchangable one // update my pointers, m_mainWindow is the only unchangable one
m_drawPanel = m_mainWindow->DrawPanel; m_drawPanel = m_mainWindow->DrawPanel;
m_pcb = m_mainWindow->m_Pcb; m_pcb = m_mainWindow->m_Pcb;
if ( m_ui ) // Use diag list boxes only in DRC dialog
{
m_ui->m_ClearanceListBox->SetList( new DRC_LIST_MARKERS( m_pcb ) );
m_ui->m_UnconnectedListBox->SetList( new DRC_LIST_UNCONNECTED( &m_unconnected ) ); if ( m_ui ) // Use diag list boxes only in DRC dialog
} {
m_ui->m_ClearanceListBox->SetList( new DRC_LIST_MARKERS( m_pcb ) );
m_ui->m_UnconnectedListBox->SetList( new DRC_LIST_UNCONNECTED( &m_unconnected ) );
}
} }
void DRC::testTracks() void DRC::testTracks()
{ {
...@@ -242,8 +242,8 @@ void DRC::testTracks() ...@@ -242,8 +242,8 @@ void DRC::testTracks()
if( !doTrackDrc( segm, segm->Next() ) ) if( !doTrackDrc( segm, segm->Next() ) )
{ {
wxASSERT( m_currentMarker ); wxASSERT( m_currentMarker );
m_pcb->Add( m_currentMarker ); m_pcb->Add( m_currentMarker );
m_currentMarker = 0; m_currentMarker = 0;
} }
} }
} }
...@@ -268,12 +268,12 @@ void DRC::testPad2Pad() ...@@ -268,12 +268,12 @@ void DRC::testPad2Pad()
for( ppad = pad_list_start; ppad<pad_list_limit; ppad++ ) for( ppad = pad_list_start; ppad<pad_list_limit; ppad++ )
{ {
D_PAD* pad = *ppad; D_PAD* pad = *ppad;
if( !doPadToPadsDrc( pad, ppad, pad_list_limit, max_size ) ) if( !doPadToPadsDrc( pad, ppad, pad_list_limit, max_size ) )
{ {
wxASSERT( m_currentMarker ); wxASSERT( m_currentMarker );
m_pcb->Add( m_currentMarker ); m_pcb->Add( m_currentMarker );
m_currentMarker = 0; m_currentMarker = 0;
} }
} }
...@@ -288,7 +288,7 @@ void DRC::testUnconnected() ...@@ -288,7 +288,7 @@ void DRC::testUnconnected()
wxClientDC dc( m_mainWindow->DrawPanel ); wxClientDC dc( m_mainWindow->DrawPanel );
m_mainWindow->Compile_Ratsnest( &dc, TRUE ); m_mainWindow->Compile_Ratsnest( &dc, TRUE );
} }
if( m_pcb->m_Ratsnest == NULL ) if( m_pcb->m_Ratsnest == NULL )
return; return;
...@@ -301,10 +301,10 @@ void DRC::testUnconnected() ...@@ -301,10 +301,10 @@ void DRC::testUnconnected()
D_PAD* padStart = rat->pad_start; D_PAD* padStart = rat->pad_start;
D_PAD* padEnd = rat->pad_end; D_PAD* padEnd = rat->pad_end;
DRC_ITEM* uncItem = new DRC_ITEM( DRCE_UNCONNECTED_PADS, padStart->GetPosition(), DRC_ITEM* uncItem = new DRC_ITEM( DRCE_UNCONNECTED_PADS, padStart->GetPosition(),
padStart->MenuText(m_pcb), padEnd->MenuText(m_pcb), padStart->MenuText(m_pcb), padEnd->MenuText(m_pcb),
padStart->GetPosition(), padEnd->GetPosition() ); padStart->GetPosition(), padEnd->GetPosition() );
m_unconnected.push_back( uncItem ); m_unconnected.push_back( uncItem );
} }
} }
...@@ -313,31 +313,31 @@ void DRC::testUnconnected() ...@@ -313,31 +313,31 @@ void DRC::testUnconnected()
void DRC::testZones(bool adoTestFillSegments) void DRC::testZones(bool adoTestFillSegments)
{ {
// Test copper areas for valide netcodes // Test copper areas for valide netcodes
// if a netcode is < 0 the netname was not found when reading a netlist // if a netcode is < 0 the netname was not found when reading a netlist
for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ ) for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
{ {
ZONE_CONTAINER* Area_To_Test = m_pcb->GetArea( ii ); ZONE_CONTAINER* Area_To_Test = m_pcb->GetArea( ii );
if( Area_To_Test->GetNet() <= 0 ) if( Area_To_Test->GetNet() <= 0 )
{ {
m_currentMarker = fillMarker( Area_To_Test, m_currentMarker = fillMarker( Area_To_Test,
DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE, m_currentMarker ); DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE, m_currentMarker );
m_pcb->Add( m_currentMarker ); m_pcb->Add( m_currentMarker );
m_currentMarker = 0; m_currentMarker = 0;
} }
} }
// Test copper areas outlines, and create markers when needed // Test copper areas outlines, and create markers when needed
m_pcb->Test_Drc_Areas_Outlines_To_Areas_Outlines( NULL, true ); m_pcb->Test_Drc_Areas_Outlines_To_Areas_Outlines( NULL, true );
TRACK* zoneSeg; TRACK* zoneSeg;
/* this was for display purposes, don't know that we need it anymore /* this was for display purposes, don't know that we need it anymore
m_pcb->m_NbSegmZone = 0; m_pcb->m_NbSegmZone = 0;
for( zoneSeg = m_pcb->m_Zone; zoneSeg; zoneSeg = zoneSeg->Next() ) for( zoneSeg = m_pcb->m_Zone; zoneSeg; zoneSeg = zoneSeg->Next() )
++m_pcb->m_NbSegmZone; ++m_pcb->m_NbSegmZone;
*/ */
if ( ! adoTestFillSegments ) return; if ( ! adoTestFillSegments ) return;
for( zoneSeg = m_pcb->m_Zone; zoneSeg && zoneSeg->Next(); zoneSeg=zoneSeg->Next() ) for( zoneSeg = m_pcb->m_Zone; zoneSeg && zoneSeg->Next(); zoneSeg=zoneSeg->Next() )
{ {
// Test zoneSeg with other zone segments and with all pads // Test zoneSeg with other zone segments and with all pads
...@@ -345,12 +345,12 @@ void DRC::testZones(bool adoTestFillSegments) ...@@ -345,12 +345,12 @@ void DRC::testZones(bool adoTestFillSegments)
{ {
wxASSERT( m_currentMarker ); wxASSERT( m_currentMarker );
m_pcb->Add( m_currentMarker ); m_pcb->Add( m_currentMarker );
m_currentMarker = 0; m_currentMarker = 0;
} }
// Test zoneSeg with all track segments // Test zoneSeg with all track segments
int tmp = m_pcb->m_NbPads; int tmp = m_pcb->m_NbPads;
m_pcb->m_NbPads = 0; // Pads already tested: disable pad test m_pcb->m_NbPads = 0; // Pads already tested: disable pad test
bool rc = doTrackDrc( zoneSeg, m_pcb->m_Track ); bool rc = doTrackDrc( zoneSeg, m_pcb->m_Track );
m_pcb->m_NbPads = tmp; m_pcb->m_NbPads = tmp;
...@@ -359,7 +359,7 @@ void DRC::testZones(bool adoTestFillSegments) ...@@ -359,7 +359,7 @@ void DRC::testZones(bool adoTestFillSegments)
{ {
wxASSERT( m_currentMarker ); wxASSERT( m_currentMarker );
m_pcb->Add( m_currentMarker ); m_pcb->Add( m_currentMarker );
m_currentMarker = 0; m_currentMarker = 0;
} }
} }
} }
...@@ -372,62 +372,62 @@ MARKER* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKE ...@@ -372,62 +372,62 @@ MARKER* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, MARKE
wxPoint position; wxPoint position;
wxPoint posB; wxPoint posB;
if( aItem ) // aItem might be NULL if( aItem ) // aItem might be NULL
{ {
textB = aItem->MenuText( m_pcb ); textB = aItem->MenuText( m_pcb );
posB = aItem->GetPosition(); posB = aItem->GetPosition();
if( aItem->Type() == TYPEPAD ) if( aItem->Type() == TYPEPAD )
position = aItem->GetPosition(); position = aItem->GetPosition();
else if( aItem->Type() == TYPEVIA ) else if( aItem->Type() == TYPEVIA )
position = aItem->GetPosition(); position = aItem->GetPosition();
else if( aItem->Type() == TYPETRACK ) else if( aItem->Type() == TYPETRACK )
{ {
TRACK* track = (TRACK*) aItem; TRACK* track = (TRACK*) aItem;
wxPoint endPos = track->m_End; wxPoint endPos = track->m_End;
// either of aItem's start or end will be used for the marker position // either of aItem's start or end will be used for the marker position
// first assume start, then switch at end if needed. decision made on // first assume start, then switch at end if needed. decision made on
// distance from end of aTrack. // distance from end of aTrack.
position = track->m_Start; position = track->m_Start;
double dToEnd = hypot( endPos.x - aTrack->m_End.x, double dToEnd = hypot( endPos.x - aTrack->m_End.x,
endPos.y - aTrack->m_End.y ); endPos.y - aTrack->m_End.y );
double dToStart = hypot( position.x - aTrack->m_End.x, double dToStart = hypot( position.x - aTrack->m_End.x,
position.y - aTrack->m_End.y ); position.y - aTrack->m_End.y );
if( dToEnd < dToStart ) if( dToEnd < dToStart )
position = endPos; position = endPos;
} }
} }
else else
position = aTrack->GetPosition(); position = aTrack->GetPosition();
if( fillMe ) if( fillMe )
{ {
if ( aItem ) if ( aItem )
fillMe->SetData( aErrorCode, position, fillMe->SetData( aErrorCode, position,
textA, aTrack->GetPosition(), textA, aTrack->GetPosition(),
textB, posB ); textB, posB );
else else
fillMe->SetData( aErrorCode, position, fillMe->SetData( aErrorCode, position,
textA, aTrack->GetPosition() ); textA, aTrack->GetPosition() );
} }
else else
{ {
if ( aItem ) if ( aItem )
fillMe = new MARKER( aErrorCode, position, fillMe = new MARKER( aErrorCode, position,
textA, aTrack->GetPosition(), textA, aTrack->GetPosition(),
textB, posB ); textB, posB );
else else
fillMe = new MARKER( aErrorCode, position, fillMe = new MARKER( aErrorCode, position,
textA, aTrack->GetPosition() ); textA, aTrack->GetPosition() );
} }
return fillMe; return fillMe;
} }
...@@ -444,7 +444,7 @@ MARKER* DRC::fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER* fillM ...@@ -444,7 +444,7 @@ MARKER* DRC::fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER* fillM
fillMe->SetData( aErrorCode, posA, textA, posA, textB, posB ); fillMe->SetData( aErrorCode, posA, textA, posA, textB, posB );
else else
fillMe = new MARKER( aErrorCode, posA, textA, posA, textB, posB ); fillMe = new MARKER( aErrorCode, posA, textA, posA, textB, posB );
return fillMe; return fillMe;
} }
...@@ -458,7 +458,7 @@ MARKER* DRC::fillMarker( ZONE_CONTAINER * aArea, int aErrorCode, MARKER* fillMe ...@@ -458,7 +458,7 @@ MARKER* DRC::fillMarker( ZONE_CONTAINER * aArea, int aErrorCode, MARKER* fillMe
fillMe->SetData( aErrorCode, posA, textA, posA ); fillMe->SetData( aErrorCode, posA, textA, posA );
else else
fillMe = new MARKER( aErrorCode, posA, textA, posA ); fillMe = new MARKER( aErrorCode, posA, textA, posA );
return fillMe; return fillMe;
} }
...@@ -473,7 +473,7 @@ MARKER* DRC::fillMarker( const ZONE_CONTAINER * aArea, const wxPoint & aPos, int ...@@ -473,7 +473,7 @@ MARKER* DRC::fillMarker( const ZONE_CONTAINER * aArea, const wxPoint & aPos, int
fillMe->SetData( aErrorCode, posA, textA, posA ); fillMe->SetData( aErrorCode, posA, textA, posA );
else else
fillMe = new MARKER( aErrorCode, posA, textA, posA ); fillMe = new MARKER( aErrorCode, posA, textA, posA );
return fillMe; return fillMe;
} }
...@@ -506,50 +506,49 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -506,50 +506,49 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
/* Phase 0 : Test vias : */ /* Phase 0 : Test vias : */
if( aRefSeg->Type() == TYPEVIA ) if( aRefSeg->Type() == TYPEVIA )
{ {
// test if via's hole is bigger than its diameter // test if via's hole is bigger than its diameter
// This test seems necessary since the dialog box that displays the // This test seems necessary since the dialog box that displays the
// desired via hole size and width does not enforce a hole size smaller // desired via hole size and width does not enforce a hole size smaller
// than the via's diameter. // than the via's diameter.
if( !aRefSeg->GetDrillValue() > aRefSeg->m_Width )
if( aRefSeg->GetDrillValue() > aRefSeg->m_Width )
{ {
m_currentMarker = fillMarker( aRefSeg, NULL, m_currentMarker = fillMarker( aRefSeg, NULL,
DRCE_VIA_HOLE_BIGGER, m_currentMarker ); DRCE_VIA_HOLE_BIGGER, m_currentMarker );
return false; return false;
} }
// For microvias: test if they are blindvias and only between 2 layers // For microvias: test if they are blindvias and only between 2 layers
// because they are used for very small drill size and are drill by laser // because they are used for very small drill size and are drill by laser
// and **only** one layer can be drilled // and **only** one layer can be drilled
if( aRefSeg->Shape() == VIA_MICROVIA ) if( aRefSeg->Shape() == VIA_MICROVIA )
{ {
int layer1, layer2; int layer1, layer2;
bool err = true; bool err = true;
((SEGVIA*)aRefSeg)->ReturnLayerPair(&layer1, &layer2); ((SEGVIA*)aRefSeg)->ReturnLayerPair(&layer1, &layer2);
if (layer1> layer2 ) EXCHG(layer1,layer2); if (layer1> layer2 ) EXCHG(layer1,layer2);
// test: // test:
if (layer1 == COPPER_LAYER_N && layer2 == LAYER_N_2 ) err = false; if (layer1 == COPPER_LAYER_N && layer2 == LAYER_N_2 ) err = false;
if (layer1 == (g_DesignSettings.m_CopperLayerCount - 2 ) && layer2 == LAYER_CMP_N ) err = false; if (layer1 == (g_DesignSettings.m_CopperLayerCount - 2 ) && layer2 == LAYER_CMP_N ) err = false;
if ( err ) if ( err )
{ {
m_currentMarker = fillMarker( aRefSeg, NULL, m_currentMarker = fillMarker( aRefSeg, NULL,
DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR, m_currentMarker ); DRCE_MICRO_VIA_INCORRECT_LAYER_PAIR, m_currentMarker );
return false; return false;
} }
} }
} }
// for a non horizontal or vertical segment Compute the segment angle // for a non horizontal or vertical segment Compute the segment angle
// in tenths of degrees and its length // in tenths of degrees and its length
if( dx || dy ) if( dx || dy )
{ {
// Compute the segment angle in 0,1 degrees // Compute the segment angle in 0,1 degrees
m_segmAngle = ArcTangente( dy, dx ); m_segmAngle = ArcTangente( dy, dx );
// Compute the segment length: we build an equivalent rotated segment, // Compute the segment length: we build an equivalent rotated segment,
// this segment is horizontal, therefore dx = length // this segment is horizontal, therefore dx = length
RotatePoint( &dx, &dy, m_segmAngle ); // dx = length, dy = 0 RotatePoint( &dx, &dy, m_segmAngle ); // dx = length, dy = 0
} }
m_segmLength = dx; m_segmLength = dx;
...@@ -557,9 +556,9 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -557,9 +556,9 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
/******************************************/ /******************************************/
/* Phase 1 : test DRC track to pads : */ /* Phase 1 : test DRC track to pads : */
/******************************************/ /******************************************/
D_PAD pseudo_pad( (MODULE*) NULL ); // construct this once outside following loop D_PAD pseudo_pad( (MODULE*) NULL ); // construct this once outside following loop
// Compute the min distance to pads // Compute the min distance to pads
w_dist = aRefSeg->m_Width >> 1; w_dist = aRefSeg->m_Width >> 1;
for( int ii=0; ii<m_pcb->m_NbPads; ++ii ) for( int ii=0; ii<m_pcb->m_NbPads; ++ii )
...@@ -568,12 +567,12 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -568,12 +567,12 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
/* No problem if pads are on an other layer, /* No problem if pads are on an other layer,
* But if a drill hole exists (a pad on a single layer can have a hole!) * But if a drill hole exists (a pad on a single layer can have a hole!)
* we must test the hole * we must test the hole
*/ */
if( (pad->m_Masque_Layer & layerMask ) == 0 ) if( (pad->m_Masque_Layer & layerMask ) == 0 )
{ {
/* We must test the pad hole. In order to use the function "checkClearanceSegmToPad", /* We must test the pad hole. In order to use the function "checkClearanceSegmToPad",
* a pseudo pad is used, with a shape and a size like the hole * a pseudo pad is used, with a shape and a size like the hole
*/ */
if( pad->m_Drill.x == 0 ) if( pad->m_Drill.x == 0 )
continue; continue;
...@@ -583,14 +582,14 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -583,14 +582,14 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
pseudo_pad.m_PadShape = pad->m_DrillShape; pseudo_pad.m_PadShape = pad->m_DrillShape;
pseudo_pad.m_Orient = pad->m_Orient; pseudo_pad.m_Orient = pad->m_Orient;
pseudo_pad.ComputeRayon(); // compute the radius pseudo_pad.ComputeRayon(); // compute the radius
m_spotcx = pseudo_pad.GetPosition().x - org_X; m_spotcx = pseudo_pad.GetPosition().x - org_X;
m_spotcy = pseudo_pad.GetPosition().y - org_Y; m_spotcy = pseudo_pad.GetPosition().y - org_Y;
if( !checkClearanceSegmToPad( &pseudo_pad, w_dist, if( !checkClearanceSegmToPad( &pseudo_pad, w_dist,
g_DesignSettings.m_TrackClearence ) ) g_DesignSettings.m_TrackClearence ) )
{ {
m_currentMarker = fillMarker( aRefSeg, pad, m_currentMarker = fillMarker( aRefSeg, pad,
DRCE_TRACK_NEAR_THROUGH_HOLE, m_currentMarker ); DRCE_TRACK_NEAR_THROUGH_HOLE, m_currentMarker );
return false; return false;
} }
...@@ -598,10 +597,10 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -598,10 +597,10 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
} }
/* The pad must be in a net (i.e pt_pad->GetNet() != 0 ) /* The pad must be in a net (i.e pt_pad->GetNet() != 0 )
* but no problem if the pad netcode is the current netcode (same net) * but no problem if the pad netcode is the current netcode (same net)
*/ */
if( pad->GetNet() && // the pad must be connected if( pad->GetNet() && // the pad must be connected
net_code_ref == pad->GetNet() ) // the pad net is the same as current net -> Ok net_code_ref == pad->GetNet() ) // the pad net is the same as current net -> Ok
continue; continue;
// DRC for the pad // DRC for the pad
...@@ -610,7 +609,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -610,7 +609,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
m_spotcy = shape_pos.y - org_Y; m_spotcy = shape_pos.y - org_Y;
if( !checkClearanceSegmToPad( pad, w_dist, g_DesignSettings.m_TrackClearence ) ) if( !checkClearanceSegmToPad( pad, w_dist, g_DesignSettings.m_TrackClearence ) )
{ {
m_currentMarker = fillMarker( aRefSeg, pad, m_currentMarker = fillMarker( aRefSeg, pad,
DRCE_TRACK_NEAR_PAD, m_currentMarker ); DRCE_TRACK_NEAR_PAD, m_currentMarker );
return false; return false;
} }
...@@ -629,8 +628,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -629,8 +628,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
int x0; int x0;
int y0; int y0;
int xf; int xf;
int yf; int yf;
// No problem if segments have the same net code: // No problem if segments have the same net code:
if( net_code_ref == track->GetNet() ) if( net_code_ref == track->GetNet() )
continue; continue;
...@@ -639,7 +638,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -639,7 +638,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
if( ( layerMask & track->ReturnMaskLayer() ) == 0 ) if( ( layerMask & track->ReturnMaskLayer() ) == 0 )
continue; continue;
// the minimum distance = clearance plus half the reference track // the minimum distance = clearance plus half the reference track
// width plus half the other track's width // width plus half the other track's width
w_dist = aRefSeg->m_Width >> 1; w_dist = aRefSeg->m_Width >> 1;
w_dist += track->m_Width >> 1; w_dist += track->m_Width >> 1;
...@@ -650,22 +649,22 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -650,22 +649,22 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
{ {
int orgx, orgy; // origine du repere d'axe X = segment a comparer int orgx, orgy; // origine du repere d'axe X = segment a comparer
int angle = 0; // angle du segment a tester; int angle = 0; // angle du segment a tester;
orgx = track->m_Start.x; orgx = track->m_Start.x;
orgy = track->m_Start.y; orgy = track->m_Start.y;
dx = track->m_End.x - orgx; dx = track->m_End.x - orgx;
dy = track->m_End.y - orgy; dy = track->m_End.y - orgy;
x0 = aRefSeg->m_Start.x - orgx; x0 = aRefSeg->m_Start.x - orgx;
y0 = aRefSeg->m_Start.y - orgy; y0 = aRefSeg->m_Start.y - orgy;
if( track->Type() == TYPEVIA ) if( track->Type() == TYPEVIA )
{ {
// Test distance between two vias // Test distance between two vias
if( (int) hypot( x0, y0 ) < w_dist ) if( (int) hypot( x0, y0 ) < w_dist )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_VIA_NEAR_VIA, m_currentMarker ); DRCE_VIA_NEAR_VIA, m_currentMarker );
return false; return false;
} }
...@@ -681,7 +680,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -681,7 +680,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
if( !checkMarginToCircle( x0, y0, w_dist, dx ) ) if( !checkMarginToCircle( x0, y0, w_dist, dx ) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_VIA_NEAR_TRACK, m_currentMarker ); DRCE_VIA_NEAR_TRACK, m_currentMarker );
return false; return false;
} }
...@@ -691,8 +690,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -691,8 +690,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
/* We compute x0,y0, xf,yf = starting and ending point coordinates for the segment to test /* We compute x0,y0, xf,yf = starting and ending point coordinates for the segment to test
* in the new axis : the new X axis is the reference segment * in the new axis : the new X axis is the reference segment
* We must translate and rotate the segment to test * We must translate and rotate the segment to test
*/ */
x0 = track->m_Start.x - org_X; x0 = track->m_Start.x - org_X;
y0 = track->m_Start.y - org_Y; y0 = track->m_Start.y - org_Y;
...@@ -706,8 +705,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -706,8 +705,8 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
{ {
if( checkMarginToCircle( x0, y0, w_dist, m_segmLength ) ) if( checkMarginToCircle( x0, y0, w_dist, m_segmLength ) )
continue; continue;
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_NEAR_VIA, m_currentMarker ); DRCE_TRACK_NEAR_VIA, m_currentMarker );
return false; return false;
} }
...@@ -730,13 +729,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -730,13 +729,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
/* Fine test : we consider the rounded shape of the ends */ /* Fine test : we consider the rounded shape of the ends */
if( x0 >= 0 && x0 <= m_segmLength ) if( x0 >= 0 && x0 <= m_segmLength )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_ENDS1, m_currentMarker ); DRCE_TRACK_ENDS1, m_currentMarker );
return false; return false;
} }
if( !checkMarginToCircle( x0, y0, w_dist, m_segmLength ) ) if( !checkMarginToCircle( x0, y0, w_dist, m_segmLength ) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_ENDS2, m_currentMarker ); DRCE_TRACK_ENDS2, m_currentMarker );
return false; return false;
} }
...@@ -746,13 +745,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -746,13 +745,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
/* Fine test : we consider the rounded shape of the ends */ /* Fine test : we consider the rounded shape of the ends */
if( xf >= 0 && xf <= m_segmLength ) if( xf >= 0 && xf <= m_segmLength )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_ENDS3, m_currentMarker ); DRCE_TRACK_ENDS3, m_currentMarker );
return false; return false;
} }
if( !checkMarginToCircle( xf, yf, w_dist, m_segmLength ) ) if( !checkMarginToCircle( xf, yf, w_dist, m_segmLength ) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_ENDS4, m_currentMarker ); DRCE_TRACK_ENDS4, m_currentMarker );
return false; return false;
} }
...@@ -760,7 +759,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -760,7 +759,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
if( x0 <=0 && xf >= 0 ) if( x0 <=0 && xf >= 0 )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACK_UNKNOWN1, m_currentMarker ); DRCE_TRACK_UNKNOWN1, m_currentMarker );
return false; return false;
} }
...@@ -775,7 +774,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -775,7 +774,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
EXCHG( y0, yf ); EXCHG( y0, yf );
if( (y0 < 0) && (yf > 0) ) if( (y0 < 0) && (yf > 0) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_TRACKS_CROSSING, m_currentMarker ); DRCE_TRACKS_CROSSING, m_currentMarker );
return false; return false;
} }
...@@ -783,13 +782,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -783,13 +782,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
// At this point the drc error is due to an end near a reference segm end // At this point the drc error is due to an end near a reference segm end
if( !checkMarginToCircle( x0, y0, w_dist, m_segmLength ) ) if( !checkMarginToCircle( x0, y0, w_dist, m_segmLength ) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_ENDS_PROBLEM1, m_currentMarker ); DRCE_ENDS_PROBLEM1, m_currentMarker );
return false; return false;
} }
if( !checkMarginToCircle( xf, yf, w_dist, m_segmLength ) ) if( !checkMarginToCircle( xf, yf, w_dist, m_segmLength ) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_ENDS_PROBLEM2, m_currentMarker ); DRCE_ENDS_PROBLEM2, m_currentMarker );
return false; return false;
} }
...@@ -798,26 +797,26 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -798,26 +797,26 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
{ {
// calcul de la "surface de securite du segment de reference // calcul de la "surface de securite du segment de reference
// First rought 'and fast) test : the track segment is like a rectangle // First rought 'and fast) test : the track segment is like a rectangle
m_xcliplo = m_ycliplo = -w_dist; m_xcliplo = m_ycliplo = -w_dist;
m_xcliphi = m_segmLength + w_dist; m_xcliphi = m_segmLength + w_dist;
m_ycliphi = w_dist; m_ycliphi = w_dist;
// A fine test is needed because a serment is not exactly a // A fine test is needed because a serment is not exactly a
// rectangle, it has rounded ends // rectangle, it has rounded ends
if( !checkLine( x0, y0, xf, yf ) ) if( !checkLine( x0, y0, xf, yf ) )
{ {
/* 2eme passe : the track has rounded ends. /* 2eme passe : the track has rounded ends.
* we must a fine test for each rounded end and the * we must a fine test for each rounded end and the
* rectangular zone * rectangular zone
*/ */
m_xcliplo = 0; m_xcliplo = 0;
m_xcliphi = m_segmLength; m_xcliphi = m_segmLength;
if( !checkLine( x0, y0, xf, yf ) ) if( !checkLine( x0, y0, xf, yf ) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_ENDS_PROBLEM3, m_currentMarker ); DRCE_ENDS_PROBLEM3, m_currentMarker );
return false; return false;
} }
...@@ -841,7 +840,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -841,7 +840,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
RotatePoint( &dx, &dy, angle ); RotatePoint( &dx, &dy, angle );
/* Comute the reference segment coordinates relatives to a /* Comute the reference segment coordinates relatives to a
* X axis = current tested segment * X axis = current tested segment
*/ */
rx0 = aRefSeg->m_Start.x - x0; rx0 = aRefSeg->m_Start.x - x0;
ry0 = aRefSeg->m_Start.y - y0; ry0 = aRefSeg->m_Start.y - y0;
...@@ -852,13 +851,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart ) ...@@ -852,13 +851,13 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart )
RotatePoint( &rxf, &ryf, angle ); RotatePoint( &rxf, &ryf, angle );
if( !checkMarginToCircle( rx0, ry0, w_dist, dx ) ) if( !checkMarginToCircle( rx0, ry0, w_dist, dx ) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_ENDS_PROBLEM4, m_currentMarker ); DRCE_ENDS_PROBLEM4, m_currentMarker );
return false; return false;
} }
if( !checkMarginToCircle( rxf, ryf, w_dist, dx ) ) if( !checkMarginToCircle( rxf, ryf, w_dist, dx ) )
{ {
m_currentMarker = fillMarker( aRefSeg, track, m_currentMarker = fillMarker( aRefSeg, track,
DRCE_ENDS_PROBLEM5, m_currentMarker ); DRCE_ENDS_PROBLEM5, m_currentMarker );
return false; return false;
} }
...@@ -877,7 +876,7 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd, ...@@ -877,7 +876,7 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd,
/*****************************************************************************/ /*****************************************************************************/
{ {
int layerMask = aRefPad->m_Masque_Layer & ALL_CU_LAYERS; int layerMask = aRefPad->m_Masque_Layer & ALL_CU_LAYERS;
int x_limite = max_size + g_DesignSettings.m_TrackClearence + int x_limite = max_size + g_DesignSettings.m_TrackClearence +
aRefPad->m_Rayon + aRefPad->GetPosition().x; aRefPad->m_Rayon + aRefPad->GetPosition().x;
...@@ -909,7 +908,7 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd, ...@@ -909,7 +908,7 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd,
if( !checkClearancePadToPad( aRefPad, pad, g_DesignSettings.m_TrackClearence ) ) if( !checkClearancePadToPad( aRefPad, pad, g_DesignSettings.m_TrackClearence ) )
{ {
// here we have a drc error! // here we have a drc error!
m_currentMarker = fillMarker( aRefPad, pad, m_currentMarker = fillMarker( aRefPad, pad,
DRCE_PAD_NEAR_PAD1, m_currentMarker ); DRCE_PAD_NEAR_PAD1, m_currentMarker );
return false; return false;
} }
...@@ -934,7 +933,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_mi ...@@ -934,7 +933,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_mi
// rel_pos is pad position relative to the aRefPad position // rel_pos is pad position relative to the aRefPad position
rel_pos.x -= shape_pos.x; rel_pos.x -= shape_pos.x;
rel_pos.y -= shape_pos.y; rel_pos.y -= shape_pos.y;
dist = (int) hypot( rel_pos.x, rel_pos.y ); dist = (int) hypot( rel_pos.x, rel_pos.y );
bool diag = true; bool diag = true;
...@@ -966,12 +965,12 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_mi ...@@ -966,12 +965,12 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_mi
case PAD_CIRCLE: // aRefPad is like a track segment with a null lenght case PAD_CIRCLE: // aRefPad is like a track segment with a null lenght
m_segmLength = 0; m_segmLength = 0;
m_segmAngle = 0; m_segmAngle = 0;
m_finx = m_finy = 0; m_finx = m_finy = 0;
m_spotcx = rel_pos.x; m_spotcx = rel_pos.x;
m_spotcy = rel_pos.y; m_spotcy = rel_pos.y;
diag = checkClearanceSegmToPad( aPad, aRefPad->m_Rayon, dist_min ); diag = checkClearanceSegmToPad( aPad, aRefPad->m_Rayon, dist_min );
break; break;
...@@ -1025,18 +1024,18 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_mi ...@@ -1025,18 +1024,18 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_mi
m_segmLength = aRefPad->m_Size.y - aRefPad->m_Size.x; m_segmLength = aRefPad->m_Size.y - aRefPad->m_Size.x;
m_segmAngle += 900; m_segmAngle += 900;
} }
/* the start point must be 0,0 and currently rel_pos is relative the center of pad coordinate */ /* the start point must be 0,0 and currently rel_pos is relative the center of pad coordinate */
int sx = -m_segmLength / 2, sy = 0; // Start point coordinate of the horizontal equivalent segment int sx = -m_segmLength / 2, sy = 0; // Start point coordinate of the horizontal equivalent segment
RotatePoint( &sx, &sy, m_segmAngle ); // True start point coordinate of the equivalent segment RotatePoint( &sx, &sy, m_segmAngle ); // True start point coordinate of the equivalent segment
m_spotcx = rel_pos.x + sx; m_spotcx = rel_pos.x + sx;
m_spotcy = rel_pos.y + sy; // pad position / segment origin m_spotcy = rel_pos.y + sy; // pad position / segment origin
m_finx = -sx; m_finx = -sx;
m_finy = -sy; // end of segment coordinate m_finy = -sy; // end of segment coordinate
diag = checkClearanceSegmToPad( aPad, segm_width / 2, dist_min ); diag = checkClearanceSegmToPad( aPad, segm_width / 2, dist_min );
break; break;
} }
...@@ -1047,14 +1046,14 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_mi ...@@ -1047,14 +1046,14 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, const int dist_mi
} }
exit: // the only way out (hopefully) for simpler debugging exit: // the only way out (hopefully) for simpler debugging
return diag; return diag;
} }
bool DRC::checkClearanceSegmToPad( const D_PAD* pad_to_test, int w_segm, int dist_min ) bool DRC::checkClearanceSegmToPad( const D_PAD* pad_to_test, int w_segm, int dist_min )
{ {
int p_dimx; int p_dimx;
int p_dimy; // half the dimension of the pad int p_dimy; // half the dimension of the pad
int orient; int orient;
int x0, y0, xf, yf; int x0, y0, xf, yf;
...@@ -1104,7 +1103,7 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* pad_to_test, int w_segm, int dis ...@@ -1104,7 +1103,7 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* pad_to_test, int w_segm, int dis
/* test de la pastille ovale ramenee au type ovale vertical */ /* test de la pastille ovale ramenee au type ovale vertical */
if( p_dimx > p_dimy ) if( p_dimx > p_dimy )
{ {
EXCHG( p_dimx, p_dimy ); EXCHG( p_dimx, p_dimy );
orient += 900; orient += 900;
if( orient >= 3600 ) if( orient >= 3600 )
orient -= 3600; orient -= 3600;
...@@ -1222,10 +1221,10 @@ bool DRC::checkMarginToCircle( int cx, int cy, int radius, int longueur ) ...@@ -1222,10 +1221,10 @@ bool DRC::checkMarginToCircle( int cx, int cy, int radius, int longueur )
{ {
if( (cx >= 0) && (cx <= longueur) ) if( (cx >= 0) && (cx <= longueur) )
return false; return false;
if( cx > longueur ) if( cx > longueur )
cx -= longueur; cx -= longueur;
if( hypot( cx, cy ) < radius ) if( hypot( cx, cy ) < radius )
return false; return false;
} }
...@@ -1293,14 +1292,14 @@ bool DRC::checkLine( int x1, int y1, int x2, int y2 ) ...@@ -1293,14 +1292,14 @@ bool DRC::checkLine( int x1, int y1, int x2, int y2 )
if( x1 < m_xcliplo ) if( x1 < m_xcliplo )
{ {
temp = USCALE( (y2 - y1), (m_xcliplo - x1), (x2 - x1) ); temp = USCALE( (y2 - y1), (m_xcliplo - x1), (x2 - x1) );
y1 += temp; y1 += temp;
x1 = m_xcliplo; x1 = m_xcliplo;
WHEN_INSIDE; WHEN_INSIDE;
} }
if( x2 > m_xcliphi ) if( x2 > m_xcliphi )
{ {
temp = USCALE( (y2 - y1), (x2 - m_xcliphi), (x2 - x1) ); temp = USCALE( (y2 - y1), (x2 - m_xcliphi), (x2 - x1) );
y2 -= temp; y2 -= temp;
x2 = m_xcliphi; x2 = m_xcliphi;
WHEN_INSIDE; WHEN_INSIDE;
} }
......
...@@ -2091,7 +2091,6 @@ class PADSTACK : public ELEM_HOLDER ...@@ -2091,7 +2091,6 @@ class PADSTACK : public ELEM_HOLDER
std::string hash; ///< a hash string used by Compare(), not Format()ed/exported. std::string hash; ///< a hash string used by Compare(), not Format()ed/exported.
std::string padstack_id; std::string padstack_id;
UNIT_RES* unit; UNIT_RES* unit;
...@@ -2121,6 +2120,10 @@ public: ...@@ -2121,6 +2120,10 @@ public:
delete rules; delete rules;
} }
const std::string& GetPadstackId()
{
return padstack_id;
}
/** /**
* Function Compare * Function Compare
...@@ -2341,6 +2344,22 @@ public: ...@@ -2341,6 +2344,22 @@ public:
return &padstacks[ndx]; return &padstacks[ndx];
} }
/**
* Function FindPADSTACK
* searches the padstack container by name.
* @return PADSTACK* - The PADSTACK with a matching name if it exists, else NULL.
*/
PADSTACK* FindPADSTACK( const std::string& aPadstackId )
{
for( unsigned i=0; i<padstacks.size(); ++i )
{
PADSTACK* ps = &padstacks[i];
if( 0 == ps->GetPadstackId().compare( aPadstackId ) )
return ps;
}
return NULL;
}
void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) void FormatContents( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{ {
if( unit ) if( unit )
...@@ -2888,6 +2907,11 @@ public: ...@@ -2888,6 +2907,11 @@ public:
supply = false; supply = false;
} }
const std::string& GetPadstackId()
{
return padstack_id;
}
void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError ) void Format( OUTPUTFORMATTER* out, int nestLevel ) throw( IOError )
{ {
const char* quote = out->GetQuoteChar( padstack_id.c_str() ); const char* quote = out->GetQuoteChar( padstack_id.c_str() );
...@@ -3711,10 +3735,11 @@ class SPECCTRA_DB : public OUTPUTFORMATTER ...@@ -3711,10 +3735,11 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
* Function makeVia * Function makeVia
* makes a round through hole PADSTACK using the given Kicad diameter in deci-mils. * makes a round through hole PADSTACK using the given Kicad diameter in deci-mils.
* @param aCopperDiameter The diameter of the copper pad. * @param aCopperDiameter The diameter of the copper pad.
* @param aDrillDiameter The drill diameter, used on re-import of the session file.
* @return PADSTACK* - The padstack, which is on the heap only, user must save * @return PADSTACK* - The padstack, which is on the heap only, user must save
* or delete it. * or delete it.
*/ */
PADSTACK* makeVia( int aCopperDiameter ); PADSTACK* makeVia( int aCopperDiameter, int aDrillDiameter );
/** /**
* Function makeVia * Function makeVia
...@@ -3734,6 +3759,9 @@ class SPECCTRA_DB : public OUTPUTFORMATTER ...@@ -3734,6 +3759,9 @@ class SPECCTRA_DB : public OUTPUTFORMATTER
*/ */
TRACK* makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) throw( IOError ); TRACK* makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) throw( IOError );
SEGVIA* makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNetCode );
//-----</FromSESSION>---------------------------------------------------- //-----</FromSESSION>----------------------------------------------------
public: public:
...@@ -3848,7 +3876,7 @@ public: ...@@ -3848,7 +3876,7 @@ public:
* *
* @param aBoard The BOARD to convert to a PCB. * @param aBoard The BOARD to convert to a PCB.
*/ */
void FromBOARD( BOARD* aBoard ); void FromBOARD( BOARD* aBoard ) throw( IOError );
/** /**
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "wxPcbStruct.h" // Change_Side_Module() #include "wxPcbStruct.h" // Change_Side_Module()
#include "pcbstruct.h" // HISTORY_NUMBER #include "pcbstruct.h" // HISTORY_NUMBER
#include "autorout.h" // NET_CODES_OK #include "autorout.h" // NET_CODES_OK
#include <set> // std::set
using namespace DSN; using namespace DSN;
...@@ -103,7 +104,11 @@ void WinEDA_PcbFrame::ExportToSpecctra( wxCommandEvent& event ) ...@@ -103,7 +104,11 @@ void WinEDA_PcbFrame::ExportToSpecctra( wxCommandEvent& event )
Affiche_Message( wxString( _("BOARD exported OK.")) ); Affiche_Message( wxString( _("BOARD exported OK.")) );
} }
else else
{
errorText += '\n';
errorText += _("Unable to export, please fix and try again.");
DisplayError( this, errorText ); DisplayError( this, errorText );
}
} }
...@@ -268,6 +273,17 @@ static bool isRectangle( POINT_PAIRS& aList ) ...@@ -268,6 +273,17 @@ static bool isRectangle( POINT_PAIRS& aList )
} }
/**
* Function isKeepout
* decides if the pad is a copper less through hole which needs to be made into
* a round keepout.
*/
static bool isKeepout( D_PAD* aPad )
{
return aPad->m_PadShape==PAD_CIRCLE && aPad->m_Drill.x >= aPad->m_Size.x;
}
/**************************************************************************/ /**************************************************************************/
static int Pad_list_Sort_by_Shapes( const void* refptr, const void* objptr ) static int Pad_list_Sort_by_Shapes( const void* refptr, const void* objptr )
/**************************************************************************/ /**************************************************************************/
...@@ -313,7 +329,7 @@ IMAGE* SPECCTRA_DB::makeIMAGE( MODULE* aModule ) ...@@ -313,7 +329,7 @@ IMAGE* SPECCTRA_DB::makeIMAGE( MODULE* aModule )
D_PAD* pad = (D_PAD*) pads[p]; D_PAD* pad = (D_PAD*) pads[p];
// see if this pad is a through hole with no copper on its perimeter // see if this pad is a through hole with no copper on its perimeter
if( pad->m_PadShape==PAD_CIRCLE && pad->m_Drill.x >= pad->m_Size.x ) if( isKeepout( pad ) )
{ {
KEEPOUT* keepout = new KEEPOUT(image, T_keepout); KEEPOUT* keepout = new KEEPOUT(image, T_keepout);
image->keepouts.push_back( keepout ); image->keepouts.push_back( keepout );
...@@ -369,7 +385,9 @@ PADSTACK* SPECCTRA_DB::makeVia( const SEGVIA* aVia ) ...@@ -369,7 +385,9 @@ PADSTACK* SPECCTRA_DB::makeVia( const SEGVIA* aVia )
circle->SetLayerId( "signal" ); circle->SetLayerId( "signal" );
snprintf( name, sizeof(name), "Via_%.6g_mil", dsnDiameter ); snprintf( name, sizeof(name), "Via_%.6g:%.6g_mil", dsnDiameter,
// encode the drill value in the name for later import
scale( aVia->GetDrillValue() ) );
name[ sizeof(name)-1 ] = 0; name[ sizeof(name)-1 ] = 0;
padstack->SetPadstackId( name ); padstack->SetPadstackId( name );
break; break;
...@@ -398,7 +416,11 @@ PADSTACK* SPECCTRA_DB::makeVia( const SEGVIA* aVia ) ...@@ -398,7 +416,11 @@ PADSTACK* SPECCTRA_DB::makeVia( const SEGVIA* aVia )
circle->SetLayerId( layerIds[layer].c_str() ); circle->SetLayerId( layerIds[layer].c_str() );
} }
snprintf( name, sizeof(name), "Via[%d-%d]_%.6g_mil", topLayer, botLayer, dsnDiameter ); snprintf( name, sizeof(name), "Via[%d-%d]_%.6g:%.6g_mil",
topLayer, botLayer, dsnDiameter,
// encode the drill value in the name for later import
scale( aVia->GetDrillValue() )
);
name[ sizeof(name)-1 ] = 0; name[ sizeof(name)-1 ] = 0;
padstack->SetPadstackId( name ); padstack->SetPadstackId( name );
break; break;
...@@ -408,7 +430,7 @@ PADSTACK* SPECCTRA_DB::makeVia( const SEGVIA* aVia ) ...@@ -408,7 +430,7 @@ PADSTACK* SPECCTRA_DB::makeVia( const SEGVIA* aVia )
} }
PADSTACK* SPECCTRA_DB::makeVia( int aCopperDiameter ) PADSTACK* SPECCTRA_DB::makeVia( int aCopperDiameter, int aDrillDiameter )
{ {
char name[48]; char name[48];
PADSTACK* padstack = new PADSTACK( pcb->library ); PADSTACK* padstack = new PADSTACK( pcb->library );
...@@ -424,7 +446,9 @@ PADSTACK* SPECCTRA_DB::makeVia( int aCopperDiameter ) ...@@ -424,7 +446,9 @@ PADSTACK* SPECCTRA_DB::makeVia( int aCopperDiameter )
circle->SetLayerId( "signal" ); circle->SetLayerId( "signal" );
snprintf( name, sizeof(name), "Via_%.6g_mil", dsnDiameter ); snprintf( name, sizeof(name), "Via_%.6g:%.6g_mil", dsnDiameter,
// encode the drill value in the name for later import
scale( aDrillDiameter ) );
name[ sizeof(name)-1 ] = 0; name[ sizeof(name)-1 ] = 0;
padstack->SetPadstackId( name ); padstack->SetPadstackId( name );
...@@ -432,6 +456,20 @@ PADSTACK* SPECCTRA_DB::makeVia( int aCopperDiameter ) ...@@ -432,6 +456,20 @@ PADSTACK* SPECCTRA_DB::makeVia( int aCopperDiameter )
} }
/**
* Struct ltWX
* is used secretly by the std:set<> class below. See STRINGSET typedef.
*/
struct ltWX
{
// a "less than" test on two wxStrings, by pointer.
bool operator()( const wxString* s1, const wxString* s2) const
{
return s1->Cmp( *s2 ) < 0; // case specific wxString compare
}
};
void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
{ {
char name[80]; // padstack name builder char name[80]; // padstack name builder
...@@ -464,10 +502,8 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) ...@@ -464,10 +502,8 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
// if pad has no copper presence, then it will be made into // if pad has no copper presence, then it will be made into
// an "image->keepout" later. No copper pad here, it is probably a hole. // an "image->keepout" later. No copper pad here, it is probably a hole.
if( (!doLayer[0] && !doLayer[1]) if( (!doLayer[0] && !doLayer[1]) || isKeepout( pad ) )
|| (pad->m_PadShape==PAD_CIRCLE && pad->m_Drill.x >= pad->m_Size.x) )
{ {
// pad->m_logical_connexion = pcb->library->padstacks.size()-1;
continue; continue;
} }
...@@ -491,7 +527,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) ...@@ -491,7 +527,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
they are present. they are present.
*/ */
int reportedLayers; // how many layers are reported. int reportedLayers; // how many in reported padstack
const char* layerName[NB_COPPER_LAYERS]; const char* layerName[NB_COPPER_LAYERS];
static const char signal[] = "signal"; static const char signal[] = "signal";
...@@ -652,7 +688,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) ...@@ -652,7 +688,7 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
int defaultViaSize = aBoard->m_BoardSettings->m_CurrentViaSize; int defaultViaSize = aBoard->m_BoardSettings->m_CurrentViaSize;
if( defaultViaSize ) if( defaultViaSize )
{ {
PADSTACK* padstack = makeVia( defaultViaSize ); PADSTACK* padstack = makeVia( defaultViaSize, g_DesignSettings.m_ViaDrill );
pcb->library->AddPadstack( padstack ); pcb->library->AddPadstack( padstack );
// remember this index, it is the default via and also the start of the // remember this index, it is the default via and also the start of the
...@@ -672,13 +708,13 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads ) ...@@ -672,13 +708,13 @@ void SPECCTRA_DB::makePADSTACKs( BOARD* aBoard, TYPE_COLLECTOR& aPads )
if( viaSize == defaultViaSize ) if( viaSize == defaultViaSize )
continue; continue;
PADSTACK* padstack = makeVia( viaSize ); PADSTACK* padstack = makeVia( viaSize, g_DesignSettings.m_ViaDrill );
pcb->library->AddPadstack( padstack ); pcb->library->AddPadstack( padstack );
} }
} }
void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
{ {
TYPE_COLLECTOR items; TYPE_COLLECTOR items;
POINT_PAIRS ppairs; POINT_PAIRS ppairs;
...@@ -686,6 +722,36 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) ...@@ -686,6 +722,36 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
static const KICAD_T scanMODULEs[] = { TYPEMODULE, EOT }; static const KICAD_T scanMODULEs[] = { TYPEMODULE, EOT };
// Not all boards are exportable. Check that all reference Ids are unique.
// Unless they are unique, we cannot import the session file which comes
// back to us later from the router.
{
items.Collect( aBoard, scanMODULEs );
typedef std::set<const wxString*, ltWX> STRINGSET;
typedef std::pair<STRINGSET::iterator, bool> PAIR;
STRINGSET references; // holds unique component references
for( int i=0; i<items.GetCount(); ++i )
{
MODULE* module = (MODULE*) items[i];
if( module->GetReference() == wxEmptyString )
{
ThrowIOError( _("Component with value of \"%s\" has empty reference id."),
module->GetValue().GetData() );
}
// if we cannot insert OK, that means the reference has been seen before.
PAIR pair = references.insert( &module->GetReference() );
if( !pair.second ) // insert failed
{
ThrowIOError( _("Multiple components have identical reference IDs of \"%s\"."),
module->GetReference().GetData() );
}
}
}
if( !pcb ) if( !pcb )
pcb = SPECCTRA_DB::MakePCB(); pcb = SPECCTRA_DB::MakePCB();
...@@ -703,8 +769,6 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) ...@@ -703,8 +769,6 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
} }
} }
//pcb->placement->flip_style = T_rotate_first;
// Since none of these statements cause any immediate output, the order // Since none of these statements cause any immediate output, the order
// of them is somewhat flexible. The outputting to disk is done at the // of them is somewhat flexible. The outputting to disk is done at the
// end. We start by gathering all the layer information from the board. // end. We start by gathering all the layer information from the board.
...@@ -845,7 +909,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) ...@@ -845,7 +909,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
//-----<rules>-------------------------------------------------------- //-----<rules>--------------------------------------------------------
{ {
// put out these rules, the user can then edit them with a text editor // put out these rules, the user can then edit them with a text editor
char rule[80]; // padstack name builder char rule[80];
int curTrackWidth = aBoard->m_BoardSettings->m_CurrentTrackWidth; int curTrackWidth = aBoard->m_BoardSettings->m_CurrentTrackWidth;
int curTrackClear = aBoard->m_BoardSettings->m_TrackClearence; int curTrackClear = aBoard->m_BoardSettings->m_TrackClearence;
...@@ -879,7 +943,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) ...@@ -879,7 +943,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
sprintf( rule, "(clearance %.6g (type smd_pin))", clearance ); sprintf( rule, "(clearance %.6g (type smd_pin))", clearance );
rules.push_back( rule ); rules.push_back( rule );
sprintf( rule, "(clearance %.6g (type smd_smd))", clearance ); sprintf( rule, "(clearance %.6g (type smd_smd))", clearance/4 );
rules.push_back( rule ); rules.push_back( rule );
} }
...@@ -905,8 +969,8 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) ...@@ -905,8 +969,8 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
int count = item->m_Poly->corner.size(); int count = item->m_Poly->corner.size();
for( int j=0; j<count; ++j ) for( int j=0; j<count; ++j )
{ {
wxPoint point( item->m_Poly->corner[j].x, item->m_Poly->corner[j].y ); wxPoint point( item->m_Poly->corner[j].x,
item->m_Poly->corner[j].y );
polygon->points.push_back( mapPt(point) ); polygon->points.push_back( mapPt(point) );
} }
...@@ -1044,12 +1108,6 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) ...@@ -1044,12 +1108,6 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
items.Collect( aBoard, scanTRACKs ); items.Collect( aBoard, scanTRACKs );
/*
if( items.GetCount() )
qsort( (void*) items.BasePtr(), items.GetCount(),
sizeof(TRACK*), Track_list_Sort_by_Netcode );
*/
std::string netname; std::string netname;
WIRING* wiring = pcb->wiring; WIRING* wiring = pcb->wiring;
PATH* path = 0; PATH* path = 0;
...@@ -1105,7 +1163,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) ...@@ -1105,7 +1163,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard )
} }
//-----<export the existing real instantiated vias>--------------------- //-----<export the existing real BOARD instantiated vias>-----------------
{ {
// export all of them for now, later we'll decide what controls we need // export all of them for now, later we'll decide what controls we need
// on this. // on this.
......
...@@ -90,6 +90,12 @@ void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event ) ...@@ -90,6 +90,12 @@ void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event )
catch( IOError ioe ) catch( IOError ioe )
{ {
setlocale( LC_NUMERIC, "" ); // revert to the current locale setlocale( LC_NUMERIC, "" ); // revert to the current locale
ioe.errorText += '\n';
ioe.errorText += _("BOARD may be corrupted, do not save it.");
ioe.errorText += '\n';
ioe.errorText += _("Fix problem and try again.");
DisplayError( this, ioe.errorText ); DisplayError( this, ioe.errorText );
return; return;
} }
...@@ -175,6 +181,76 @@ TRACK* SPECCTRA_DB::makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) thro ...@@ -175,6 +181,76 @@ TRACK* SPECCTRA_DB::makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) thro
} }
SEGVIA* SPECCTRA_DB::makeVIA( PADSTACK* aPadstack, const POINT& aPoint, int aNetCode )
{
SEGVIA* via = 0;
SHAPE* shape;
int shapeCount = aPadstack->Length();
int drillDiam = -1;
int viaDiam = 400;
// @todo this needs a lot of work yet, it is not complete yet.
// The drill diameter is encoded in the padstack name if PCBNEW did the DSN export.
// It is in mils and is after the colon and before the last '_'
int drillStartNdx = aPadstack->padstack_id.find( ':' );
if( drillStartNdx != -1 )
{
int drillEndNdx = aPadstack->padstack_id.rfind( '_' );
if( drillEndNdx != -1 )
{
std::string drillDiam( aPadstack->padstack_id, drillStartNdx, drillEndNdx-drillStartNdx-1 );
drillDiam = atoi( drillDiam.c_str() );
}
}
if( shapeCount == 0 )
{
}
else if( shapeCount == 1 )
{
shape = (SHAPE*) (*aPadstack)[0];
if( shape->shape->Type() == T_circle )
{
CIRCLE* circle = (CIRCLE*) shape->shape;
viaDiam = scale( circle->diameter, routeResolution );
via = new SEGVIA( sessionBoard );
via->SetPosition( mapPt( aPoint, routeResolution ) );
via->SetDrillValue( drillDiam );
via->m_Shape = VIA_THROUGH;
via->m_Width = viaDiam;
via->SetLayerPair( CMP_N, COPPER_LAYER_N );
}
}
else if( shapeCount == sessionBoard->GetCopperLayerCount() )
{
shape = (SHAPE*) (*aPadstack)[0];
if( shape->shape->Type() == T_circle )
{
CIRCLE* circle = (CIRCLE*) shape->shape;
viaDiam = scale( circle->diameter, routeResolution );
via = new SEGVIA( sessionBoard );
via->SetPosition( mapPt( aPoint, routeResolution ) );
via->SetDrillValue( drillDiam );
via->m_Shape = VIA_THROUGH;
via->m_Width = viaDiam;
via->SetLayerPair( CMP_N, COPPER_LAYER_N );
}
}
if( via )
via->SetNet( aNetCode );
return via;
}
// no UI code in this function, throw exception to report problems to the // no UI code in this function, throw exception to report problems to the
// UI handler: void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event ) // UI handler: void WinEDA_PcbFrame::ImportSpecctraSession( wxCommandEvent& event )
...@@ -268,15 +344,21 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError ) ...@@ -268,15 +344,21 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError )
NET_OUTS& net_outs = session->route->net_outs; NET_OUTS& net_outs = session->route->net_outs;
for( NET_OUTS::iterator net=net_outs.begin(); net!=net_outs.end(); ++net ) for( NET_OUTS::iterator net=net_outs.begin(); net!=net_outs.end(); ++net )
{ {
wxString netName( CONV_FROM_UTF8( net->net_id.c_str() ) ); int netCode = 0;
EQUIPOT* equipot = aBoard->FindNet( netName ); // page 143 of spec says wire's net_id is optional
if( !equipot ) if( net->net_id.size() )
{ {
ThrowIOError( _("Session file uses invalid net::net_id \"%s\""), wxString netName = CONV_FROM_UTF8( net->net_id.c_str() );
netName.GetData() );
EQUIPOT* equipot = aBoard->FindNet( netName );
if( equipot )
netCode = equipot->GetNet();
// else netCode remains 0
} }
WIRES& wires = net->wires; WIRES& wires = net->wires;
for( unsigned i=0; i<wires.size(); ++i ) for( unsigned i=0; i<wires.size(); ++i )
{ {
...@@ -296,7 +378,7 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError ) ...@@ -296,7 +378,7 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError )
PATH* path = (PATH*) wire->shape; PATH* path = (PATH*) wire->shape;
for( unsigned pt=0; pt<path->points.size()-1; ++pt ) for( unsigned pt=0; pt<path->points.size()-1; ++pt )
{ {
TRACK* track = makeTRACK( path, pt, equipot->GetNet() ); TRACK* track = makeTRACK( path, pt, netCode );
TRACK* insertAid = track->GetBestInsertPoint( aBoard ); TRACK* insertAid = track->GetBestInsertPoint( aBoard );
track->Insert( aBoard, insertAid ); track->Insert( aBoard, insertAid );
...@@ -304,10 +386,48 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError ) ...@@ -304,10 +386,48 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard ) throw( IOError )
} }
WIRE_VIAS& wire_vias = net->wire_vias; WIRE_VIAS& wire_vias = net->wire_vias;
LIBRARY& library = *session->route->library;
for( unsigned i=0; i<wire_vias.size(); ++i ) for( unsigned i=0; i<wire_vias.size(); ++i )
{ {
// WIRE_VIA* wire_via = &wire_vias[i]; int netCode = 0;
// page 144 of spec says wire_via's net_id is optional
if( net->net_id.size() )
{
wxString netName = CONV_FROM_UTF8( net->net_id.c_str() );
EQUIPOT* equipot = aBoard->FindNet( netName );
if( equipot )
netCode = equipot->GetNet();
// else netCode remains 0
}
WIRE_VIA* wire_via = &wire_vias[i];
// example: (via Via_15:8_mil 149000 -71000 )
PADSTACK* padstack = library.FindPADSTACK( wire_via->GetPadstackId() );
if( !padstack )
{
// Could use a STRINGFORMATTER here and convert the entire
// wire_via to text and put that text into the exception.
wxString psid( CONV_FROM_UTF8( wire_via->GetPadstackId().c_str() ) );
ThrowIOError( _("A wire_via references a missing padstack \"%s\""),
psid.GetData() );
}
for( unsigned v=0; v<wire_via->vertexes.size(); ++v )
{
SEGVIA* via = makeVIA( padstack, wire_via->vertexes[v], netCode );
if( !via )
ThrowIOError( _("Unable to make a via") );
TRACK* insertAid = via->GetBestInsertPoint( aBoard );
via->Insert( aBoard, insertAid );
}
} }
} }
} }
......
...@@ -6,8 +6,8 @@ folks will see these items and volunteer to do them. ...@@ -6,8 +6,8 @@ folks will see these items and volunteer to do them.
*** improved xpm handling *** improved xpm handling
We should: We should:
1) make a library out of ALL the xpm files, and 1) make a library out of ALL the xpm files, and
2) develop a simple header file which declares ALL of them using conventional C/C++: 2) develop a simple header file which declares ALL of them using conventional C/C++:
extern char * somename2_xpm[]; extern char * somename2_xpm[];
extern char * somename3_xpm[]; extern char * somename3_xpm[];
...@@ -15,7 +15,7 @@ We should: ...@@ -15,7 +15,7 @@ We should:
: :
This way the linker can bundle in the xpms that it has seen referenced. I don't This way the linker can bundle in the xpms that it has seen referenced. I don't
think seeing the extern declaration is cause to do this, it must actually be think seeing the extern declaration is cause to do this, it must actually be
referenced. I think this would be an easier way to manage xpms. referenced. I think this would be an easier way to manage xpms.
*** @todo: grep for @todo and finish off those tasks, scattered throughout the source. *** @todo: grep for @todo and finish off those tasks, scattered throughout the source.
...@@ -24,26 +24,9 @@ referenced. I think this would be an easier way to manage xpms. ...@@ -24,26 +24,9 @@ referenced. I think this would be an easier way to manage xpms.
*** use BOARD_ITEM::MenuIcon() in the onrightclick.cpp *** use BOARD_ITEM::MenuIcon() in the onrightclick.cpp
2007-Dec-4 Assigned To: Jean-Pierre, per his email
asked by: Dick Hollenbeck
================================================================================
1) Improve the zone support so that the perimeters of each zone are editable.
2) Allow zones to be added early in the routing process.
3) Remove the requirement to route tracks for situations where a zone is.
4) Support connections from zones to vias, and zones to tracks, and zones to pads.
rework zones so they are modifiable and so that the user does not
need to enter tracks for thru hole pads or vias which connect to a zone.
I propose a two step solution:
1) interim enhancement: make zone edges retained in BRD file and make the
edges editable.
2) final solution: get rid of requirement for tracks buried within a zone.
Reivew the GEDA source code and other sources to gather ideas before doing 2).
*** Use DOXYGEN compatible comments on member functions. As configured, *** Use DOXYGEN compatible comments on member functions. As configured,
Doxygen gives priority to comments in header files over *.cpp files. Doxygen gives priority to comments in header files over *.cpp files.
Review the generated docs and start to go through the source and make the Review the generated docs and start to go through the source and make the
generated doxygen docs readable and clear using the JavaDoc style comments, generated doxygen docs readable and clear using the JavaDoc style comments,
mostly in the header files. The error and warning output of the doxygen mostly in the header files. The error and warning output of the doxygen
compiler can help with this too. compiler can help with this too.
...@@ -56,7 +39,6 @@ understanding by new developers. ...@@ -56,7 +39,6 @@ understanding by new developers.
*** Add tooltip text to all non-obvious controls in every dialog window. *** Add tooltip text to all non-obvious controls in every dialog window.
Need to do this using DialogBlocks. Need to do this using DialogBlocks.
2007-Nov-30 Assigned To: nobody 2007-Nov-30 Assigned To: nobody
asked by: Dick Hollenbeck asked by: Dick Hollenbeck
================================================================================ ================================================================================
...@@ -71,9 +53,27 @@ asked by: jp Charras ...@@ -71,9 +53,27 @@ asked by: jp Charras
Use the collector classes in eeschema. Use the collector classes in eeschema.
2008-Jan-25 Assigned To: any one who wants to 2008-Feb-8 Assigned To: dick
asked by: dick asked by: dick
================================================================================ ================================================================================
Split the QARCs being created as 1/2 circles into quarter arcs. Problem specctra:
is in 4 places in specctra_export.cpp no blank pin numbers.
check that pin numbers are unique within a part, combine all such pins
into common padstack.
prompt for board boundary control, copper areas, tracks and vias, via per net, fixed vs. normal.
do write up.
2008-Feb-8 Assigned To: Jean-Pierre, per his email
asked by: Dick Hollenbeck
================================================================================
1) Remove the requirement to route tracks for situations where a zone is.
2) Support connections from zones to vias, and zones to tracks, and zones to pads.
rework zones so they are modifiable and so that the user does not
need to enter tracks for thru hole pads or vias which connect to a zone.
I propose a two step solution:
1) interim enhancement: make zone edges retained in BRD file and make the
edges editable.
2) final solution: get rid of requirement for tracks buried within a zone.
Reivew the GEDA source code and other sources to gather ideas before doing 2).
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