~cern-kicad/kicad/kicad-pns-tom

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
// PolyLine.h ... definition of CPolyLine class

//
// A polyline contains one or more contours, where each contour
// is defined by a list of corners and side-styles
// There may be multiple contours in a polyline.
// The last contour may be open or closed, any others must be closed.
// All of the corners and side-styles are concatenated into 2 arrays,
// separated by setting the end_contour flag of the last corner of
// each contour.
//
// When used for copper (or technical layers) areas, the first contour is the outer edge
// of the area, subsequent ones are "holes" in the copper.

#ifndef POLYLINE_H
#define POLYLINE_H

#include <vector>

#include <pad_shapes.h>
#include <wx/gdicmn.h>      // for wxPoint definition
#include <layers_id_colors_and_visibility.h>
#include <polygons_defs.h>

class CRect
{
public:
    int left, right, top, bottom;
};

class CSegment
{
public:
    wxPoint m_Start;
    wxPoint m_End;

    CSegment() { };
    CSegment( const wxPoint& aStart, const wxPoint& aEnd )
    {
        m_Start = aStart;
        m_End   = aEnd;
    }

    CSegment( int x0, int y0, int x1, int y1 )
    {
        m_Start.x   = x0; m_Start.y = y0;
        m_End.x     = x1; m_End.y = y1;
    }
};

class CPolyPt : public wxPoint
{
public:
    CPolyPt( int aX = 0, int aY = 0, bool aEnd = false, int aUtility = 0 ) :
        wxPoint( aX, aY ), end_contour( aEnd ), m_utility( aUtility )
    {}

    // / Pure copy constructor is here to dis-ambiguate from the
    // / specialized CPolyPt( const wxPoint& ) constructor version below.
    CPolyPt( const CPolyPt& aPt ) :
        wxPoint( aPt.x, aPt.y ), end_contour( aPt.end_contour ), m_utility( aPt.m_utility )
    {}

    CPolyPt( const wxPoint& aPoint ) :
        wxPoint( aPoint ), end_contour( false ), m_utility( 0 )
    {}


    bool    end_contour;
    int     m_utility;

    bool operator ==( const CPolyPt& cpt2 ) const
    { return (x == cpt2.x) && (y == cpt2.y) && (end_contour == cpt2.end_contour); }

    bool operator !=( CPolyPt& cpt2 ) const
    { return (x != cpt2.x) || (y != cpt2.y) || (end_contour != cpt2.end_contour); }
};

/**
 * CPOLYGONS_LIST handle a list of contours (polygons corners).
 * Each corner is a CPolyPt item.
 * The last cornet of each contour has its end_contour member = true
 */
class CPOLYGONS_LIST
{
private:
    std::vector <CPolyPt> m_cornersList;    // array of points for corners
public:
    CPOLYGONS_LIST() {};

    CPolyPt& operator [](int aIdx) {return m_cornersList[aIdx]; }

    // Accessor:
    const std::vector <CPolyPt>& GetList() const {return m_cornersList;}
    int        GetX( int ic ) const { return m_cornersList[ic].x; }
    void       SetX( int ic, int aValue ) { m_cornersList[ic].x = aValue; }
    int        GetY( int ic ) const { return m_cornersList[ic].y; }
    void       SetY( int ic, int aValue ) { m_cornersList[ic].y = aValue; }
    int        GetUtility( int ic ) const { return m_cornersList[ic].m_utility; }
    void       SetFlag( int ic, int aFlag )
    {
        m_cornersList[ic].m_utility = aFlag;
    }

    bool       IsEndContour( int ic ) const
    {
        return m_cornersList[ic].end_contour;
    }

    void        SetEndContour( int ic, bool end_contour )
    {
        m_cornersList[ic].end_contour = end_contour;
    }

    const wxPoint&  GetPos( int ic ) const { return m_cornersList[ic]; }
    const CPolyPt&  GetCorner( int ic ) const { return m_cornersList[ic]; }

    // vector <> methods
    void reserve( int aSize ) { m_cornersList.reserve( aSize ); }


    void RemoveAllContours( void ) { m_cornersList.clear(); }
    CPolyPt& GetLastCorner() { return m_cornersList.back(); }

    unsigned GetCornersCount() const { return m_cornersList.size(); }

    void DeleteCorner( int aIdx )
    {
        m_cornersList.erase( m_cornersList.begin() + aIdx );
    }

    void DeleteCorners( int aIdFirstCorner, int aIdLastCorner )
    {
        m_cornersList.erase( m_cornersList.begin() + aIdFirstCorner,
                             m_cornersList.begin() + aIdLastCorner + 1 );
    }

    void Append( const CPOLYGONS_LIST& aList )
    {
        m_cornersList.insert( m_cornersList.end(),
                              aList.m_cornersList.begin(),
                              aList.m_cornersList.end() );
    }

