53#include <api/common/types/base_types.pb.h>
92 switch( aShape.
Type() )
96 auto rect = static_cast<const SHAPE_RECT&>( aShape );
97 m_shape = SHAPE_T::RECTANGLE;
98 SetStart( rect.GetPosition() );
99 SetEnd( rect.GetPosition() + rect.GetSize() );
105 auto seg = static_cast<const SHAPE_SEGMENT&>( aShape );
106 m_shape = SHAPE_T::SEGMENT;
107 SetStart( seg.GetSeg().A );
108 SetEnd( seg.GetSeg().B );
109 SetWidth( seg.GetWidth() );
115 auto line = static_cast<const SHAPE_LINE_CHAIN&>( aShape );
116 m_shape = SHAPE_T::POLY;
117 GetPolyShape() = SHAPE_POLY_SET();
118 GetPolyShape().AddOutline( line );
119 SetWidth( line.Width() );
125 auto circle = static_cast<const SHAPE_CIRCLE&>( aShape );
126 m_shape = SHAPE_T::CIRCLE;
127 SetStart( circle.GetCenter() );
128 SetEnd( circle.GetCenter() + circle.GetRadius() );
134 auto arc = static_cast<const SHAPE_ARC&>( aShape );
135 m_shape = SHAPE_T::ARC;
137 if( arc.IsClockwise() )
138 SetArcGeometry( arc.GetP0(), arc.GetArcMid(), arc.GetP1() );
140 SetArcGeometry( arc.GetP1(), arc.GetArcMid(), arc.GetP0() );
142 SetWidth( arc.GetWidth() );
148 auto poly = static_cast<const SHAPE_SIMPLE&>( aShape );
149 m_shape = SHAPE_T::POLY;
150 poly.TransformToPolygon( GetPolyShape(), 0, ERROR_INSIDE );
156 auto ellipse = static_cast<const SHAPE_ELLIPSE&>( aShape );
157 m_shape = ellipse.IsArc() ? SHAPE_T::ELLIPSE_ARC : SHAPE_T::ELLIPSE;
158 SetEllipseCenter( ellipse.GetCenter() );
159 SetEllipseMajorRadius( ellipse.GetMajorRadius() );
160 SetEllipseMinorRadius( ellipse.GetMinorRadius() );
161 SetEllipseRotation( ellipse.GetRotation() );
163 if( ellipse.IsArc() )
165 SetEllipseStartAngle( ellipse.GetStartAngle() );
166 SetEllipseEndAngle( ellipse.GetEndAngle() );
207 m_poly = std::make_unique<SHAPE_POLY_SET>( *aOther.
m_poly );
213 if(
this == &aOther )
235 m_poly = std::make_unique<SHAPE_POLY_SET>( *aOther.
m_poly );
257 types::GraphicFillAttributes* fill = shape.mutable_attributes()->mutable_fill();
270 types::GraphicSegmentAttributes* segment = shape.mutable_segment();
278 types::GraphicRectangleAttributes* rectangle = shape.mutable_rectangle();
287 types::GraphicArcAttributes* arc = shape.mutable_arc();
296 types::GraphicCircleAttributes*
circle = shape.mutable_circle();
310 types::GraphicBezierAttributes* bezier = shape.mutable_bezier();
320 types::GraphicEllipseAttributes* ellipse = shape.mutable_ellipse();
330 types::GraphicEllipseArcAttributes* arc = shape.mutable_ellipse_arc();
341 wxASSERT_MSG(
false,
"Unhandled shape in EDA_SHAPE::Serialize" );
357 kiapi::common::types::GraphicShape shape;
359 aContainer.PackFrom( shape );
390 if( shape.attributes().has_fill() )
394 if( shape.attributes().fill().has_color() )
398 if( shape.has_segment() )
404 else if( shape.has_rectangle() )
411 else if( shape.has_arc() )
418 else if( shape.has_circle() )
424 else if( shape.has_polygon() )
429 else if( shape.has_bezier() )
438 else if( shape.has_ellipse() )
446 else if( shape.has_ellipse_arc() )
457 if( shape.has_start_ending() )
460 if( shape.has_end_ending() )
468 kiapi::common::types::GraphicShape shape;
470 if( !aContainer.UnpackTo( &shape ) )
485 default:
return wxT(
"??" );
500 default:
return wxT(
"??" );
521 return wxEmptyString;
617 int maxRadius = std::min( width, height ) / 2;
786 std::vector<double> slopes;
796 slopes = { 1.0, -1.0 };
832 for(
int ii = 0; ii < shapeBuffer.
OutlineCount(); ++ii )
852 chain.SetClosed(
true );
872 if( majorAxis / spacing > 100 )
873 spacing = majorAxis / 100;
890 for(
const SEG& seg : hatchSegs )
893 int maxError = lineWidth;
907 int gridsize = spacing;
916 hole_base.
Append( corner );
917 corner.
x += hole_size;
918 hole_base.
Append( corner );
919 corner.
y += hole_size;
920 hole_base.
Append( corner );
922 hole_base.
Append( corner );
929 int x_offset = bbox.
GetX() - ( bbox.
GetX() ) % gridsize - gridsize;
930 int y_offset = bbox.
GetY() - ( bbox.
GetY() ) % gridsize - gridsize;
932 for(
int xx = x_offset; xx <= bbox.
GetRight(); xx += gridsize )
934 for(
int yy = y_offset; yy <= bbox.
GetBottom(); yy += gridsize )
976 m_end += aMoveVector;
985 m_end += aMoveVector;
998 m_end += aMoveVector;
1013 seg.
A += aMoveVector;
1014 seg.
B += aMoveVector;
1029 pt.x =
KiROUND( pt.x * aScale );
1030 pt.y =
KiROUND( pt.y * aScale );
1048 std::vector<VECTOR2I> pts;
1054 pts.emplace_back( pt );
1055 scalePt( pts.back() );
1199 m_ellipse.Mirror( aCentre, aFlipDirection );
1228 std::vector<VECTOR2I> bezierPoints;
1233 converter.
GetPoly( bezierPoints, aMaxError );
1235 return bezierPoints;
1258 const double phi =
m_ellipse.Rotation.AsRadians();
1273 const double phi =
m_ellipse.Rotation.AsRadians();
1274 const double cosPhi = std::cos( phi );
1275 const double sinPhi = std::sin( phi );
1278 auto eval = [&](
double theta ) ->
VECTOR2I
1280 const double lx = a * std::cos( theta );
1281 const double ly = b * std::sin( theta );
1372 if( aEndAngle == aStartAngle )
1375 while( aEndAngle < aStartAngle )
1399 if(
radius > (
double) INT_MAX / 2.0 )
1400 radius = (double) INT_MAX / 2.0;
1478 return endAngle - startAngle;
1506 if( aCheckNegativeAngle && aAngle <
ANGLE_0 )
1522 default:
return _(
"Unrecognized" );
1527 return _(
"Connected Lines" );
1541 default:
return _(
"Unrecognized" );
1551 wxString shape =
_(
"Shape" );
1564 aList.emplace_back(
_(
"Angle" ), msg );
1596 msg.Printf( wxS(
"%d" ), pointCount );
1597 aList.emplace_back(
_(
"Points" ), msg );
1620 m_stroke.GetMsgPanelInfo( aFrame, aList );
1658 for(
auto iter =
GetPolyShape().CIterate(); iter; iter++ )
1659 bbox.
Merge( *iter );
1691 const SHAPE& hitShape = shape;
1693 return hitShape.
Collide( aPosition, std::max( 0, aAccuracy ) );
1696 double maxdist = aAccuracy;
1709 return dist <=
radius + maxdist;
1710 else if( abs(
radius - dist ) <= maxdist )
1734 if( dist >
radius + maxdist )
1740 if( abs(
radius - dist ) > maxdist )
1755 if( endAngle > startAngle )
1756 return relPosAngle >= startAngle && relPosAngle <= endAngle;
1758 return relPosAngle >= startAngle || relPosAngle <= endAngle;
1764 std::vector<VECTOR2I> updatedBezierPoints;
1769 converter.
GetPoly( updatedBezierPoints, aAccuracy / 2 );
1770 pts = &updatedBezierPoints;
1773 for(
unsigned int i = 1; i < pts->size(); i++ )
1775 if(
TestSegmentHit( aPosition, ( *pts )[i - 1], ( *pts )[i], maxdist ) )
1793 return poly.
Collide( aPosition, maxdist );
1801 if( poly.
CollideEdge( aPosition,
nullptr, maxdist ) )
1832 copy.SetClosed(
true );
1833 return copy.Collide( aPosition, maxdist );
1842 if(
GetPolyShape().CollideEdge( aPosition,
nullptr, maxdist ) )
1856 const double maxdistSq = maxdist * maxdist;
1861 if(
static_cast<double>( e.
SquaredDistance( aPosition,
false ) ) <= maxdistSq )
1867 if(
static_cast<double>( e.
SquaredDistance( aPosition,
true ) ) <= maxdistSq )
1903 int count = (int) outline.GetPointCount();
1905 for(
int ii = 0; ii < count; ii++ )
1907 VECTOR2I vertex = outline.GetPoint( ii );
1913 if( ii + 1 < count )
1915 VECTOR2I vertexNext = outline.GetPoint( ii + 1 );
1921 else if( outline.IsClosed() )
1923 VECTOR2I vertexNext = outline.GetPoint( 0 );
1989 return checkOutline( poly.
Outline( 0 ) );
2054 std::vector<VECTOR2I> updatedBezierPoints;
2059 converter.
GetPoly( updatedBezierPoints, aAccuracy / 2 );
2060 pts = &updatedBezierPoints;
2063 for(
unsigned ii = 1; ii < pts->size(); ii++ )
2065 VECTOR2I vertex = ( *pts )[ii - 1];
2066 VECTOR2I vertexNext = ( *pts )[ii];
2093 const int tessError = std::max( 1, aAccuracy / 2 );
2098 return checkOutline(
chain );
2120 std::vector<VECTOR2I> pts;
2124 pts.emplace_back( topLeft );
2125 pts.emplace_back( botRight.
x, topLeft.
y );
2126 pts.emplace_back( botRight );
2127 pts.emplace_back( topLeft.
x, botRight.
y );
2135 std::vector<VECTOR2I> pts;
2188 pts.emplace_back( tl );
2189 pts.emplace_back( tr );
2190 pts.emplace_back( br );
2191 pts.emplace_back( bl );
2204 std::vector<VECTOR2I> corners;
2209 corners.emplace_back( pt );
2212 if( corners.empty() )
2215 while( corners.size() < 4 )
2216 corners.emplace_back( corners.back() +
VECTOR2I( 10, 10 ) );
2223 for(
const VECTOR2I& corner : corners )
2225 if( corner.x < minX.
x )
2228 if( corner.x > maxX.
x )
2231 if( corner.y < minY.
y )
2234 if( corner.y > maxY.
y )
2240 pts.emplace_back( minX );
2241 pts.emplace_back( minY );
2242 pts.emplace_back( maxX );
2243 pts.emplace_back( maxY );
2247 pts.emplace_back( maxY );
2248 pts.emplace_back( minX );
2249 pts.emplace_back( minY );
2250 pts.emplace_back( maxX );
2254 pts.emplace_back( maxX );
2255 pts.emplace_back( maxY );
2256 pts.emplace_back( minX );
2257 pts.emplace_back( minY );
2261 pts.emplace_back( minY );
2262 pts.emplace_back( maxX );
2263 pts.emplace_back( maxY );
2264 pts.emplace_back( minX );
2293 if( t1 < ANGLE_0 && t2 >
ANGLE_0 )
2296 if( t1 < ANGLE_90 && t2 >
ANGLE_90 )
2307 if( t1 < ANGLE_0 || t2 >
ANGLE_0 )
2310 if( t1 < ANGLE_90 || t2 >
ANGLE_90 )
2336 if( aLineWidth < 0 )
2348 std::vector<VECTOR2I> pts;
2351 pts.emplace_back(
VECTOR2I( pt ) );
2388 std::vector<SHAPE*> effectiveShapes;
2418 effectiveShapes.emplace_back(
new SHAPE_SIMPLE( outline ) );
2420 if( width > 0 || !solidFill )
2422 std::set<size_t> arcsHandled;
2428 size_t arcIndex = outline.
ArcIndex( ii );
2430 if( !arcsHandled.contains( arcIndex ) )
2432 arcsHandled.insert( arcIndex );
2433 effectiveShapes.emplace_back(
new SHAPE_ARC( outline.
Arc( arcIndex ), width ) );
2448 effectiveShapes.emplace_back(
new SHAPE_SIMPLE( pts ) );
2450 if( width > 0 || !solidFill )
2452 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts[0], pts[1], width ) );
2453 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts[1], pts[2], width ) );
2454 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts[2], pts[3], width ) );
2455 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts[3], pts[0], width ) );
2466 if( width > 0 || !solidFill )
2475 VECTOR2I start_pt = bezierPoints[0];
2477 for(
unsigned int jj = 1; jj < bezierPoints.size(); jj++ )
2479 VECTOR2I end_pt = bezierPoints[jj];
2480 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( start_pt, end_pt, width ) );
2502 if( aLineChainOnly && l.
IsClosed() )
2505 for(
int jj = 0; jj < segCount; jj++ )
2520 std::vector<VECTOR2I> pts;
2522 for(
int ii = 0; ii <
chain.PointCount(); ++ii )
2523 pts.emplace_back(
chain.CPoint( ii ) );
2525 effectiveShapes.emplace_back(
new SHAPE_SIMPLE( pts ) );
2528 if( width > 0 || !solidFill )
2533 for(
int ii = 0; ii <
chain.SegmentCount(); ++ii )
2545 return effectiveShapes;
2553 for(
size_t ii = 0; ii < aPolygon.size(); ++ii )
2555 if( ii == aPolygon.size() - 1 && aPolygon[ii] == aPolygon.front() )
2558 chain.Append( aPolygon[ii] );
2561 chain.SetClosed(
true );
2578 std::vector<VECTOR2I> polygon;
2579 aEnding.
GetShapes( aPoint, aTangent, aLineWidth, polygon );
2581 if( polygon.empty() )
2588 if( polygon.size() >= 3 )
2590 aShapes.emplace_back(
new SHAPE_SEGMENT( polygon[0], polygon[1], std::max( 0, width ) ) );
2591 aShapes.emplace_back(
new SHAPE_SEGMENT( polygon[1], polygon[2], std::max( 0, width ) ) );
2597 if( polygon.size() < 3 )
2615 std::vector<SHAPE*> effectiveShapes;
2620 return effectiveShapes;
2623 return effectiveShapes;
2633 return effectiveShapes;
2639 std::vector<SHAPE*> effectiveShapes;
2640 bool shortenBody =
m_startEnding.GetShortenDepth( aLineWidth ) > 0 ||
m_endEnding.GetShortenDepth( aLineWidth ) > 0;
2669 EDA_ANGLE originalStartAngle = startAngle;
2670 EDA_ANGLE arcAngle = endAngle - startAngle;
2686 for(
size_t ii = 1; ii < pts.size(); ++ii )
2711 std::vector<VECTOR2I> pts;
2715 for(
size_t jj = 1; jj < pts.size(); ++jj )
2716 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts[jj - 1], pts[jj], width ) );
2719 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts.back(), pts.front(), width ) );
2729 std::vector<VECTOR2I> pts;
2733 for(
size_t jj = 1; jj < pts.size(); ++jj )
2734 effectiveShapes.emplace_back(
new SHAPE_SEGMENT( pts[jj - 1], pts[jj], width ) );
2746 return effectiveShapes;
2755 effectiveShapes.emplace_back( shape );
2757 return effectiveShapes;
2768 std::vector<VECTOR2I> polygon;
2769 aEnding.
GetShapes( aPoint, aTangent, aLineWidth, polygon );
2771 if( polygon.empty() )
2774 auto addStrokedSegment = [&](
const VECTOR2I& aStart,
const VECTOR2I& aEnd,
int aStrokeWidth )
2776 int width = std::max( 0, aStrokeWidth ) + 2 * aClearance;
2786 if( polygon.size() >= 3 )
2788 addStrokedSegment( polygon[0], polygon[1], strokeWidth );
2789 addStrokedSegment( polygon[1], polygon[2], strokeWidth );
2795 if( polygon.size() < 3 )
2805 for(
int ii = 0; ii < outline.
PointCount(); ++ii )
2808 if( aClearance > 0 )
2810 int inflate = aClearance;
2833 int aLineWidth )
const
2855 ERROR_LOC aErrorLoc,
bool ignoreLineWidth )
const
2866 int width = ignoreLineWidth ? 0 :
GetWidth();
2867 width += 2 * aClearance;
2888 EDA_ANGLE originalStartAngle = startAngle;
2889 EDA_ANGLE arcAngle = endAngle - startAngle;
2907 for(
size_t ii = 1; ii < pts.size(); ++ii )
2933 std::vector<VECTOR2I> pts;
2938 for(
size_t jj = 1; jj < pts.size(); ++jj )
2956 std::vector<VECTOR2I> pts;
2960 for(
size_t jj = 1; jj < pts.size(); ++jj )
2965 if(
chain.IsClosed() )
2992 std::vector<VECTOR2I> polygon;
2993 aEnding.
GetShapes( aPoint, aTangent, aLineWidth, polygon );
2995 if( polygon.empty() )
3000 for(
const VECTOR2I& point : polygon )
3001 endingBBox.
Merge( point );
3006 stroke = aLineWidth;
3008 endingBBox.
Inflate( std::max( 0, stroke ) / 2 );
3017 aBBox.
Merge( endingBBox );
3030 bool hasBox =
false;
3036 mergeEnding(
m_startEnding, startPoint, startTangent, hasBox );
3037 mergeEnding(
m_endEnding, endPoint, endTangent, hasBox );
3051 std::vector<VECTOR2I> points;
3057 points.reserve( totalCount );
3062 points.emplace_back( pt );
3072 m_poly = std::make_unique<SHAPE_POLY_SET>();
3080 m_poly = std::make_unique<SHAPE_POLY_SET>();
3196 poly.
Append( aPosition,
true );
3207#define sq( x ) pow( x, 2 )
3283 if( chordBefore > 0 )
3284 ratio = chordAfter / chordBefore;
3287 radius = std::max( sqrt(
sq(
radius ) * ratio ), sqrt( chordAfter ) / 2 );
3294 double radialA =
m_start.Distance( aPosition );
3295 double radialB =
m_end.Distance( aPosition );
3296 radius = ( radialA + radialB ) / 2.0;
3313 double sqRadDiff = (
radius *
radius ) - ( l * l ) / 4.0;
3318 if( l > 0 && sqRadDiff >= 0 )
3366 const VECTOR2I secondCorner = aPosition;
3368 const int halfW =
std::abs( secondCorner.
x - firstCorner.
x ) / 2;
3369 const int halfH =
std::abs( secondCorner.
y - firstCorner.
y ) / 2;
3375 if( halfW >= halfH )
3377 majorRadius = std::max( halfW, 1 );
3378 minorRadius = std::max( halfH, 1 );
3383 majorRadius = std::max( halfH, 1 );
3384 minorRadius = std::max( halfW, 1 );
3405 const VECTOR2I secondCorner = aPosition;
3407 const int halfW =
std::abs( secondCorner.
x - firstCorner.
x ) / 2;
3408 const int halfH =
std::abs( secondCorner.
y - firstCorner.
y ) / 2;
3414 if( halfW >= halfH )
3416 majorRadius = std::max( halfW, 1 );
3417 minorRadius = std::max( halfH, 1 );
3422 majorRadius = std::max( halfH, 1 );
3423 minorRadius = std::max( halfW, 1 );
3445 const double a = std::max( 1,
m_ellipse.MajorRadius );
3446 const double b = std::max( 1,
m_ellipse.MinorRadius );
3449 const double dx = aPosition.
x -
center.x;
3450 const double dy = aPosition.
y -
center.y;
3452 const double cosRot = rotation.
Cos();
3453 const double sinRot = rotation.
Sin();
3454 const double lx = dx * cosRot + dy * sinRot;
3455 const double ly = -dx * sinRot + dy * cosRot;
3469 while( cursorAngle <=
m_ellipse.StartAngle )
3526#define SWAPITEM( x ) std::swap( x, image->x )
3554#define TEST( a, b ) \
3559#define TEST_E( a, b ) \
3561 if( abs( a - b ) > EPSILON ) \
3564#define TEST_PT( a, b ) \
3566 TEST_E( a.x, b.x ); \
3567 TEST_E( a.y, b.y ); \
3624 bool ignoreLineWidth,
bool includeFill )
const
3627 int width = ignoreLineWidth ? 0 :
GetWidth();
3629 width += 2 * aClearance;
3656 width / 2, aError, aErrorLoc );
3666 std::set<size_t> arcsHandled;
3672 size_t arcIndex = outline.
ArcIndex( ii );
3674 if( arcsHandled.contains( arcIndex ) )
3677 arcsHandled.insert( arcIndex );
3703 if( width > 0 || !solidFill )
3742 int inflate = width / 2;
3759 for(
int jj = 0; jj < (int) poly.
SegmentCount(); ++jj )
3774 std::vector<VECTOR2I> poly;
3775 converter.
GetPoly( poly, aError );
3777 for(
unsigned ii = 1; ii < poly.size(); ii++ )
3796 for(
int ii = 0; ii <
chain.PointCount(); ++ii )
3801 int inflate = width / 2;
3814 for(
int ii = 0; ii <
chain.SegmentCount(); ++ii )
3816 const SEG& seg =
chain.CSegment( ii );
3955 default:
return false;
3973 double similarity = 1.0;
4008 similarity *= std::pow( 0.9, m + n - 2 * longest );
4014 std::vector<VECTOR2I> poly;
4015 std::vector<VECTOR2I> otherPoly;
4023 for(
int ii = 0; ii < m; ++ii )
4025 poly.emplace_back( lastPt -
GetPolyShape().CVertex( ii ) );
4031 for(
int ii = 0; ii < n; ++ii )
4039 similarity *= std::pow( 0.9, m + n - 2 * longest );
4068 aEndTangent = lineAngle;
4084 aStartTangent = startAngle +
ANGLE_90;
4089 aStartTangent = startAngle -
ANGLE_90;
4105 std::optional<double> totalLength;
4109 auto fallbackStartTangent =
4115 if( bpts.size() >= 2 )
4116 return EDA_ANGLE( bpts.front() - bpts[1] );
4121 auto fallbackEndTangent =
4127 if( bpts.size() >= 2 )
4128 return EDA_ANGLE( bpts.back() - bpts[bpts.size() - 2] );
4133 auto openArrowFlexTangent =
4134 [&](
const LINE_ENDING& aEnding,
bool aStart ) -> std::optional<EDA_ANGLE>
4137 return std::nullopt;
4142 return std::nullopt;
4147 if( *totalLength <= 0.0 )
4148 return std::nullopt;
4150 double distanceFromStart = std::min<double>( depth, *totalLength );
4153 distanceFromStart = *totalLength - distanceFromStart;
4156 VECTOR2D sample = sourceCurve.PointAt( t );
4160 if(
delta.EuclideanNorm() <= 0.0 )
4161 return std::nullopt;
4171 aStartTangent =
EDA_ANGLE( startDelta );
4173 aStartTangent = fallbackStartTangent();
4180 aEndTangent = fallbackEndTangent();
4184 aStartTangent = fallbackStartTangent();
4185 aEndTangent = fallbackEndTangent();
4188 if( std::optional<EDA_ANGLE> startFlex = openArrowFlexTangent(
m_startEnding,
true ) )
4189 aStartTangent = *startFlex;
4191 if( std::optional<EDA_ANGLE> endFlex = openArrowFlexTangent(
m_endEnding,
false ) )
4192 aEndTangent = *endFlex;
4247 aStartPoint = outline.
CPoint( 0 );
4256 if( bpts.size() < 2 )
4259 aStartPoint = bpts.front();
4260 aEndPoint = bpts.back();
4274 double len =
delta.EuclideanNorm();
4281 int totalDepth = std::max( 0, startDepth ) + std::max( 0, endDepth );
4283 if( totalDepth <= 0 )
4286 if( totalDepth >= len )
4294 if( startDepth > 0 )
4296 aStart.
x +=
KiROUND( dir.
x * startDepth );
4297 aStart.
y +=
KiROUND( dir.
y * startDepth );
4311 int aLineWidth )
const
4316 int startDepth =
m_startEnding.GetShortenDepth( aLineWidth );
4317 int endDepth =
m_endEnding.GetShortenDepth( aLineWidth );
4318 int totalDepth = std::max( 0, startDepth ) + std::max( 0, endDepth );
4320 if( totalDepth <= 0 )
4325 if( totalDepth >= arcLength )
4336 aStartAngle += startOffset;
4337 aArcAngle -= totalOffset;
4341 aStartAngle -= startOffset;
4342 aArcAngle += totalOffset;
4351 double tInv = 1.0 - aT;
4353 VECTOR2D derivative = 3.0 * tInv * tInv * ( aBezier.
C1 - aBezier.
Start )
4354 + 6.0 * tInv * aT * ( aBezier.
C2 - aBezier.
C1 )
4355 + 3.0 * aT * aT * ( aBezier.
End - aBezier.
C2 );
4368 static constexpr double nodes[] = {
4369 0.0950125098376374, 0.2816035507792590, 0.4580167776572274, 0.6178762444026438,
4370 0.7554044083550030, 0.8656312023878318, 0.9445750230732326, 0.9894009349916499
4373 static constexpr double weights[] = { 0.1894506104550685, 0.1826034150449236, 0.1691565193950025,
4374 0.1495959888165767, 0.1246289712555339, 0.0951585116824928,
4375 0.0622535239386479, 0.0271524594117541 };
4377 static_assert( std::size( nodes ) == std::size( weights ) );
4379 double halfWidth = ( aT1 - aT0 ) / 2.0;
4380 double center = ( aT0 + aT1 ) / 2.0;
4381 double length = 0.0;
4383 for(
size_t ii = 0; ii < std::size( nodes ); ++ii )
4385 double offset = halfWidth * nodes[ii];
4390 return halfWidth * length;
4396 if( aTargetLength <= 0.0 )
4399 if( aTargetLength >= aTotalLength )
4406 static constexpr int paramSearchIterations = 24;
4408 for(
int ii = 0; ii < paramSearchIterations; ++ii )
4410 double mid = ( low + high ) / 2.0;
4413 if( len < aTargetLength )
4419 return ( low + high ) / 2.0;
4426 return std::nullopt;
4436 if( startDepth <= 0 && endDepth <= 0 )
4441 if( totalLength <= 0.0 || startDepth + endDepth >= totalLength )
4442 return std::nullopt;
4448 return std::nullopt;
4450 return curve.SubCurve( t0, t1 );
4456 std::vector<VECTOR2D> pts;
4464 std::vector<VECTOR2D> ctrlPts = { curve->Start, curve->C1, curve->C2, curve->End };
4474 const VECTOR2D& aPenultimate,
int aLineWidth )
const
4476 int startDepth =
m_startEnding.GetShortenDepth( aLineWidth );
4477 int endDepth =
m_endEnding.GetShortenDepth( aLineWidth );
4478 int totalDepth = std::max( 0, startDepth ) + std::max( 0, endDepth );
4480 if( totalDepth <= 0 )
4483 double startSegLen = ( aSecond - aFirst ).EuclideanNorm();
4484 double endSegLen = ( aLast - aPenultimate ).EuclideanNorm();
4485 bool twoPointPoly = aSecond == aLast && aPenultimate == aFirst;
4487 if( twoPointPoly && startSegLen <= totalDepth )
4493 if( startDepth > 0 )
4497 if( startSegLen > startDepth )
4498 aFirst = aFirst + dir * ( startDepth / startSegLen );
4505 VECTOR2D dir = aLast - aPenultimate;
4507 if( endSegLen > endDepth )
4508 aLast = aLast - dir * ( endDepth / endSegLen );
4510 aLast = aPenultimate;
4519 if( aPoints.size() < 2 )
4522 if(
IsClosed() || aOutlineIdx != 0 )
4535 aPoints.front() =
VECTOR2I( first );
4543 std::vector<VECTOR2I>& aPoints,
int aLineWidth )
const
4553 aPoints.emplace_back( pt );
4581 if( lineStyleEnum.
Choices().GetCount() == 0 )
4592 if( hatchModeEnum.
Choices().GetCount() == 0 )
4604 auto isNotPolygonOrCircle =
4634 auto isEllipseOrEllipseArc =
4654 const wxString shapeProps =
_HKI(
"Shape Properties" );
4720 wxASSERT_MSG( aValue.CheckType<
int>(),
4721 "Expecting int-containing value" );
4723 int radius = aValue.As<
int>();
4728 return std::nullopt;
4730 int maxRadius = std::min( prop_shape->GetRectangleWidth(),
4731 prop_shape->GetRectangleHeight() ) / 2;
4734 return std::make_unique<VALIDATION_ERROR_TOO_LARGE<int>>(
radius, maxRadius );
4736 return std::make_unique<VALIDATION_ERROR_TOO_SMALL<int>>(
radius, 0 );
4738 return std::nullopt;
4797 double degrees = 0.0;
4799 if( aValue.GetAs( °rees ) && degrees == 0.0 )
4801 return std::make_unique<VALIDATION_ERROR_MSG>(
_(
"Arc angle must not be zero." ) );
4804 return std::nullopt;
4807 auto fillAvailable =
4820 switch( edaShape->GetShape() )
4851 return !shape->IsClosed();
4858 if( endingStyleEnum.
Choices().GetCount() == 0 )
KICOMMON_API types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICOMMON_API 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.
Generic cubic Bezier representation.
VECTOR2< NumericType > Start
VECTOR2< NumericType > C1
VECTOR2< NumericType > C2
VECTOR2< NumericType > End
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
FRAME_T GetFrameType() 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
static bool ShortenSegmentForEndings(VECTOR2I &aStart, VECTOR2I &aEnd, const LINE_ENDING &aStartEnding, const LINE_ENDING &aEndEnding, int aLineWidth)
Shorten a segment body for line endings.
virtual int GetHatchLineSpacing() const
EDA_ANGLE GetArcAngle() const
int GetStartEndingLength() const
virtual void SetEnd(const VECTOR2I &aEnd)
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
void SetArcOrSegment(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the shape from three points, falling back to a SEGMENT from aStart to aEnd when the points are co...
const VECTOR2I & GetBezierC2() const
const VECTOR2I & GetEllipseCenter() const
bool GetLineEndingsBoundingBox(BOX2I &aBBox, int aLineWidth) const
void move(const VECTOR2I &aMoveVector)
virtual 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)
std::vector< SHAPE * > MakeEffectiveShapesWithLineEndings(int aLineWidth) const
Make effective geometry for the shape body shortened for line endings plus the line-ending geometry i...
const std::vector< VECTOR2I > buildBezierToSegmentsPointsList(int aMaxError) const
void SetEndEndingLength(int aLength)
void SetStartEndingStyle(LINE_ENDING_STYLE aStyle)
const SHAPE_POLY_SET & GetHatching() const
EDA_ANGLE GetEllipseEndAngle() const
FILL_T GetFillMode() const
void SetEndEndingWidth(int aWidth)
virtual void SetCornerRadius(int aRadius)
long long int m_rectangleHeight
int GetEllipseMajorRadius() const
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.
void TransformWithLineEndingsToPolygon(SHAPE_POLY_SET &aBuffer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const
Convert the shape body shortened for line endings plus line-ending geometry to polygons.
COLOR4D GetLineColor() const
bool ShortenBodyPolyPoints(std::vector< VECTOR2I > &aPoints, int aOutlineIdx, int aLineWidth) const
Apply line-ending body shortening to copied/generated polyline points.
SHAPE_ELLIPSE buildShapeEllipse() const
void TransformLineEndingsToPolygon(SHAPE_POLY_SET &aBuffer, int aClearance, int aError, ERROR_LOC aErrorLoc, int aLineWidth) const
Append only the line-ending geometry associated with this shape to a polygon set.
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)
std::vector< SHAPE * > makeShortenedBodyShapes(int aLineWidth, bool aEdgeOnly=false) const
Make effective geometry for the shape body shortened for line endings, without the line-ending geomet...
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.
bool ShortenPolyForEndings(VECTOR2D &aFirst, VECTOR2D &aLast, const VECTOR2D &aSecond, const VECTOR2D &aPenultimate, int aLineWidth) const
SHAPE_POLY_SET & GetPolyShape()
void GetEndingTangents(EDA_ANGLE &aStartTangent, EDA_ANGLE &aEndTangent, int aLineWidth=0) const
Compute outward-facing tangent angles at the start and end of the shape.
int GetStartEndingStrokeWidth() const
void CalcArcAngles(EDA_ANGLE &aStartAngle, EDA_ANGLE &aEndAngle) const
Calc arc start and end angles such that aStartAngle < aEndAngle.
virtual std::vector< VECTOR2I > GetCornersInSequence(EDA_ANGLE angle) const
EDA_ANGLE GetEllipseRotation() const
void ShapeGetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList)
void SetEndEndingStyle(LINE_ENDING_STYLE aStyle)
virtual bool isMoving() const
virtual void SetEllipseEndAngle(const EDA_ANGLE &aA)
int GetEndEndingStrokeWidth() const
bool operator==(const EDA_SHAPE &aOther) const
std::vector< SHAPE * > MakeEffectiveShapesForStroking(int aLineWidth=-1) const
Make a set of SHAPE objects to hand to STROKE_PARAMS::Stroke().
virtual void SetBezierC2(const VECTOR2I &aPt)
bool GetShortenedBodyPolyPoints(const SHAPE_LINE_CHAIN &aOutline, int aOutlineIdx, std::vector< VECTOR2I > &aPoints, int aLineWidth) const
Copy an outline and apply line-ending body shortening when applicable.
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 SetBezierC1(const VECTOR2I &aPt)
int GetStartEndingWidth() const
bool GetLineEndingEndpoints(VECTOR2I &aStartPoint, VECTOR2I &aEndPoint) const
Return the source endpoints used to place line endings.
virtual void SetFilled(bool aFlag)
virtual bool IsFilledForHitTesting() const
virtual void SetEllipseRotation(const EDA_ANGLE &aA)
bool continueEdit(const VECTOR2I &aPosition)
virtual void SetArcAngle(const EDA_ANGLE &aAngle)
wxString ShowShape() const
LINE_ENDING_STYLE GetStartEndingStyle() const
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.
virtual int GetHatchLineWidth() const
void flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection)
int GetEndEndingWidth() const
EDA_SHAPE(SHAPE_T aType, int aLineWidth, FILL_T aFill)
std::vector< SEG > & hatchLines() const
void beginEdit(const VECTOR2I &aStartPoint)
int GetEndEndingLength() const
int GetPointCount() const
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
LINE_STYLE GetLineStyle() const
void endEdit(bool aClosed=true)
Finish editing the shape.
virtual void SetEllipseCenter(const VECTOR2I &aPt)
void SetStartEndingLength(int aLength)
void SetEndEndingStrokeWidth(int aWidth)
virtual void SetEllipseMinorRadius(int aR)
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
virtual void SetEllipseMajorRadius(int aR)
void SetLineColor(const COLOR4D &aColor)
COLOR4D GetFillColor() const
void SetRectangle(const long long int &aHeight, const long long int &aWidth)
virtual void SetShape(SHAPE_T aShape)
void SwapShape(EDA_SHAPE *aImage)
std::vector< VECTOR2I > GetRectCorners() const
std::vector< SHAPE * > MakeLineEndingEffectiveShapes(int aLineWidth) const
Make the line-ending geometry associated with this shape.
void SetStartEndingWidth(int aWidth)
std::vector< VECTOR2I > m_bezierPoints
void setPosition(const VECTOR2I &aPos)
EDA_ANGLE GetEllipseStartAngle() const
const std::vector< VECTOR2I > & GetBezierPoints() const
virtual bool IsProxyItem() const
void computeArcBBox(BOX2I &aBBox) const
const LINE_ENDING & GetStartEnding() const
virtual void UpdateHatching() const
LINE_ENDING m_startEnding
void SetRectangleWidth(const int &aWidth)
virtual void SetEllipseStartAngle(const EDA_ANGLE &aA)
virtual 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
std::optional< BEZIER< double > > ShortenedBezierCurve(int aLineWidth) const
Return the cubic Bezier curve shortened for line endings.
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
bool ShortenArcForEndings(EDA_ANGLE &aStartAngle, EDA_ANGLE &aArcAngle, double aRadius, int aLineWidth) const
Shorten an arc body for line endings.
std::vector< VECTOR2D > ShortenedBezierPolyline(int aLineWidth) const
Return the flattened Bezier polyline after line-ending shortening.
VECTOR2I getPosition() const
bool IsClockwiseArc() const
const LINE_ENDING & GetEndEnding() const
LINE_ENDING_STYLE GetEndEndingStyle() const
void RebuildBezierToSegmentsPointsList()
void SetPolyPoints(const std::vector< VECTOR2I > &aPoints)
EDA_SHAPE & operator=(const EDA_SHAPE &aOther)
virtual void SetWidth(int aWidth)
EDA_ANGLE GetSegmentAngle() const
void SetStartEndingStrokeWidth(int aWidth)
int GetCornerRadius() const
void SetFillMode(FILL_T aFill)
std::unique_ptr< SHAPE_POLY_SET > m_poly
virtual void SetPolyShape(const SHAPE_POLY_SET &aShape)
virtual void SetStart(const VECTOR2I &aStart)
wxString getFriendlyName(FRAME_T aFrameType) const
long long int m_rectangleWidth
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.
Decorative shape (arrowhead, circle, square) at the start or end of a graphic line,...
int GetShortenDepth(int aLineWidth) const
Return how far the line should be shortened at this ending.
int GetCurveOrientationDepth(int aLineWidth) const
Return how far along a curved body to look when orienting this ending.
LINE_ENDING_STYLE GetStyle() const
void GetShapes(const VECTOR2I &aPoint, const EDA_ANGLE &aTangent, int aLineWidth, std::vector< VECTOR2I > &aPolygon) const
Generate ending geometry as polygon vertices at the given point and direction.
int GetStrokeWidth() const
Outline stroke width.
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 & SetIsCopyable(bool aIsCopyable=true)
PROPERTY_BASE & SetIsHiddenFromRulesEditor(bool aHide=true)
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.
virtual bool Collide(const VECTOR2I &aP, int aClearance=0, int *aActual=nullptr, VECTOR2I *aLocation=nullptr) const
Check if the boundary of shape (this) lies closer to the point aP than aClearance,...
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 void addLineEndingEffectiveShapes(std::vector< SHAPE * > &aShapes, const LINE_ENDING &aEnding, const VECTOR2I &aPoint, const EDA_ANGLE &aTangent, int aLineWidth)
static void addLineEndingPolygon(SHAPE_POLY_SET &aBuffer, const LINE_ENDING &aEnding, const VECTOR2I &aPoint, const EDA_ANGLE &aTangent, int aClearance, int aError, ERROR_LOC aErrorLoc, int aLineWidth)
static bool hasLineEnding(const LINE_ENDING &aStartEnding, const LINE_ENDING &aEndEnding)
static double bezierSpeedAt(const BEZIER< double > &aBezier, double aT)
static double findBezierTAtLength(const BEZIER< double > &aBezier, double aTargetLength, double aTotalLength)
static struct EDA_SHAPE_DESC _EDA_SHAPE_DESC
static double bezierLength(const BEZIER< double > &aBezier, double aT0, double aT1)
static SHAPE_LINE_CHAIN lineEndingClosedChain(const std::vector< VECTOR2I > &aPolygon)
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
FRAME_T
The set of EDA_BASE_FRAME derivatives, typically stored in EDA_BASE_FRAME::m_Ident.
@ FRAME_SCH_SYMBOL_EDITOR
a few functions useful in geometry calculations.
LINE_ENDING_STYLE
Line ending styles for graphic lines, arcs, and beziers.
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.
SHAPE_LINE_CHAIN BoxToLineChain(const BOX2I &aBox)
Get a SHAPE_LINE_CHAIN representing the outline of a box.
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 PackLineEnding(types::LineEnding &aOutput, const LINE_ENDING &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackColor(types::Color &aOutput, const KIGFX::COLOR4D &aInput)
KICOMMON_API void UnpackStroke(STROKE_PARAMS &aOutput, const types::StrokeAttributes &aInput, const EDA_IU_SCALE &aScale)
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 LINE_ENDING UnpackLineEnding(const types::LineEnding &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 void PackStroke(types::StrokeAttributes &aOutput, const STROKE_PARAMS &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)
Macro to define read-only fields (no setter method available)
@ PT_COORD
Coordinate expressed in distance units (mm/inch)
@ PT_DECIDEGREE
Angle expressed in decidegrees.
@ PT_SIZE
Size expressed in distance units (mm/inch)
#define REGISTER_TYPE(x)
Helper macro to map type hashes to names.
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)
Utility functions for working with shapes.
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.
double RAD2DEG(double rad)
bool IsStraightArc(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
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