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

3D viewer: Modify yhe way board items shapes are built:

* All items shapes  are converted to polygons.
* Polygons are merged layer by layer (for calculation time reasons,zones are not merged)
* for copper layers, vias and pads holes are substracted from polygons (but, for calculation time reasons,  not inside zones areas).
* the look is better, mainly when displaying the copper thickness
* solder and paste layers are now shown in 3D viewer.
* the code was seriously cleaned (but still needs to be enhanced).
* Note this is a work in progress which needs refinements.
parent 0e903dba
Loading
Loading
Loading
Loading
+9 −39
Original line number Diff line number Diff line
@@ -100,7 +100,8 @@ public:

    /**
     * Function CreateDrawGL_List
     * creates the OpenGL draw list items.
     * Prepares the parameters of the OpenGL draw list
     * creates the OpenGL draw list items (board, grid ...
     */
    GLuint CreateDrawGL_List();
    void   InitGL();
@@ -111,47 +112,16 @@ public:
        m_draw3dOffset.y = aPosY;
    }

    void   DrawGrid( double aGriSizeMM );

    /**
     * Function Draw3D_Track
     * @param aTrack = the aTrack to draw
    */
    void   Draw3D_Track( TRACK* aTrack );

    /**
     * Function Draw3D_Via
     * draws 3D via as a cylinder and filled circles.
     */
    void   Draw3D_Via( SEGVIA* via );

    /**
     * Function Draw3D_DrawSegment
     * draws a 3D segment (line, arc or circle).
     * Function BuildBoard3DView
     * Called by CreateDrawGL_List()
     * Fills the OpenGL draw list with board items draw list.
     */
    void   Draw3D_DrawSegment( DRAWSEGMENT* segment );
    void   BuildBoard3DView();

    /**
     * Function Draw3D_Zone
     * draw all solid areas in aZone
     * @param aZone = the zone to draw
    */
    void Draw3D_Zone( ZONE_CONTAINER* aZone );

    /**
     * Function Draw3D_DrawText
     * draws 3D segments to create text objects.
     * When DrawGraphicText is called to draw a text to an OpenGL DC
     * it calls Draw3dTextSegm to each segment to draw.
     * 2 parameters used by Draw3D_FilledSegment are not handled by DrawGraphicText
     * but are used in Draw3D_FilledSegment().
     * they are 2 local variables. This is an ugly, but trivial code.
     * Using DrawGraphicText to draw all texts ensure texts have the same shape
     * in all contexts
     */
    void   Draw3D_DrawText( TEXTE_PCB* text );

    //int Get3DLayerEnable(int act_layer);
    void   DrawGrid( double aGriSizeMM );
    void   Draw3DViaHole( SEGVIA * aVia );
    void   Draw3DPadHole( D_PAD * aPad );

    DECLARE_EVENT_TABLE()
};
+359 −683

File changed.

Preview size limit exceeded, changes collapsed.

+140 −1
Original line number Diff line number Diff line
@@ -32,6 +32,82 @@
#include <common.h>
#include <convert_basic_shapes_to_polygon.h>

/* Helper functions:
 * We are using a lots polygons in calculations.
 * and we are using 2 descriptions,
 * one easy to use with boost::polygon (KI_POLYGON_SET)
 * one easy to use in zones and in draw functions (std::vector<CPolyPt>)
 * Copy polygons from a KI_POLYGON_SET set of polygons to
 * a std::vector<CPolyPt> polygon list
 * Therefore we need conversion functions between these 2 descriptions
 */
void CopyPolygonsFromKiPolygonListToPolysList( KI_POLYGON_SET& aKiPolyList,
                                               std::vector<CPolyPt>& aPolysList )
{
    for( unsigned ii = 0; ii < aKiPolyList.size(); ii++ )
    {
        KI_POLYGON& poly = aKiPolyList[ii];
        CPolyPt   corner( 0, 0, false );

        for( unsigned jj = 0; jj < poly.size(); jj++ )
        {
            KI_POLY_POINT point = *(poly.begin() + jj);
            corner.x = point.x();
            corner.y = point.y();
            corner.end_contour = false;
            aPolysList.push_back( corner );
        }

        corner.end_contour = true;
        aPolysList.pop_back();
        aPolysList.push_back( corner );
    }
}

/**
 * Helper function AddPolygonCornersToKiPolygonList
 * This function adds a KI_POLYGON_SET description to a
 * std::vector<CPolyPt> description
 * @param aCornersBuffer = source (set of polygons using CPolyPt corners descr)
 * @param aPolysList = destination (set of polygons)
 */
void AddPolygonCornersToKiPolygonList( std::vector <CPolyPt>& aCornersBuffer,
                                      KI_POLYGON_SET&           aKiPolyList )
{
    std::vector<KI_POLY_POINT> cornerslist;
    unsigned corners_count = aCornersBuffer.size();

    // Count the number of polygons in aCornersBuffer
    int polycount = 0;
    for( unsigned ii = 0; ii < corners_count; ii++ )
    {
        if( aCornersBuffer[ii].end_contour )
            polycount++;
    }

    aKiPolyList.reserve( polycount );

    for( unsigned icnt = 0; icnt < corners_count; )
    {
        KI_POLYGON poly;
        cornerslist.clear();

        unsigned ii;
        for( ii = icnt; ii < aCornersBuffer.size(); ii++ )
        {
            cornerslist.push_back( KI_POLY_POINT( aCornersBuffer[ii].x, aCornersBuffer[ii].y ) );

            if( aCornersBuffer[ii].end_contour )
                break;
        }

        bpl::set_points( poly, cornerslist.begin(), cornerslist.end() );
        aKiPolyList.push_back( poly );
        icnt = ii + 1;
    }
}