    void Append( const CPolyPt& aItem )
    {
        m_cornersList.push_back( aItem );
    }

    void Append( const wxPoint& aItem )
    {
        CPolyPt item( aItem );

        m_cornersList.push_back( aItem );
    }

    void InsertCorner( int aPosition, const CPolyPt& aItem )
    {
        m_cornersList.insert( m_cornersList.begin() + aPosition + 1, aItem );
    }

    /**
     * Function ExportTo
     * Copy all contours to a KI_POLYGON_SET
     * @param aPolygons = the KI_POLYGON_WITH_HOLES to populate
     */
    void    ExportTo( KI_POLYGON_SET& aPolygons );

    /**
     * Function ExportTo
     * Copy the contours to a KI_POLYGON_WITH_HOLES
     * The first contour is the main outline, others are holes
     * @param aPolygoneWithHole = the KI_POLYGON_WITH_HOLES to populate
     */
    void    ExportTo( KI_POLYGON_WITH_HOLES& aPolygoneWithHole );

    /**
     * Function ImportFrom
     * Copy all polygons from a KI_POLYGON_SET in list
     * @param aPolygons = the KI_POLYGON_SET to import
     */
    void    ImportFrom( KI_POLYGON_SET& aPolygons );

    /**
     * function AddCorner
     * add a corner to the list
     */
    void    AddCorner( const CPolyPt& aCorner )
    {
        m_cornersList.push_back( aCorner );
    }

    /**
     * function CloseLastContour
     * Set the .end_contour member of the last corner in list to true
     */
    void    CloseLastContour()
    {
        if( m_cornersList.size() > 0 )
            m_cornersList.back().end_contour = true;
    }
};

class CPolyLine
{
public:
    enum HATCH_STYLE { NO_HATCH, DIAGONAL_FULL, DIAGONAL_EDGE };    // hatch styles

    // constructors/destructor
    CPolyLine();
    CPolyLine( const CPolyLine& aCPolyLine);
    ~CPolyLine();

    /**
     * Function ImportSettings
     * Copy settings (layer, hatch styles) from aPoly
     * @param aPoly is the CPolyLine to import settings
     */
    void        ImportSettings( const CPolyLine* aPoly );

    // functions for modifying the CPolyLine contours

    /* initialize a contour
     * set layer, hatch style, and starting point
     */
    void        Start( LAYER_NUM layer, int x, int y, int hatch );

    void        AppendCorner( int x, int y );
    void        InsertCorner( int ic, int x, int y );

    /**
     * Function DeleteCorner
     * remove the given corner. if it is the last point of a contour
     * keep the controur closed by modifying the previous corner
     * @param ic = the index of the corner to delete
     */
    void        DeleteCorner( int ic );
    void        MoveCorner( int ic, int x, int y );

    /**
     * function CloseLastContour
     * Set the .end_contour member of the last corner
     *  of the last contour to true
     */
    void        CloseLastContour()
    {
        m_CornersList.CloseLastContour();
    }

    void        RemoveContour( int icont );

    /**
     * Function IsPolygonSelfIntersecting
     * Test a CPolyLine for self-intersection of vertex (all contours).
     *
     * @return :
     *  false if no intersecting sides
     *  true if intersecting sides
     * When a CPolyLine is self intersectic, it need to be normalized.
     * (converted to non intersecting polygons)
     */
    bool        IsPolygonSelfIntersecting();

    /**
     * Function Chamfer
     * returns a chamfered version of a polygon.
     * @param aDistance is the chamfering distance.
     * @return CPolyLine* - Pointer to new polygon.
     */
    CPolyLine*  Chamfer( unsigned int aDistance );

    /**
     * Function Fillet
     * returns a filleted version of a polygon.
     * @param aRadius is the fillet radius.
     * @param aSegments is the number of segments / fillet.
     * @return CPolyLine* - Pointer to new polygon.
     */
    CPolyLine*  Fillet( unsigned int aRadius, unsigned int aSegments );

    /**
     * Function RemoveNullSegments
     * Removes corners which create a null segment edge
     * (i.e. when 2 successive corners are at the same location)
     * @return the count of removed corners.
     */
    int         RemoveNullSegments();

    void        RemoveAllContours( void );

    // Remove or create hatch
    void        UnHatch();
    void        Hatch();

    // Transform functions
    void        MoveOrigin( int x_off, int y_off );

    // misc. functions
    CRect       GetBounds();
    CRect       GetCornerBounds();
    CRect       GetCornerBounds( int icont );
    void        Copy( const CPolyLine* src );
    bool        TestPointInside( int x, int y );

    /**
     * @return true if the corner aCornerIdx is on a hole inside the main outline
     * and false if it is on the main outline
     */
    bool        IsCutoutContour( int aCornerIdx );

