Commit 1e2b145a authored by jean-pierre charras's avatar jean-pierre charras

Pcbnew: Add NPTH pads (seen changelog).

Minor fixes and enhancements.
parent c64a6937
......@@ -4,6 +4,14 @@ KiCad ChangeLog 2010
Please add newer entries at the top, list the date and your name with
email address.
2011-Aug-19, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================
Pcbnew:
Add support for not plated through holes (NPTH) pads
* These NPTH pads are used for mechanical purpose only, and cannot be connected to a net.
* When these pads have a same size and shape for the hole and the pad, the pad is not plotted
in GERBER files.
2011-Apr-12, UPDATE Jerry Jacobs <xor.gate.engineering@gmail.com>
================================================================================
Minor UI changes that affect OS X platform.
......
......@@ -33,6 +33,8 @@ bool SCH_EDIT_FRAME::ProcessStuffFile( FILE* aFile, bool aSetFieldAttributeToVis
SCH_REFERENCE_LIST referencesList;
SheetList.GetComponents( referencesList, false );
// Now, foe each component found in file,
// replace footprint field value by the new value:
while( GetLine( aFile, Line, &LineNum, sizeof(Line) ) )
{
if( sscanf( Line, "comp = \"%s module = \"%s", Ref, FootPrint ) == 2 )
......@@ -58,12 +60,20 @@ bool SCH_EDIT_FRAME::ProcessStuffFile( FILE* aFile, bool aSetFieldAttributeToVis
// So we do not stop the search here
SCH_COMPONENT* component = referencesList[ii].GetComponent();
SCH_FIELD * fpfield = component->GetField( FOOTPRINT );
/* Give a reasonable value to the field position and
* orientation, if the text is empty at position 0, because
* it is probably not yet initialized
*/
if( fpfield->m_Text.IsEmpty()
&& ( fpfield->m_Pos == wxPoint( 0, 0 ) ) )
&& ( fpfield->m_Pos == component->m_Pos ) )
{
fpfield->m_Orient = component->GetField( VALUE )->m_Orient;
fpfield->m_Pos = component->GetField( VALUE )->m_Pos;
fpfield->m_Pos.y -= 100;
fpfield->m_Size = component->GetField( VALUE )->m_Size;
if( fpfield->m_Orient == 0 )
fpfield->m_Pos.y += 100;
else
fpfield->m_Pos.x += 100;
}
fpfield->m_Text = footprint;
......
......@@ -1065,20 +1065,25 @@ bool SCH_SCREEN::SetComponentFootprint( SCH_SHEET_PATH* aSheetPath, const wxStri
* orientation, if the text is empty at position 0, because
* it is probably not yet initialized
*/
if( component->GetField( FOOTPRINT )->m_Text.IsEmpty()
&& ( component->GetField( FOOTPRINT )->m_Pos == wxPoint( 0, 0 ) ) )
SCH_FIELD * fpfield = component->GetField( FOOTPRINT );
if( fpfield->m_Text.IsEmpty()
&& ( fpfield->m_Pos == component->m_Pos ) )
{
component->GetField( FOOTPRINT )->m_Orient = component->GetField( VALUE )->m_Orient;
component->GetField( FOOTPRINT )->m_Pos = component->GetField( VALUE )->m_Pos;
component->GetField( FOOTPRINT )->m_Pos.y -= 100;
fpfield->m_Orient = component->GetField( VALUE )->m_Orient;
fpfield->m_Pos = component->GetField( VALUE )->m_Pos;
fpfield->m_Size = component->GetField( VALUE )->m_Size;
if( fpfield->m_Orient == 0 )
fpfield->m_Pos.y += 100;
else
fpfield->m_Pos.x += 100;
}
component->GetField( FOOTPRINT )->m_Text = aFootPrint;
fpfield->m_Text = aFootPrint;
if( aSetVisible )
component->GetField( FOOTPRINT )->m_Attributs &= ~TEXT_NO_VISIBLE;
fpfield->m_Attributs &= ~TEXT_NO_VISIBLE;
else
component->GetField( FOOTPRINT )->m_Attributs |= TEXT_NO_VISIBLE;
fpfield->m_Attributs |= TEXT_NO_VISIBLE;
found = true;
}
......
......@@ -406,8 +406,23 @@ public:
void Plot_Layer( PLOTTER* plotter,
int Layer,
GRTraceMode trace_mode );
/**
* Function Plot_Standard_Layer
* plot copper or technical layers.
* not used for silk screen layers, because these layers have specific
* requirements, mainly for pads
* @param aPlotter = the plotter to use
* @param aLayerMask = the mask to define the layers to plot
* @param aPlotVia = true to plot vias, false to skip vias (has meaning
* only for solder mask layers).
* @param aPlotMode = the plot mode (files, sketch). Has meaning for some formats only
* @param aSkipNPTH_Pads = true to skip NPTH Pads, when the pad size and the pad hole
* have the same size. Used in GERBER format only.
*/
void Plot_Standard_Layer( PLOTTER* aPlotter, int aLayerMask,
bool aPlotVia, GRTraceMode aPlotMode );
bool aPlotVia, GRTraceMode aPlotMode,
bool aSkipNPTH_Pads = false );
void Plot_Serigraphie( PLOTTER* plotter,
int masque_layer,
GRTraceMode trace_mode );
......
......@@ -42,18 +42,19 @@ const wxChar* s_AllowedExtensionsToList[] =
wxT( "^[^$].*\\.brd$" ),
wxT( "^.*\\.net$" ),
wxT( "^.*\\.txt$" ),
wxT( "^.*\\.pho$" ), // Gerber file
wxT( "^.*\\.gbr$" ), // Gerber file
wxT( "^.*\\.gb[alops]$" ), // Gerber back (or bottom) layer file
wxT( "^.*\\.gt[alops]$" ), // Gerber front (or top) layer file
wxT( "^.*\\.g[0-9]{1,2}$" ), // Gerber inner layer file
wxT( "^.*\\.pho$" ), // Gerber file
wxT( "^.*\\.gbr$" ), // Gerber file
wxT( "^.*\\.gb[alops]$" ), // Gerber back (or bottom) layer file
wxT( "^.*\\.gt[alops]$" ), // Gerber front (or top) layer file
wxT( "^.*\\.g[0-9]{1,2}$" ), // Gerber inner layer file
wxT( "^.*\\.odt$" ),
wxT( "^.*\\.sxw$" ),
wxT( "^.*\\.htm$" ),
wxT( "^.*\\.html$" ),
wxT( "^.*\\.rpt$" ),
wxT( "^.*\\.csv$" ),
NULL // end of list
wxT( "^.*\\.drl$" ), // Excellon drill files
NULL // end of list
};
......
......@@ -17,7 +17,7 @@
// Due to a bug in previous versions ( m_LengthDie not initialized in D_PAD ctor)
// m_LengthDie is no more read from .brd files
// Uncomment this next line to read m_LengthDie from .brd files
// #define READ_PAD_LENGTH_DIE
#define READ_PAD_LENGTH_DIE
int D_PAD::m_PadSketchModePenSize = 0; // Pen size used to draw pads in sketch mode
......@@ -758,13 +758,19 @@ void D_PAD::DisplayInfo( EDA_DRAW_FRAME* frame )
else
Line.Printf( wxT( "%3.1f" ), (float) m_Orient / 10 );
frame->AppendMsgPanel( _( "Orient" ), Line, BLUE );
frame->AppendMsgPanel( _( "Orient" ), Line, LIGHTBLUE );
valeur_param( m_Pos.x, Line );
frame->AppendMsgPanel( _( "X Pos" ), Line, BLUE );
frame->AppendMsgPanel( _( "X Pos" ), Line, LIGHTBLUE );
valeur_param( m_Pos.y, Line );
frame->AppendMsgPanel( _( "Y pos" ), Line, BLUE );
frame->AppendMsgPanel( _( "Y pos" ), Line, LIGHTBLUE );
if( m_LengthDie )
{
valeur_param( m_LengthDie, Line );
frame->AppendMsgPanel( _( "Length on die" ), Line, CYAN );
}
}
......@@ -900,15 +906,16 @@ wxString D_PAD::ShowPadAttr() const
wxString D_PAD::GetSelectMenuText() const
{
wxString text;
BOARD * board = GetBoard();
text << _( "Pad" ) << wxT( " \"" ) << ReturnStringPadName() << wxT( "\" (" );
if ( (m_Masque_Layer & ALL_CU_LAYERS) == ALL_CU_LAYERS )
text << _("all copper layers");
else if( (m_Masque_Layer & LAYER_BACK) == LAYER_BACK )
text << GetLayerName();
else if( (m_Masque_Layer & LAYER_BACK ) == LAYER_BACK )
text << board->GetLayerName(LAYER_N_BACK);
else if( (m_Masque_Layer & LAYER_FRONT) == LAYER_FRONT )
text << GetLayerName();
text << board->GetLayerName(LAYER_N_FRONT);
else
text << _( "???" );
......
......@@ -27,7 +27,7 @@ class Pcb3D_GLCanvas;
#define PAD_SMD_DEFAULT_LAYERS LAYER_FRONT | SOLDERMASK_LAYER_FRONT
//PAD_HOLE_NOT_PLATED:
#define PAD_HOLE_NOT_PLATED_DEFAULT_LAYERS LAYER_BACK | SILKSCREEN_LAYER_FRONT | \
#define PAD_HOLE_NOT_PLATED_DEFAULT_LAYERS ALL_CU_LAYERS | SILKSCREEN_LAYER_FRONT | \
SOLDERMASK_LAYER_BACK | SOLDERMASK_LAYER_FRONT
......@@ -40,12 +40,14 @@ public:
int m_Color; // color used to draw the pad shape , from pad layers and
// visible layers
int m_HoleColor; // color used to draw the pad hole
int m_NPHoleColor; // color used to draw a pad Not Plated hole
int m_PadClearance; // clearance value, used to draw the pad area outlines
wxSize m_Mask_margin; // margin, used to draw solder paste when only one layer is shown
bool m_Display_padnum; // true to show pad number
bool m_Display_netname; // true to show net name
bool m_ShowPadFilled; // true to show pad as solid area, false to show pas in sketch mode
bool m_ShowNCMark; // true to show pad not connected mark
bool m_ShowNotPlatedHole; // true when the pad hole in not plated, to draw a specifib pad shape
bool m_IsPrinting; // true to print, false to display on screen.
wxPoint m_Offset; // general draw offset
......@@ -103,13 +105,12 @@ public:
// module anchor, orientation 0
int m_ShapeMaxRadius; // radius of the circle containing the pad shape
int m_Attribut; // NORMAL, PAD_SMD, PAD_CONN
int m_Attribut; // NORMAL, PAD_SMD, PAD_CONN, PAD_HOLE_NOT_PLATED
int m_Orient; // in 1/10 degrees
static int m_PadSketchModePenSize; // Pen size used to draw pads in sketch mode
// (mode used to print pads on silkscreen layer)
// Length net from pad to die on chip
int m_LengthDie;
int m_LengthDie; // Length net from pad to die on chip
// Local clearance. When null, the module default value is used.
// when the module default value is null, the netclass value is used
......
......@@ -32,11 +32,13 @@ PAD_DRAWINFO::PAD_DRAWINFO()
m_DrawMode = 0;
m_Color = BLACK;
m_HoleColor = BLACK; // could be DARKGRAY;
m_NPHoleColor = YELLOW;
m_PadClearance = 0;
m_Display_padnum = true;
m_Display_netname = true;
m_ShowPadFilled = true;
m_ShowNCMark = true;
m_ShowNotPlatedHole = false;
m_IsPrinting = false;
}
......@@ -320,6 +322,8 @@ void D_PAD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, int aDraw_mode, const wxPoi
if( ( m_Masque_Layer & ALL_CU_LAYERS ) == 0 )
DisplayIsol = FALSE;
if( m_Attribut == PAD_HOLE_NOT_PLATED )
drawInfo.m_ShowNotPlatedHole = true;
drawInfo.m_DrawMode = aDraw_mode;
drawInfo.m_Color = color;
......@@ -344,7 +348,7 @@ void D_PAD::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, int aDraw_mode, const wxPoi
drawInfo.m_Display_netname = false;
// Display net names is restricted to pads that are on the active layer
// in cotranst mode displae
// in hight contrast mode display
if( !IsOnLayer( screen->m_Active_Layer ) && DisplayOpt.ContrastModeDisplay )
drawInfo.m_Display_netname = false;
......@@ -453,7 +457,10 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
wxPoint holepos = m_Pos - aDrawInfo.m_Offset;
int hole = m_Drill.x >> 1;
if( aDrawInfo.m_ShowPadFilled && hole )
bool drawhole = hole > 0;
if( !aDrawInfo.m_ShowPadFilled && !aDrawInfo. m_ShowNotPlatedHole )
drawhole = false;
if( drawhole )
{
bool blackpenstate = false;
if( aDrawInfo.m_IsPrinting )
......@@ -468,13 +475,16 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
else
GRSetDrawMode( aDC, GR_XOR );
int hole_color = aDrawInfo.m_HoleColor;
if( aDrawInfo. m_ShowNotPlatedHole ) // Draw a specific hole color
hole_color = aDrawInfo.m_NPHoleColor;
switch( m_DrillShape )
{
case PAD_CIRCLE:
if( aDC->LogicalToDeviceXRel( hole ) > 1 )
GRFilledCircle( aClipBox, aDC, holepos.x, holepos.y, hole, 0,
aDrawInfo.m_Color, aDrawInfo.m_HoleColor );
aDrawInfo.m_Color, hole_color );
break;
case PAD_OVAL:
......@@ -497,7 +507,7 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
GRFillCSegm( aClipBox, aDC, holepos.x + delta_cx, holepos.y + delta_cy,
holepos.x - delta_cx, holepos.y - delta_cy, seg_width,
aDrawInfo.m_HoleColor );
hole_color );
break;
default:
......
/**
** @file dialog_gendrill.cpp
*/
** @file dialog_gendrill.cpp
*/
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
......@@ -43,16 +44,16 @@
#define UnitDrillInchKey wxT( "DrillUnit" )
#define DrillOriginIsAuxAxisKey wxT( "DrillAuxAxis" )
// list of allowed precision for EXCELLON files, when interger format:
// list of allowed precision for EXCELLON files, for integer format:
// Due to difference between inches and mm,
// there are 2 set of reasonnable precision values, one for inches and one for metric
static DRILL_PRECISION precisionListForInches[] =
{
DRILL_PRECISION(2,3), DRILL_PRECISION(2,4)
DRILL_PRECISION( 2, 3 ), DRILL_PRECISION( 2, 4 )
};
static DRILL_PRECISION precisionListForMetric[] =
{
DRILL_PRECISION(3,2), DRILL_PRECISION(3,3)
DRILL_PRECISION( 3, 2 ), DRILL_PRECISION( 3, 3 )
};
......@@ -75,6 +76,8 @@ bool DIALOG_GENDRILL::m_MinimalHeader = false;
bool DIALOG_GENDRILL::m_Mirror = true;
bool DIALOG_GENDRILL::m_DrillOriginIsAuxAxis = false;
int DIALOG_GENDRILL:: m_PrecisionFormat = 1;
bool DIALOG_GENDRILL::m_createRpt = false;
int DIALOG_GENDRILL::m_createMap = 0;
/*!
* DIALOG_GENDRILL destructor
......@@ -107,6 +110,7 @@ void DIALOG_GENDRILL::initDialog()
InitDisplayParams();
}
/* some param values initialization before display dialog window
*/
void DIALOG_GENDRILL::InitDisplayParams( void )
......@@ -119,7 +123,7 @@ void DIALOG_GENDRILL::InitDisplayParams( void )
if( m_ZerosFormat == EXCELLON_WRITER::DECIMAL_FORMAT )
m_Choice_Precision->Enable( false );
UpdatePrecisionOptions( );
UpdatePrecisionOptions();
m_Check_Minimal->SetValue( m_MinimalHeader );
......@@ -128,6 +132,9 @@ void DIALOG_GENDRILL::InitDisplayParams( void )
m_Check_Mirror->SetValue( m_Mirror );
m_Choice_Drill_Map->SetSelection( m_createMap );
m_Choice_Drill_Report->SetSelection( m_createRpt );
m_ViaDrillValue->SetLabel( _( "Use Netclasses values" ) );
m_MicroViaDrillValue->SetLabel( _( "Use Netclasses values" ) );
......@@ -142,26 +149,28 @@ void DIALOG_GENDRILL::InitDisplayParams( void )
// See if we have some buried vias or/and microvias, and display
// microvias drill value if so
m_ThroughViasCount = 0;
m_MicroViasCount = 0;
m_BlindOrBuriedViasCount = 0;
m_throughViasCount = 0;
m_microViasCount = 0;
m_blindOrBuriedViasCount = 0;
for( TRACK* track = m_Parent->GetBoard()->m_Track; track != NULL;
track = track->Next() )
{
if( track->Type() != TYPE_VIA )
continue;
if( track->Shape() == VIA_THROUGH )
m_ThroughViasCount++;
m_throughViasCount++;
else if( track->Shape() == VIA_MICROVIA )
m_MicroViasCount++;
m_microViasCount++;
else if( track->Shape() == VIA_BLIND_BURIED )
m_BlindOrBuriedViasCount++;
m_blindOrBuriedViasCount++;
}
m_MicroViaDrillValue->Enable( m_MicroViasCount );
m_MicroViaDrillValue->Enable( m_microViasCount );
// Pads holes round:
m_PadsHoleCount = 0;
/* Count plated pad holes and not plated pad holes:
*/
m_platedPadsHoleCount = 0;
m_notplatedPadsHoleCount = 0;
for( MODULE* module = m_Parent->GetBoard()->m_Modules;
module != NULL; module = module->Next() )
{
......@@ -170,31 +179,47 @@ void DIALOG_GENDRILL::InitDisplayParams( void )
if( pad->m_DrillShape == PAD_CIRCLE )
{
if( pad->m_Drill.x != 0 )
m_PadsHoleCount++;
{
if( pad->m_Attribut == PAD_HOLE_NOT_PLATED )
m_notplatedPadsHoleCount++;
else
m_platedPadsHoleCount++;
}
}
else
if( MIN( pad->m_Drill.x, pad->m_Drill.y ) != 0 )
m_PadsHoleCount++;
{
if( pad->m_Attribut == PAD_HOLE_NOT_PLATED )
m_notplatedPadsHoleCount++;
else
m_platedPadsHoleCount++;
}
}
}
msg = m_PadsCountInfoMsg->GetLabel();
msg << wxT( " " ) << m_PadsHoleCount;
m_PadsCountInfoMsg->SetLabel( msg );
// Display hole counts:
msg = m_PlatedPadsCountInfoMsg->GetLabel();
msg << wxT( " " ) << m_platedPadsHoleCount;
m_PlatedPadsCountInfoMsg->SetLabel( msg );
msg = m_NotPlatedPadsCountInfoMsg->GetLabel();
msg << wxT( " " ) << m_notplatedPadsHoleCount;
m_NotPlatedPadsCountInfoMsg->SetLabel( msg );
msg = m_ThroughViasInfoMsg->GetLabel();
msg << wxT( " " ) << m_ThroughViasCount;
msg << wxT( " " ) << m_throughViasCount;
m_ThroughViasInfoMsg->SetLabel( msg );
msg = m_MicroViasInfoMsg->GetLabel();
msg << wxT( " " ) << m_MicroViasCount;
msg << wxT( " " ) << m_microViasCount;
m_MicroViasInfoMsg->SetLabel( msg );
msg = m_BuriedViasInfoMsg->GetLabel();
msg << wxT( " " ) << m_BlindOrBuriedViasCount;
msg << wxT( " " ) << m_blindOrBuriedViasCount;
m_BuriedViasInfoMsg->SetLabel( msg );
}
/* Save drill options: */
void DIALOG_GENDRILL::UpdateConfig()
{
......@@ -213,13 +238,14 @@ void DIALOG_GENDRILL::UpdateConfig()
}
}
/*!
* wxEVT_COMMAND_RADIOBOX_SELECTED event handler for ID_RADIOBOX
*/
void DIALOG_GENDRILL::OnSelDrillUnitsSelected( wxCommandEvent& event )
{
UpdatePrecisionOptions( );
UpdatePrecisionOptions();
}
......@@ -229,8 +255,8 @@ void DIALOG_GENDRILL::OnSelDrillUnitsSelected( wxCommandEvent& event )
void DIALOG_GENDRILL::OnOkClick( wxCommandEvent& event )
{
GenDrillAndReportFiles( );
EndModal( wxID_OK);
GenDrillAndReportFiles();
EndModal( wxID_OK );
}
......@@ -240,8 +266,8 @@ void DIALOG_GENDRILL::OnOkClick( wxCommandEvent& event )
void DIALOG_GENDRILL::OnCancelClick( wxCommandEvent& event )
{
UpdateConfig(); /* Save drill options: */
EndModal( wxID_CANCEL); // Process the default cancel event (close dialog)
UpdateConfig(); /* Save drill options: */
EndModal( wxID_CANCEL ); // Process the default cancel event (close dialog)
}
......@@ -251,11 +277,11 @@ void DIALOG_GENDRILL::OnCancelClick( wxCommandEvent& event )
void DIALOG_GENDRILL::OnSelZerosFmtSelected( wxCommandEvent& event )
{
UpdatePrecisionOptions( );
UpdatePrecisionOptions();
}
void DIALOG_GENDRILL::UpdatePrecisionOptions( )
void DIALOG_GENDRILL::UpdatePrecisionOptions()
{
if( m_Choice_Unit->GetSelection()== 1 ) // Units = inches
{
......@@ -281,6 +307,9 @@ void DIALOG_GENDRILL::SetParams( void )
wxString msg;
long ltmp;
m_createMap = m_Choice_Drill_Map->GetSelection();
m_createRpt = m_Choice_Drill_Report->GetSelection();
m_UnitDrillIsInch = (m_Choice_Unit->GetSelection() == 0) ? FALSE : TRUE;
m_MinimalHeader = m_Check_Minimal->IsChecked();
m_Mirror = m_Check_Mirror->IsChecked();
......
......@@ -46,10 +46,13 @@ public:
private:
PCB_EDIT_FRAME* m_Parent;
int m_PadsHoleCount;
int m_ThroughViasCount;
int m_MicroViasCount;
int m_BlindOrBuriedViasCount;
int m_platedPadsHoleCount;
int m_notplatedPadsHoleCount;
int m_throughViasCount;
int m_microViasCount;
int m_blindOrBuriedViasCount;
static bool m_createRpt; // true to create a drill file report
static int m_createMap; // > 0 to create a map file report
public: DIALOG_GENDRILL( PCB_EDIT_FRAME* parent );
~DIALOG_GENDRILL();
......
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Sep 8 2010)
// C++ code generated with wxFormBuilder (version Jun 30 2011)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
......@@ -127,17 +127,21 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con
wxStaticBoxSizer* sbSizerHoles;
sbSizerHoles = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Holes Count:") ), wxVERTICAL );
m_PadsCountInfoMsg = new wxStaticText( this, wxID_ANY, _("Pads:"), wxDefaultPosition, wxDefaultSize, 0 );
m_PadsCountInfoMsg->Wrap( -1 );
sbSizerHoles->Add( m_PadsCountInfoMsg, 0, wxALL, 5 );
m_PlatedPadsCountInfoMsg = new wxStaticText( this, wxID_ANY, _("Plated Pads:"), wxDefaultPosition, wxDefaultSize, 0 );
m_PlatedPadsCountInfoMsg->Wrap( -1 );
sbSizerHoles->Add( m_PlatedPadsCountInfoMsg, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_NotPlatedPadsCountInfoMsg = new wxStaticText( this, wxID_ANY, _("Not Plated Pads:"), wxDefaultPosition, wxDefaultSize, 0 );
m_NotPlatedPadsCountInfoMsg->Wrap( -1 );
sbSizerHoles->Add( m_NotPlatedPadsCountInfoMsg, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_ThroughViasInfoMsg = new wxStaticText( this, wxID_ANY, _("Through Vias:"), wxDefaultPosition, wxDefaultSize, 0 );
m_ThroughViasInfoMsg->Wrap( -1 );
sbSizerHoles->Add( m_ThroughViasInfoMsg, 0, wxALL, 5 );
sbSizerHoles->Add( m_ThroughViasInfoMsg, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_MicroViasInfoMsg = new wxStaticText( this, wxID_ANY, _("Micro Vias:"), wxDefaultPosition, wxDefaultSize, 0 );
m_MicroViasInfoMsg->Wrap( -1 );
sbSizerHoles->Add( m_MicroViasInfoMsg, 0, wxALL, 5 );
sbSizerHoles->Add( m_MicroViasInfoMsg, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_BuriedViasInfoMsg = new wxStaticText( this, wxID_ANY, _("Buried Vias:"), wxDefaultPosition, wxDefaultSize, 0 );
m_BuriedViasInfoMsg->Wrap( -1 );
......
This source diff could not be displayed because it is too large. You can view the blob instead.
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Sep 8 2010)
// C++ code generated with wxFormBuilder (version Jun 30 2011)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __dialog_gendrill_base__
#define __dialog_gendrill_base__
#ifndef __DIALOG_GENDRILL_BASE_H__
#define __DIALOG_GENDRILL_BASE_H__
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include <wx/string.h>
#include <wx/radiobox.h>
#include <wx/gdicmn.h>
......@@ -51,11 +52,11 @@ class DIALOG_GENDRILL_BASE : public wxDialog
wxStaticText* m_ViaDrillValue;
wxStaticBoxSizer* m_MicroViasDrillSizer;
wxStaticText* m_MicroViaDrillValue;
wxStaticText* m_PadsCountInfoMsg;
wxStaticText* m_PlatedPadsCountInfoMsg;
wxStaticText* m_NotPlatedPadsCountInfoMsg;
wxStaticText* m_ThroughViasInfoMsg;
wxStaticText* m_MicroViasInfoMsg;
wxStaticText* m_BuriedViasInfoMsg;
wxButton* m_OkButton;
wxButton* m_CancelButton;
......@@ -68,9 +69,9 @@ class DIALOG_GENDRILL_BASE : public wxDialog
public:
DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Drill Files Generation"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 447,385 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Drill Files Generation"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 447,385 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_GENDRILL_BASE();
};
#endif //__dialog_gendrill_base__
#endif //__DIALOG_GENDRILL_BASE_H__
......@@ -26,6 +26,7 @@ void PCB_EDIT_FRAME::InstallNetlistFrame( wxDC* DC )
{
fn = GetScreen()->GetFileName();
fn.SetExt( NetExtBuffer );
lastNetlistName = fn.GetFullPath();
}
DIALOG_NETLIST frame( this, DC, lastNetlistName );
......
......@@ -79,7 +79,7 @@ private:
void PadTypeSelected( wxCommandEvent& event );
void PadPropertiesAccept( wxCommandEvent& event );
void SetPadLayersList( long layer_mask );
void OnSetLayer( wxCommandEvent& event );
void OnSetLayers( wxCommandEvent& event );
void OnCancelButtonClick( wxCommandEvent& event );
void OnPaintShowPanel( wxPaintEvent& event );
bool TransfertDataToPad( D_PAD* aPad, bool aPromptOnError = false );
......@@ -112,6 +112,8 @@ void DIALOG_PAD_PROPERTIES::OnPaintShowPanel( wxPaintEvent& event )
drawInfo.m_Offset = m_dummyPad->m_Pos;
drawInfo.m_Display_padnum = true;
drawInfo.m_Display_netname = true;
if( m_dummyPad->m_Attribut == PAD_HOLE_NOT_PLATED )
drawInfo.m_ShowNotPlatedHole = true;
// Shows the local pad clearance
drawInfo.m_PadClearance = m_dummyPad->m_LocalClearance;
......@@ -217,6 +219,7 @@ void DIALOG_PAD_PROPERTIES::initValues()
m_PadShapeOffsetX_Unit->SetLabel( GetUnitsLabel( g_UserUnit ) );
m_PadShapeOffsetY_Unit->SetLabel( GetUnitsLabel( g_UserUnit ) );
m_PadShapeDelta_Unit->SetLabel( GetUnitsLabel( g_UserUnit ) );
m_PadLengthDie_Unit->SetLabel( GetUnitsLabel( g_UserUnit ) );
m_NetClearanceUnits->SetLabel( GetUnitsLabel( g_UserUnit ) );
// Display current pad masks clearances units
......@@ -248,6 +251,8 @@ void DIALOG_PAD_PROPERTIES::initValues()
m_radioBtnDeltaYdir->SetValue(true);
}
PutValueInLocalUnits( *m_LengthDieCtrl, m_dummyPad->m_LengthDie, internalUnits );
PutValueInLocalUnits( *m_NetClearanceValueCtrl, m_dummyPad->m_LocalClearance, internalUnits );
PutValueInLocalUnits( *m_SolderMaskMarginCtrl,
m_dummyPad->m_LocalSolderMaskMargin,
......@@ -333,7 +338,7 @@ void DIALOG_PAD_PROPERTIES::initValues()
msg.Printf( wxT( "%d" ), m_dummyPad->m_Orient );
m_PadOrientCtrl->SetValue( msg );
// Selection du type
// Type of pad selection
m_PadType->SetSelection( 0 );
for( int ii = 0; ii < NBTYPES; ii++ )
{
......@@ -344,14 +349,22 @@ void DIALOG_PAD_PROPERTIES::initValues()
}
}
// Enable/disable Pad name,and pad length die
// (disable for NPTH pads (mechanical pads)
bool enable = m_dummyPad->m_Attribut != PAD_HOLE_NOT_PLATED;
m_PadNumCtrl->Enable( enable );
m_PadNetNameCtrl->Enable( enable );
m_LengthDieCtrl->Enable( enable );
if( m_dummyPad->m_DrillShape != PAD_OVAL )
m_DrillShapeCtrl->SetSelection( 0 );
else
m_DrillShapeCtrl->SetSelection( 1 );
// Setup layers names from board
m_PadLayerCu->SetLabel( m_Board->GetLayerName( LAYER_N_BACK ) );
m_PadLayerCmp->SetLabel( m_Board->GetLayerName( LAYER_N_FRONT ) );
m_rbCopperLayersSel->SetString( 0, m_Board->GetLayerName( LAYER_N_FRONT ) );
m_rbCopperLayersSel->SetString( 1, m_Board->GetLayerName( LAYER_N_BACK ) );
m_PadLayerAdhCmp->SetLabel( m_Board->GetLayerName( ADHESIVE_N_FRONT ) );
m_PadLayerAdhCu->SetLabel( m_Board->GetLayerName( ADHESIVE_N_BACK ) );
......@@ -500,6 +513,13 @@ void DIALOG_PAD_PROPERTIES::PadTypeSelected( wxCommandEvent& event )
// Enable/disable drill dialog items:
event.SetId( m_DrillShapeCtrl->GetSelection() );
OnDrillShapeSelected( event );
// Enable/disable Pad name,and pad length die
// (disable for NPTH pads (mechanical pads)
bool enable = ii != 3;
m_PadNumCtrl->Enable( enable );
m_PadNetNameCtrl->Enable( enable );
m_LengthDieCtrl->Enable( enable );
}
......@@ -512,8 +532,14 @@ void DIALOG_PAD_PROPERTIES::SetPadLayersList( long layer_mask )
* @param layer_mask = pad layer mask (ORed layers bit mask)
*/
{
m_PadLayerCu->SetValue( ( layer_mask & LAYER_BACK ) );
m_PadLayerCmp->SetValue( ( layer_mask & LAYER_FRONT ) );
if( ( layer_mask & ALL_CU_LAYERS ) == LAYER_FRONT )
m_rbCopperLayersSel->SetSelection(0);
else if( ( layer_mask & ALL_CU_LAYERS ) == LAYER_BACK)
m_rbCopperLayersSel->SetSelection(1);
else if( ( layer_mask & ALL_CU_LAYERS ) != 0 )
m_rbCopperLayersSel->SetSelection(2);
else
m_rbCopperLayersSel->SetSelection(3);
m_PadLayerAdhCmp->SetValue( ( layer_mask & ADHESIVE_LAYER_FRONT ) );
m_PadLayerAdhCu->SetValue( ( layer_mask & ADHESIVE_LAYER_BACK ) );
......@@ -535,7 +561,7 @@ void DIALOG_PAD_PROPERTIES::SetPadLayersList( long layer_mask )
// Called when select/deselect a layer.
void DIALOG_PAD_PROPERTIES::OnSetLayer( wxCommandEvent& event )
void DIALOG_PAD_PROPERTIES::OnSetLayers( wxCommandEvent& event )
{
TransfertDataToPad( m_dummyPad );
m_panelShowPad->Refresh();
......@@ -592,6 +618,9 @@ void DIALOG_PAD_PROPERTIES::PadPropertiesAccept( wxCommandEvent& event )
m_CurrentPad->m_DrillShape = g_Pad_Master.m_DrillShape;
m_CurrentPad->m_Offset = g_Pad_Master.m_Offset;
m_CurrentPad->m_Offset.y *= isign;
m_CurrentPad->m_LengthDie = g_Pad_Master.m_LengthDie;
if( m_CurrentPad->m_Masque_Layer != g_Pad_Master.m_Masque_Layer )
{
rastnestIsChanged = true;
......@@ -645,7 +674,9 @@ void DIALOG_PAD_PROPERTIES::PadPropertiesAccept( wxCommandEvent& event )
m_Parent->GetBoard()->m_Status_Pcb = 0;
}
// Copy values from dialog to aPad parameters.
// If aPromptOnError is true, and an incorrect value is detected,
// user will be prompted for an error
bool DIALOG_PAD_PROPERTIES::TransfertDataToPad( D_PAD* aPad, bool aPromptOnError )
{
long PadLayerMask;
......@@ -704,6 +735,9 @@ bool DIALOG_PAD_PROPERTIES::TransfertDataToPad( D_PAD* aPad, bool aPromptOnError
delta.y = ReturnValueFromTextCtrl( *m_ShapeDelta_Ctrl, internalUnits );
aPad->m_DeltaSize = delta;
// Read pad lenght die
aPad->m_LengthDie = ReturnValueFromTextCtrl( *m_LengthDieCtrl, internalUnits );
// Test bad values (be sure delta values are not to large)
// remember DeltaSize.x is the Y size variation
bool error = false;
......@@ -774,20 +808,37 @@ bool DIALOG_PAD_PROPERTIES::TransfertDataToPad( D_PAD* aPad, bool aPromptOnError
break;
case PAD_HOLE_NOT_PLATED:
// Mechanical purpose only:
// no offset, no net name, no pad name allowed
aPad->m_Offset = wxSize( 0, 0 );
aPad->SetPadName( wxEmptyString );
aPad->SetNetname( wxEmptyString );
break;
default:
DisplayError( this, wxT( "Error: unknown pad type" ) );
DisplayError( NULL, wxT( "Error: unknown pad type" ) );
break;
}
PadLayerMask = 0;
if( m_PadLayerCu->GetValue() )
PadLayerMask |= LAYER_BACK;
if( m_PadLayerCmp->GetValue() )
PadLayerMask |= LAYER_FRONT;
if( ( PadLayerMask & (LAYER_BACK | LAYER_FRONT) ) == (LAYER_BACK | LAYER_FRONT) )
PadLayerMask |= ALL_CU_LAYERS;
switch( m_rbCopperLayersSel->GetSelection() )
{
case 0:
PadLayerMask |= LAYER_FRONT;
break;
case 1:
PadLayerMask |= LAYER_BACK;
break;
case 2:
PadLayerMask |= ALL_CU_LAYERS;
break;
case 3: // No copper layers
break;
}
if( m_PadLayerAdhCmp->GetValue() )
PadLayerMask |= ADHESIVE_LAYER_FRONT;
if( m_PadLayerAdhCu->GetValue() )
......@@ -819,7 +870,7 @@ bool DIALOG_PAD_PROPERTIES::TransfertDataToPad( D_PAD* aPad, bool aPromptOnError
if( (aPad->m_Size.x < aPad->m_Drill.x)
|| (aPad->m_Size.y < aPad->m_Drill.y) )
{
DisplayError( this, _( "Incorrect value for pad drill: pad drill bigger than pad size" ) );
DisplayError( NULL, _( "Incorrect value for pad drill: pad drill bigger than pad size" ) );
return false;
}
......@@ -828,7 +879,14 @@ bool DIALOG_PAD_PROPERTIES::TransfertDataToPad( D_PAD* aPad, bool aPromptOnError
{
if( aPad->m_Drill.x || aPad->m_Drill.y )
{
DisplayError( this, _( "Error: pad is not on a copper layer and has a hole" ) );
msg = _( "Error: pad is not on a copper layer and has a hole" );
if( aPad->m_Attribut == PAD_HOLE_NOT_PLATED )
{
msg += wxT("\n");
msg += _( "For NPTH pad, set pad drill value to pad size value,\n\
if you do not want this pad plotted in gerber files");
}
DisplayError( NULL, msg );
return false;
}
}
......@@ -836,13 +894,13 @@ bool DIALOG_PAD_PROPERTIES::TransfertDataToPad( D_PAD* aPad, bool aPromptOnError
if( ( aPad->m_Size.x / 2 <= ABS( aPad->m_Offset.x ) )
|| ( aPad->m_Size.y / 2 <= ABS( aPad->m_Offset.y ) ) )
{
DisplayError( this, _( "Incorrect value for pad offset" ) );
DisplayError( NULL, _( "Incorrect value for pad offset" ) );
return false;
}
if( error )
{
DisplayError( this, _( "Too large value for pad delta size" ) );
DisplayError( NULL, _( "Too large value for pad delta size" ) );
return false;
}
}
......
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Sep 8 2010)
// C++ code generated with wxFormBuilder (version Jun 30 2011)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __dialog_pad_properties_base__
#define __dialog_pad_properties_base__
#ifndef __DIALOG_PAD_PROPERTIES_BASE_H__
#define __DIALOG_PAD_PROPERTIES_BASE_H__
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include <wx/string.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
......@@ -91,6 +92,12 @@ class DIALOG_PAD_PROPERTIES_BASE : public wxDialog
wxRadioButton* m_radioBtnDeltaXdir;
wxRadioButton* m_radioBtnDeltaYdir;
wxStaticText* m_staticTextDDirInfo;
wxStaticLine* m_staticline10;
wxStaticLine* m_staticline101;
wxStaticLine* m_staticline1011;
wxStaticText* m_staticText38;
wxTextCtrl* m_LengthDieCtrl;
wxStaticText* m_PadLengthDie_Unit;
wxBoxSizer* m_DrillShapeBoxSizer;
wxRadioBox* m_PadShape;
wxRadioBox* m_DrillShapeCtrl;
......@@ -120,9 +127,7 @@ class DIALOG_PAD_PROPERTIES_BASE : public wxDialog
wxTextCtrl* m_SolderPasteMarginRatioCtrl;
wxStaticText* m_SolderPasteRatioMarginUnits;
wxRadioBox* m_PadType;
wxCheckBox* m_PadLayerCmp;
wxCheckBox* m_PadLayerCu;
wxRadioBox* m_rbCopperLayersSel;
wxCheckBox* m_PadLayerAdhCmp;
wxCheckBox* m_PadLayerAdhCu;
wxCheckBox* m_PadLayerPateCmp;
......@@ -145,16 +150,16 @@ class DIALOG_PAD_PROPERTIES_BASE : public wxDialog
virtual void PadOrientEvent( wxCommandEvent& event ) { event.Skip(); }
virtual void OnPaintShowPanel( wxPaintEvent& event ) { event.Skip(); }
virtual void PadTypeSelected( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSetLayer( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSetLayers( wxCommandEvent& event ) { event.Skip(); }
virtual void OnCancelButtonClick( wxCommandEvent& event ) { event.Skip(); }
virtual void PadPropertiesAccept( wxCommandEvent& event ) { event.Skip(); }
public:
DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_DIALOG_EDIT_PAD, const wxString& title = _("Pad Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 733,486 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSUNKEN_BORDER );
DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_DIALOG_EDIT_PAD, const wxString& title = _("Pad Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 733,535 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSUNKEN_BORDER );
~DIALOG_PAD_PROPERTIES_BASE();
};
#endif //__dialog_pad_properties_base__
#endif //__DIALOG_PAD_PROPERTIES_BASE_H__
......@@ -266,8 +266,7 @@ void Gen_Drill_PcbMap( BOARD* aPcb, PLOTTER* aPlotter,
// Plot the drill map:
for( unsigned ii = 0; ii < aHoleListBuffer.size(); ii++ )
{
pos.x = aHoleListBuffer[ii].m_Hole_Pos_X;
pos.y = aHoleListBuffer[ii].m_Hole_Pos_Y;
pos = aHoleListBuffer[ii].m_Hole_Pos;
/* Always plot the drill symbol (for slots identifies the needed
* cutter!) */
......@@ -276,8 +275,7 @@ void Gen_Drill_PcbMap( BOARD* aPcb, PLOTTER* aPlotter,
if( aHoleListBuffer[ii].m_Hole_Shape != 0 )
{
wxSize oblong_size;
oblong_size.x = aHoleListBuffer[ii].m_Hole_SizeX;
oblong_size.y = aHoleListBuffer[ii].m_Hole_SizeY;
oblong_size = aHoleListBuffer[ii].m_Hole_Size;
aPlotter->flash_pad_oval( pos, oblong_size,
aHoleListBuffer[ii].m_Hole_Orient, FILAIRE );
}
......@@ -299,6 +297,7 @@ void GenDrillReportFile( FILE* aFile, BOARD* aPcb,
int layer1 = LAYER_N_BACK;
int layer2 = LAYER_N_FRONT;
bool gen_through_holes = true;
bool gen_NPTH_holes = false;
fprintf( aFile, "Drill report for %s\n", TO_UTF8( aBoardFilename ) );
......@@ -314,6 +313,7 @@ void GenDrillReportFile( FILE* aFile, BOARD* aPcb,
/* build hole lists:
* 1 - through holes
* 2 - for partial holes only: by layer pair
* 3 - Not Plated through holes
*/
for( ; ; )
......@@ -323,11 +323,16 @@ void GenDrillReportFile( FILE* aFile, BOARD* aPcb,
aToolListBuffer,
layer1,
layer2,
gen_through_holes ? false : true );
gen_through_holes ? false : true, gen_NPTH_holes );
TotalHoleCount = 0;
if( gen_through_holes )
if( gen_NPTH_holes )
{
sprintf( line, "Drill report for Not Plated through holes :\n" );
}
else if( gen_through_holes )
{
sprintf( line, "Drill report for through holes :\n" );
}
......@@ -384,25 +389,41 @@ void GenDrillReportFile( FILE* aFile, BOARD* aPcb,
TotalHoleCount += aToolListBuffer[ii].m_TotalCount;
}
sprintf( line, "\ntotal holes count %d\n\n\n", TotalHoleCount );
if( gen_NPTH_holes )
sprintf( line, "\ntotal Not Plated holes count %d\n\n\n", TotalHoleCount );
else
sprintf( line, "\ntotal plated holes count %d\n\n\n", TotalHoleCount );
fputs( line, aFile );
if( aPcb->GetCopperLayerCount() <= 2 )
if( gen_NPTH_holes )
{
break;
if( gen_through_holes )
layer2 = layer1 + 1;
}
else
{
if( layer2 >= LAYER_N_FRONT ) // no more layer pair to consider
break;
layer1++; layer2++; // use next layer pair
if( aPcb->GetCopperLayerCount() <= 2 )
{
gen_NPTH_holes = true;
continue;
}
if( layer2 == aPcb->GetCopperLayerCount() - 1 )
layer2 = LAYER_N_FRONT; // the last layer is always the
// component layer
if( gen_through_holes )
layer2 = layer1 + 1;
else
{
if( layer2 >= LAYER_N_FRONT ) // no more layer pair to consider
{
gen_NPTH_holes = true;
continue;
}
layer1++; layer2++; // use next layer pair
if( layer2 == aPcb->GetCopperLayerCount() - 1 )
layer2 = LAYER_N_FRONT; // the last layer is always the
// component layer
}
gen_through_holes = false;
}
gen_through_holes = false;
}
fclose( aFile );
......
......@@ -24,28 +24,32 @@ static bool CmpHoleDiameterValue( const HOLE_INFO& a, const HOLE_INFO& b )
{
if( a.m_Hole_Diameter != b.m_Hole_Diameter )
return a.m_Hole_Diameter < b.m_Hole_Diameter;
if( a.m_Hole_Pos_X != b.m_Hole_Pos_X )
return a.m_Hole_Pos_X < b.m_Hole_Pos_X;
return a.m_Hole_Pos_Y < b.m_Hole_Pos_Y;
if( a.m_Hole_Pos.x != b.m_Hole_Pos.x )
return a.m_Hole_Pos.x < b.m_Hole_Pos.x;
return a.m_Hole_Pos.y < b.m_Hole_Pos.y;
}
/**
/*
* Function BuildHolesList
* Create the list of holes and tools for a given board
* The list is sorted by increasing drill values
* Only holes from aFirstLayer to aLastLayer copper layers are listed (for vias, because pad holes are always through holes)
* @param aPcb : the given board
* @param aHoleListBuffer : the std::vector<HOLE_INFO> to fill with pcb holes info
* @param aToolListBuffer : the std::vector<DRILL_TOOL> to fill with tools to use
* @param aFirstLayer = first layer to consider. if < 0 aFirstLayer is ignored (used to creates report file)
* @param aLastLayer = last layer to consider. if < 0 aLastLayer is ignored
* @param aExcludeThroughHoles : if true, exclude through holes ( pads and vias through )
* param aPcb : the given board
* param aHoleListBuffer : the std::vector<HOLE_INFO> to fill with pcb holes info
* param aToolListBuffer : the std::vector<DRILL_TOOL> to fill with tools to use
* param aFirstLayer = first layer to consider. if < 0 aFirstLayer is ignored (used to creates report file)
* param aLastLayer = last layer to consider. if < 0 aLastLayer is ignored
* param aExcludeThroughHoles : if true, exclude through holes ( pads and vias through )
* param aGenerateNPTH_list :
* true to create NPTH only list (with no plated holes)
* false to created plated holes list (with no NPTH )
*/
void Build_Holes_List( BOARD* aPcb,
std::vector<HOLE_INFO>& aHoleListBuffer,
std::vector<DRILL_TOOL>& aToolListBuffer,
int aFirstLayer, int aLastLayer, bool aExcludeThroughHoles )
int aFirstLayer, int aLastLayer, bool aExcludeThroughHoles,
bool aGenerateNPTH_list )
{
HOLE_INFO new_hole;
int hole_value;
......@@ -59,40 +63,43 @@ void Build_Holes_List( BOARD* aPcb,
EXCHG( aFirstLayer, aLastLayer );
}
/* build hole list for vias */
TRACK* track = aPcb->m_Track;
for( ; track != NULL; track = track->Next() )
/* build hole list for vias
*/
if( ! aGenerateNPTH_list ) // vias are always plated !
{
if( track->Type() != TYPE_VIA )
continue;
SEGVIA* via = (SEGVIA*) track;
hole_value = via->GetDrillValue();
if( hole_value == 0 )
continue;
new_hole.m_Tool_Reference = -1; // Flag value for Not initialized
new_hole.m_Hole_Orient = 0;
new_hole.m_Hole_Diameter = hole_value;
new_hole.m_Hole_SizeX = new_hole.m_Hole_SizeY = new_hole.m_Hole_Diameter;
new_hole.m_Hole_Shape = 0; // hole shape: round
new_hole.m_Hole_Pos_X = via->m_Start.x;
new_hole.m_Hole_Pos_Y = via->m_Start.y; // hole position
via->ReturnLayerPair( &new_hole.m_Hole_Top_Layer, &new_hole.m_Hole_Bottom_Layer );
// ReturnLayerPair return params with m_Hole_Bottom_Layer < m_Hole_Top_Layer
if( (new_hole.m_Hole_Bottom_Layer > aFirstLayer) && (aFirstLayer >= 0) )
continue;
if( (new_hole.m_Hole_Top_Layer < aLastLayer) && (aLastLayer >= 0) )
continue;
if( aExcludeThroughHoles && (new_hole.m_Hole_Bottom_Layer == LAYER_N_BACK)
&& (new_hole.m_Hole_Top_Layer == LAYER_N_FRONT) )
continue;
aHoleListBuffer.push_back( new_hole );
TRACK* track = aPcb->m_Track;
for( ; track != NULL; track = track->Next() )
{
if( track->Type() != TYPE_VIA )
continue;
SEGVIA* via = (SEGVIA*) track;
hole_value = via->GetDrillValue();
if( hole_value == 0 )
continue;
new_hole.m_Tool_Reference = -1; // Flag value for Not initialized
new_hole.m_Hole_Orient = 0;
new_hole.m_Hole_Diameter = hole_value;
new_hole.m_Hole_Size.x = new_hole.m_Hole_Size.y = new_hole.m_Hole_Diameter;
new_hole.m_Hole_Shape = 0; // hole shape: round
new_hole.m_Hole_Pos = via->m_Start;
via->ReturnLayerPair( &new_hole.m_Hole_Top_Layer, &new_hole.m_Hole_Bottom_Layer );
// ReturnLayerPair return params with m_Hole_Bottom_Layer < m_Hole_Top_Layer
if( (new_hole.m_Hole_Bottom_Layer > aFirstLayer) && (aFirstLayer >= 0) )
continue;
if( (new_hole.m_Hole_Top_Layer < aLastLayer) && (aLastLayer >= 0) )
continue;
if( aExcludeThroughHoles && (new_hole.m_Hole_Bottom_Layer == LAYER_N_BACK)
&& (new_hole.m_Hole_Top_Layer == LAYER_N_FRONT) )
continue;
aHoleListBuffer.push_back( new_hole );
}
}
/* build hole list for pads (assumed always through holes) */
if( !aExcludeThroughHoles )
if( !aExcludeThroughHoles || aGenerateNPTH_list )
{
MODULE* Module = aPcb->m_Modules;
for( ; Module != NULL; Module = Module->Next() )
......@@ -101,21 +108,24 @@ void Build_Holes_List( BOARD* aPcb,
D_PAD* pad = Module->m_Pads;
for( ; pad != NULL; pad = pad->Next() )
{
if( ! aGenerateNPTH_list && pad->m_Attribut == PAD_HOLE_NOT_PLATED )
continue;
if( aGenerateNPTH_list && pad->m_Attribut != PAD_HOLE_NOT_PLATED )
continue;
if( pad->m_Drill.x == 0 )
continue;
new_hole.m_Hole_NotPlated = (pad->m_Attribut == PAD_HOLE_NOT_PLATED);
new_hole.m_Tool_Reference = -1; // Flag is: Not initialized
new_hole.m_Hole_Orient = pad->m_Orient;
new_hole.m_Hole_Shape = 0; // hole shape: round
new_hole.m_Hole_Diameter = min( pad->m_Drill.x, pad->m_Drill.y );
new_hole.m_Hole_SizeX = new_hole.m_Hole_SizeY = new_hole.m_Hole_Diameter;
new_hole.m_Hole_Size.x = new_hole.m_Hole_Size.y = new_hole.m_Hole_Diameter;
if( pad->m_DrillShape != PAD_CIRCLE )
new_hole.m_Hole_Shape = 1; // oval flag set
new_hole.m_Hole_SizeX = pad->m_Drill.x;
new_hole.m_Hole_SizeY = pad->m_Drill.y;
new_hole.m_Hole_Pos_X = pad->m_Pos.x;
new_hole.m_Hole_Pos_Y = pad->m_Pos.y; // hole position
new_hole.m_Hole_Size = pad->m_Drill;
new_hole.m_Hole_Pos = pad->m_Pos; // hole position
new_hole.m_Hole_Bottom_Layer = LAYER_N_BACK;
new_hole.m_Hole_Top_Layer = LAYER_N_FRONT; // pad holes are through holes
new_hole.m_Hole_Top_Layer = LAYER_N_FRONT;// pad holes are through holes
aHoleListBuffer.push_back( new_hole );
}
}
......
This diff is collapsed.
......@@ -44,20 +44,30 @@ public: DRILL_TOOL( int diametre )
};
/* the HOLE_INFO class handle hole which must be drilled (diameter, position and layers) */
/* the HOLE_INFO class handle hole which must be drilled (diameter, position and layers)
* For buried or micro vias, the hole is not on all layers.
* So we must generate a drill file for each layer pair (adjacent layers)
* Not plated holes are always through holes, and must be output on a specific drill file
* because they are drilled after the Pcb process is finished.
*/
class HOLE_INFO
{
public:
int m_Hole_Diameter; // hole value, and for oblong min(hole size x, hole size y)
int m_Hole_Diameter; // hole value, and for oblong: min(hole size x, hole size y)
int m_Tool_Reference; // Tool reference for this hole = 1 ... n (values <=0 must not be used)
int m_Hole_SizeX; // hole size x for oblong holes
int m_Hole_SizeY; // hole size y for oblong holes
wxSize m_Hole_Size; // hole size for oblong holes
int m_Hole_Orient; // Hole rotation (= pad rotation) for oblong holes
int m_Hole_Shape; // hole shape: round (0) or oval (1)
int m_Hole_Pos_X; // hole position X
int m_Hole_Pos_Y; // hole position Y
int m_Hole_Bottom_Layer; // hole starting layer (usually copper)
int m_Hole_Top_Layer; // hole ending layer (usually component): m_Hole_First_Layer < m_Hole_Last_Layer
wxPoint m_Hole_Pos; // hole position
int m_Hole_Bottom_Layer; // hole starting layer (usually back layer)
int m_Hole_Top_Layer; // hole ending layer (usually front layer):
// m_Hole_First_Layer < m_Hole_Last_Layer
bool m_Hole_NotPlated; // hole not plated. Must be in a specific drill file
public:
HOLE_INFO()
{
m_Hole_NotPlated = false;
}
};
......@@ -184,12 +194,14 @@ private:
* @param aToolListBuffer : the std::vector<DRILL_TOOL> to fill with tools to use
* @param aFirstLayer = first layer to consider. if < 0 aFirstLayer is ignored
* @param aLastLayer = last layer to consider. if < 0 aLastLayer is ignored
* @param aExcludeThroughHoles : if true, exclude through holes ( pads and vias through )
* @param aGenerateNPTH_list :
* true to create NPTH only list (with no plated holes)
* false to created plated holes list (with no NPTH )
*/
void Build_Holes_List( BOARD* aPcb, std::vector<HOLE_INFO>& aHoleListBuffer,
std::vector<DRILL_TOOL>& aToolListBuffer,
int aFirstLayer, int aLastLayer, bool aExcludeThroughHoles );
int aFirstLayer, int aLastLayer, bool aExcludeThroughHoles,
bool aGenerateNPTH_list );
void GenDrillMapFile( BOARD* aPcb,
FILE* aFile,
......
......@@ -169,8 +169,9 @@ private:
/**
* Function loadNewModules
* Load from libraries new modules found in netlist and add them to the current Board.
* @return false if a footprint is not found, true if all footprints are loaded
*/
void loadNewModules();
bool loadNewModules();
/**
* function readModuleComponentLinkfile
......@@ -417,7 +418,9 @@ bool NETLIST_READER::ReadNetList( FILE* aFile,
}
/* Load new footprints */
loadNewModules();
bool success = loadNewModules();
if( ! success )
wxMessageBox( _("Some footprints are not found in libraries") );
/* Second read , All footprints are on board.
* One must update the schematic info (pad netnames)
......@@ -1042,16 +1045,18 @@ bool NETLIST_READER::readModuleComponentLinkfile( const wxString* aCmpIdent,
/* Load new modules from library.
* If a new module is already loaded it is duplicated, which avoids multiple
* unnecessary disk or net access to read libraries.
* return false if a footprint is not found, true if OK
*/
void NETLIST_READER::loadNewModules()
bool NETLIST_READER::loadNewModules()
{
MODULE_INFO* ref, * cmp;
MODULE* Module = NULL;
wxPoint ModuleBestPosition;
BOARD* pcb = m_pcbframe->GetBoard();
bool success = true;
if( m_newModulesList.size() == 0 )
return;
return true;
sort( m_newModulesList.begin(), m_newModulesList.end(), SortByLibName );
......@@ -1075,11 +1080,18 @@ void NETLIST_READER::loadNewModules()
ref = cmp;
if( Module == NULL )
{
success = false;
wxString msg;
msg.Printf( _( "Component [%s]: footprint <%s> not found" ),
GetChars( cmp->m_CmpName ),
GetChars( cmp->m_LibName ) );
DisplayError( NULL, msg );
if( m_messageWindow )
{
msg += wxT("\n");
m_messageWindow->AppendText( msg );
}
else
DisplayError( NULL, msg );
continue;
}
Module->SetPosition( ModuleBestPosition );
......@@ -1108,4 +1120,6 @@ void NETLIST_READER::loadNewModules()
Module->m_Path = cmp->m_TimeStampPath;
}
}
return success;
}
......@@ -74,6 +74,7 @@ PCB_PLOT_PARAMS::PCB_PLOT_PARAMS()
layerSelection = LAYER_BACK | LAYER_FRONT
| SILKSCREEN_LAYER_FRONT | SILKSCREEN_LAYER_BACK;
useGerberExtensions = true;
m_SkipNPTH_Pads = false;
m_ExcludeEdgeLayer = true;
m_PlotLineWidth = g_DrawDefaultLineThickness;
m_PlotFrameRef = false;
......
......@@ -59,6 +59,8 @@ public:
bool m_PlotPSNegative; // True to create a negative board ps plot
// Flags to enable or disable ploting of various PCB elements.
bool m_SkipNPTH_Pads; // true to disable plot NPTH pads if hole and size have same value
// GERBER only
bool m_PlotReference;
bool m_PlotValue;
bool m_PlotTextOther;
......
......@@ -681,7 +681,8 @@ void PCB_BASE_FRAME::Plot_Layer( PLOTTER* plotter, int Layer, GRTraceMode trace_
case LAYER_N_14:
case LAYER_N_15:
case LAST_COPPER_LAYER:
Plot_Standard_Layer( plotter, layer_mask, true, trace_mode );
Plot_Standard_Layer( plotter, layer_mask, true, trace_mode,
g_PcbPlotOptions.m_SkipNPTH_Pads );
// Adding drill marks, if required and if the plotter is able to plot
// them:
......@@ -736,9 +737,10 @@ void PCB_BASE_FRAME::Plot_Layer( PLOTTER* plotter, int Layer, GRTraceMode trace_
* HPGL unit = 0.98 mils (1 mil = 1.02041 unit HPGL).
*/
void PCB_BASE_FRAME::Plot_Standard_Layer( PLOTTER* aPlotter,
int aLayerMask,
bool aPlotVia,
GRTraceMode aPlotMode )
int aLayerMask,
bool aPlotVia,
GRTraceMode aPlotMode,
bool aSkipNPTH_Pads )
{
wxPoint pos;
wxSize size;
......@@ -772,8 +774,7 @@ void PCB_BASE_FRAME::Plot_Standard_Layer( PLOTTER* aPlotter,
break;
default:
DisplayError( this,
wxT( "Plot_Standard_Layer() error : Unexpected Draw Type" ) );
wxMessageBox( wxT( "Plot_Standard_Layer() error : Unexpected Draw Type" ) );
break;
}
}
......@@ -838,10 +839,18 @@ void PCB_BASE_FRAME::Plot_Standard_Layer( PLOTTER* aPlotter,
switch( pad->m_PadShape )
{
case PAD_CIRCLE:
if( aSkipNPTH_Pads &&
(pad->m_Size == pad->m_Drill) &&
(pad->m_Attribut == PAD_HOLE_NOT_PLATED) )
break;
aPlotter->flash_pad_circle( pos, size.x, aPlotMode );
break;
case PAD_OVAL:
if( aSkipNPTH_Pads &&
(pad->m_Size == pad->m_Drill) &&
(pad->m_Attribut == PAD_HOLE_NOT_PLATED) )
break;
aPlotter->flash_pad_oval( pos, size, pad->m_Orient, aPlotMode );
break;
......
......@@ -61,12 +61,18 @@ bool PCB_BASE_FRAME::Genere_GERBER( const wxString& FullFileName, int Layer,
if( plotter->start_plot( output_file ) )
{
// Skip NPTH pads on copper layers
// ( only if hole size == pad size ):
if( (Layer >= LAYER_N_BACK) && (Layer <= LAYER_N_FRONT) )
g_PcbPlotOptions.m_SkipNPTH_Pads = true;
// Sheet refs on gerber CAN be useful... and they're always 1:1
if( g_PcbPlotOptions.m_PlotFrameRef )
PlotWorkSheet( plotter, GetScreen() );
Plot_Layer( plotter, Layer, trace_mode );
plotter->end_plot();
g_PcbPlotOptions.m_SkipNPTH_Pads = false;
}
else // error in start_plot( ): failed opening a temporary file
......
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