Commit d696ee8c authored by jean-pierre charras's avatar jean-pierre charras
Browse files

Gerbview: added support og regular polygon aperure definition.

parent 6417db15
Loading
Loading
Loading
Loading
+1 −2
Original line number Original line Diff line number Diff line
@@ -12,12 +12,11 @@ email address.
    graphics items are now specific to gerbview (added a GERBER_DRAW_ITEM class)
    graphics items are now specific to gerbview (added a GERBER_DRAW_ITEM class)
    and do not use tracks from pcbnew.
    and do not use tracks from pcbnew.
    The way used to draw them is also new.
    The way used to draw them is also new.
    Apertures are now correctly drawn for round, oval and rectangular shapes
    Apertures are now correctly drawn for round, oval, rectangular and regular polygon shapes
        (with or without holes)
        (with or without holes)
    Aperture definition type Polygon is not yet handle.
    Aperture definition type Polygon is not yet handle.
    Polygons are correctly drawn.
    Polygons are correctly drawn.
    TODO:
    TODO:
        Draw functions for aperture definition type Polygon.
        Draw functions for aperture macros.
        Draw functions for aperture macros.
    Work in progress.
    Work in progress.


+5 −1
Original line number Original line Diff line number Diff line
@@ -106,10 +106,13 @@ wxString GERBER_DRAW_ITEM::ShowGBRShape()
    case GBR_SPOT_RECT:
    case GBR_SPOT_RECT:
        return wxT( "spot_rect" );
        return wxT( "spot_rect" );


    case GBR_SPOT_POLY:
        return wxT( "spot_poly" );

    case GBR_POLYGON:
    case GBR_POLYGON:
        return wxT( "polygon" );
        return wxT( "polygon" );


    case GBR_MACRO:
    case GBR_SPOT_MACRO:
        return wxT( "apt_macro" );  // TODO: add aperture macro name
        return wxT( "apt_macro" );  // TODO: add aperture macro name


    default:
    default:
@@ -276,6 +279,7 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode,
    case GBR_SPOT_CIRCLE:
    case GBR_SPOT_CIRCLE:
    case GBR_SPOT_RECT:
    case GBR_SPOT_RECT:
    case GBR_SPOT_OVAL:
    case GBR_SPOT_OVAL:
    case GBR_SPOT_POLY:
        isFilled = DisplayOpt.DisplayPadFill ? true : false;
        isFilled = DisplayOpt.DisplayPadFill ? true : false;
        d_codeDescr->DrawFlashedShape( &panel->m_ClipBox, DC, color,
        d_codeDescr->DrawFlashedShape( &panel->m_ClipBox, DC, color,
                                       m_Start, isFilled );
                                       m_Start, isFilled );
+2 −1
Original line number Original line Diff line number Diff line
@@ -40,7 +40,8 @@ enum Gbr_Basic_Shapes {
    GBR_SPOT_CIRCLE,        // flashed shape: round shape (can have hole)
    GBR_SPOT_CIRCLE,        // flashed shape: round shape (can have hole)
    GBR_SPOT_RECT,          // flashed shape: rectangular shape can have hole)
    GBR_SPOT_RECT,          // flashed shape: rectangular shape can have hole)
    GBR_SPOT_OVAL,          // flashed shape: oval shape
    GBR_SPOT_OVAL,          // flashed shape: oval shape
    GBR_MACRO,              // complex shape described by a macro
    GBR_SPOT_POLY,          // flashed shape: regulat polygon, 3 to 12 edges
    GBR_SPOT_MACRO,         // complex shape described by a macro
    GBR_LAST                // last value for this list
    GBR_LAST                // last value for this list
};
};


+113 −102
Original line number Original line Diff line number Diff line
@@ -56,11 +56,12 @@ void D_CODE::Clear_D_CODE_Data()
    m_Size.y     = DEFAULT_SIZE;
    m_Size.y     = DEFAULT_SIZE;
    m_Shape      = APT_CIRCLE;
    m_Shape      = APT_CIRCLE;
    m_Drill.x    = m_Drill.y = 0;
    m_Drill.x    = m_Drill.y = 0;
    m_DrillShape = 0;
    m_DrillShape = APT_DEF_NO_HOLE;
    m_InUse      = FALSE;
    m_InUse      = FALSE;
    m_Defined    = FALSE;
    m_Defined    = FALSE;
    m_Macro      = 0;
    m_Macro      = NULL;
    m_Rotation   = 0.0;
    m_Rotation   = 0.0;
    m_EdgesCount = 0;
}
}




