Commit 7d676fbf authored by CHARRAS's avatar CHARRAS

support for micro vias. small problem in zone detection solved

parent 1d683046
...@@ -5,6 +5,22 @@ Please add newer entries at the top, list the date and your name with ...@@ -5,6 +5,22 @@ Please add newer entries at the top, list the date and your name with
email address. email address.
2007-Dec-18 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
+pcbnew:
rework of drill filles creation (excellon and reports)
needed to have a clean implantation of buried vias and mainly microvia
which involve a more complex drill files generation
This is better to continue work on zones because :
hight density boards = use of BGA = microvias + good zones handling
When a board has buried or blind vias (microvia are blind vias),
pcbnew creates a drill file per layer pair. for a 4 layer board:
drill file for layer1 to layer 2
drill file for layer2 to layer 3
drill file for layer3 to layer 4
2008-Jan-18 UPDATE Dick Hollenbeck <dick@softplc.com> 2008-Jan-18 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================ ================================================================================
how-to-build-kicad.txt: added the Boost C++ Libraries installation info how-to-build-kicad.txt: added the Boost C++ Libraries installation info
......
...@@ -323,7 +323,9 @@ void SEGVIA::SetLayerPair( int top_layer, int bottom_layer ) ...@@ -323,7 +323,9 @@ void SEGVIA::SetLayerPair( int top_layer, int bottom_layer )
void SEGVIA::ReturnLayerPair( int* top_layer, int* bottom_layer ) const void SEGVIA::ReturnLayerPair( int* top_layer, int* bottom_layer ) const
/*********************************************************************/ /*********************************************************************/
/* Return the 2 layers used by the via (the via actually uses /**
* Function ReturnLayerPair
* Return the 2 layers used by the via (the via actually uses
* all layers between these 2 layers) * all layers between these 2 layers)
* @param top_layer = pointer to the first layer (can be null) * @param top_layer = pointer to the first layer (can be null)
* @param bottom_layer = pointer to the last layer (can be null) * @param bottom_layer = pointer to the last layer (can be null)
......
...@@ -149,14 +149,13 @@ private: ...@@ -149,14 +149,13 @@ private:
void InitDisplayParams(void); void InitDisplayParams(void);
void SetParams(void); void SetParams(void);
void GenDrillFiles( wxCommandEvent& event ); void GenDrillFiles( wxCommandEvent& event );
void GenDrillMap( std::vector<DRILL_TOOL> & buffer, int format ); void GenDrillMap( const wxString aFileName, std::vector<HOLE_INFO> & aHoleListBuffer, std::vector<DRILL_TOOL> & aToolListBuffer, int format );
void UpdatePrecisionOptions( wxCommandEvent& event ); void UpdatePrecisionOptions( wxCommandEvent& event );
void UpdateConfig(); void UpdateConfig();
int Plot_Drill_PcbMap( std::vector<DRILL_TOOL> & buffer, int format ); void Write_Excellon_Header( FILE * aFile);
void GenDrillReport( std::vector<DRILL_TOOL> & buffer ); void GenDrillReport( const wxString aFileName, std::vector<DRILL_TOOL> & buffer );
int Gen_Liste_Forets( std::vector<DRILL_TOOL> & buffer, bool print_header ); int Create_Drill_File_EXCELLON( std::vector<HOLE_INFO> & aHoleListBuffer,
int Create_Drill_File_EXCELLON( std::vector<DRILL_TOOL> & buffer ); std::vector<DRILL_TOOL> & aToolListBuffer );
void Init_Drill();
int Gen_Liste_Tools( std::vector<DRILL_TOOL> & buffer, bool print_header ); int Gen_Liste_Tools( std::vector<DRILL_TOOL> & buffer, bool print_header );
}; };
......
...@@ -297,12 +297,6 @@ void WinEDA_PcbTracksDialog::AcceptPcbOptions(wxCommandEvent& event) ...@@ -297,12 +297,6 @@ void WinEDA_PcbTracksDialog::AcceptPcbOptions(wxCommandEvent& event)
g_DesignSettings.m_CurrentViaType = VIA_THROUGH; g_DesignSettings.m_CurrentViaType = VIA_THROUGH;
if ( m_OptViaType->GetSelection() > 0 ) if ( m_OptViaType->GetSelection() > 0 )
g_DesignSettings.m_CurrentViaType = VIA_BLIND_BURIED; g_DesignSettings.m_CurrentViaType = VIA_BLIND_BURIED;
if ( g_DesignSettings.m_CurrentViaType != VIA_THROUGH )
{
if( ! IsOK(this,
_("You have selected VIA Blind and Buried\nWARNING: this feature is EXPERIMENTAL!!! Accept ?") ) )
g_DesignSettings.m_CurrentViaType = VIA_THROUGH;
}
g_DesignSettings.m_CurrentViaSize = g_DesignSettings.m_CurrentViaSize =
ReturnValueFromTextCtrl(*m_OptViaSize, m_Parent->m_InternalUnits); ReturnValueFromTextCtrl(*m_OptViaSize, m_Parent->m_InternalUnits);
......
This diff is collapsed.
/*************************************************************************/
/* Functions to create drill data used to create files and report files */
/*************************************************************************/
#include "fctsys.h"
using namespace std;
#include <vector>
#include "common.h"
#include "plot_common.h"
#include "pcbnew.h"
#include "pcbplot.h"
#include "macros.h"
#include "gendrill.h"
/* Local Functions */
/* Compare function used for sorting holes by increasing diameter value */
static bool CmpHoleDiameterValue( const HOLE_INFO& a, const HOLE_INFO& b )
{
return a.m_Hole_Diameter < b.m_Hole_Diameter;
}
/**
* Function BuildHolesList
* Create the list of holes and tools for a given board
* The list is sorted by incraesin drill values
* Only holes from aFirstLayer to aLastLayer copper layers are listed (for vias, because pad holes are always through holes)
* @param Pcb : 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
* @param aLastLayer = last layer to consider
*/
void Build_Holes_List( BOARD* aPcb,
std::vector<HOLE_INFO>& aHoleListBuffer,
std::vector<DRILL_TOOL>& aToolListBuffer,
int aFirstLayer, int aLastLayer )
{
HOLE_INFO new_hole;
int hole_value;
aHoleListBuffer.clear();
aToolListBuffer.clear();
if( aFirstLayer > aLastLayer )
EXCHG( aFirstLayer, aLastLayer );
/* build hole list for vias */
TRACK* track = aPcb->m_Track;
for( ; track != NULL; track = track->Next() )
{
if( track->Type() != TYPEVIA )
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 )
continue;
if( new_hole.m_Hole_Top_Layer < aLastLayer )
continue;
aHoleListBuffer.push_back( new_hole );
}
/* build hole list for pads */
MODULE* Module = aPcb->m_Modules;
for( ; Module != NULL; Module = Module->Next() )
{
/* Read and analyse pads */
D_PAD* pad = Module->m_Pads;
for( ; pad != NULL; pad = pad->Next() )
{
if( pad->m_Drill.x == 0 )
continue;
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.x );
new_hole.m_Hole_SizeX = new_hole.m_Hole_SizeY = 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_Bottom_Layer = COPPER_LAYER_N;
new_hole.m_Hole_Top_Layer = LAYER_CMP_N; // pad holes are through holes
aHoleListBuffer.push_back( new_hole );
}
}
// Sort holes per increasing diameter value
sort( aHoleListBuffer.begin(), aHoleListBuffer.end(), CmpHoleDiameterValue );
// build the tool list
int LastHole = -1; /* Set to not initialised
* (this is a value not used for aHoleListBuffer[ii].m_Hole_Diameter) */
DRILL_TOOL new_tool( 0 );
unsigned jj;
for( unsigned ii = 0; ii < aHoleListBuffer.size(); ii++ )
{
if( aHoleListBuffer[ii].m_Hole_Diameter != LastHole )
{
new_tool.m_Diameter = ( aHoleListBuffer[ii].m_Hole_Diameter );
aToolListBuffer.push_back( new_tool );
LastHole = new_tool.m_Diameter;
}
jj = aToolListBuffer.size();
if( jj == 0 )
continue; // Should not occurs
aHoleListBuffer[ii].m_Tool_Reference = jj; // Tool value Initialized (value >= 1)
aToolListBuffer.back().m_TotalCount++;
if( aHoleListBuffer[ii].m_Hole_Shape )
aToolListBuffer.back().m_OvalCount++;
}
}
This diff is collapsed.
/*******************************************************************************/
/* classes and functions declaration unsed in drill file and report generation */
/*******************************************************************************/
#ifndef GENDRILL_H
#define GENDRILL_H
/* the DRILL_TOOL class handle tools used in the excellon drill file */
class DRILL_TOOL
{
public:
int m_Diameter; // the diameter of the used tool (for oblong, the smaller size)
int m_TotalCount; // how many times it is used (round and oblong)
int m_OvalCount; // oblong count
public:
DRILL_TOOL( int diametre )
{
m_TotalCount = 0;
m_OvalCount = 0;
m_Diameter = diametre;
}
};
/* the HOLE_INFO class handle hole which must be drilled (diameter, position and layers) */
class HOLE_INFO
{
public:
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
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
};
/* the DrillPrecision class to handle drill precision format in excellon files*/
class DrillPrecision
{
public:
int m_lhs;
int m_rhs;
public:
DrillPrecision( int l, int r ) { m_lhs = l; m_rhs = r; }
};
/* zeros format */
enum zeros_fmt {
DECIMAL_FORMAT,
SUPPRESS_LEADING,
SUPPRESS_TRAILING,
KEEP_ZEROS
};
/**
* Function BuildHolesList
* Create the list of holes and tools for a given board
* @param Pcb : the given board
* @param aHoleListBuffer : the std::vector<HOLE_INFO> to fill with pcb info
* @param aToolListBuffer : the std::vector<DRILL_TOOL> to fill with tools to use
*/
void Build_Holes_List( BOARD* Pcb, std::vector<HOLE_INFO>& aHoleListBuffer,
std::vector<DRILL_TOOL>& aToolListBuffer,
int aFirstLayer, int aLastLayer );
void GenDrillMapFile( BOARD* aPcb,
FILE* aFile,
const wxString& aFullFileName,
wxSize aSheetSize,
std::vector<HOLE_INFO> aHoleListBuffer,
std::vector<DRILL_TOOL> aToolListBuffer,
bool aUnit_Drill_is_Inch,
int format );
void Gen_Drill_PcbMap( BOARD* aPcb, FILE* aFile,
std::vector<HOLE_INFO>& aHoleListBuffer,
std::vector<DRILL_TOOL>& aToolListBuffer,
int format );
/*
* Create a list of drill values and drill count
*/
void GenDrillReportFile( FILE* aFile, const wxString& aBoardFilename,
std::vector<DRILL_TOOL>& aToolListBuffer, bool aUnit_Drill_is_Inch );
#endif // #ifndef GENDRILL_H
...@@ -88,6 +88,8 @@ OBJECTS= $(TARGET).o classpcb.o\ ...@@ -88,6 +88,8 @@ OBJECTS= $(TARGET).o classpcb.o\
librairi.o edgemod.o\ librairi.o edgemod.o\
connect.o muonde.o attribut.o\ connect.o muonde.o attribut.o\
gendrill.o\ gendrill.o\
gen_holes_and_tools_lists_for_drill.o\
gen_drill_report_files.o\
sel_layer.o \ sel_layer.o \
cotation.o\ cotation.o\
automove.o\ automove.o\
......
...@@ -657,14 +657,14 @@ void WinEDA_PcbFrame::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu ...@@ -657,14 +657,14 @@ void WinEDA_PcbFrame::createPopUpMenuForZones( ZONE_CONTAINER* edge_zone, wxMenu
ADD_MENUITEM_WITH_SUBMENU( aPopMenu, zones_menu, ADD_MENUITEM_WITH_SUBMENU( aPopMenu, zones_menu,
-1, _( "Zones" ), add_zone_xpm ); -1, _( "Zones" ), add_zone_xpm );
int index; int index;
if( ( index = edge_zone->HitTestForCorner( GetScreen()->m_Curseur ) ) >= 0 ) if( ( index = edge_zone->HitTestForCorner( GetScreen()->RefPos( true ) ) ) >= 0 )
{ {
ADD_MENUITEM( zones_menu, ID_POPUP_PCB_MOVE_ZONE_CORNER, ADD_MENUITEM( zones_menu, ID_POPUP_PCB_MOVE_ZONE_CORNER,
_( "Move Corner" ), move_xpm ); _( "Move Corner" ), move_xpm );
ADD_MENUITEM( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CORNER, ADD_MENUITEM( zones_menu, ID_POPUP_PCB_DELETE_ZONE_CORNER,
_( "Delete Corner" ), delete_xpm ); _( "Delete Corner" ), delete_xpm );
} }
else if( ( index = edge_zone->HitTestForEdge( GetScreen()->m_Curseur ) ) >= 0 ) else if( ( index = edge_zone->HitTestForEdge( GetScreen()->RefPos( true ) ) ) >= 0 )
{ {
ADD_MENUITEM( zones_menu, ID_POPUP_PCB_ADD_ZONE_CORNER, ADD_MENUITEM( zones_menu, ID_POPUP_PCB_ADD_ZONE_CORNER,
_( "Create Corner" ), Add_Corner_xpm ); _( "Create Corner" ), Add_Corner_xpm );
......
...@@ -611,6 +611,7 @@ WinEDAChoiceBox* WinEDA_PcbFrame::ReCreateLayerBox( WinEDA_Toolbar* parent ) ...@@ -611,6 +611,7 @@ WinEDAChoiceBox* WinEDA_PcbFrame::ReCreateLayerBox( WinEDA_Toolbar* parent )
/**************************************************************************/ /**************************************************************************/
{ {
int ii, jj, ll; int ii, jj, ll;
unsigned lenght = 0;
bool rebuild = FALSE; bool rebuild = FALSE;
long current_mask_layer; long current_mask_layer;
...@@ -679,10 +680,12 @@ WinEDAChoiceBox* WinEDA_PcbFrame::ReCreateLayerBox( WinEDA_Toolbar* parent ) ...@@ -679,10 +680,12 @@ WinEDAChoiceBox* WinEDA_PcbFrame::ReCreateLayerBox( WinEDA_Toolbar* parent )
msg = AddHotkeyName( msg, s_Board_Editor_Hokeys_Descr, HK_SwitchLayer[ii] ); msg = AddHotkeyName( msg, s_Board_Editor_Hokeys_Descr, HK_SwitchLayer[ii] );
m_SelLayerBox->Append( msg ); m_SelLayerBox->Append( msg );
m_SelLayerBox->SetClientData( jj, (void*) ii ); m_SelLayerBox->SetClientData( jj, (void*) ii );
lenght = max(lenght, msg.Len() );
jj++; jj++;
} }
} }
int lchar = m_SelLayerBox->GetFont().GetPointSize();
m_SelLayerBox->SetSize(wxSize(lenght * lchar,-1));
m_SelLayerBox->SetToolTip( _( "+/- to switch" ) ); m_SelLayerBox->SetToolTip( _( "+/- to switch" ) );
} }
......
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