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

Gerbview: minor enhancement. Boost::Polygon: commit forgotten file

parent bd022c23
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ int g_DrawBgColor = WHITE;
#define USE_CLIP_FILLED_POLYGONS

#ifdef USE_CLIP_FILLED_POLYGONS
void ClipAndDrawFilledPoly( EDA_Rect * ClipBox, wxDC * DC, wxPoint Points[], int n );
static void ClipAndDrawFilledPoly( EDA_Rect * ClipBox, wxDC * DC, wxPoint Points[], int n );
#endif

/* These functions are used by corresponding functions
@@ -1281,7 +1281,11 @@ static void GRSClosedPoly( EDA_Rect* ClipBox,
    {
        GRSMoveTo( aPoints[aPointCount - 1].x, aPoints[aPointCount - 1].y );
        GRSetBrush( DC, BgColor, FILLED );
        DC->DrawPolygon( aPointCount, aPoints, 0, 0, wxODDEVEN_RULE );
#ifdef USE_CLIP_FILLED_POLYGONS
        ClipAndDrawFilledPoly( ClipBox, DC, aPoints, aPointCount );
#else
        DC->DrawPolygon( aPointCount, aPoints );  // does not work very well under linux
#endif
    }
    else
    {
+2 −2
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ set(GERBVIEW_SRCS
    dialog_print_using_printer.cpp
    dialog_print_using_printer_base.cpp
    dummy_functions.cpp
    draw_gerber_screen.cpp
    edit.cpp
    export_to_pcbnew.cpp
    files.cpp
@@ -46,8 +47,7 @@ set(GERBVIEW_SRCS
    rs274d.cpp
    rs274x.cpp
    select_layers_to_pcb.cpp
    toolbars_gerber.cpp
    tracepcb.cpp )
    toolbars_gerber.cpp )

###
# We need some extra sources from pcbnew
+156 −33
Original line number Diff line number Diff line
@@ -139,7 +139,6 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,

    wxPoint curPos = aShapePos;
    D_CODE* tool   = aParent->GetDcodeDescr();
    bool    gerberMetric = m_GerbMetric;
    int rotation;
    if( mapExposure( aParent ) == false )
    {
@@ -155,9 +154,9 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
         * type (1), exposure, diameter, pos.x, pos.y
         * type is not stored in parameters list, so the first parameter is exposure
         */
        curPos += mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ), gerberMetric );
        curPos += mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ), m_GerbMetric );
        curPos = aParent->GetABPosition( curPos );
        int radius = scale( params[1].GetValue( tool ), gerberMetric ) / 2;
        int radius = scale( params[1].GetValue( tool ), m_GerbMetric ) / 2;
        if( !aFilledShape )
            GRCircle( aClipBox, aDC, curPos, radius, 0, aColor );
        else
@@ -173,7 +172,7 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
         * type (2), exposure, width, start.x, start.y, end.x, end.y, rotation
         * type is not stored in parameters list, so the first parameter is exposure
         */
        ConvertShapeToPolygon( aParent, polybuffer, gerberMetric );
        ConvertShapeToPolygon( aParent, polybuffer );

        // shape rotation:
        rotation = wxRound( params[6].GetValue( tool ) * 10.0 );
@@ -202,7 +201,7 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
         * type (21), exposure, ,width, height, center pos.x, center pos.y, rotation
         * type is not stored in parameters list, so the first parameter is exposure
         */
        ConvertShapeToPolygon( aParent, polybuffer, gerberMetric );
        ConvertShapeToPolygon( aParent, polybuffer );

        // shape rotation:
        rotation = wxRound( params[5].GetValue( tool ) * 10.0 );
@@ -231,7 +230,7 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
         * type (22), exposure, ,width, height, corner pos.x, corner pos.y, rotation
         * type is not stored in parameters list, so the first parameter is exposure
         */
        ConvertShapeToPolygon( aParent, polybuffer, gerberMetric );
        ConvertShapeToPolygon( aParent, polybuffer );

        // shape rotation:
        rotation = wxRound( params[5].GetValue( tool ) * 10.0 );
