forked from KiCad/kicad-source-mirror
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patheda_shape.h
314 lines (248 loc) · 10 KB
/
eda_shape.h
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
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef EDA_SHAPE_H
#define EDA_SHAPE_H
#include <eda_units.h>
#include <convert_to_biu.h>
#include <trigo.h>
#include <geometry/shape_poly_set.h>
#include <geometry/geometry_utils.h>
class LINE_READER;
class EDA_DRAW_FRAME;
class FOOTPRINT;
class MSG_PANEL_ITEM;
enum class SHAPE_T : int
{
SEGMENT = 0,
RECT,
ARC,
CIRCLE,
POLY,
BEZIER,
LAST ///< marker for list end
};
// WARNING: Do not change these values without updating dialogs that depend on their position values
enum class FILL_T : int
{
NO_FILL = 1,
FILLED_SHAPE, // Fill with object color
FILLED_WITH_BG_BODYCOLOR, // Fill with background body color
FILLED_WITH_COLOR // Fill with a separate color
};
class EDA_SHAPE
{
public:
EDA_SHAPE( SHAPE_T aType, int aLineWidth, FILL_T aFill, bool eeWinding );
// Do not create a copy constructor & operator=.
// The ones generated by the compiler are adequate.
~EDA_SHAPE();
void SwapShape( EDA_SHAPE* aImage );
wxString ShowShape() const;
wxString SHAPE_T_asString() const;
void SetFillMode( FILL_T aFill ) { m_fill = aFill; }
FILL_T GetFillType() const { return m_fill; }
bool IsFilled() const { return GetFillType() != FILL_T::NO_FILL; }
void SetFilled( bool aFlag )
{
m_fill = aFlag ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL;
}
void SetWidth( int aWidth ) { m_width = aWidth; }
int GetWidth() const { return m_width; }
void SetShape( SHAPE_T aShape ) { m_shape = aShape; }
SHAPE_T GetShape() const { return m_shape; }
/**
* Return the starting point of the graphic.
*/
const wxPoint& GetStart() const { return m_start; }
int GetStartY() { return m_start.y; }
int GetStartX() { return m_start.x; }
void SetStart( const wxPoint& aStart )
{
m_start = aStart;
m_endsSwapped = false;
}
void SetStartY( int y )
{
m_start.y = y;
m_endsSwapped = false;
}
void SetStartX( int x )
{
m_start.x = x;
m_endsSwapped = false;
}
/**
* Return the ending point of the graphic.
*/
const wxPoint& GetEnd() const { return m_end; }
int GetEndY() { return m_end.y; }
int GetEndX() { return m_end.x; }
void SetEnd( const wxPoint& aEnd )
{
m_end = aEnd;
m_endsSwapped = false;
}
void SetEndY( int y )
{
m_end.y = y;
m_endsSwapped = false;
}
void SetEndX( int x )
{
m_end.x = x;
m_endsSwapped = false;
}
void SetBezierC1( const wxPoint& aPt ) { m_bezierC1 = aPt; }
const wxPoint& GetBezierC1() const { return m_bezierC1; }
void SetBezierC2( const wxPoint& aPt ) { m_bezierC2 = aPt; }
const wxPoint& GetBezierC2() const { return m_bezierC2; }
wxPoint getCenter() const;
void SetCenter( const wxPoint& aCenter );
/**
* Set the end point from the angle center and start.
*
* @param aAngle is tenths of degrees.
*/
void SetArcAngleAndEnd( double aAngle, bool aCheckNegativeAngle = false );
double GetArcAngle() const;
/**
* Have the start and end points been swapped since they were set?
* @return true if they have
*/
bool EndsSwapped() const { return m_endsSwapped; }
// Some attributes are read only, since they are derived from m_Start, m_End, and m_Angle.
// No Set...() function for these attributes.
wxPoint GetArcMid() const;
std::vector<wxPoint> GetRectCorners() const;
/**
* Calc arc start and end angles such that aStartAngle < aEndAngle. Each may be between
* -360.0 and 360.0.
*/
void CalcArcAngles( double& aStartAngle, double& aEndAngle ) const;
int GetRadius() const;
/**
* Set the three controlling points for an arc.
*
* NB: these are NOT what's currently stored, so we have to do some calculations behind
* the scenes. However, they are what SHOULD be stored.
*/
void SetArcGeometry( const wxPoint& aStart, const wxPoint& aMid, const wxPoint& aEnd );
const std::vector<wxPoint>& GetBezierPoints() const { return m_bezierPoints; }
/**
* Duplicate the list of corners in a std::vector<wxPoint>
*
* It must be used only to convert the SHAPE_POLY_SET internal corner buffer
* to a list of wxPoints, and nothing else, because it duplicates the buffer,
* that is inefficient to know for instance the corner count
*/
void DupPolyPointsList( std::vector<wxPoint>& aBuffer ) const;
/**
* @return the number of corners of the polygonal shape
*/
int GetPointCount() const;
// Accessors to the polygonal shape
SHAPE_POLY_SET& GetPolyShape() { return m_poly; }
const SHAPE_POLY_SET& GetPolyShape() const { return m_poly; }
/**
* @return true if the polygonal shape is valid (has more than 2 points)
*/
bool IsPolyShapeValid() const;
void SetPolyShape( const SHAPE_POLY_SET& aShape ) { m_poly = aShape; }
void SetBezierPoints( const std::vector<wxPoint>& aPoints ) { m_bezierPoints = aPoints; }
/**
* Rebuild the m_BezierPoints vertex list that approximate the Bezier curve
* by a list of segments.
*
* Has meaning only for BEZIER shape.
*
* @param aMinSegLen is the min length of segments approximating the bezier. The shape's last
* segment can be shorter. This parameter avoids having too many very short
* segment in list. Good values are between m_width/2 and m_width.
*/
void RebuildBezierToSegmentsPointsList( int aMinSegLen );
void SetPolyPoints( const std::vector<wxPoint>& aPoints );
/**
* Make a set of SHAPE objects representing the EDA_SHAPE. Caller owns the objects.
*/
// fixme: move to shape_compound
std::vector<SHAPE*> MakeEffectiveShapes() const;
void ShapeGetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList );
/**
* Return the length of the track using the hypotenuse calculation.
*
* @return the length of the track
*/
double GetLength() const;
/**
* Convert the shape to a closed polygon.
*
* Used in filling zones calculations. Circles and arcs are approximated by segments.
*
* @param aCornerBuffer is a buffer to store the polygon.
* @param aClearanceValue is the clearance around the pad.
* @param aError is the maximum deviation from a true arc.
* @param aErrorLoc whether any approximation error shoule be placed inside or outside
* @param ignoreLineWidth is used for edge cut items where the line width is only
* for visualization
*/
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, int aClearanceValue,
int aError, ERROR_LOC aErrorLoc,
bool ignoreLineWidth ) const;
int Compare( const EDA_SHAPE* aOther ) const;
protected:
void setPosition( const wxPoint& aPos );
wxPoint getPosition() const;
void move( const wxPoint& aMoveVector );
void rotate( const wxPoint& aRotCentre, double aAngle );
void flip( const wxPoint& aCentre, bool aFlipLeftRight );
void scale( double aScale );
// To be implemented by concrete classes
virtual double getParentOrientation() const = 0;
virtual wxPoint getParentPosition() const = 0;
const EDA_RECT getBoundingBox() const;
void computeArcBBox( EDA_RECT& aBBox ) const;
bool hitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const;
bool hitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const;
const std::vector<wxPoint> buildBezierToSegmentsPointsList( int aMinSegLen ) const;
void beginEdit( const wxPoint& aStartPoint );
bool continueEdit( const wxPoint& aPosition );
void calcEdit( const wxPoint& aPosition );
void endEdit();
void setEditState( int aState ) { m_editState = aState; }
protected:
bool m_endsSwapped; // true if start/end were swapped e.g. SetArcAngleAndEnd
SHAPE_T m_shape; // Shape: line, Circle, Arc
int m_width; // thickness of lines ...
FILL_T m_fill;
wxPoint m_start; // Line start point or Circle center
wxPoint m_end; // Line end point or Circle 3 o'clock point
wxPoint m_arcCenter; // Used only for Arcs: arc end point
wxPoint m_bezierC1; // Bezier Control Point 1
wxPoint m_bezierC2; // Bezier Control Point 2
std::vector<wxPoint> m_bezierPoints;
SHAPE_POLY_SET m_poly; // Stores the S_POLYGON shape
int m_editState;
bool m_eeWinding; // Awful hack
};
#endif // EDA_SHAPE_H