    /**
     * Function AppendArc.
     * Adds segments to current contour to approximate the given arc
     */
    void        AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int num );

    // access functions
    void       SetLayer( LAYER_NUM aLayer ) { m_layer = aLayer; }
    LAYER_NUM  GetLayer() const { return m_layer; }

    int GetCornersCount() const
    {
        return m_CornersList.GetCornersCount();
    }
    int         GetClosed();
    int         GetContoursCount();
    int         GetContour( int ic );
    int         GetContourStart( int icont );
    int         GetContourEnd( int icont );
    int         GetContourSize( int icont );

    int        GetX( int ic ) const { return m_CornersList.GetX( ic ); }
    int        GetY( int ic ) const { return m_CornersList.GetY( ic ); }
    bool       IsEndContour( int ic ) const
    { return m_CornersList.IsEndContour( ic ); }

    const wxPoint& GetPos( int ic ) const { return m_CornersList.GetPos( ic ); }

    int GetEndContour( int ic );

    int        GetUtility( int ic ) const { return m_CornersList.GetUtility( ic ); };
    void       SetUtility( int ic, int aFlag ) { m_CornersList.SetFlag( ic, aFlag ); };

    int        GetHatchPitch() const { return m_hatchPitch; }
    static int GetDefaultHatchPitchMils() { return 20; }    // default hatch pitch value in mils

    enum HATCH_STYLE GetHatchStyle() const { return m_hatchStyle; }
    void       SetHatch( int aHatchStyle, int aHatchPitch, bool aRebuildHatch )
    {
        SetHatchPitch( aHatchPitch );
        m_hatchStyle = (enum HATCH_STYLE) aHatchStyle;

        if( aRebuildHatch )
            Hatch();
    }

    void    SetX( int ic, int x )
    {
        m_CornersList.SetX( ic, x );
    }

    void    SetY( int ic, int y )
    {
        m_CornersList.SetY( ic, y );
    }

    void    SetEndContour( int ic, bool end_contour )
    {
        m_CornersList.SetEndContour( ic, end_contour );
    }

    void       SetHatchStyle( enum HATCH_STYLE style )
    {
        m_hatchStyle = style;
    }

    void       SetHatchPitch( int pitch ) { m_hatchPitch = pitch; }

    /**
     * Function NormalizeAreaOutlines
     * Convert a self-intersecting polygon to one (or more) non self-intersecting polygon(s)
     * @param aNewPolygonList = a std::vector<CPolyLine*> reference where to store new CPolyLine
     * needed by the normalization
     * @return the polygon count (always >= 1, because there is at least one polygon)
     * There are new polygons only if the polygon count  is > 1
     */
    int     NormalizeAreaOutlines( std::vector<CPolyLine*>* aNewPolygonList );

    // Bezier Support
    void    AppendBezier( int x1, int y1, int x2, int y2, int x3, int y3 );
    void    AppendBezier( int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4 );

    /**
     * Function Distance
     * Calculates the distance between a point and the zone:
     * @param aPoint the coordinate of the point.
     * @return int = distance between the point and outline.
     *               0 if the point is inside
     */
    int     Distance( const wxPoint& aPoint );

    /**
     * Function Distance
     * Calculates the distance between a segment and the zone:
     * @param aStart the starting point of the segment.
     * @param aEnd  the ending point of the segment.
     * @param aWidth  the width of the segment.
     * @return int = distance between the segment and outline.
     *               0 if segment intersects or is inside
     */
    int     Distance( wxPoint aStart, wxPoint aEnd, int aWidth );

private:
    LAYER_NUM           m_layer;            // layer to draw on
    enum HATCH_STYLE    m_hatchStyle;       // hatch style, see enum above
    int                     m_hatchPitch;   // for DIAGONAL_EDGE hatched outlines, basic distance between 2 hatch lines
                                            // and the len of eacvh segment
                                            // for DIAGONAL_FULL, the pitch is twice this value
    int                     m_utility;      // a flag used in some calculations
public:
    CPOLYGONS_LIST          m_CornersList;  // array of points for corners
    std::vector <CSegment>  m_HatchLines;   // hatch lines showing the polygon area
};

/**
 * Function ConvertPolysListWithHolesToOnePolygon
 * converts the outline contours aPolysListWithHoles with holes to one polygon
 * with no holes (only one contour)
 * holes are linked to main outlines by overlap segments, to give only one polygon
 *
 * @param aPolysListWithHoles = the list of corners of contours
 *                             (main outline and holes)
 * @param aOnePolyList = a polygon with no holes
 */
void    ConvertPolysListWithHolesToOnePolygon( const CPOLYGONS_LIST&    aPolysListWithHoles,
                                               CPOLYGONS_LIST&          aOnePolyList );

#endif    // #ifndef POLYLINE_H