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

Gerbview: support for plot lines (currently: not arcs) with a rectangular pen...

Gerbview: support for plot lines (currently: not arcs) with a rectangular pen (Yes, it exists!). pcbnew: try to fix an issue when exporting arcs in gencad.
parent 1206177c
Loading
Loading
Loading
Loading
+97 −10
Original line number Original line Diff line number Diff line
@@ -88,8 +88,7 @@ GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( const GERBER_DRAW_ITEM& aSource ) :
    m_mirrorA       = aSource.m_mirrorA;
    m_mirrorA       = aSource.m_mirrorA;
    m_mirrorB       = aSource.m_mirrorB;
    m_mirrorB       = aSource.m_mirrorB;
    m_layerOffset   = aSource.m_layerOffset;
    m_layerOffset   = aSource.m_layerOffset;
    m_drawScale.x   = aSource.m_drawScale.x;
    m_drawScale     = aSource.m_drawScale;
    m_drawScale.y   = aSource.m_drawScale.y;
    m_lyrRotation   = aSource.m_lyrRotation;
    m_lyrRotation   = aSource.m_lyrRotation;
}
}


@@ -222,7 +221,13 @@ wxString GERBER_DRAW_ITEM::ShowGBRShape()
        return wxT( "polygon" );
        return wxT( "polygon" );


    case GBR_SPOT_MACRO:
    case GBR_SPOT_MACRO:
        return wxT( "apt_macro" );  // TODO: add aperture macro name
    {
        wxString name = wxT( "apt_macro" );
        D_CODE* dcode = GetDcodeDescr();
        if( dcode && dcode->GetMacro() )
            name << wxT(" ") << dcode->GetMacro()->name;
        return name;
    }


    default:
    default:
        return wxT( "??" );
        return wxT( "??" );
@@ -363,8 +368,8 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode,
        break;
        break;


    case GBR_CIRCLE:
    case GBR_CIRCLE:
        radius = (int) hypot( (double) ( m_End.x - m_Start.x ),
        radius = wxRound(hypot( (double) ( m_End.x - m_Start.x ),
                             (double) ( m_End.y - m_Start.y ) );
                             (double) ( m_End.y - m_Start.y ) ));


        halfPenWidth = m_Size.x >> 1;
        halfPenWidth = m_Size.x >> 1;


@@ -384,6 +389,8 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode,
        break;
        break;


    case GBR_ARC:
    case GBR_ARC:
        // Currently, arcs plotted witha rectangular aperture are not supported.
        // a round pen only is expected.
#if 0     // for arc debug only
#if 0     // for arc debug only
        GRLine( &aPanel->m_ClipBox, aDC, GetABPosition( m_Start ),
        GRLine( &aPanel->m_ClipBox, aDC, GetABPosition( m_Start ),
                GetABPosition( m_ArcCentre ), 0, color );
                GetABPosition( m_ArcCentre ), 0, color );
@@ -415,12 +422,30 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode,
        break;
        break;


    case GBR_SEGMENT:
    case GBR_SEGMENT:
        /* Plot a line from m_Start to m_End.
         * Usually, a round pen is used, but some gerber files use a rectangular pen
         * In fact, any aperture can be used to plot a line.
         * currently: only a square pen is handled (I believe using a polygon gives a strange plot).
         */
        if( d_codeDescr->m_Shape == APT_RECT )
        {
            if( m_PolyCorners.size() == 0 )
                ConvertSegmentToPolygon( );
            DrawGbrPoly( &aPanel->m_ClipBox, aDC, color, aOffset, isFilled );
        }
        else
        {
            if( !isFilled )
            if( !isFilled )
            {
                    GRCSegm( &aPanel->m_ClipBox, aDC, GetABPosition( m_Start ),
                    GRCSegm( &aPanel->m_ClipBox, aDC, GetABPosition( m_Start ),
                             GetABPosition( m_End ), m_Size.x, color );
                             GetABPosition( m_End ), m_Size.x, color );
            }
            else
            else
            {
                GRFilledSegment( &aPanel->m_ClipBox, aDC, GetABPosition( m_Start ),
                GRFilledSegment( &aPanel->m_ClipBox, aDC, GetABPosition( m_Start ),
                                 GetABPosition( m_End ), m_Size.x, color );
                                 GetABPosition( m_End ), m_Size.x, color );
            }
        }
        break;
        break;


    default:
    default:
@@ -433,9 +458,71 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode,
    }
    }
}
}


/** function ConvertSegmentToPolygon
 * convert a line to an equivalent polygon.
 * Useful when a line is plotted using a rectangular pen.
 * In this case, the usual segment plot cannot be used
 * The equivalent polygon is the area paint by the rectancular pen
 * from m_Start to m_End.
 */