@@ -252,17 +253,29 @@ void WinEDA_GerberFrame::CopyDCodesSizeToItems()
            {
            {
            case APT_LINE:          // might not appears here, but some broken
            case APT_LINE:          // might not appears here, but some broken
            // gerber files use it
            // gerber files use it
            case APT_CIRCLE:        /* spot round (for GERBER) */
            case APT_CIRCLE:        /* spot round */
                gerb_item->m_Shape = GBR_SPOT_CIRCLE;
                gerb_item->m_Shape = GBR_SPOT_CIRCLE;
                break;
                break;


            case APT_OVAL:          /* spot oval (for GERBER)*/
            case APT_OVAL:          /* spot oval*/
                gerb_item->m_Shape = GBR_SPOT_OVAL;
                gerb_item->m_Shape = GBR_SPOT_OVAL;
                break;
                break;


            default:                /* spot rect (for GERBER)*/
            case APT_RECT:                /* spot rect*/
                gerb_item->m_Shape = GBR_SPOT_RECT;
                gerb_item->m_Shape = GBR_SPOT_RECT;
                break;
                break;

            case APT_POLYGON:                /* spot regular polyg 3 to 1 edges */
                gerb_item->m_Shape = GBR_SPOT_POLY;
                break;

            case APT_MACRO:                /* spot defined by a macro */
                gerb_item->m_Shape = GBR_SPOT_MACRO;
                break;

            default:
                wxMessageBox( wxT("WinEDA_GerberFrame::CopyDCodesSizeToItems() error" ) );
                break;
            }
            }
        }
        }
    }
    }