@@ -260,8 +259,8 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
         * type (7), center.x , center.y, outside diam, inside diam, crosshair thickness, rotation
         * type is not stored in parameters list, so the first parameter is center.x
         */
        curPos += mapPt( params[0].GetValue( tool ), params[1].GetValue( tool ), gerberMetric );
        ConvertShapeToPolygon( aParent, polybuffer, gerberMetric );
        curPos += mapPt( params[0].GetValue( tool ), params[1].GetValue( tool ), m_GerbMetric );
        ConvertShapeToPolygon( aParent, polybuffer );

        // shape rotation:
        rotation = wxRound( params[5].GetValue( tool ) * 10.0 );
@@ -293,16 +292,16 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
    case AMP_MOIRE:     // A cross hair with n concentric circles
    {
        curPos += mapPt( params[0].GetValue( tool ), params[1].GetValue( tool ),
                         gerberMetric );
                         m_GerbMetric );

        /* Generated by an aperture macro declaration like:
         * "6,0,0,0.125,.01,0.01,3,0.003,0.150,0"
         * type(6), pos.x, pos.y, diam, penwidth, gap, circlecount, crosshair thickness, crosshaire len, rotation
         * type is not stored in parameters list, so the first parameter is pos.x
         */
        int outerDiam    = scale( params[2].GetValue( tool ), gerberMetric );
        int penThickness = scale( params[3].GetValue( tool ), gerberMetric );
        int gap = scale( params[4].GetValue( tool ), gerberMetric );
        int outerDiam    = scale( params[2].GetValue( tool ), m_GerbMetric );
        int penThickness = scale( params[3].GetValue( tool ), m_GerbMetric );
        int gap = scale( params[4].GetValue( tool ), m_GerbMetric );
        int numCircles = wxRound( params[5].GetValue( tool ) );

        // Draw circles:
@@ -327,7 +326,7 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
        }

        // Draw the cross:
        ConvertShapeToPolygon( aParent, polybuffer, gerberMetric );
        ConvertShapeToPolygon( aParent, polybuffer );

        rotation = wxRound( params[8].GetValue( tool ) * 10.0 );
        for( unsigned ii = 0; ii < polybuffer.size(); ii++ )
@@ -358,8 +357,8 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
        for( int i = 0; i<numPoints + 1; ++i )
        {
            int jj = i * 2 + 2;
            pos.x = scale( params[jj].GetValue( tool ), gerberMetric );
            pos.y = scale( params[jj + 1].GetValue( tool ), gerberMetric );
            pos.x = scale( params[jj].GetValue( tool ), m_GerbMetric );
            pos.y = scale( params[jj + 1].GetValue( tool ), m_GerbMetric );
            polybuffer.push_back(pos);
        }
        // rotate polygon and move it to the actual position
@@ -387,10 +386,9 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
         * type(5), exposure, vertices count, pox.x, pos.y, diameter, rotation
         * type is not stored in parameters list, so the first parameter is exposure
         */
        curPos += mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ),
                         gerberMetric );
        curPos += mapPt( params[2].GetValue( tool ), params[3].GetValue( tool ), m_GerbMetric );
        // Creates the shape:
        ConvertShapeToPolygon( aParent, polybuffer, gerberMetric );
        ConvertShapeToPolygon( aParent, polybuffer );

        // rotate polygon and move it to the actual position
        rotation  = wxRound( params[5].GetValue( tool ) * 10.0 );