void GERBER_DRAW_ITEM::ConvertSegmentToPolygon( )
{
    m_PolyCorners.clear();
    m_PolyCorners.reserve(6);

    wxPoint start = m_Start;
    wxPoint end = m_End;
    // make calculations more easy if ensure start.x < end.x
    // (only 2 quadrants to consider)
    if( start.x > end.x )
        EXCHG( start, end );

    // calculate values relative to start point:
    wxPoint delta = end - start;
    // calculate corners for the first quadrant only (delta.x and delta.y > 0 )
    // currently, delta.x already is > 0.
    // make delta.y > 0
    bool change = delta.y < 0;
    if( change )
        NEGATE( delta.y);
    // Now create the full polygon.
    // Due to previous chnages, the shape is always something like
    //          3 4
    // 2          5
    // 1 6
    wxPoint corner;
    corner.x -= m_Size.x/2;
    corner.y -= m_Size.y/2;
    m_PolyCorners.push_back( corner );  // Lower left corner, start point (1)
    corner.y += m_Size.y;
    m_PolyCorners.push_back( corner );  // upper left corner, start point (2)
    if( delta.x || delta.y)
    {
        corner += delta;
        m_PolyCorners.push_back( corner );  // upper left corner, end point (3)
    }
    corner.x += m_Size.x;
    m_PolyCorners.push_back( corner );  // upper right corner, end point (4)
    corner.y -= m_Size.y;
    m_PolyCorners.push_back( corner );  // lower right corner, end point (5)
    if( delta.x || delta.y )
    {
        corner -= delta;
        m_PolyCorners.push_back( corner );  // lower left corner, start point (6)
    }

    // Create final polygon:
    for( unsigned ii = 0; ii < m_PolyCorners.size(); ii++ )
    {
        if( change )
            NEGATE( m_PolyCorners[ii].y);
         m_PolyCorners[ii] += start;
    }
}



/** function DrawGbrPoly
/** function DrawGbrPoly
 * a helper function used id ::Draw to draw the polygon stored ion m_PolyCorners
 * a helper function used id ::Draw to draw the polygon stored in m_PolyCorners
 * Draw filled polygons
 * Draw filled polygons
 */
 */