@@ -280,14 +293,16 @@ void D_CODE::DrawFlashedShape( EDA_Rect* aClipBox, wxDC* aDC, int aColor,


    switch( m_Shape )
    switch( m_Shape )
    {
    {

    case APT_MACRO: // TODO: current a round shape
    case APT_CIRCLE:
    case APT_CIRCLE:
        radius = m_Size.x >> 1;
        radius = m_Size.x >> 1;
        if( !aFilledShape )
        if( !aFilledShape )
            GRCircle( aClipBox, aDC, aShapePos.x, aShapePos.y, radius, aColor );
            GRCircle( aClipBox, aDC, aShapePos.x, aShapePos.y, radius, aColor );
        else
        else
            if( m_DrillShape == 0 )
            if( m_DrillShape == APT_DEF_NO_HOLE )
                GRFilledCircle( aClipBox, aDC, aShapePos, radius, aColor );
                GRFilledCircle( aClipBox, aDC, aShapePos, radius, aColor );
            else if( m_DrillShape == 1 )    // round hole
            else if( APT_DEF_ROUND_HOLE == 1 )    // round hole in shape
            {
            {
                int width = (m_Size.x - m_Drill.x ) / 2;
                int width = (m_Size.x - m_Drill.x ) / 2;
                GRCircle( aClipBox, aDC, aShapePos, radius - (width / 2), width, aColor );
                GRCircle( aClipBox, aDC, aShapePos, radius - (width / 2), width, aColor );
@@ -301,6 +316,7 @@ void D_CODE::DrawFlashedShape( EDA_Rect* aClipBox, wxDC* aDC, int aColor,
        break;
        break;


    case APT_LINE:
    case APT_LINE:

        // not used for flashed items
        // not used for flashed items
        break;
        break;


@@ -315,7 +331,7 @@ void D_CODE::DrawFlashedShape( EDA_Rect* aClipBox, wxDC* aDC, int aColor,
            GRRect( aClipBox, aDC, start.x, start.y, end.x, end.y,
            GRRect( aClipBox, aDC, start.x, start.y, end.x, end.y,
                    0, aColor );
                    0, aColor );
        }
        }
        else if( m_DrillShape == 0 )
        else if( m_DrillShape == APT_DEF_NO_HOLE )
        {
        {
            GRFilledRect( aClipBox, aDC, start.x, start.y, end.x, end.y,
            GRFilledRect( aClipBox, aDC, start.x, start.y, end.x, end.y,
                          0, aColor, aColor );
                          0, aColor, aColor );
@@ -352,7 +368,7 @@ void D_CODE::DrawFlashedShape( EDA_Rect* aClipBox, wxDC* aDC, int aColor,
            GRCSegm( aClipBox, aDC, start.x, start.y,
            GRCSegm( aClipBox, aDC, start.x, start.y,
                     end.x, end.y, radius, aColor );
                     end.x, end.y, radius, aColor );
        }
        }
        else if( m_DrillShape == 0 )
        else if( m_DrillShape == APT_DEF_NO_HOLE )
        {
        {
            GRFillCSegm( aClipBox, aDC, start.x,
            GRFillCSegm( aClipBox, aDC, start.x,
                         start.y, end.x, end.y, radius, aColor );
                         start.y, end.x, end.y, radius, aColor );
@@ -371,10 +387,6 @@ void D_CODE::DrawFlashedShape( EDA_Rect* aClipBox, wxDC* aDC, int aColor,
            ConvertShapeToPolygon();
            ConvertShapeToPolygon();
        DrawFlashedPolygon( aClipBox, aDC, aColor, aFilledShape, aShapePos );
        DrawFlashedPolygon( aClipBox, aDC, aColor, aFilledShape, aShapePos );
        break;
        break;
    
    case APT_MACRO:
        // TODO
        break;
    }
    }
}
}


@@ -403,6 +415,15 @@ void D_CODE::DrawFlashedPolygon( EDA_Rect* aClipBox, wxDC* aDC,
}
}




#define SEGS_CNT 32     // number of segments to approximate a circle

// A helper function for D_CODE::ConvertShapeToPolygon().
// Add a hole to a polygon
static void addHoleToPolygon( std::vector<wxPoint>& aBuffer,
                              APERTURE_DEF_HOLETYPE aHoleShape,
                              wxSize                aSize,
                              wxPoint                aAnchorPos );

/** function ConvertShapeToPolygon
/** function ConvertShapeToPolygon
 * convert a shape to an equivalent polygon.
 * convert a shape to an equivalent polygon.
 * Arcs and circles are approximated by segments
 * Arcs and circles are approximated by segments
@@ -411,7 +432,6 @@ void D_CODE::DrawFlashedPolygon( EDA_Rect* aClipBox, wxDC* aDC,
 */
 */
void D_CODE::ConvertShapeToPolygon()
void D_CODE::ConvertShapeToPolygon()
{
{
    #define SEGS_CNT 32     // number of segments to approximate a circle
    wxPoint initialpos;
    wxPoint initialpos;
    wxPoint currpos;;
    wxPoint currpos;;
    m_PolyCorners.clear();
    m_PolyCorners.clear();
@@ -427,35 +447,12 @@ void D_CODE::ConvertShapeToPolygon()
            RotatePoint( &currpos, ii * 3600 / SEGS_CNT );
            RotatePoint( &currpos, ii * 3600 / SEGS_CNT );
            m_PolyCorners.push_back( currpos );
            m_PolyCorners.push_back( currpos );
        }
        }
        if( m_DrillShape == 1 )

        {
        addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos );
            for( unsigned ii = 0 ; ii <= SEGS_CNT; ii++ )
            {
                currpos.x = m_Drill.x / 2;
                currpos.y = 0;
                RotatePoint( &currpos, ii * 3600 / SEGS_CNT );
                m_PolyCorners.push_back( currpos );
            }
            m_PolyCorners.push_back( initialpos );  // link to outline
        }
        if( m_DrillShape == 2 )  // Create rectangular hole
        {
            currpos.x = m_Drill.x / 2;
            currpos.y = m_Drill.y / 2;
            m_PolyCorners.push_back( currpos );     // link to hole and begin hole
            currpos.x -= m_Drill.x;
            m_PolyCorners.push_back( currpos );
            currpos.y -= m_Drill.y;
            m_PolyCorners.push_back( currpos );
            currpos.x += m_Drill.x;
            m_PolyCorners.push_back( currpos );
            currpos.y += m_Drill.y;
            m_PolyCorners.push_back( currpos );     // close hole
            m_PolyCorners.push_back( initialpos );  // link to outline
        }
        break;
        break;


    case APT_LINE:
    case APT_LINE:

        // Not used for flashed shapes
        // Not used for flashed shapes
        break;
        break;


@@ -472,32 +469,8 @@ void D_CODE::ConvertShapeToPolygon()
        m_PolyCorners.push_back( currpos );
        m_PolyCorners.push_back( currpos );
        currpos.y += m_Size.y;
        currpos.y += m_Size.y;
        m_PolyCorners.push_back( currpos );    // close polygon
        m_PolyCorners.push_back( currpos );    // close polygon
        if( m_DrillShape == 1 )                     // build a round hole

        {
        addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos );
            for( int ii = 0 ; ii <= SEGS_CNT; ii++ )
            {
                currpos.x = 0;
                currpos.y = m_Drill.x / 2;      // m_Drill.x / 2 is the radius of the hole
                RotatePoint( &currpos, ii * 3600 / SEGS_CNT );
                m_PolyCorners.push_back( currpos );
            }
            m_PolyCorners.push_back( initialpos );  // link to outline
        }
        if( m_DrillShape == 2 )  // Create rectangular hole
        {
            currpos.x = m_Drill.x / 2;
            currpos.y = m_Drill.y / 2;
            m_PolyCorners.push_back( currpos );     // link to hole and begin hole
            currpos.x -= m_Drill.x;
            m_PolyCorners.push_back( currpos );
            currpos.y -= m_Drill.y;
            m_PolyCorners.push_back( currpos );
            currpos.x += m_Drill.x;
            m_PolyCorners.push_back( currpos );
            currpos.y += m_Drill.y;
            m_PolyCorners.push_back( currpos );     // close hole
            m_PolyCorners.push_back( initialpos );  // link to outline
        }
        break;
        break;


    case APT_OVAL:
    case APT_OVAL:
@@ -537,47 +510,85 @@ void D_CODE::ConvertShapeToPolygon()
            currpos.x -= delta;
            currpos.x -= delta;
            m_PolyCorners.push_back( currpos );
            m_PolyCorners.push_back( currpos );
        }
        }

        m_PolyCorners.push_back( initialpos );      // close outline
        m_PolyCorners.push_back( initialpos );      // close outline
        if( m_Size.y > m_Size.x )                   // vertical oval, rotate polygon.
        if( m_Size.y > m_Size.x )                   // vertical oval, rotate polygon.
        {
        {
            for( unsigned jj = 0; jj < m_PolyCorners.size(); jj++ )
            for( unsigned jj = 0; jj < m_PolyCorners.size(); jj++ )
                RotatePoint( &m_PolyCorners[jj], 900 );
                RotatePoint( &m_PolyCorners[jj], 900 );
        }
        }
        if( m_DrillShape == 1 )                     // build a round hole

        {
        addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos );
            for( ii = 0 ; ii <= SEGS_CNT; ii++ )
    }
    break;

    case APT_POLYGON:
        currpos.x  = m_Size.x >> 1;     // first point is on X axis
        initialpos = currpos;
        // rs274x said: m_EdgesCount = 3 ... 12
        if( m_EdgesCount < 3 )
            m_EdgesCount = 3;
        if( m_EdgesCount > 12 )
            m_EdgesCount = 12;
        for( int ii = 0; ii <= m_EdgesCount; ii++ )
        {
        {
                currpos.x = 0;
            currpos = initialpos;
                currpos.y = m_Drill.x / 2;      // m_Drill.x / 2 is the radius of the hole
            RotatePoint( &currpos, ii * 3600 / m_EdgesCount );
                RotatePoint( &currpos, ii * 3600 / SEGS_CNT );
            m_PolyCorners.push_back( currpos );
            m_PolyCorners.push_back( currpos );
        }
        }
            m_PolyCorners.push_back( initialpos );  // link to outline
        addHoleToPolygon( m_PolyCorners, m_DrillShape, m_Drill, initialpos );
        }
        if( m_Rotation )                   // vertical oval, rotate polygon.
        if( m_DrillShape == 2 )  // Create rectangular hole
        {
        {
            currpos.x = m_Drill.x / 2;
            int angle = wxRound( m_Rotation*10 );
            currpos.y = m_Drill.y / 2;
            for( unsigned jj = 0; jj < m_PolyCorners.size(); jj++ )
            m_PolyCorners.push_back( currpos );     // link to hole and begin hole
            {
            currpos.x -= m_Drill.x;
                // Remember the Y axis is from top to bottom when draw items.
            m_PolyCorners.push_back( currpos );
                RotatePoint( &m_PolyCorners[jj], -angle );
            currpos.y -= m_Drill.y;
                NEGATE(m_PolyCorners[jj].y);
            m_PolyCorners.push_back( currpos );
            currpos.x += m_Drill.x;
            m_PolyCorners.push_back( currpos );
            currpos.y += m_Drill.y;
            m_PolyCorners.push_back( currpos );     // close hole
            m_PolyCorners.push_back( initialpos );  // link to outline
            }
            }
        }
        }
        break;
        break;


    case APT_POLYGON:
        // TODO
        break;
    
    case APT_MACRO:
    case APT_MACRO:

        // TODO
        // TODO
        break;
        break;
    }
    }
}
}

