54#include <api/common/types/base_types.pb.h>
89 switch( aShape.
Type() )
93 auto rect = static_cast<const SHAPE_RECT&>( aShape );
94 m_shape = SHAPE_T::RECTANGLE;
95 SetStart( rect.GetPosition() );
96 SetEnd( rect.GetPosition() + rect.GetSize() );
102 auto seg = static_cast<const SHAPE_SEGMENT&>( aShape );
103 m_shape = SHAPE_T::SEGMENT;
104 SetStart( seg.GetSeg().A );
105 SetEnd( seg.GetSeg().B );
106 SetWidth( seg.GetWidth() );
112 auto line = static_cast<const SHAPE_LINE_CHAIN&>( aShape );
113 m_shape = SHAPE_T::POLY;
114 GetPolyShape() = SHAPE_POLY_SET();
115 GetPolyShape().AddOutline( line );
116 SetWidth( line.Width() );
122 auto circle = static_cast<const SHAPE_CIRCLE&>( aShape );
123 m_shape = SHAPE_T::CIRCLE;
124 SetStart( circle.GetCenter() );
125 SetEnd( circle.GetCenter() + circle.GetRadius() );
131 auto arc = static_cast<const SHAPE_ARC&>( aShape );
132 m_shape = SHAPE_T::ARC;
133 SetArcGeometry( arc.GetP0(), arc.GetArcMid(), arc.GetP1() );
134 SetWidth( arc.GetWidth() );
140 auto poly = static_cast<const SHAPE_SIMPLE&>( aShape );
141 m_shape = SHAPE_T::POLY;
142 poly.TransformToPolygon( GetPolyShape(), 0, ERROR_INSIDE );
148 auto ellipse = static_cast<const SHAPE_ELLIPSE&>( aShape );
149 m_shape = ellipse.IsArc() ? SHAPE_T::ELLIPSE_ARC : SHAPE_T::ELLIPSE;
150 SetEllipseCenter( ellipse.GetCenter() );
151 SetEllipseMajorRadius( ellipse.GetMajorRadius() );
152 SetEllipseMinorRadius( ellipse.GetMinorRadius() );
153 SetEllipseRotation( ellipse.GetRotation() );
155 if( ellipse.IsArc() )
157 SetEllipseStartAngle( ellipse.GetStartAngle() );
158 SetEllipseEndAngle( ellipse.GetEndAngle() );
197 m_poly = std::make_unique<SHAPE_POLY_SET>( *aOther.
m_poly );
203 if(
this == &aOther )
225 m_poly = std::make_unique<SHAPE_POLY_SET>( *aOther.
m_poly );
244 types::GraphicShape shape;
246 types::StrokeAttributes* stroke = shape.mutable_attributes()->mutable_stroke();
247 types::GraphicFillAttributes* fill = shape.mutable_attributes()->mutable_fill();
264 types::GraphicSegmentAttributes* segment = shape.mutable_segment();
272 types::GraphicRectangleAttributes* rectangle = shape.mutable_rectangle();
281 types::GraphicArcAttributes* arc = shape.mutable_arc();
290 types::GraphicCircleAttributes*
circle = shape.mutable_circle();
304 types::GraphicBezierAttributes* bezier = shape.mutable_bezier();
314 types::GraphicEllipseAttributes* ellipse = shape.mutable_ellipse();
324 types::GraphicEllipseArcAttributes* arc = shape.mutable_ellipse_arc();
335 wxASSERT_MSG(
false,
"Unhandled shape in EDA_SHAPE::Serialize" );
340 aContainer.PackFrom( shape );
354 types::GraphicShape shape;
356 if( !aContainer.UnpackTo( &shape ) )
372 if( shape.attributes().stroke().has_color() )
377 if( shape.attributes().fill().has_color() )
380 if( shape.attributes().has_stroke() )
386 if( shape.attributes().has_fill() )
389 if( shape.has_segment() )
395 else if( shape.has_rectangle() )
402 else if( shape.has_arc() )
409 else if( shape.has_circle() )
415 else if( shape.has_polygon() )
420 else if( shape.has_bezier() )
429 else if( shape.has_ellipse() )
437 else if( shape.has_ellipse_arc() )
460 default:
return wxT(
"??" );
475 default:
return wxT(
"??" );
496 return wxEmptyString;
591 int maxRadius = std::min( width, height ) / 2;
752 std::vector<double> slopes;
762 slopes = { 1.0, -1.0 };
803 chain.SetClosed(
true );
823 if( majorAxis / spacing > 100 )
824 spacing = majorAxis / 100;
841 for(
const SEG& seg : hatchSegs )
844 int maxError = lineWidth;
858 int gridsize = spacing;
867 hole_base.
Append( corner );
868 corner.
x += hole_size;
869 hole_base.
Append( corner );
870 corner.
y += hole_size;
871 hole_base.
Append( corner );
873 hole_base.
Append( corner );
880 int x_offset = bbox.
GetX() - ( bbox.
GetX() ) % gridsize - gridsize;
881 int y_offset = bbox.
GetY() - ( bbox.
GetY() ) % gridsize - gridsize;
883 for(
int xx = x_offset; xx <= bbox.
GetRight(); xx += gridsize )
885 for(
int yy = y_offset; yy <= bbox.
GetBottom(); yy += gridsize )
927 m_end += aMoveVector;
936 m_end += aMoveVector;
949 m_end += aMoveVector;
964 seg.
A += aMoveVector;
965 seg.
B += aMoveVector;
980 pt.x =
KiROUND( pt.x * aScale );
981 pt.y =
KiROUND( pt.y * aScale );
999 std::vector<VECTOR2I> pts;
1005 pts.emplace_back( pt );
1006 scalePt( pts.back() );
1150 m_ellipse.Mirror( aCentre, aFlipDirection );
1179 std::vector<VECTOR2I> bezierPoints;
1184 converter.
GetPoly( bezierPoints, aMaxError );
1186 return bezierPoints;
1207 const double phi =
m_ellipse.Rotation.AsRadians();
1222 const double phi =
m_ellipse.Rotation.AsRadians();
1223 const double cosPhi = std::cos( phi );
1224 const double sinPhi = std::sin( phi );
1227 auto eval = [&](
double theta ) ->
VECTOR2I
1229 const double lx = a * std::cos( theta );
1230 const double ly = b * std::sin( theta );
1315 if( aEndAngle == aStartAngle )
1318 while( aEndAngle < aStartAngle )
1342 if(
radius > (
double) INT_MAX / 2.0 )
1343 radius = (double) INT_MAX / 2.0;
1405 return endAngle - startAngle;
1433 if( aCheckNegativeAngle && aAngle <
ANGLE_0 )
1449 default:
return _(
"Unrecognized" );
1464 default:
return _(
"Unrecognized" );
1474 wxString shape =
_(
"Shape" );
1487 aList.emplace_back(
_(
"Angle" ), msg );
1513 msg.Printf( wxS(
"%d" ),
GetPolyShape().Outline(0).PointCount() );
1514 aList.emplace_back(
_(
"Points" ), msg );
1537 m_stroke.GetMsgPanelInfo( aFrame, aList );
1574 for(
auto iter =
GetPolyShape().CIterate(); iter; iter++ )
1575 bbox.
Merge( *iter );
1601 double maxdist = aAccuracy;
1614 return dist <=
radius + maxdist;
1615 else if( abs(
radius - dist ) <= maxdist )
1639 if( dist >
radius + maxdist )
1645 if( abs(
radius - dist ) > maxdist )
1660 if( endAngle > startAngle )
1661 return relPosAngle >= startAngle && relPosAngle <= endAngle;
1663 return relPosAngle >= startAngle || relPosAngle <= endAngle;
1669 std::vector<VECTOR2I> updatedBezierPoints;
1674 converter.
GetPoly( updatedBezierPoints, aAccuracy / 2 );
1675 pts = &updatedBezierPoints;
1678 for(
unsigned int i = 1; i < pts->size(); i++ )
1680 if(
TestSegmentHit( aPosition, ( *pts )[i - 1], ( *pts )[i], maxdist ) )
1698 return poly.
Collide( aPosition, maxdist );
1706 if( poly.
CollideEdge( aPosition,
nullptr, maxdist ) )
1737 copy.SetClosed(
true );
1738 return copy.Collide( aPosition, maxdist );
1747 if(
GetPolyShape().CollideEdge( aPosition,
nullptr, maxdist ) )
1761 const double maxdistSq = maxdist * maxdist;
1766 if(
static_cast<double>( e.
SquaredDistance( aPosition,
false ) ) <= maxdistSq )
1772 if(
static_cast<double>( e.
SquaredDistance( aPosition,
true ) ) <= maxdistSq )
1791 BOX2I arect = aRect;
1800 int count = (int) outline.GetPointCount();
1802 for(
int ii = 0; ii < count; ii++ )
1804 VECTOR2I vertex = outline.GetPoint( ii );
1810 if( ii + 1 < count )
1812 VECTOR2I vertexNext = outline.GetPoint( ii + 1 );
1818 else if( outline.IsClosed() )
1820 VECTOR2I vertexNext = outline.GetPoint( 0 );
1886 return checkOutline( poly.
Outline( 0 ) );
1951 std::vector<VECTOR2I> updatedBezierPoints;
1956 converter.
GetPoly( updatedBezierPoints, aAccuracy / 2 );
1957 pts = &updatedBezierPoints;
1960 for(
unsigned ii = 1; ii < pts->size(); ii++ )
1962 VECTOR2I vertex = ( *pts )[ii - 1];
1963 VECTOR2I vertexNext = ( *pts )[ii];
1988 const int tessError = std::max( 1, aAccuracy / 2 );
1993 return checkOutline(
chain );
2013 std::vector<VECTOR2I> pts;
2017 pts.emplace_back( topLeft );
2018 pts.emplace_back( botRight.
x, topLeft.
y );
2019 pts.emplace_back( botRight );
2020 pts.emplace_back( topLeft.
x, botRight.
y );
2028 std::vector<VECTOR2I> pts;
2077 std::vector<VECTOR2I> corners;
2082 corners.emplace_back( pt );
2085 while( corners.size() < 4 )
2086 corners.emplace_back( corners.back() +
VECTOR2I( 10, 10 ) );
2093 for(
const VECTOR2I& corner : corners )
2095 if( corner.x < minX.
x )
2098 if( corner.x > maxX.
x )
2101 if( corner.y < minY.
y )
2104 if( corner.y > maxY.
y )
2110 pts.emplace_back( minX );
2111 pts.emplace_back( minY );
2112 pts.emplace_back( maxX );
2113 pts.emplace_back( maxY );
2117 pts.emplace_back( maxY );
2118 pts.emplace_back( minX );
2119 pts.emplace_back( minY );
2120 pts.emplace_back( maxX );
2124 pts.emplace_back( maxX );
2125 pts.emplace_back( maxY );
2126 pts.emplace_back( minX );
2127 pts.emplace_back( minY );
2131 pts.emplace_back( minY );
2132 pts.emplace_back( maxX );
2133 pts.emplace_back( maxY );
2134 pts.emplace_back( minX );
2163 if( t1 < ANGLE_0 && t2 >
ANGLE_0 )
2166 if( t1 < ANGLE_90 && t2 >
ANGLE_90 )
2177 if( t1 < ANGLE_0 || t2 >
ANGLE_0 )
2180 if( t1 < ANGLE_90 || t2 >
ANGLE_90 )
2204 std::vector<SHAPE*> effectiveShapes;
2234 effectiveShapes.emplace_back(
new SHAPE_SIMPLE( outline ) );
2236 if( width > 0 || !solidFill )
2238 std::set<size_t> arcsHandled;
2244 size_t arcIndex = outline.
ArcIndex( ii );
2246 if( !arcsHandled.contains( arcIndex ) )
2248 arcsHandled.insert( arcIndex );
2249 effectiveShapes.emplace_back(
new SHAPE_ARC( outline.
Arc( arcIndex ), width ) );
2264 effectiveShapes.emplace_back(
new SHAPE_SIMPLE( pts ) );
2266 if( width > 0 || !solidFill )
2268 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts[0], pts[1], width ) );
2269 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts[1], pts[2], width ) );
2270 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts[2], pts[3], width ) );
2271 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts[3], pts[0], width ) );
2282 if( width > 0 || !solidFill )
2291 VECTOR2I start_pt = bezierPoints[0];
2293 for(
unsigned int jj = 1; jj < bezierPoints.size(); jj++ )
2295 VECTOR2I end_pt = bezierPoints[jj];
2296 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( start_pt, end_pt, width ) );
2319 if( aLineChainOnly && l.
IsClosed() )
2322 for(
int jj = 0; jj < segCount; jj++ )
2337 std::vector<VECTOR2I> pts;
2339 for(
int ii = 0; ii <
chain.PointCount(); ++ii )
2340 pts.emplace_back(
chain.CPoint( ii ) );
2342 effectiveShapes.emplace_back(
new SHAPE_SIMPLE( pts ) );
2345 if( width > 0 || !solidFill )
2350 for(
int ii = 0; ii <
chain.SegmentCount(); ++ii )
2362 return effectiveShapes;
2368 std::vector<VECTOR2I> points;
2377 points.reserve( points.size() + pointCount );
2380 points.emplace_back( pt );
2391 m_poly = std::make_unique<SHAPE_POLY_SET>();
2399 m_poly = std::make_unique<SHAPE_POLY_SET>();
2515 poly.
Append( aPosition,
true );
2528#define sq( x ) pow( x, 2 )
2606 if( chordBefore > 0 )
2607 ratio = chordAfter / chordBefore;
2610 radius = std::max( sqrt(
sq(
radius ) * ratio ), sqrt( chordAfter ) / 2 );
2616 double radialA =
m_start.Distance( aPosition );
2617 double radialB =
m_end.Distance( aPosition );
2618 radius = ( radialA + radialB ) / 2.0;
2632 double sqRadDiff = (
radius *
radius ) - ( l * l ) / 4.0;
2637 if( l > 0 && sqRadDiff >= 0 )
2686 const VECTOR2I secondCorner = aPosition;
2688 const int halfW =
std::abs( secondCorner.
x - firstCorner.
x ) / 2;
2689 const int halfH =
std::abs( secondCorner.
y - firstCorner.
y ) / 2;
2695 if( halfW >= halfH )
2697 majorRadius = std::max( halfW, 1 );
2698 minorRadius = std::max( halfH, 1 );
2703 majorRadius = std::max( halfH, 1 );
2704 minorRadius = std::max( halfW, 1 );
2725 const VECTOR2I secondCorner = aPosition;
2727 const int halfW =
std::abs( secondCorner.
x - firstCorner.
x ) / 2;
2728 const int halfH =
std::abs( secondCorner.
y - firstCorner.
y ) / 2;
2734 if( halfW >= halfH )
2736 majorRadius = std::max( halfW, 1 );
2737 minorRadius = std::max( halfH, 1 );
2742 majorRadius = std::max( halfH, 1 );
2743 minorRadius = std::max( halfW, 1 );
2765 const double a = std::max( 1,
m_ellipse.MajorRadius );
2766 const double b = std::max( 1,
m_ellipse.MinorRadius );
2769 const double dx = aPosition.
x -
center.x;
2770 const double dy = aPosition.
y -
center.y;
2772 const double cosRot = rotation.
Cos();
2773 const double sinRot = rotation.
Sin();
2774 const double lx = dx * cosRot + dy * sinRot;
2775 const double ly = -dx * sinRot + dy * cosRot;
2789 while( cursorAngle <=
m_ellipse.StartAngle )
2856 #define SWAPITEM( x ) std::swap( x, image->x )
2882#define TEST( a, b ) { if( a != b ) return a - b; }
2883#define TEST_E( a, b ) { if( abs( a - b ) > EPSILON ) return a - b; }
2884#define TEST_PT( a, b ) { TEST_E( a.x, b.x ); TEST_E( a.y, b.y ); }
2937 ERROR_LOC aErrorLoc,
bool ignoreLineWidth,
bool includeFill )
const
2940 int width = ignoreLineWidth ? 0 :
GetWidth();
2942 width += 2 * aClearance;
2969 0.0, 0, width / 2, aError, aErrorLoc );
2979 std::set<size_t> arcsHandled;
2985 size_t arcIndex = outline.
ArcIndex( ii );
2987 if( arcsHandled.contains( arcIndex ) )
2990 arcsHandled.insert( arcIndex );
3016 if( width > 0 || !solidFill )
3055 int inflate = width / 2;
3072 for(
int jj = 0; jj < (int) poly.
SegmentCount(); ++jj )
3087 std::vector<VECTOR2I> poly;
3088 converter.
GetPoly( poly, aError );
3090 for(
unsigned ii = 1; ii < poly.size(); ii++ )
3109 for(
int ii = 0; ii <
chain.PointCount(); ++ii )
3114 int inflate = width / 2;
3127 for(
int ii = 0; ii <
chain.SegmentCount(); ++ii )
3129 const SEG& seg =
chain.CSegment( ii );
3281 double similarity = 1.0;
3316 similarity *= std::pow( 0.9, m + n - 2 * longest );
3322 std::vector<VECTOR2I> poly;
3323 std::vector<VECTOR2I> otherPoly;
3331 for(
int ii = 0; ii < m; ++ii )
3333 poly.emplace_back( lastPt -
GetPolyShape().CVertex( ii ) );
3339 for(
int ii = 0; ii < n; ++ii )
3347 similarity *= std::pow( 0.9, m + n - 2 * longest );
3375 if( lineStyleEnum.
Choices().GetCount() == 0 )
3386 if( hatchModeEnum.
Choices().GetCount() == 0 )
3398 auto isNotPolygonOrCircle =
3428 auto isEllipseOrEllipseArc = [](
INSPECTABLE* aItem ) ->
bool
3438 auto isEllipseArc = [](
INSPECTABLE* aItem ) ->
bool
3446 const wxString shapeProps =
_HKI(
"Shape Properties" );
3512 wxASSERT_MSG( aValue.CheckType<
int>(),
3513 "Expecting int-containing value" );
3515 int radius = aValue.As<
int>();
3520 return std::nullopt;
3522 int maxRadius = std::min( prop_shape->GetRectangleWidth(),
3523 prop_shape->GetRectangleHeight() ) / 2;
3526 return std::make_unique<VALIDATION_ERROR_TOO_LARGE<int>>(
radius, maxRadius );
3528 return std::make_unique<VALIDATION_ERROR_TOO_SMALL<int>>(
radius, 0 );
3530 return std::nullopt;
3579 angle->SetAvailableFunc(
3589 auto fillAvailable =
3602 switch( edaShape->GetShape() )
types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
constexpr EDA_IU_SCALE pcbIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Bezier curves to polygon converter.
void GetPoly(std::vector< VECTOR2I > &aOutput, int aMaxError=10)
Convert a Bezier curve to a polygon.
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
constexpr void SetOrigin(const Vec &pos)
constexpr BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
constexpr coord_type GetY() const
constexpr size_type GetWidth() const
constexpr Vec Centre() const
constexpr coord_type GetX() const
bool IntersectsCircleEdge(const Vec &aCenter, const int aRadius, const int aWidth) const
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr const Vec GetCenter() const
constexpr size_type GetHeight() const
constexpr coord_type GetLeft() const
constexpr bool Contains(const Vec &aPoint) const
constexpr coord_type GetRight() const
constexpr void SetEnd(coord_type x, coord_type y)
constexpr coord_type GetTop() const
constexpr bool Intersects(const BOX2< Vec > &aRect) const
constexpr coord_type GetBottom() const
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
int AsTenthsOfADegree() const
The base class for create windows for drawing purpose.
A base class for most all the KiCad significant classes used in schematics and boards.
UI_FILL_MODE GetFillModeProp() const
void SetEllipseRotation(const EDA_ANGLE &aA)
virtual int GetHatchLineSpacing() const
EDA_ANGLE GetArcAngle() const
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false, bool includeFill=false) const
Convert the shape to a closed polygon.
int GetEllipseMinorRadius() const
const VECTOR2I & GetBezierC2() const
const VECTOR2I & GetEllipseCenter() const
void SetBezierC2(const VECTOR2I &aPt)
void move(const VECTOR2I &aMoveVector)
void SetCenter(const VECTOR2I &aCenter)
VECTOR2I getCenter() const
void SetFillModeProp(UI_FILL_MODE)
virtual int getMaxError() const
void rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle)
void SetEllipseCenter(const VECTOR2I &aPt)
const std::vector< VECTOR2I > buildBezierToSegmentsPointsList(int aMaxError) const
const SHAPE_POLY_SET & GetHatching() const
EDA_ANGLE GetEllipseEndAngle() const
FILL_T GetFillMode() const
void SetCornerRadius(int aRadius)
long long int m_rectangleHeight
int GetEllipseMajorRadius() const
void SetEllipseStartAngle(const EDA_ANGLE &aA)
std::unique_ptr< EDA_SHAPE_HATCH_CACHE_DATA > m_hatchingCache
virtual int GetEffectiveWidth() const
std::vector< VECTOR2I > GetPolyPoints() const
Duplicate the polygon outlines into a flat list of VECTOR2I points.
COLOR4D GetLineColor() const
SHAPE_ELLIPSE buildShapeEllipse() const
std::vector< SHAPE * > makeEffectiveShapes(bool aEdgeOnly, bool aLineChainOnly=false, bool aHittesting=false) const
Make a set of SHAPE objects representing the EDA_SHAPE.
int GetRectangleWidth() const
void SetLineStyle(const LINE_STYLE aStyle)
void recalcEllipseArcEndpoints()
When m_shape == ELLIPSE_ARC, recompute m_start/m_end from m_ellipse.
void calcEdit(const VECTOR2I &aPosition)
virtual std::vector< SHAPE * > MakeEffectiveShapes(bool aEdgeOnly=false) const
Make a set of SHAPE objects representing the EDA_SHAPE.
SHAPE_POLY_SET & GetPolyShape()
void CalcArcAngles(EDA_ANGLE &aStartAngle, EDA_ANGLE &aEndAngle) const
Calc arc start and end angles such that aStartAngle < aEndAngle.
std::vector< VECTOR2I > GetCornersInSequence(EDA_ANGLE angle) const
EDA_ANGLE GetEllipseRotation() const
void ShapeGetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList)
virtual bool isMoving() const
bool operator==(const EDA_SHAPE &aOther) const
void SetPolyShape(const SHAPE_POLY_SET &aShape)
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
const std::vector< SEG > & GetHatchLines() const
void SetRectangleHeight(const int &aHeight)
SHAPE_POLY_SET & hatching() const
bool IsHatchedFill() const
virtual SHAPE_POLY_SET getHatchingKnockouts() const
virtual void SetFilled(bool aFlag)
virtual bool IsFilledForHitTesting() const
bool continueEdit(const VECTOR2I &aPosition)
wxString ShowShape() const
void SetEllipseEndAngle(const EDA_ANGLE &aA)
void SetFillColor(const COLOR4D &aColor)
bool hitTest(const VECTOR2I &aPosition, int aAccuracy=0) const
void SetCachedArcData(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd, const VECTOR2I &aCenter)
Set the data used for mid point caching.
void RebuildBezierToSegmentsPointsList(int aMaxError)
Rebuild the m_bezierPoints vertex list that approximate the Bezier curve by a list of segments.
virtual int GetHatchLineWidth() const
void flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection)
EDA_SHAPE(SHAPE_T aType, int aLineWidth, FILL_T aFill)
std::vector< SEG > & hatchLines() const
void beginEdit(const VECTOR2I &aStartPoint)
int GetPointCount() const
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
void SetStart(const VECTOR2I &aStart)
LINE_STYLE GetLineStyle() const
void endEdit(bool aClosed=true)
Finish editing the shape.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
void SetLineColor(const COLOR4D &aColor)
COLOR4D GetFillColor() const
void SetRectangle(const long long int &aHeight, const long long int &aWidth)
void SetShape(SHAPE_T aShape)
void SwapShape(EDA_SHAPE *aImage)
std::vector< VECTOR2I > GetRectCorners() const
std::vector< VECTOR2I > m_bezierPoints
void setPosition(const VECTOR2I &aPos)
EDA_ANGLE GetEllipseStartAngle() const
virtual bool IsProxyItem() const
void computeArcBBox(BOX2I &aBBox) const
virtual void UpdateHatching() const
void SetEnd(const VECTOR2I &aEnd)
void SetRectangleWidth(const int &aWidth)
void SetBezierC1(const VECTOR2I &aPt)
void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the three controlling points for an arc.
wxString SHAPE_T_asString() const
void scale(double aScale)
double Similarity(const EDA_SHAPE &aOther) const
const VECTOR2I & GetBezierC1() const
const BOX2I getBoundingBox() const
void SetArcAngleAndEnd(const EDA_ANGLE &aAngle, bool aCheckNegativeAngle=false)
Set the end point from the angle center and start.
int GetRectangleHeight() const
virtual int GetWidth() const
VECTOR2I getPosition() const
bool IsClockwiseArc() const
void SetEllipseMajorRadius(int aR)
void SetPolyPoints(const std::vector< VECTOR2I > &aPoints)
wxString getFriendlyName() const
EDA_SHAPE & operator=(const EDA_SHAPE &aOther)
void SetWidth(int aWidth)
EDA_ANGLE GetSegmentAngle() const
int GetCornerRadius() const
void SetFillMode(FILL_T aFill)
std::unique_ptr< SHAPE_POLY_SET > m_poly
long long int m_rectangleWidth
void SetEllipseMinorRadius(int aR)
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
bool IsPolyShapeValid() const
int Compare(const EDA_SHAPE *aOther) const
VECTOR2I GetArcMid() const
VECTOR2< NumericType > Center
ENUM_MAP & Map(T aValue, const wxString &aName)
static ENUM_MAP< T > & Instance()
Class that other classes need to inherit from, in order to be inspectable.
A color representation with 4 components: red, green, blue, alpha.
PROPERTY_BASE & SetAvailableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Set a callback function to determine whether an object provides this property.
PROPERTY_BASE & SetValidator(PROPERTY_VALIDATOR_FN &&aValidator)
PROPERTY_BASE & SetIsHiddenFromRulesEditor(bool aHide=true)
Provide class metadata.Helper macro to map type hashes to names.
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
A round rectangle shape, based on a rectangle and a radius.
void TransformToPolygon(SHAPE_POLY_SET &aBuffer, int aMaxError) const
Get the polygonal representation of the roundrect.
int Length() const
Return the length (this).
const VECTOR2I & GetArcMid() const
const VECTOR2I & GetP1() const
const VECTOR2I & GetP0() const
SHAPE_TYPE Type() const
Return the type of the shape.
SHAPE_LINE_CHAIN ConvertToPolyline(int aMaxError) const
Build a polyline approximation of the ellipse or arc.
SEG::ecoord SquaredDistance(const VECTOR2I &aP, bool aOutlineOnly=false) const override
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void Move(const VECTOR2I &aVector) override
const SHAPE_ARC & Arc(size_t aArc) const
bool IsClosed() const override
virtual const VECTOR2I GetPoint(int aIndex) const override
void SetPoint(int aIndex, const VECTOR2I &aPos)
Move a point to a specific location.
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
int PointCount() const
Return the number of points (vertices) in this line chain.
ssize_t ArcIndex(size_t aSegment) const
Return the arc index for the given segment index.
SEG Segment(int aIndex) const
Return a copy of the aIndex-th segment in the line chain.
virtual size_t GetPointCount() const override
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
virtual const SEG GetSegment(int aIndex) const override
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
int SegmentCount() const
Return the number of segments in this line chain.
const VECTOR2I & CLastPoint() const
Return the last point in the line chain.
void Remove(int aStartIndex, int aEndIndex)
Remove the range of points [start_index, end_index] from the line chain.
const SEG CSegment(int aIndex) const
Return a constant copy of the aIndex segment in the line chain.
bool IsArcSegment(size_t aSegment) const
const std::vector< VECTOR2I > & CPoints() const
Represent a set of closed polygons.
void Rotate(const EDA_ANGLE &aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Rotate all vertices by a given angle.
void RemoveAllContours()
Remove all outlines & holes (clears) the polygon set.
bool CollideEdge(const VECTOR2I &aPoint, VERTEX_INDEX *aClosestVertex=nullptr, int aClearance=0) const
Check whether aPoint collides with any edge of any of the contours of the polygon.
void ClearArcs()
Removes all arc references from all the outlines and holes in the polyset.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
int VertexCount(int aOutline=-1, int aHole=-1) const
Return the number of vertices in a given outline/hole.
bool IsEmpty() const
Return true if the set is empty (no polygons at all)
bool Collide(const SHAPE *aShape, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const override
Check if the boundary of shape (this) lies closer to the shape aShape than aClearance,...
int TotalVertices() const
Return total number of vertices stored in the set.
void Inflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, bool aSimplify=false)
Perform outline inflation/deflation.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
const std::vector< SEG > GenerateHatchLines(const std::vector< double > &aSlopes, int aSpacing, int aLineLength) const
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int NewOutline()
Creates a new empty polygon in the set and returns its index.
void Mirror(const VECTOR2I &aRef, FLIP_DIRECTION aFlipDirection)
Mirror the line points about y or x (or both)
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the index-th vertex in a given hole outline within a given outline.
int OutlineCount() const
Return the number of outlines in the set.
void Move(const VECTOR2I &aVector) override
void Fracture(bool aSimplify=true)
Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the oute...
SHAPE_POLY_SET CloneDropTriangulation() const
void BooleanSubtract(const SHAPE_POLY_SET &b)
Perform boolean polyset difference.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
Represent a simple polygon consisting of a zero-thickness closed chain of connected line segments.
An abstract shape on 2D plane.
LINE_STYLE GetLineStyle() const
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
double Distance(const VECTOR2< extended_type > &aVector) const
Compute the distance between two vectors.
constexpr extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
void TransformRingToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aCentre, int aRadius, int aWidth, int aError, ERROR_LOC aErrorLoc)
Convert arcs to multiple straight segments.
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aBuffer, const VECTOR2I &aCenter, int aRadius, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a circle to a polygon, using multiple straight lines.
void TransformArcToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc)
Convert arc to multiple straight segments.
void TransformRoundChamferedRectToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aPosition, const VECTOR2I &aSize, const EDA_ANGLE &aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aInflate, int aError, ERROR_LOC aErrorLoc)
Convert a rectangle with rounded corners and/or chamfered corners to a polygon.
void TransformOvalToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a oblong shape to a polygon, using multiple segments.
@ ROUND_ALL_CORNERS
All angles are rounded.
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_90
static constexpr EDA_ANGLE ANGLE_45
static constexpr EDA_ANGLE ANGLE_270
static constexpr EDA_ANGLE ANGLE_360
static constexpr EDA_ANGLE ANGLE_180
static struct EDA_SHAPE_DESC _EDA_SHAPE_DESC
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
a few functions useful in geometry calculations.
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
#define UNIMPLEMENTED_FOR(type)
constexpr void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
KICOMMON_API wxString MessageTextFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
A helper to convert the double length aValue to a string in inches, millimeters, or unscaled units.
bool ShapeHitTest(const SHAPE_LINE_CHAIN &aHitter, const SHAPE &aHittee, bool aHitteeContained)
Perform a shape-to-shape hit test.
size_t longest_common_subset(const _Container &__c1, const _Container &__c2)
Returns the length of the longest common subset of values between two containers.
KICOMMON_API void PackColor(types::Color &aOutput, const KIGFX::COLOR4D &aInput)
KICOMMON_API int UnpackDistance(const types::Distance &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackPolySet(types::PolySet &aOutput, const SHAPE_POLY_SET &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API KIGFX::COLOR4D UnpackColor(const types::Color &aInput)
KICOMMON_API VECTOR2I UnpackVector2(const types::Vector2 &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackDistance(types::Distance &aOutput, int aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackVector2(types::Vector2 &aOutput, const VECTOR2I &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API SHAPE_POLY_SET UnpackPolySet(const types::PolySet &aInput, const EDA_IU_SCALE &aScale)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
#define IMPLEMENT_ENUM_TO_WXANY(type)
#define NO_SETTER(owner, type)
@ PT_COORD
Coordinate expressed in distance units (mm/inch)
@ PT_DECIDEGREE
Angle expressed in decidegrees.
@ PT_SIZE
Size expressed in distance units (mm/inch)
std::optional< std::unique_ptr< VALIDATION_ERROR > > VALIDATOR_RESULT
Null optional means validation succeeded.
@ SH_POLY_SET
set of polygons (with holes, etc.)
@ SH_SIMPLE
simple polygon
@ SH_ELLIPSE
ellipse or elliptical arc
@ SH_NULL
empty shape (no shape...),
@ SH_POLY_SET_TRIANGLE
a single triangle belonging to a POLY_SET triangulation
@ SH_LINE_CHAIN
line chain (polyline)
@ SH_COMPOUND
compound shape, consisting of multiple simple shapes
static bool Collide(const SHAPE_CIRCLE &aA, const SHAPE_CIRCLE &aB, int aClearance, int *aActual, VECTOR2I *aLocation, VECTOR2I *aMTV)
LINE_STYLE
Dashed line types.
const SHAPE_LINE_CHAIN chain
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
bool TestSegmentHit(const VECTOR2I &aRefPoint, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
const VECTOR2I CalcArcCenter(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Determine the center of an arc or circle given three points on its circumference.
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D