@@ -426,8 +424,7 @@ void AM_PRIMITIVE::DrawBasicShape( GERBER_DRAW_ITEM* aParent,
 * and draw them as polygons is not a good idea.
 */
void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM*     aParent,
                                          std::vector<wxPoint>& aBuffer,
                                          bool                  aUnitsMetric )
                                          std::vector<wxPoint>& aBuffer )
{
    D_CODE* tool = aParent->GetDcodeDescr();

@@ -439,11 +436,11 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent,
    case AMP_LINE2:
    case AMP_LINE20:        // Line with rectangle ends. (Width, start and end pos + rotation)
    {
        int     width = scale( params[1].GetValue( tool ), aUnitsMetric );
        int     width = scale( params[1].GetValue( tool ), m_GerbMetric );
        wxPoint start = mapPt( params[2].GetValue( tool ),
                               params[3].GetValue( tool ), aUnitsMetric );
                               params[3].GetValue( tool ), m_GerbMetric );
        wxPoint end = mapPt( params[4].GetValue( tool ),
                             params[5].GetValue( tool ), aUnitsMetric );
                             params[5].GetValue( tool ), m_GerbMetric );
        wxPoint delta = end - start;
        int     len   = wxRound( hypot( delta.x, delta.y ) );

@@ -471,8 +468,8 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent,

    case AMP_LINE_CENTER:
    {
        wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), aUnitsMetric );
        wxPoint pos  = mapPt( params[3].GetValue( tool ), params[4].GetValue( tool ), aUnitsMetric );
        wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric );
        wxPoint pos  = mapPt( params[3].GetValue( tool ), params[4].GetValue( tool ), m_GerbMetric );

        // Build poly:
        pos.x -= size.x / 2;
@@ -489,9 +486,9 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent,

    case AMP_LINE_LOWER_LEFT:
    {
        wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), aUnitsMetric );
        wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric );
        wxPoint lowerLeft = mapPt( params[3].GetValue( tool ), params[4].GetValue(
                                       tool ), aUnitsMetric );
                                       tool ), m_GerbMetric );

        // Build poly:
        aBuffer.push_back( lowerLeft );
@@ -509,9 +506,9 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent,
        // Only 1/4 of the full shape is built, because the other 3 shapes will be draw from this first
        // rotated by 90, 180 and 270 deg.
        // params = center.x (unused here), center.y (unused here), outside diam, inside diam, crosshair thickness
        int outerRadius   = scale( params[2].GetValue( tool ), aUnitsMetric ) / 2;
        int innerRadius   = scale( params[3].GetValue( tool ), aUnitsMetric ) / 2;
        int halfthickness = scale( params[4].GetValue( tool ), aUnitsMetric ) / 2;
        int outerRadius   = scale( params[2].GetValue( tool ), m_GerbMetric ) / 2;
        int innerRadius   = scale( params[3].GetValue( tool ), m_GerbMetric ) / 2;
        int halfthickness = scale( params[4].GetValue( tool ), m_GerbMetric ) / 2;
        int angle_start   = wxRound( asin(
                                         (double) halfthickness / innerRadius ) * 1800 / M_PI );

@@ -560,8 +557,8 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent,
    case AMP_MOIRE:     // A cross hair with n concentric circles. Only the cros is build as polygon
                        // because circles can be drawn easily
    {
        int crossHairThickness = scale( params[6].GetValue( tool ), aUnitsMetric );
        int crossHairLength    = scale( params[7].GetValue( tool ), aUnitsMetric );
        int crossHairThickness = scale( params[6].GetValue( tool ), m_GerbMetric );
        int crossHairLength    = scale( params[7].GetValue( tool ), m_GerbMetric );

        // Create cross. First create 1/4 of the shape.
        // Others point are the same, totated by 90, 180 and 270 deg
@@ -594,7 +591,7 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent,
    case AMP_POLYGON:   // Creates a regular polygon
    {
        int vertexcount = wxRound( params[1].GetValue( tool ) );
        int radius    = scale( params[4].GetValue( tool ), aUnitsMetric ) / 2;
        int radius    = scale( params[4].GetValue( tool ), m_GerbMetric ) / 2;
        // rs274x said: vertex count = 3 ... 10, and the first corner is on the X axis
        if( vertexcount < 3 )
            vertexcount = 3;
@@ -615,6 +612,108 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent,
    }
}