// The helper function for D_CODE::ConvertShapeToPolygon().
// Add a hole to a polygon
static void addHoleToPolygon( std::vector<wxPoint>& aBuffer,
                              APERTURE_DEF_HOLETYPE aHoleShape,
                              wxSize                aSize,
                              wxPoint               aAnchorPos )
{
    wxPoint currpos;
    if( aHoleShape == APT_DEF_ROUND_HOLE )                     // build a round hole
    {
        for( int ii = 0; ii <= SEGS_CNT; ii++ )
        {
            currpos.x = 0;
            currpos.y = aSize.x / 2;      // aSize.x / 2 is the radius of the hole
            RotatePoint( &currpos, ii * 3600 / SEGS_CNT );
            aBuffer.push_back( currpos );
        }

        aBuffer.push_back( aAnchorPos );  // link to outline
    }
    if( aHoleShape == APT_DEF_RECT_HOLE )     // Create rectangular hole
    {
        currpos.x = aSize.x / 2;
        currpos.y = aSize.y / 2;
        aBuffer.push_back( currpos );     // link to hole and begin hole
        currpos.x -= aSize.x;
        aBuffer.push_back( currpos );
        currpos.y -= aSize.y;
        aBuffer.push_back( currpos );
        currpos.x += aSize.x;
        aBuffer.push_back( currpos );
        currpos.y += aSize.y;
        aBuffer.push_back( currpos );     // close hole
        aBuffer.push_back( aAnchorPos );  // link to outline
    }
}
+65 −48
Original line number Original line Diff line number Diff line
@@ -16,8 +16,7 @@
 * is the set of all gerber aperture types allowed, according to page 16 of
 * is the set of all gerber aperture types allowed, according to page 16 of
 * http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
 * http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
 */
 */