/**
 * Function TransformCircleToPolygon
 * convert a circle to a polygon, using multiple straight lines
@@ -192,5 +268,68 @@ void TransformArcToPolygon( std::vector <CPolyPt>& aCornerBuffer,

    if( curr_end != arc_end )
        TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
                                              curr_end, arc_end, aCircleToSegmentsCount, aWidth );
                                              curr_end, arc_end,
                                              aCircleToSegmentsCount, aWidth );
}

/**
 * Function TransformRingToPolygon
 * Creates a polygon from a ring
 * Convert arcs to multiple straight segments
 * @param aCornerBuffer = a buffer to store the polygon
 * @param aCentre = centre of the arc or circle
 * @param aRadius = radius of the circle
 * @param aCircleToSegmentsCount = the number of segments to approximate a circle
 * @param aWidth = width (thickness) of the ring
 */
void TransformRingToPolygon( std::vector <CPolyPt>& aCornerBuffer,
                            wxPoint aCentre, int aRadius,
                            int aCircleToSegmentsCount, int aWidth )
{
    int     delta = 3600 / aCircleToSegmentsCount;   // rotate angle in 0.1 degree

    // Compute the corners posituions and creates poly
    wxPoint curr_point;
    int inner_radius = aRadius - ( aWidth / 2 );
    int outer_radius = inner_radius + aWidth;
    CPolyPt polycorner;

    // Draw the inner circle of the ring
    for( int ii = 0; ii < 3600; ii += delta )
    {
        curr_point.x = inner_radius;
        curr_point.y = 0;
        RotatePoint( &curr_point, ii );
        curr_point += aCentre;
        polycorner.x = curr_point.x;
        polycorner.y = curr_point.y;
        aCornerBuffer.push_back( polycorner );
    }

    // Draw the last point of inner circle
    polycorner.x = aCentre.x + inner_radius;
    polycorner.y = aCentre.y;
    aCornerBuffer.push_back( polycorner );

    // Draw the outer circle of the ring
    for( int ii = 0; ii < 3600; ii += delta )
    {
        curr_point.x = outer_radius;
        curr_point.y = 0;
        RotatePoint( &curr_point, -ii );
        curr_point += aCentre;
        polycorner.x = curr_point.x;
        polycorner.y = curr_point.y;
        aCornerBuffer.push_back( polycorner );
    }

    // Draw the last point of outer circle
    polycorner.x = aCentre.x + outer_radius;
    polycorner.y = aCentre.y;
    aCornerBuffer.push_back( polycorner );

    // Close the polygon
    polycorner.x = aCentre.x + inner_radius;
    polycorner.end_contour = true;
    aCornerBuffer.push_back( polycorner );
}
+1 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ set(CVPCB_DIALOGS

set(CVPCB_SRCS
    ../common/base_units.cpp
    ../pcbnew/board_items_to_polygon_shape_transform.cpp
    ../pcbnew/class_drc_item.cpp
    autosel.cpp
    cfg.cpp
+41 −0
Original line number Diff line number Diff line
@@ -35,6 +35,33 @@
#include <macros.h>
#include <PolyLine.h>

/**
 * Helper function CopyPolygonsFromKiPolygonListToPolysList
 * We are using a lots polygons in calculations.
 * and we are using 2 descriptions,
 * one easy to use with boost::polygon (KI_POLYGON_SET)
 * one easy to use in zones and in draw functions (std::vector<CPolyPt>)
 * Copy polygons from a KI_POLYGON_SET set of polygons to
 * a std::vector<CPolyPt> polygon list
 * Therefore we need conversion functions between these 2 descriptions
 * This function converts a KI_POLYGON_SET description to a
 * std::vector<CPolyPt> description
 * @param aKiPolyList = source (set of polygons)
 * @param aPolysList = destination (set of polygons using CPolyPt corners descr)
 */
void CopyPolygonsFromKiPolygonListToPolysList( KI_POLYGON_SET& aKiPolyList,
                                               std::vector<CPolyPt>& aPolysList );

/**
 * Helper function AddPolygonCornersToKiPolygonList
 * This function adds a KI_POLYGON_SET description to a
 * std::vector<CPolyPt> description
 * @param aCornersBuffer = source (set of polygons using CPolyPt corners descr)
 * @param aPolysList = destination (set of polygons)
 */
void AddPolygonCornersToKiPolygonList( std::vector <CPolyPt>& aCornersBuffer,
                                       KI_POLYGON_SET&        aKiPolyList );

/**
 * Function TransformCircleToPolygon
 * convert a circle to a polygon, using multiple straight lines
@@ -82,4 +109,18 @@ void TransformArcToPolygon( std::vector <CPolyPt>& aCornerBuffer,
                            wxPoint aCentre, wxPoint aStart, int aArcAngle,
                            int aCircleToSegmentsCount, int aWidth );

/**
 * Function TransformRingToPolygon
 * Creates a polygon from a ring
 * Convert arcs to multiple straight segments
 * @param aCornerBuffer = a buffer to store the polygon
 * @param aCentre = centre of the arc or circle
 * @param aRadius = radius of the circle
 * @param aCircleToSegmentsCount = the number of segments to approximate a circle
 * @param aWidth = width (thickness) of the ring
 */
void TransformRingToPolygon( std::vector <CPolyPt>& aCornerBuffer,
                            wxPoint aCentre, int aRadius,
                            int aCircleToSegmentsCount, int aWidth );

#endif     // CONVERT_BASIC_SHAPES_TO_POLYGON_H
Loading