Commit df29e89c authored by dickelbeck's avatar dickelbeck
Browse files

beginnings of aperture macro support

parent a2a02496
Loading
Loading
Loading
Loading
+62 −85
Original line number Diff line number Diff line
@@ -64,10 +64,10 @@
*/

/*********************************/
/* class GERBER_Descr : Methodes */
/* class GERBER : Methodes */
/*********************************/

GERBER_Descr::GERBER_Descr( int layer )
GERBER::GERBER( int layer )
{
    int ii;

@@ -79,7 +79,7 @@ GERBER_Descr::GERBER_Descr( int layer )
}


GERBER_Descr::~GERBER_Descr()
GERBER::~GERBER()
{
    int ii;

@@ -95,12 +95,9 @@ GERBER_Descr::~GERBER_Descr()


/******************************************/
void GERBER_Descr::ResetDefaultValues()
void GERBER::ResetDefaultValues()
/******************************************/
{
    m_Parent = NULL;
    m_Pback  = NULL;
    m_Pnext  = NULL;
    m_FileName.Empty();
    m_Name = wxT( "no name" );          // Layer name
    m_LayerNegative = FALSE;            // TRUE = Negative Layer
@@ -136,7 +133,7 @@ void GERBER_Descr::ResetDefaultValues()


/********************************************/
int GERBER_Descr::ReturnUsedDcodeNumber()
int GERBER::ReturnUsedDcodeNumber()
/********************************************/
{
    int ii, jj;
@@ -155,7 +152,7 @@ int GERBER_Descr::ReturnUsedDcodeNumber()


/******************************/
void GERBER_Descr::InitToolTable()
void GERBER::InitToolTable()
/******************************/

/* Creation du tableau des MAX_TOOLS DCodes utilisables, si il n'existe pas,
@@ -187,6 +184,7 @@ void GERBER_Descr::InitToolTable()
D_CODE::D_CODE( int num_dcode )
{
    m_Num_Dcode = num_dcode;
    m_Macro = 0;
    Clear_D_CODE_Data();
}

@@ -200,7 +198,7 @@ void D_CODE::Clear_D_CODE_Data()
{
    m_Size.x     = DEFAULT_SIZE;
    m_Size.y     = DEFAULT_SIZE;
    m_Shape      = GERB_CIRCLE;
    m_Shape      = APT_CIRCLE;
    m_Drill.x    = m_Drill.y = 0;
    m_DrillShape = 0;
    m_InUse   = FALSE;
@@ -211,44 +209,22 @@ void D_CODE::Clear_D_CODE_Data()
/******************************************************************************/
int WinEDA_GerberFrame::Read_D_Code_File( const wxString& D_Code_FullFileName )
/******************************************************************************/

/* Routine de Lecture d'un fichier de D Codes.
  * Accepte format standard ou ALSPCB
  *     un ';' demarre un commentaire.
 *
  * Format Standard:
  * tool,	 Horiz,		  Vert,	  drill, vitesse, acc. ,Type ; [DCODE (commentaire)]
  * ex:	   1,		  12,		12,		0,		  0,	 0,	  3 ; D10
 *
  * Format:
  * Ver  ,  Hor , Type , Tool [,Drill]
  * ex:	0.012, 0.012,  L   , D10
 *
  * Classe les caract en buf_tmp sous forme de tableau de structures D_CODE.
  * Retourne:
  *     < 0 si erreur:
  *         -1 = Fichier non trouve
  *         -2 = Erreur lecture fichier
  *     0 si pas de nom de fichier (inits seules)
  *     1 si OK
 */
{
    int      current_Dcode, ii, dcode_scale;
    char*    ptcar;
    int      dimH, dimV, drill, type_outil, dummy;
    int      dimH, dimV, drill, dummy;
    float    fdimH, fdimV, fdrill;
    char     c_type_outil[256];
    char     Line[2000];
    char     line[GERBER_BUFZ];
    wxString msg;
    D_CODE*  pt_Dcode;
    FILE*    dest;
    int      layer = GetScreen()->m_Active_Layer;
    D_CODE** ListeDCode;

    int      type_outil;

    if( g_GERBER_Descr_List[layer] == NULL )
    if( g_GERBER_List[layer] == NULL )
    {
        g_GERBER_Descr_List[layer] = new GERBER_Descr( layer );
        g_GERBER_List[layer] = new GERBER( layer );
    }

    /* Mise a jour de l'echelle gerber : */
@@ -260,7 +236,6 @@ int WinEDA_GerberFrame::Read_D_Code_File( const wxString& D_Code_FullFileName )
        return 0;

    dest = wxFopen( D_Code_FullFileName, wxT( "rt" ) );

    if( dest == 0 )
    {
        msg = _( "File " ) + D_Code_FullFileName + _( " not found" );
@@ -268,30 +243,31 @@ int WinEDA_GerberFrame::Read_D_Code_File( const wxString& D_Code_FullFileName )
        return -1;
    }

    g_GERBER_Descr_List[layer]->InitToolTable();

    ListeDCode = g_GERBER_Descr_List[layer]->m_Aperture_List;
    g_GERBER_List[layer]->InitToolTable();

    while( fgets( Line, sizeof(Line) - 1, dest ) != NULL )
    while( fgets( line, sizeof(line) - 1, dest ) != NULL )
    {
        if( *Line == ';' )
        if( *line == ';' )
            continue;                       /* Commentaire */
        if( strlen( Line ) < 10 )
        if( strlen( line ) < 10 )
            continue;                       /* Probablemant ligne vide */

        pt_Dcode = NULL; current_Dcode = 0;

        /* Determination du type de fichier D_Code */
        ptcar = Line; ii = 0;
        ptcar = line;
        ii = 0;
        while( *ptcar )
            if( *(ptcar++) == ',' )
                ii++;

        if( ii >= 6 )   /* valeurs en mils */
        {
            sscanf( Line, "%d,%d,%d,%d,%d,%d,%d", &ii,
            sscanf( line, "%d,%d,%d,%d,%d,%d,%d", &ii,
                &dimH, &dimV, &drill,
                &dummy, &dummy,
                &type_outil );

            dimH  = (int) ( (dimH * dcode_scale) + 0.5 );
            dimV  = (int) ( (dimV * dcode_scale) + 0.5 );
            drill = (int) ( (drill * dcode_scale) + 0.5 );
@@ -302,13 +278,14 @@ int WinEDA_GerberFrame::Read_D_Code_File( const wxString& D_Code_FullFileName )
        else        /* valeurs en inches a convertir en mils */
        {
            fdrill = 0; current_Dcode = 0; fdrill = 0;
            sscanf( Line, "%f,%f,%1s", &fdimV, &fdimH, c_type_outil );
            ptcar = Line;
            sscanf( line, "%f,%f,%1s", &fdimV, &fdimH, c_type_outil );
            ptcar = line;
            while( *ptcar )
            {
                if( *ptcar == 'D' )
                {
                    sscanf( ptcar + 1, "%d,%f", &current_Dcode, &fdrill ); break;
                    sscanf( ptcar + 1, "%d,%f", &current_Dcode, &fdrill );
                    break;
                }
                else
                    ptcar++;
@@ -317,29 +294,27 @@ int WinEDA_GerberFrame::Read_D_Code_File( const wxString& D_Code_FullFileName )
            dimH       = (int) ( (fdimH * dcode_scale * 1000) + 0.5 );
            dimV       = (int) ( (fdimV * dcode_scale * 1000) + 0.5 );
            drill      = (int) ( (fdrill * dcode_scale * 1000) + 0.5 );
            type_outil = -1;
            if( c_type_outil[0] == 'L' )
                type_outil = GERB_LINE;
            if( c_type_outil[0] == 'R' )
                type_outil = GERB_RECT;
            if( c_type_outil[0] == 'C' )
                type_outil = GERB_CIRCLE;
            if( c_type_outil[0] == 'O' )
                type_outil = GERB_OVALE;
            if( type_outil == -1 )

            if( strchr( "CLROP", c_type_outil[0] ) )
                type_outil = (APERTURE_T) c_type_outil[0];
            else
            {
                fclose( dest ); return -2;
                fclose( dest );
                return -2;
            }
        }

        /* Mise a jour de la liste des d_codes si valeurs lues coherentes*/
        if( current_Dcode < FIRST_DCODE )
            continue;

        if( current_Dcode >= MAX_TOOLS )
            continue;

        pt_Dcode = ReturnToolDescr( layer, current_Dcode );
        pt_Dcode->m_Size.x  = dimH;
        pt_Dcode->m_Size.y  = dimV;
        pt_Dcode->m_Shape   = type_outil;
        pt_Dcode->m_Shape   = (APERTURE_T) type_outil;
        pt_Dcode->m_Drill.x = pt_Dcode->m_Drill.y = drill;
        pt_Dcode->m_Defined = TRUE;
    }
@@ -392,12 +367,12 @@ void WinEDA_GerberFrame::CopyDCodesSizeToItems()

            switch( pt_Dcode->m_Shape )
            {
            case GERB_LINE:             // ne devrait pas etre utilis� ici
            case GERB_CIRCLE:           /* spot rond (for GERBER)*/
            case APT_LINE:          // ne devrait pas etre utilis� ici
            case APT_CIRCLE:        /* spot round (for GERBER)*/
                track->m_Shape = S_SPOT_CIRCLE;
                break;

            case GERB_OVALE:        /* spot ovale (for GERBER)*/
            case APT_OVAL:          /* spot oval (for GERBER)*/
                track->m_Shape = S_SPOT_OVALE;
                break;

@@ -425,19 +400,16 @@ void WinEDA_GerberFrame::CopyDCodesSizeToItems()
/*********************************************************/
D_CODE* ReturnToolDescr( int layer, int Dcode, int* index )
/*********************************************************/

/* Retourne un pointeur sur la description de l'outil DCode de reference Dcode
  * (rappel : Dcode >= 10)
 */
{
    GERBER_Descr* DcodeList = g_GERBER_Descr_List[layer];
    GERBER*     gerber = g_GERBER_List[layer];
    D_CODE*     pt_dcode  = NULL;

    if( index )
        *index = 0;
    if( DcodeList && Dcode >= FIRST_DCODE && Dcode < MAX_TOOLS )

    if( gerber && Dcode >= FIRST_DCODE && Dcode < MAX_TOOLS )
    {
        pt_dcode = DcodeList->m_Aperture_List[Dcode - FIRST_DCODE];
        pt_dcode = gerber->m_Aperture_List[Dcode - FIRST_DCODE];
        if( index )
            *index = Dcode - FIRST_DCODE + 1;
    }
@@ -456,18 +428,20 @@ void WinEDA_GerberFrame::Liste_D_Codes( wxDC* DC )
    int                 scale      = 10000;
    int                 curr_layer = GetScreen()->m_Active_Layer;
    int                 layer;
    GERBER_Descr*     DcodeList;
    GERBER*             gerber;

    /* Construction de la liste des messages */
    List = new WinEDA_TextFrame( this, _( "List D codes" ) );

    for( layer = 0; layer < 32; layer++ )
    {
        DcodeList = g_GERBER_Descr_List[layer];
        if( DcodeList == NULL )
        gerber = g_GERBER_List[layer];
        if( gerber == NULL )
            continue;
        if( DcodeList->ReturnUsedDcodeNumber() == 0 )

        if( gerber->ReturnUsedDcodeNumber() == 0 )
            continue;

        if( layer == curr_layer )
            Line.Printf( wxT( "*** Active layer (%2.2d) ***" ), layer + 1 );
        else
@@ -476,11 +450,13 @@ void WinEDA_GerberFrame::Liste_D_Codes( wxDC* DC )

        for( ii = 0, jj = 1; ii < MAX_TOOLS; ii++ )
        {
            pt_D_code = DcodeList->m_Aperture_List[ii];
            pt_D_code = gerber->m_Aperture_List[ii];
            if( pt_D_code == NULL )
                continue;

            if( !pt_D_code->m_InUse && !pt_D_code->m_Defined )
                continue;

            Line.Printf( wxT(
                    "tool %2.2d:   D%2.2d  V %2.4f  H %2.4f  %s" ),
                jj,
@@ -500,7 +476,8 @@ void WinEDA_GerberFrame::Liste_D_Codes( wxDC* DC )
        }
    }

    ii = List->ShowModal(); List->Destroy();
    ii = List->ShowModal();
    List->Destroy();
    if( ii < 0 )
        return;

+1 −1
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ void WinEDA_GerberFrame::Process_Special_Functions( wxCommandEvent& event )
{
    int           id    = event.GetId();
    int           layer = GetScreen()->m_Active_Layer;
    GERBER_Descr* gerber_layer = g_GERBER_Descr_List[layer];
    GERBER*       gerber_layer = g_GERBER_List[layer];
    wxPoint       pos;
    wxClientDC    dc( DrawPanel );

+10 −10
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ void WinEDA_GerberFrame::ExportDataInPcbnewFormat( wxCommandEvent& event )
    // Check whether any of the Gerber layers are actually currently used
    while( no_used_layers && ii < 32 )
    {
        if( g_GERBER_Descr_List[ii] != NULL )
        if( g_GERBER_List[ii] != NULL )
            no_used_layers = false;
        ii++;
    }
+4 −4
Original line number Diff line number Diff line
@@ -209,7 +209,7 @@ void WinEDA_GerberFrame::SetToolbars()
 */
{
    int           layer = ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer;
    GERBER_Descr* Gerber_layer_descr = g_GERBER_Descr_List[layer];
    GERBER*       gerber = g_GERBER_List[layer];

    if( m_HToolBar == NULL )
        return;
@@ -242,14 +242,14 @@ void WinEDA_GerberFrame::SetToolbars()
        m_SelLayerBox->SetSelection( ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer );
    }

    if( Gerber_layer_descr )
    if( gerber )
    {
        int sel_index;
        m_SelLayerTool->Enable( TRUE );
        if( Gerber_layer_descr->m_Selected_Tool < FIRST_DCODE )  // No tool selected
        if( gerber->m_Selected_Tool < FIRST_DCODE )  // No tool selected
            sel_index = 0;
        else
            sel_index = Gerber_layer_descr->m_Selected_Tool - FIRST_DCODE + 1;
            sel_index = gerber->m_Selected_Tool - FIRST_DCODE + 1;

        if( sel_index != m_SelLayerTool->GetSelection() )
        {
+176 −39
Original line number Diff line number Diff line
@@ -5,6 +5,10 @@
#ifndef GERBVIEW_H
#define GERBVIEW_H

#include <vector>
#include <set>


#ifndef eda_global
#define eda_global extern
#endif
@@ -21,6 +25,7 @@ typedef enum {
    FORMAT_POST
} PlotFormat;


//eda_global wxString g_Plot_FileName;
eda_global wxString g_PhotoFilenameExt;
eda_global wxString g_DrillFilenameExt;
@@ -38,7 +43,22 @@ eda_global int g_Plot_Spot_Mini; /* Diametre mini de l'ouverture pour
/* Constantes utiles en trace GERBER */
/*************************************/

/* codes de type de forme d'outils */
/**
 * Enum APERTURE_T
 * is the set of all gerber aperture types allowed, according to page 16 of
 * http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
 */
enum APERTURE_T
{
    APT_CIRCLE = 'C',
    APT_LINE = 'L',
    APT_RECT = 'R',
    APT_OVAL = '0',
    APT_POLYGON = 'P',
    APT_MACRO = 'M'
};

/* replaced by APERTURE_T
enum Gerb_StandardShape {
    GERB_CIRCLE = 1,
    GERB_RECT,
@@ -46,6 +66,8 @@ enum Gerb_StandardShape {
    GERB_OVALE,
    GERB_SPECIAL_SHAPE
};
*/


// Interpolation type
enum Gerb_Interpolation {
@@ -90,18 +112,132 @@ enum Gerb_Analyse_Cmd {
};


class D_CODE;
/**
 * Struct DCODE_PARAM
 * holds a parameter for a DCODE or an "aperture macro" as defined within standard RS274X.
 * The \a value field can be either a constant or a place holder for a DCODE
 * parameter.
 */
struct DCODE_PARAM
{
    DCODE_PARAM() :
        isImmediate(true),
        value(0.0)
    {}

    bool    isImmediate;    ///< the \a value field is an actual value, not a parameter place holder.
    double  value;          ///< if immediate then the value, else an integer index into D_CODE.m_am_params.
};


/**
 * Enum AM_PRIMITIVE_ID
 * is the set of all "aperture macro primitives" (primitive numbers).  See
 * Table 3 in http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
 */
enum AM_PRIMITIVE_ID
{
    AMP_CIRCLE  = 1,
    AMP_LINE2 = 2,
    AMP_LINE20 = 20,
    AMP_LINE_CENTER = 21,
    AMP_LINE_LOWER_LEFT = 22,
    AMP_EOF = 3,
    AMP_OUTLINE = 4,
    AMP_POLYGON = 5,
    AMP_MOIRE = 6,
    AMP_THERMAL = 7,
};


typedef std::vector<DCODE_PARAM>   DCODE_PARAMS;

/**
 * Struct AM_PRIMITIVE
 * holds an aperture macro primitive as given in Table 3 of
 * http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
 */
struct AM_PRIMITIVE
{
    AM_PRIMITIVE_ID     primitive_id;
    DCODE_PARAMS        params;
};


typedef std::vector<AM_PRIMITIVE>   AM_PRIMITIVES;

/**
 * Class GERBER_Descr
 * Struct APERTURE_MACRO
 * helps support the "aperture macro" defined within standard RS274X.
 */
struct APERTURE_MACRO
{
    wxString        name;
    AM_PRIMITIVES   primitives;
};


/**
 * Struct APERTURE_MACRO_less_than
 * is used by std:set<APERTURE_MACRO> instantiation which uses APERTURE_MACRO.name as its key.
 */
struct APERTURE_MACRO_less_than
{
    // a "less than" test on two wxStrings
    bool operator()( const APERTURE_MACRO& am1, const APERTURE_MACRO& am2) const
    {
        return am1.name.Cmp( am2.name ) < 0;  // case specific wxString compare
    }
};


/**
 * Type APERTURE_MACRO_SET
 * is a sorted collection of APERTURE_MACROS whose key is the name field in
 * the APERTURE_MACRO.
 */
typedef std::set<APERTURE_MACRO, APERTURE_MACRO_less_than>  APERTURE_MACRO_SET;
typedef std::pair<APERTURE_MACRO_SET::iterator, bool> APERTURE_MACRO_SET_PAIR;


/**
 * Class D_CODE
 * holds a gerber DCODE definition.
 */
class D_CODE
{
public:
    wxSize      m_Size;        /* Dimensions horiz et Vert */
    APERTURE_T  m_Shape;       /* shape ( Line, rect , circulaire , ovale .. ) */
    int         m_Num_Dcode;   /* numero de code ( >= 10 ) */
    wxSize      m_Drill;       /* dimension du trou central (s'il existe) */
    int         m_DrillShape;  /* forme du trou central ( rond = 1, rect = 2 ) */
    bool        m_InUse;       /* FALSE si non utilis */
    bool        m_Defined;     /* FALSE si non defini */
    wxString    m_SpecialDescr;

    APERTURE_MACRO* m_Macro;    ///< no ownership, points to GERBER.m_aperture_macros element

    /**
     * parameters used only when this D_CODE holds a reference to an aperture
     * macro, and these parameters would customize the macro.
     */
    DCODE_PARAMS   m_am_params;

public:
    D_CODE( int num_dcode );
    ~D_CODE();
    void Clear_D_CODE_Data();
};


/**
 * Class GERBER
 * holds the data for one gerber file or layer
 */
class GERBER_Descr
class GERBER
{
public:
    GERBER_Descr* m_Parent;                                     // Pointeur sur la racine pour layers imbriques
    GERBER_Descr* m_Pback;                                      // Pointeur de chainage arriere pour layers imbriques
    GERBER_Descr* m_Pnext;                                      // Pointeur de chainage avant pour layers imbriques
    wxString      m_FileName;                                   // Full File Name for this layer
    wxString      m_Name;                                       // Layer name
    int           m_Layer;                                      // Layer Number
@@ -139,10 +275,12 @@ public:
    bool          m_PolygonFillMode;                            // Enbl polygon mode (read coord as a polygone descr)
    int           m_PolygonFillModeState;                       // In polygon mode: 0 = first segm, 1 = next segm

    APERTURE_MACRO_SET   m_aperture_macros;

public:
    GERBER_Descr( int layer );
    ~GERBER_Descr();
    void    Clear_GERBER_Descr();
    GERBER( int layer );
    ~GERBER();
    void    Clear_GERBER();
    int     ReturnUsedDcodeNumber();
    void    ResetDefaultValues();
    void    InitToolTable();
@@ -174,29 +312,18 @@ public:
     * executes 1 commande
     */
    bool    ExecuteRS274XCommand( int command, char aBuff[GERBER_BUFZ], char*& text );
};


    /**
 * Class D_CODE
 * holds a gerber DCODE definition.
     * Function ReadApertureMacro
     * reads in an aperture macro and saves it in m_aperture_macros.
     * @param aBuff a character buffer at least GERBER_BUFZ long that can be
     *          used to read successive lines from the gerber file.
     * @param text A reference to a character pointer which gives the initial text to read from.
     * @param gerber_file Which file to read from for continuation.
     * @return bool - true if a macro was read in successfully, else false.
     */
class D_CODE
{
public:
    wxSize   m_Size;        /* Dimensions horiz et Vert */
    int      m_Shape;       /* shape ( Line, rect , circulaire , ovale .. ) */
    int      m_Num_Dcode;   /* numero de code ( >= 10 ) */
    wxSize   m_Drill;       /* dimension du trou central (s'il existe) */
    int      m_DrillShape;  /* forme du trou central ( rond = 1, rect = 2 ) */
    bool     m_InUse;       /* FALSE si non utilis */
    bool     m_Defined;     /* FALSE si non defini */
    wxString m_SpecialDescr;

public:
    D_CODE( int num_dcode );
    ~D_CODE();
    void Clear_D_CODE_Data();
    bool    ReadApertureMacro( char aBuff[GERBER_BUFZ], char*& text, FILE* gerber_file );
};


@@ -206,9 +333,15 @@ public:
/**************/
bool GetEndOfBlock( char buff[GERBER_BUFZ], char*& text, FILE* gerber_file );

/*************/
/* dcode.cpp */
/*************/

/**
 * Function ReturnToolDescr
 * returns a D_CODE given a global layer index and Dcode value.
 * @param aLayer The index into the global array of GERBER called g_GERBER_List[].
 * @param aDcode The dcode value to look up.
 * @param aIndex If not null, where to put a one basedindex into the GERBER's m_Aperture_List[] array.
 * @return D_CODE* - the looked up D_CODE or NULL if none was encountered in the gerber file for given \a aDcode.
 */
D_CODE * ReturnToolDescr( int layer, int Dcode, int * index = NULL );


@@ -222,11 +355,15 @@ eda_global const wxChar* g_GERBER_Tool_Type[6]
#endif
;

eda_global GERBER_Descr* g_GERBER_Descr_List[32];
eda_global int           g_DisplayPolygonsModeSketch; /* How to show filled polygons :
eda_global GERBER* g_GERBER_List[32];


/**
 * How to show filled polygons :
 * 0 = filled
 * 1 = Sketch mode
 */
eda_global int           g_DisplayPolygonsModeSketch;


#include "pcbnew.h"
Loading