enum APERTURE_T
enum APERTURE_T {
{
    APT_CIRCLE  = 'C',
    APT_CIRCLE  = 'C',
    APT_LINE    = 'L',
    APT_LINE    = 'L',
    APT_RECT    = 'R',
    APT_RECT    = 'R',
@@ -26,9 +25,20 @@ enum APERTURE_T
    APT_MACRO   = 'M'
    APT_MACRO   = 'M'
};
};


// In aperture definition, round, oval and rectangular flashed shapes
// can have a hole (ropund or rectangular)
// this option is stored in .m_DrillShape D_CODE member
enum APERTURE_DEF_HOLETYPE {
    APT_DEF_NO_HOLE = 0,
    APT_DEF_ROUND_HOLE,
    APT_DEF_RECT_HOLE
};


/* define min and max values for D Codes values.
 * note: values >= 0 and > FIRST_DCODE can be used for specila purposes
 */
#define FIRST_DCODE     10
#define FIRST_DCODE     10
#define LAST_DCODE 999      // dcodes values are from 10 to 999
#define LAST_DCODE      999
#define TOOLS_MAX_COUNT (LAST_DCODE + 1)
#define TOOLS_MAX_COUNT (LAST_DCODE + 1)


class D_CODE;
class D_CODE;
@@ -51,12 +61,14 @@ public:
    {}
    {}


    double GetValue( const D_CODE* aDcode ) const;
    double GetValue( const D_CODE* aDcode ) const;

    void SetValue( double aValue )
    void SetValue( double aValue )
    {
    {
        value = aValue;
        value = aValue;
        index = -1;
        index = -1;
    }
    }



    /**
    /**
     * Function IsImmediate
     * Function IsImmediate
     * tests if this DCODE_PARAM holds an immediate parameter or is a pointer
     * tests if this DCODE_PARAM holds an immediate parameter or is a pointer
@@ -69,11 +81,13 @@ public:
        return (unsigned) index;
        return (unsigned) index;
    }
    }



    void SetIndex( int aIndex )
    void SetIndex( int aIndex )
    {
    {
        index = aIndex;
        index = aIndex;
    }
    }



private:
private:
    int    index;       ///< if -1, then \a value field is an immediate value,
    int    index;       ///< if -1, then \a value field is an immediate value,
                        //   else this is an index into parent's
                        //   else this is an index into parent's
@@ -88,8 +102,7 @@ private:
 * is the set of all "aperture macro primitives" (primitive numbers).  See
 * is the set of all "aperture macro primitives" (primitive numbers).  See
 * Table 3 in http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
 * Table 3 in http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
 */
 */