/** GetShapeDim
 * Calculate a value that can be used to evaluate the size of text
 * when displaying the D-Code of an item
 * due to the complexity of the shape of some primitives
 * one cannot calculate the "size" of a shape (only abounding box)
 * but here, the "dimension" of the shape is the diameter of the primitive
 * or for lines the width of the line
 * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
 * @return a dimension, or -1 if no dim to calculate
  */
int AM_PRIMITIVE::GetShapeDim( GERBER_DRAW_ITEM* aParent )
{
    int dim = -1;
    D_CODE* tool = aParent->GetDcodeDescr();

    switch( primitive_id )
    {
    case AMP_CIRCLE:
        // params = exposure, diameter, pos.x, pos.y
        dim = scale( params[1].GetValue( tool ), m_GerbMetric );     // Diameter
        break;

    case AMP_LINE2:
    case AMP_LINE20:        // Line with rectangle ends. (Width, start and end pos + rotation)
        dim  = scale( params[1].GetValue( tool ), m_GerbMetric );   // linne width
    break;

    case AMP_LINE_CENTER:
    {
        wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric );
        dim = MIN(size.x, size.y);
    }
    break;

    case AMP_LINE_LOWER_LEFT:
    {
        wxPoint size = mapPt( params[1].GetValue( tool ), params[2].GetValue( tool ), m_GerbMetric );
        dim = MIN(size.x, size.y);
    }
    break;

    case AMP_THERMAL:
    {
        // Only 1/4 of the full shape is built, because the other 3 shapes will be draw from this first
        // rotated by 90, 180 and 270 deg.
        // params = center.x (unused here), center.y (unused here), outside diam, inside diam, crosshair thickness
        dim   = scale( params[2].GetValue( tool ), m_GerbMetric ) / 2;  // Outer diam
    }
    break;

    case AMP_MOIRE:     // A cross hair with n concentric circles.
        dim = scale( params[7].GetValue( tool ), m_GerbMetric );    // = cross hair len
        break;

    case AMP_OUTLINE:   // a free polygon :
    // dim = min side of the bounding box (this is a poor criteria, but what is a good criteria b?)
    {
        // exposure, corners count, corner1.x, corner.1y, ..., rotation
        int numPoints = (int) params[1].GetValue( tool );
        // Read points. numPoints does not include the starting point, so add 1.
        // and calculate the bounding box;
        wxSize pos_min, pos_max, pos;
        for( int i = 0; i<numPoints + 1; ++i )
        {
            int jj = i * 2 + 2;
            pos.x = scale( params[jj].GetValue( tool ), m_GerbMetric );
            pos.y = scale( params[jj + 1].GetValue( tool ), m_GerbMetric );
            if( i == 0 )
                pos_min = pos_max = pos;
            else
            {
                // upper right corner:
                if( pos_min.x > pos.x )
                    pos_min.x = pos.x;
                if( pos_min.y > pos.y )
                    pos_min.y = pos.y;
                // lower left corner:
                if( pos_max.x < pos.x )
                    pos_max.x = pos.x;
                if( pos_max.y < pos.y )
                    pos_max.y = pos.y;
            }
        }
        // calculate dim
        wxSize size;
        size.x = pos_max.x - pos_min.x;
        size.y = pos_max.y - pos_min.y;
        dim = MIN( size.x, size.y );
    }
        break;

    case AMP_POLYGON:   // Regular polygon
        dim = scale( params[4].GetValue( tool ), m_GerbMetric ) / 2;      // Radius
        break;

    case AMP_UNKNOWN:
    case AMP_EOF:
        break;
    }
    return dim;
}


/** function DrawApertureMacroShape
 * Draw the primitive shape for flashed items.
@@ -634,3 +733,27 @@ void APERTURE_MACRO::DrawApertureMacroShape( GERBER_DRAW_ITEM* aParent,
                                    aFilledShape );
    }
}

/** GetShapeDim
 * Calculate a value that can be used to evaluate the size of text
 * when displaying the D-Code of an item
 * due to the complexity of a shape using many primitives
 * one cannot calculate the "size" of a shape (only abounding box)
 * but most of aperture macro are using one or few primitives
 * and the "dimension" of the shape is the diameter of the primitive
 * (or the max diameter of primitives)
 * @return a dimension, or -1 if no dim to calculate
 */