void GERBER_DRAW_ITEM::DrawGbrPoly( EDA_Rect*      aClipBox,
void GERBER_DRAW_ITEM::DrawGbrPoly( EDA_Rect*      aClipBox,
+8 −1
Original line number Original line Diff line number Diff line
@@ -194,8 +194,15 @@ public:
                   int               aDrawMode,
                   int               aDrawMode,
                   const wxPoint&    aOffset = ZeroOffset );
                   const wxPoint&    aOffset = ZeroOffset );


    /** function ConvertSegmentToPolygon
     * convert a line to an equivalent polygon.
     * Useful when a line is plotted using a rectangular pen.
     * In this case, the usual segment plot function cannot be used
     */
    void ConvertSegmentToPolygon( );

    /** function DrawGbrPoly
    /** function DrawGbrPoly
     * a helper function used id ::Draw to draw the polygon stored ion m_PolyCorners
     * a helper function used id ::Draw to draw the polygon stored in m_PolyCorners
     */
     */
    void DrawGbrPoly( EDA_Rect* aClipBox,
    void DrawGbrPoly( EDA_Rect* aClipBox,
                      wxDC* aDC, int aColor,
                      wxDC* aDC, int aColor,
+16 −0
Original line number Original line Diff line number Diff line
*
%FSLAX23Y23*%
%MOIN*%
%ADD10R,0.025X0.025*%
%ADD11R,0.03X0.06*%
%IPPOS*%
%LNtest_rect.gbr*%
%LPD*%
G75*
G54D10*
X04000Y00100D02*
X04400Y00140D01*
G54D11*
X03000Y00100D02*
X02400Y-00340D01*
M02*
+11 −12
Original line number Original line Diff line number Diff line
@@ -137,23 +137,23 @@ static void fillFlashedGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
 * @param aGbrItem The GERBER_DRAW_ITEM to fill in.
 * @param aGbrItem The GERBER_DRAW_ITEM to fill in.
 * @param Dcode_index The DCODE value, like D14
 * @param Dcode_index The DCODE value, like D14
 * @param aLayer The layer index to set into the GBRITEM
 * @param aLayer The layer index to set into the GBRITEM
 * @param aPos The center point of the flash
 * @param aStart The starting point of the line
 * @param aDiameter The diameter of the round flash
 * @param aEnd The ending point of the line
 * @param aPenSize The size of the flash. Note rectangular shapes are legal.
 * @param aLayerNegative = true if the current layer is negative
 * @param aLayerNegative = true if the current layer is negative
 * @param aImageNegative = true if the current image is negative
 */
 */
static void fillLineGBRITEM(  GERBER_DRAW_ITEM* aGbrItem,
static void fillLineGBRITEM(  GERBER_DRAW_ITEM* aGbrItem,
                              int               Dcode_index,
                              int               Dcode_index,
                              int               aLayer,
                              int               aLayer,
                              const wxPoint&    aStart,
                              const wxPoint&    aStart,
                              const wxPoint&    aEnd,
                              const wxPoint&    aEnd,
                              int               aWidth,
                              wxSize            aPenSize,
                              bool              aLayerNegative  )
                              bool              aLayerNegative  )
{
{
    aGbrItem->SetLayer( aLayer );
    aGbrItem->SetLayer( aLayer );
    aGbrItem->m_Flashed = false;
    aGbrItem->m_Flashed = false;


    aGbrItem->m_Size.x = aGbrItem->m_Size.y = aWidth;
    aGbrItem->m_Size = aPenSize;


    aGbrItem->m_Start = aStart;
    aGbrItem->m_Start = aStart;
    aGbrItem->m_End   = aEnd;
    aGbrItem->m_End   = aEnd;
@@ -188,13 +188,12 @@ static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
 *   must be calculated from the previously given constraint: arc only in the
 *   must be calculated from the previously given constraint: arc only in the
 * same quadrant.
 * same quadrant.
 * @param aDiameter The diameter of the round flash
 * @param aDiameter The diameter of the round flash
 * @param aWidth is the pen width.
 * @param aPenSize The size of the flash. Note rectangular shapes are legal.
 * @param aLayerNegative = true if the current layer is negative
 * @param aLayerNegative = true if the current layer is negative
 * @param aImageNegative = true if the current image is negative
 */
 */
static void fillArcGBRITEM(  GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aLayer,
static void fillArcGBRITEM(  GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aLayer,
                             const wxPoint& aStart, const wxPoint& aEnd,
                             const wxPoint& aStart, const wxPoint& aEnd,
                             const wxPoint& aRelCenter, int aWidth,
                             const wxPoint& aRelCenter, wxSize aPenSize,
                             bool aClockwise, bool aMultiquadrant,
                             bool aClockwise, bool aMultiquadrant,
                             bool aLayerNegative  )
                             bool aLayerNegative  )
{
{
@@ -202,7 +201,7 @@ static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aL


    aGbrItem->m_Shape = GBR_ARC;
    aGbrItem->m_Shape = GBR_ARC;
    aGbrItem->SetLayer( aLayer );
    aGbrItem->SetLayer( aLayer );
    aGbrItem->m_Size.x  = aGbrItem->m_Size.y = aWidth;
    aGbrItem->m_Size  = aPenSize;
    aGbrItem->m_Flashed = false;
    aGbrItem->m_Flashed = false;




@@ -333,7 +332,7 @@ static void fillArcPOLY( BOARD* aPcb, GERBER_DRAW_ITEM* aGbrItem,
    aGbrItem->SetLayerPolarity( aLayerNegative );
    aGbrItem->SetLayerPolarity( aLayerNegative );


    fillArcGBRITEM(  &dummyGbrItem, 0, 0,
    fillArcGBRITEM(  &dummyGbrItem, 0, 0,
                     aStart, aEnd, rel_center, 0,
                     aStart, aEnd, rel_center, wxSize(0, 0),
                     clockwise, multiquadrant, aLayerNegative );
                     clockwise, multiquadrant, aLayerNegative );


    wxPoint   center;
    wxPoint   center;
@@ -688,7 +687,7 @@ bool GERBER_IMAGE::Execute_DCODE_Command( char*& text, int D_commande )
//                           m_PreviousPos.x, m_PreviousPos.y,
//                           m_PreviousPos.x, m_PreviousPos.y,
//                            m_CurrentPos.x, m_CurrentPos.y ); )
//                            m_CurrentPos.x, m_CurrentPos.y ); )
                fillLineGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos,
                fillLineGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos,
                                 m_CurrentPos, size.x, GetLayerParams().m_LayerNegative );
                                 m_CurrentPos, size, GetLayerParams().m_LayerNegative );
                StepAndRepeatItem( *gbritem );
                StepAndRepeatItem( *gbritem );
                break;
                break;


@@ -708,7 +707,7 @@ bool GERBER_IMAGE::Execute_DCODE_Command( char*& text, int D_commande )
//                           m_CurrentPos.y, m_IJPos.x,
//                           m_CurrentPos.y, m_IJPos.x,
//                            m_IJPos.y, m_Iterpolation, m_360Arc_enbl ); )
//                            m_IJPos.y, m_Iterpolation, m_360Arc_enbl ); )
                fillArcGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos,
                fillArcGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos,
                                m_CurrentPos, m_IJPos, size.x,
                                m_CurrentPos, m_IJPos, size,
                                ( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ?
                                ( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ?
                                false : true, m_360Arc_enbl, GetLayerParams().m_LayerNegative );
                                false : true, m_360Arc_enbl, GetLayerParams().m_LayerNegative );
                StepAndRepeatItem( *gbritem );
                StepAndRepeatItem( *gbritem );
+2 −0
Original line number Original line Diff line number Diff line
@@ -245,9 +245,11 @@ void DRAWSEGMENT::Draw( WinEDA_DrawPanel* panel, wxDC* DC,
    GRSetDrawMode( DC, draw_mode );
    GRSetDrawMode( DC, draw_mode );
    l_piste = m_Width >> 1;  /* half trace width */
    l_piste = m_Width >> 1;  /* half trace width */


    // Line start point or Circle and Arc center
    ux0 = m_Start.x;
    ux0 = m_Start.x;
    uy0 = m_Start.y;
    uy0 = m_Start.y;


    // Line end point or circle and arc start point
    dx = m_End.x;
    dx = m_End.x;
    dy = m_End.y;
    dy = m_End.y;


Loading