enum AM_PRIMITIVE_ID
enum AM_PRIMITIVE_ID {
{
    AMP_CIRCLE = 1,
    AMP_CIRCLE = 1,
    AMP_LINE2  = 2,
    AMP_LINE2  = 2,
    AMP_LINE20 = 20,
    AMP_LINE20 = 20,
@@ -194,8 +207,9 @@ public:
    APERTURE_T            m_Shape;                  /* shape ( Line, rectangle, circle , oval .. ) */
    APERTURE_T            m_Shape;                  /* shape ( Line, rectangle, circle , oval .. ) */
    int                   m_Num_Dcode;              /* D code ( >= 10 ) */
    int                   m_Num_Dcode;              /* D code ( >= 10 ) */
    wxSize                m_Drill;                  /* dimension of the hole (if any) */
    wxSize                m_Drill;                  /* dimension of the hole (if any) */
    int         m_DrillShape;  /* shape of the hole (round = 1, rect = 2) */
    APERTURE_DEF_HOLETYPE m_DrillShape;             /* shape of the hole (0 = no hole, round = 1, rect = 2) */
    double                m_Rotation;               /* shape rotation in degrees */
    double                m_Rotation;               /* shape rotation in degrees */
    int                   m_EdgesCount;             /* in apeture definition Polygon only: number of edges for the polygon */
    bool                  m_InUse;                  /* FALSE if not used */
    bool                  m_InUse;                  /* FALSE if not used */
    bool                  m_Defined;                /* FALSE if not defined */
    bool                  m_Defined;                /* FALSE if not defined */
    wxString              m_SpecialDescr;
    wxString              m_SpecialDescr;
@@ -214,10 +228,13 @@ public:
        m_am_params.push_back( param );
        m_am_params.push_back( param );
    }
    }



    void SetMacro( APERTURE_MACRO* aMacro )
    void SetMacro( APERTURE_MACRO* aMacro )
    {
    {
        m_Macro = aMacro;
        m_Macro = aMacro;
    }
    }


    APERTURE_MACRO* GetMacro() { return m_Macro; }
    APERTURE_MACRO* GetMacro() { return m_Macro; }


    /**
    /**
@@ -250,7 +267,6 @@ public:
     * rotated shape ... ) and cannot be easily drawn.
     * rotated shape ... ) and cannot be easily drawn.
     */
     */
    void                 ConvertShapeToPolygon();
    void                 ConvertShapeToPolygon();

};
};




@@ -263,6 +279,7 @@ inline double DCODE_PARAM::GetValue( const D_CODE* aDcode ) const
        // the first one was numbered 1, not zero, as in $1, see page 19 of spec.
        // the first one was numbered 1, not zero, as in $1, see page 19 of spec.
        unsigned ndx = GetIndex() - 1;
        unsigned ndx = GetIndex() - 1;
        wxASSERT( aDcode );
        wxASSERT( aDcode );

        // get the parameter from the aDcode
        // get the parameter from the aDcode
        if( ndx < aDcode->m_am_params.size() )
        if( ndx < aDcode->m_am_params.size() )
            return aDcode->m_am_params[ndx].GetValue( NULL );
            return aDcode->m_am_params[ndx].GetValue( NULL );
Loading