int APERTURE_MACRO::GetShapeDim( GERBER_DRAW_ITEM* aParent )
{
    int dim = -1;
    for( AM_PRIMITIVES::iterator prim_macro = primitives.begin();
         prim_macro != primitives.end(); ++prim_macro )
    {
        int pdim = prim_macro->GetShapeDim( aParent );
        if( dim < pdim )
            dim = pdim;
    }

    return dim;
}
+26 −1
Original line number Diff line number Diff line
@@ -119,6 +119,18 @@ public:
    void DrawBasicShape( GERBER_DRAW_ITEM* aParent, EDA_Rect* aClipBox, wxDC* aDC,
                         int aColor, int aAltColor, wxPoint aShapePos, bool aFilledShape );

    /** GetShapeDim
     * Calculate a value that can be used to evaluate the size of text
     * when displaying the D-Code of an item
     * due to the complexity of the shape of some primitives
     * one cannot calculate the "size" of a shape (only a bounding box)
     * but here, the "dimension" of the shape is the diameter of the primitive
     * or for lines the width of the line
     * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
     * @return a dimension, or -1 if no dim to calculate
     */
    int GetShapeDim( GERBER_DRAW_ITEM* aParent );

private:

    /** function ConvertShapeToPolygon
@@ -127,7 +139,7 @@ private:
     * Useful when a shape is not a graphic primitive (shape with hole,
     * rotated shape ... ) and cannot be easily drawn.
     */
    void ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, std::vector<wxPoint>& aBuffer, bool aUnitsMetric);
    void ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, std::vector<wxPoint>& aBuffer );
};


@@ -155,6 +167,19 @@ struct APERTURE_MACRO
     */
    void DrawApertureMacroShape( GERBER_DRAW_ITEM* aParent, EDA_Rect* aClipBox, wxDC* aDC,
                                 int aColor, int aAltColor, wxPoint aShapePos, bool aFilledShape );

    /** GetShapeDim
     * Calculate a value that can be used to evaluate the size of text
     * when displaying the D-Code of an item
     * due to the complexity of a shape using many primitives
     * one cannot calculate the "size" of a shape (only abounding box)
     * but most of aperture macro are using one or few primitives
     * and the "dimension" of the shape is the diameter of the primitive
     * (or the max diameter of primitives)
     * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
     * @return a dimension, or -1 if no dim to calculate
     */
    int GetShapeDim( GERBER_DRAW_ITEM* aParent );
};


+41 −0
Original line number Diff line number Diff line
@@ -98,6 +98,47 @@ const wxChar* D_CODE::ShowApertureType( APERTURE_T aType )
    return ret;
}

/** GetShapeDim
 * Calculate a value that can be used to evaluate the size of text
 * when displaying the D-Code of an item
 * due to the complexity of some shapes,
 * one cannot calculate the "size" of a shape (only a bounding box)
 * but here, the "dimension" of the shape is the diameter of the primitive
 * or for lines the width of the line if the shape is a line
 * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
 * @return a dimension, or -1 if no dim to calculate
 */
int D_CODE::GetShapeDim( GERBER_DRAW_ITEM* aParent )
{
    int dim = -1;
    switch( m_Shape )
    {
    case APT_CIRCLE:
    case APT_LINE:
        dim = m_Size.x;
        break;

    case APT_RECT:
    case APT_OVAL:
        dim = MIN( m_Size.x, m_Size.y );
        break;

    case APT_POLYGON:
        dim = MIN( m_Size.x, m_Size.y );
        break;

    case APT_MACRO:
        if( m_Macro )
            dim = m_Macro->GetShapeDim( aParent );
        break;

    default:
        break;
    }

    return dim;
}


/** Function Read_D_Code_File
 * Can be useful only with old RS274D Gerber file format.
Loading