KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_shape.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21#include <sch_render_settings.h>
22#include <sch_draw_panel.h>
23#include <macros.h>
24#include <plotters/plotter.h>
25#include <base_units.h>
26#include <widgets/msgpanel.h>
27#include <bitmaps.h>
28#include <eda_draw_frame.h>
29#include <gr_basic.h>
31#include <geometry/shape_arc.h>
34#include <schematic.h>
35#include <api/api_utils.h>
36#include <api/schematic/schematic_types.pb.h>
37#include <sch_shape.h>
38#include <properties/property.h>
40
41
42SCH_SHAPE::SCH_SHAPE( SHAPE_T aShape, SCH_LAYER_ID aLayer, int aLineWidth, FILL_T aFillType,
43 KICAD_T aType ) :
44 SCH_ITEM( nullptr, aType ),
45 EDA_SHAPE( aShape, aLineWidth, aFillType )
46{
47 SetLayer( aLayer );
48}
49
50
52{
53 return new SCH_SHAPE( *this );
54}
55
56
57void SCH_SHAPE::Serialize( google::protobuf::Any& aContainer ) const
58{
59 using namespace kiapi::common;
60
61 kiapi::schematic::types::SchematicGraphicShape msg;
62
63 msg.mutable_id()->set_value( m_Uuid.AsStdString() );
64 msg.set_locked( IsLocked() ? types::LockedState::LS_LOCKED : types::LockedState::LS_UNLOCKED );
65
66 EDA_SHAPE::Serialize( *msg.mutable_shape(), schIUScale );
67
68 kiapi::common::PackCustomProperties( msg.mutable_custom_properties(), *this );
69 aContainer.PackFrom( msg );
70}
71
72
73bool SCH_SHAPE::Deserialize( const google::protobuf::Any& aContainer )
74{
75 using namespace kiapi::common;
76
77 kiapi::schematic::types::SchematicGraphicShape msg;
78
79 if( !aContainer.UnpackTo( &msg ) )
80 return false;
81
82 const_cast<KIID&>( m_Uuid ) = KIID( msg.id().value() );
83 SetLocked( msg.locked() == types::LockedState::LS_LOCKED );
84 kiapi::common::UnpackCustomProperties( msg.custom_properties(), *this );
85
86 return EDA_SHAPE::Deserialize( msg.shape(), schIUScale );
87}
88
89
91{
92 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( aItem );
93
94 EDA_SHAPE::SwapShape( shape );
95}
96
97
98void SCH_SHAPE::SetStroke( const STROKE_PARAMS& aStroke )
99{
100 m_stroke = aStroke;
101}
102
103
104void SCH_SHAPE::SetFilled( bool aFilled )
105{
106 if( !aFilled )
108 else if( GetParentSymbol() )
110 else
112}
113
114
116{
117 if( !IsMoving() )
118 {
120 return;
121 }
122
123 SCH_SHAPE* movingShape = const_cast<SCH_SHAPE*>( this );
124 movingShape->ClearFlags( IS_MOVING );
126 movingShape->SetFlags( IS_MOVING );
127}
128
129
130void SCH_SHAPE::Move( const VECTOR2I& aOffset )
131{
132 move( aOffset );
133}
134
135
137{
139 {
140 VECTOR2I size = GetEnd() - GetPosition();
141
142 if( size.y < 0 )
143 {
144 SetStartY( GetStartY() + size.y );
145 SetEndY( GetStartY() - size.y );
146 }
147
148 if( size.x < 0 )
149 {
150 SetStartX( GetStartX() + size.x );
151 SetEndX( GetStartX() - size.x );
152 }
153 }
154}
155
156
158{
159 flip( VECTOR2I( aCenter, 0 ), FLIP_DIRECTION::LEFT_RIGHT );
160}
161
162
164{
165 flip( VECTOR2I( 0, aCenter ), FLIP_DIRECTION::TOP_BOTTOM );
166}
167
168
169void SCH_SHAPE::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
170{
171 rotate( aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
172}
173
174
175bool SCH_SHAPE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
176{
177 return hitTest( aPosition, aAccuracy );
178}
179
180
181bool SCH_SHAPE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
182{
184 return false;
185
186 return hitTest( aRect, aContained, aAccuracy );
187}
188
189
190bool SCH_SHAPE::HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
191{
193 return false;
194
195 std::vector<SHAPE*> shapes = MakeEffectiveShapes( false );
196
197 for( SHAPE* shape : shapes )
198 {
199 bool hit = KIGEOM::ShapeHitTest( aPoly, *shape, aContained );
200
201 if( hit )
202 {
203 for( SHAPE* s : shapes )
204 delete s;
205 return true;
206 }
207 }
208
209 for( SHAPE* shape : shapes )
210 delete shape;
211
212 return false;
213}
214
215
216bool SCH_SHAPE::IsEndPoint( const VECTOR2I& aPt ) const
217{
218 SHAPE_T shape = GetShape();
219
220 if( shape == SHAPE_T::ARC || shape == SHAPE_T::BEZIER || shape == SHAPE_T::SEGMENT )
221 return ( aPt == GetStart() ) || ( aPt == GetEnd() );
222
223 if( shape == SHAPE_T::RECTANGLE )
224 {
225 for( const VECTOR2I& corner : GetRectCorners() )
226 {
227 if( corner == aPt )
228 return true;
229 }
230
231 return false;
232 }
233
234 if( shape == SHAPE_T::POLY )
235 {
236 for( const VECTOR2I& pt : GetPolyPoints() )
237 {
238 if( pt == aPt )
239 return true;
240 }
241
242 return false;
243 }
244
245 return false;
246}
247
248
249void SCH_SHAPE::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts,
250 int aUnit, int aBodyStyle, const VECTOR2I& aOffset, bool aDimmed )
251{
252 if( IsPrivate() )
253 return;
254
255 // note: if aBodyStyle == -1 the outline shape is not plotted. Only the filled area
256 // is plotted (used to plot cells for SCH_TABLE items
257
258 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
259 int pen_size = GetEffectivePenWidth( renderSettings );
260
261 static std::vector<VECTOR2I> ptList;
262
263 COLOR4D color = GetStroke().GetColor();
264 COLOR4D bg = renderSettings->GetBackgroundColor();
265 LINE_STYLE lineStyle = GetStroke().GetLineStyle();
266 FILL_T fill = m_fill;
267
268 if( aBackground )
269 {
270 switch( m_fill )
271 {
273 // Fill in the foreground layer
274 return;
275
276 case FILL_T::HATCH:
279 if( !aPlotter->GetColorMode() || color == COLOR4D::UNSPECIFIED )
280 color = renderSettings->GetLayerColor( m_layer );
281
282 color.a = color.a * 0.4;
283 break;
284
286 // drop separate fills in B&W mode
287 if( !aPlotter->GetColorMode() && pen_size > 0 )
288 return;
289
290 color = GetFillColor();
291
292 if( color == COLOR4D::UNSPECIFIED )
293 color = renderSettings->GetLayerColor( m_layer );
294
295 break;
296
298 // drop fill in B&W mode
299 if( !aPlotter->GetColorMode() )
300 return;
301
302 color = renderSettings->GetLayerColor( LAYER_DEVICE_BACKGROUND );
303 break;
304
305 default:
306 return;
307 }
308
309 pen_size = 0;
310 lineStyle = LINE_STYLE::SOLID;
311 }
312 else /* if( aForeground ) */
313 {
314 if( !aPlotter->GetColorMode() || color == COLOR4D::UNSPECIFIED )
315 color = renderSettings->GetLayerColor( m_layer );
316
317 if( lineStyle == LINE_STYLE::DEFAULT )
318 lineStyle = LINE_STYLE::SOLID;
319
321 fill = m_fill;
322 else
323 fill = FILL_T::NO_FILL;
324
325 pen_size = aBodyStyle == -1 ? 0 : GetEffectivePenWidth( renderSettings );
326 }
327
328 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
329 bg = COLOR4D::WHITE;
330
331 if( color.m_text && Schematic() )
332 color = COLOR4D( ResolveText( *color.m_text, &Schematic()->CurrentSheet() ) );
333
334 if( aDimmed )
335 {
336 color.Desaturate( );
337 color = color.Mix( bg, 0.5f );
338 }
339
340 aPlotter->SetColor( color );
341
342 if( aBackground && IsHatchedFill() )
343 {
344 for( int ii = 0; ii < GetHatching().OutlineCount(); ++ii )
345 {
346 SHAPE_LINE_CHAIN outline = GetHatching().COutline( ii );
347
348 for( int jj = 0; jj < outline.PointCount(); ++jj )
349 outline.SetPoint( jj, renderSettings->TransformCoordinate( outline.CPoint( jj ) ) + aOffset );
350
351 aPlotter->PlotPoly( outline, FILL_T::FILLED_SHAPE, 0, nullptr );
352 }
353
354 return;
355 }
356
357 aPlotter->SetCurrentLineWidth( pen_size );
358 aPlotter->SetDash( pen_size, lineStyle );
359
360 VECTOR2I start = renderSettings->TransformCoordinate( m_start ) + aOffset;
361 VECTOR2I end = renderSettings->TransformCoordinate( m_end ) + aOffset;
362 VECTOR2I mid, center;
363
364 auto transformBezierPoint =
365 [&]( const VECTOR2D& aPoint )
366 {
367 return renderSettings->TransformCoordinate( VECTOR2I( aPoint ) ) + aOffset;
368 };
369
370 std::vector<VECTOR2I> lineEndingPlotPoints;
371
372 switch( GetShape() )
373 {
374 case SHAPE_T::ARC:
375 {
376 mid = renderSettings->TransformCoordinate( GetArcMid() ) + aOffset;
377
378 // Save original endpoints before shortening.
379 VECTOR2I origArcStart = start;
380 VECTOR2I origArcEnd = end;
381
382 SHAPE_ARC arc( start, mid, end, 0 );
383 VECTOR2I c = arc.GetCenter();
384 EDA_ANGLE startAngle = arc.GetStartAngle();
385 EDA_ANGLE arcAngle = arc.GetCentralAngle();
386
387 // Determine arc direction from start/mid/end.
388 EDA_ANGLE origStart = startAngle;
389
390 if( ShortenArcForEndings( startAngle, arcAngle, arc.GetRadius(), pen_size ) )
391 {
392 RotatePoint( start, c, origStart - startAngle );
393
394 VECTOR2I newEnd = start;
395 RotatePoint( newEnd, c, -arcAngle );
396
397 VECTOR2I newMid = start;
398 RotatePoint( newMid, c, -arcAngle / 2 );
399
400 aPlotter->Arc( start, newMid, newEnd, fill, pen_size );
401 }
402
403 // Restore original endpoints for ending placement.
404 start = origArcStart;
405 end = origArcEnd;
406
407 break;
408 }
409
410 case SHAPE_T::CIRCLE:
411 center = renderSettings->TransformCoordinate( getCenter() ) + aOffset;
412 aPlotter->Circle( center, GetRadius() * 2, fill, pen_size );
413 break;
414
416 aPlotter->Rect( start, end, fill, pen_size, GetCornerRadius() );
417 break;
418
419 case SHAPE_T::SEGMENT:
421 aPlotter->ThickSegment( start, end, pen_size, nullptr );
422
423 break;
424
425 case SHAPE_T::POLY:
426 ptList.clear(); // clear every time; it's static
427
428 if( !GetPolyShape().IsEmpty() )
429 {
430 for( const VECTOR2I& pt : GetPolyShape().Outline( 0 ).CPoints() )
431 ptList.push_back( renderSettings->TransformCoordinate( pt ) + aOffset );
432
433 if( ShortenBodyPolyPoints( ptList, 0, pen_size ) )
434 aPlotter->PlotPoly( ptList, fill, pen_size, nullptr );
435 }
436
437 lineEndingPlotPoints = ptList;
438 break;
439
440 case SHAPE_T::BEZIER:
441 if( std::optional<BEZIER<double>> curve = ShortenedBezierCurve( pen_size ) )
442 {
443 if( aPlotter->GetPlotterType() == PLOT_FORMAT::SVG )
444 {
445 aPlotter->BezierCurve( transformBezierPoint( curve->Start ), transformBezierPoint( curve->C1 ),
446 transformBezierPoint( curve->C2 ), transformBezierPoint( curve->End ),
447 GetMaxError(), pen_size );
448 }
449 else
450 {
451 std::vector<VECTOR2D> pts = ShortenedBezierPolyline( pen_size );
452 std::vector<VECTOR2I> plotPts;
453
454 plotPts.reserve( pts.size() );
455
456 for( const VECTOR2D& pt : pts )
457 plotPts.push_back( transformBezierPoint( pt ) );
458
459 aPlotter->PlotPoly( plotPts, fill, pen_size, nullptr );
460 }
461 }
462
463 break;
464
465 case SHAPE_T::ELLIPSE:
467 {
468 ptList.clear(); // clear every time; it's static
469
471
472 if( GetShortenedBodyPolyPoints( chain, 0, ptList, pen_size ) )
473 aPlotter->PlotPoly( ptList, fill, pen_size, nullptr );
474
475 break;
476 }
477
478 default:
480 }
481
482 aPlotter->SetDash( pen_size, LINE_STYLE::SOLID );
483
484 // Plot line endings
485 if( GetStartEnding().GetStyle() != LINE_ENDING_STYLE::NONE
486 || GetEndEnding().GetStyle() != LINE_ENDING_STYLE::NONE )
487 {
488 VECTOR2I startPt, endPt;
489
490 if( !GetLineEndingEndpoints( startPt, endPt ) )
491 return;
492
493 startPt = renderSettings->TransformCoordinate( startPt ) + aOffset;
494 endPt = renderSettings->TransformCoordinate( endPt ) + aOffset;
495
496 EDA_SHAPE endingShape( *this );
497
498 switch( GetShape() )
499 {
500 case SHAPE_T::ARC:
501 endingShape.SetArcGeometry( startPt, mid, endPt );
502 break;
503
504 case SHAPE_T::POLY:
505 if( lineEndingPlotPoints.size() >= 2 )
506 {
507 SHAPE_POLY_SET plotPoly;
508 plotPoly.NewOutline();
509
510 for( const VECTOR2I& pt : lineEndingPlotPoints )
511 plotPoly.Append( pt );
512
513 if( GetPolyShape().OutlineCount() > 0 )
514 plotPoly.Outline( 0 ).SetClosed( GetPolyShape().COutline( 0 ).IsClosed() );
515
516 endingShape.SetPolyShape( plotPoly );
517 }
518
519 break;
520
521 case SHAPE_T::BEZIER:
522 endingShape.SetStart( startPt );
523 endingShape.SetBezierC1( transformBezierPoint( GetBezierC1() ) );
524 endingShape.SetBezierC2( transformBezierPoint( GetBezierC2() ) );
525 endingShape.SetEnd( endPt );
527 break;
528
529 case SHAPE_T::SEGMENT:
530 endingShape.SetStart( startPt );
531 endingShape.SetEnd( endPt );
532 break;
533
534 default: break;
535 }
536
537 EDA_ANGLE startTangent;
538 EDA_ANGLE endTangent;
539
540 endingShape.GetEndingTangents( startTangent, endTangent, pen_size );
541 GetStartEnding().Plot( aPlotter, startPt, startTangent, pen_size );
542 GetEndEnding().Plot( aPlotter, endPt, endTangent, pen_size );
543 }
544}
545
546
548{
549 if( GetPenWidth() > 0 )
550 return GetPenWidth();
551
552 // Historically 0 meant "default width" and negative numbers meant "don't stroke".
553 if( GetPenWidth() < 0 )
554 return 0;
555
557
558 if( schematic )
559 return schematic->Settings().m_DefaultLineWidth;
560
561 return schIUScale.MilsToIU( DEFAULT_LINE_WIDTH_MILS );
562}
563
564
566{
567 return getBoundingBox();
568}
569
570
571void SCH_SHAPE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
572{
573 SCH_ITEM::GetMsgPanelInfo( aFrame, aList );
574
575 ShapeGetMsgPanelInfo( aFrame, aList );
576}
577
578
579wxString SCH_SHAPE::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
580{
581 switch( GetShape() )
582 {
583 case SHAPE_T::ARC:
584 return wxString::Format( _( "Arc, radius %s" ),
585 aUnitsProvider->MessageTextFromValue( GetRadius() ) );
586
587 case SHAPE_T::CIRCLE:
588 return wxString::Format( _( "Circle, radius %s" ),
589 aUnitsProvider->MessageTextFromValue( GetRadius() ) );
590
592 return wxString::Format( _( "Rectangle, width %s height %s" ),
593 aUnitsProvider->MessageTextFromValue( std::abs( m_start.x - m_end.x ) ),
594 aUnitsProvider->MessageTextFromValue( std::abs( m_start.y - m_end.y ) ) );
595
596 case SHAPE_T::SEGMENT:
597 return wxString::Format( _( "Line, length %s" ),
598 aUnitsProvider->MessageTextFromValue( GetLength() ) );
599
600 case SHAPE_T::POLY:
601 return wxString::Format( _( "Polyline, %d points" ),
602 int( GetPolyShape().IsEmpty() ? 0 : GetPolyShape().Outline( 0 ).GetPointCount() ) );
603
604 case SHAPE_T::BEZIER:
605 return wxString::Format( _( "Bezier Curve, %d points" ),
606 int( m_bezierPoints.size() ) );
607
608 case SHAPE_T::ELLIPSE:
609 return wxString::Format( _( "Ellipse, %s x %s" ),
610 aUnitsProvider->MessageTextFromValue( GetEllipseMajorRadius() ),
611 aUnitsProvider->MessageTextFromValue( GetEllipseMinorRadius() ) );
612
614 return wxString::Format( _( "Elliptical Arc, %s x %s" ),
615 aUnitsProvider->MessageTextFromValue( GetEllipseMajorRadius() ),
616 aUnitsProvider->MessageTextFromValue( GetEllipseMinorRadius() ) );
617
618 default:
620 return wxEmptyString;
621 }
622}
623
624
643
644
645std::vector<int> SCH_SHAPE::ViewGetLayers() const
646{
647 std::vector<int> layers( 3 );
648
649 layers[0] = IsPrivate() ? LAYER_PRIVATE_NOTES : m_layer;
650
651 if( m_layer == LAYER_DEVICE )
652 {
654 layers[1] = LAYER_DEVICE_BACKGROUND;
655 else
656 layers[1] = LAYER_SHAPES_BACKGROUND;
657 }
658 else
659 {
660 layers[1] = LAYER_SHAPES_BACKGROUND;
661 }
662
663 layers[2] = LAYER_SELECTION_SHADOWS;
664
665 return layers;
666}
667
668
669void SCH_SHAPE::SetArcOrLine( const VECTOR2I& aStart, const VECTOR2I& aMid, const VECTOR2I& aEnd )
670{
671 if( IsStraightArc( aStart, aMid, aEnd ) )
672 {
674 AddPoint( aStart );
675 AddPoint( aEnd );
676 }
677 else
678 {
679 SetArcGeometry( aStart, aMid, aEnd );
680 }
681}
682
683
684void SCH_SHAPE::AddPoint( const VECTOR2I& aPosition )
685{
686 if( GetShape() == SHAPE_T::POLY )
687 {
688 if( GetPolyShape().IsEmpty() )
689 {
691 GetPolyShape().Outline( 0 ).SetClosed( false );
692 }
693
694 GetPolyShape().Outline( 0 ).Append( aPosition, true );
695 }
696 else
697 {
699 }
700}
701
702
703bool SCH_SHAPE::operator==( const SCH_ITEM& aOther ) const
704{
705 if( aOther.Type() != Type() )
706 return false;
707
708 const SCH_SHAPE& other = static_cast<const SCH_SHAPE&>( aOther );
709
710 return SCH_ITEM::operator==( aOther ) && EDA_SHAPE::operator==( other );
711}
712
713
714double SCH_SHAPE::Similarity( const SCH_ITEM& aOther ) const
715{
716 if( m_Uuid == aOther.m_Uuid )
717 return 1.0;
718
719 if( aOther.Type() != Type() )
720 return 0.0;
721
722 const SCH_SHAPE& other = static_cast<const SCH_SHAPE&>( aOther );
723
724 double similarity = SimilarityBase( other );
725
726 similarity *= EDA_SHAPE::Similarity( other );
727
728 return similarity;
729}
730
731
732int SCH_SHAPE::compare( const SCH_ITEM& aOther, int aCompareFlags ) const
733{
734 // The object UUIDs must be compared after the shape coordinates because shapes do not
735 // have immutable UUIDs.
736 int retv = SCH_ITEM::compare( aOther, aCompareFlags & ~COMPARE_FLAGS::UUID );
737
738 if( retv )
739 return retv;
740
741 retv = EDA_SHAPE::Compare( &static_cast<const SCH_SHAPE&>( aOther ) );
742
743 if( retv )
744 return retv;
745
746 if( aCompareFlags & COMPARE_FLAGS::UUID )
747 {
748 if( m_Uuid < aOther.m_Uuid )
749 return -1;
750
751 if( m_Uuid > aOther.m_Uuid )
752 return 1;
753 }
754
755 return 0;
756}
757
758
759static struct SCH_SHAPE_DESC
760{
762 {
764
765 if( fillEnum.Choices().GetCount() == 0 )
766 {
767 fillEnum.Map( FILL_T::NO_FILL, _HKI( "None" ) )
768 .Map( FILL_T::FILLED_SHAPE, _HKI( "Body outline color" ) )
769 .Map( FILL_T::FILLED_WITH_BG_BODYCOLOR, _HKI( "Body background color" ) )
770 .Map( FILL_T::FILLED_WITH_COLOR, _HKI( "Fill color" ) )
771 .Map( FILL_T::HATCH, _HKI( "Hatch" ) )
772 .Map( FILL_T::REVERSE_HATCH, _HKI( "Reverse hatch" ) )
773 .Map( FILL_T::CROSS_HATCH, _HKI( "Cross hatch" ) );
774 }
775
782
783 // Polygons and ellipses have meaningful Position properties (first vertex / center).
784 // On other shapes, Position duplicates the Start properties.
785 auto isPolygonOrEllipse =
786 []( INSPECTABLE* aItem ) -> bool
787 {
788 if( SCH_SHAPE* shape = dynamic_cast<SCH_SHAPE*>( aItem ) )
789 {
790 const SHAPE_T t = shape->GetShape();
791 return t == SHAPE_T::POLY || t == SHAPE_T::ELLIPSE || t == SHAPE_T::ELLIPSE_ARC;
792 }
793 return false;
794 };
795
796 // Hide Start/End for shapes that don't use them directly
797 // (polygon uses first vertex via Position; circle uses Center; ellipse uses Center + radii).
798 auto isNotPolygonOrCircleOrEllipse =
799 []( INSPECTABLE* aItem ) -> bool
800 {
801 if( SCH_SHAPE* shape = dynamic_cast<SCH_SHAPE*>( aItem ) )
802 {
803 const SHAPE_T t = shape->GetShape();
804 return t != SHAPE_T::POLY
805 && t != SHAPE_T::CIRCLE
806 && t != SHAPE_T::ELLIPSE
807 && t != SHAPE_T::ELLIPSE_ARC;
808 }
809 return true;
810 };
811
812 auto isSymbolItem =
813 []( INSPECTABLE* aItem ) -> bool
814 {
815 if( SCH_SHAPE* shape = dynamic_cast<SCH_SHAPE*>( aItem ) )
816 return shape->GetLayer() == LAYER_DEVICE;
817
818 return false;
819 };
820
821 auto isSchematicItem =
822 []( INSPECTABLE* aItem ) -> bool
823 {
824 if( SCH_SHAPE* shape = dynamic_cast<SCH_SHAPE*>( aItem ) )
825 return shape->GetLayer() != LAYER_DEVICE;
826
827 return false;
828 };
829
830 auto isFillColorEditable =
831 []( INSPECTABLE* aItem ) -> bool
832 {
833 if( SCH_SHAPE* shape = dynamic_cast<SCH_SHAPE*>( aItem ) )
834 {
835 if( shape->GetParentSymbol() )
836 return shape->GetFillMode() == FILL_T::FILLED_WITH_COLOR;
837 else
838 return shape->IsSolidFill();
839 }
840
841 return true;
842 };
843
844 const wxString shapeProps = _HKI( "Shape Properties" );
845
846 propMgr.AddProperty( new PROPERTY<SCH_SHAPE, int>( _HKI( "Position X" ),
849 shapeProps )
850 .SetAvailableFunc( isPolygonOrEllipse );
851
852 propMgr.AddProperty( new PROPERTY<SCH_SHAPE, int>( _HKI( "Position Y" ),
855 shapeProps )
856 .SetAvailableFunc( isPolygonOrEllipse );
857
858 propMgr.OverrideAvailability( TYPE_HASH( SCH_SHAPE ), TYPE_HASH( EDA_SHAPE ), _HKI( "Start X" ),
859 isNotPolygonOrCircleOrEllipse );
860 propMgr.OverrideAvailability( TYPE_HASH( SCH_SHAPE ), TYPE_HASH( EDA_SHAPE ), _HKI( "Start Y" ),
861 isNotPolygonOrCircleOrEllipse );
863 isNotPolygonOrCircleOrEllipse );
865 isNotPolygonOrCircleOrEllipse );
866
867 propMgr.OverrideAvailability( TYPE_HASH( SCH_SHAPE ), TYPE_HASH( EDA_SHAPE ), _HKI( "Filled" ),
868 isSchematicItem );
869
870 propMgr.OverrideWriteability( TYPE_HASH( SCH_SHAPE ), TYPE_HASH( EDA_SHAPE ), _HKI( "Fill Color" ),
871 isFillColorEditable );
872
873 void ( SCH_SHAPE::*fillModeSetter )( FILL_T ) = &SCH_SHAPE::SetFillMode;
874 FILL_T ( SCH_SHAPE::*fillModeGetter )() const = &SCH_SHAPE::GetFillMode;
875
876 propMgr.AddProperty( new PROPERTY_ENUM<SCH_SHAPE, FILL_T>( _HKI( "Fill Mode" ),
877 fillModeSetter, fillModeGetter ),
878 _HKI( "Shape Properties" ) )
879 .SetAvailableFunc( isSymbolItem );
880 }
882
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:130
BITMAPS
A list of all bitmap identifiers.
@ add_rectangle
@ add_ellipse_arc
@ add_graphical_segments
BOX2< VECTOR2I > BOX2I
Definition box2.h:914
Generic cubic Bezier representation.
static const COLOR4D WHITE
Definition color4d.h:403
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:400
The base class for create windows for drawing purpose.
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition eda_item.h:158
const KIID m_Uuid
Definition eda_item.h:599
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition eda_item.h:160
EDA_ITEM_FLAGS m_flags
Definition eda_item.h:608
bool IsMoving() const
Definition eda_item.h:132
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:84
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 void SetEnd(const VECTOR2I &aEnd)
Definition eda_shape.h:337
void SetStartX(int x)
Definition eda_shape.h:301
int GetEllipseMinorRadius() const
Definition eda_shape.h:403
const VECTOR2I & GetBezierC2() const
Definition eda_shape.h:376
VECTOR2I getCenter() const
int GetStartY() const
Definition eda_shape.h:284
void rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle)
const SHAPE_POLY_SET & GetHatching() const
FILL_T GetFillMode() const
Definition eda_shape.h:150
int GetEllipseMajorRadius() const
Definition eda_shape.h:394
void SetEndY(int aY)
Definition eda_shape.h:344
std::vector< VECTOR2I > GetPolyPoints() const
Duplicate the polygon outlines into a flat list of VECTOR2I points.
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 SetStartY(int y)
Definition eda_shape.h:294
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.
void ShapeGetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList)
bool operator==(const EDA_SHAPE &aOther) const
int GetRadius() const
SHAPE_T GetShape() const
Definition eda_shape.h:177
virtual void SetBezierC2(const VECTOR2I &aPt)
Definition eda_shape.h:375
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.
bool IsHatchedFill() const
Definition eda_shape.h:132
virtual void SetBezierC1(const VECTOR2I &aPt)
Definition eda_shape.h:372
bool GetLineEndingEndpoints(VECTOR2I &aStartPoint, VECTOR2I &aEndPoint) const
Return the source endpoints used to place line endings.
bool hitTest(const VECTOR2I &aPosition, int aAccuracy=0) const
void SetEndX(int aX)
Definition eda_shape.h:351
void RebuildBezierToSegmentsPointsList(int aMaxError)
Rebuild the m_bezierPoints vertex list that approximate the Bezier curve by a list of segments.
void flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection)
EDA_SHAPE(SHAPE_T aType, int aLineWidth, FILL_T aFill)
Definition eda_shape.cpp:56
VECTOR2I m_start
Definition eda_shape.h:767
int GetPointCount() const
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition eda_shape.h:333
bool IsClosed() const
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition eda_shape.h:283
COLOR4D GetFillColor() const
Definition eda_shape.h:161
virtual void SetShape(SHAPE_T aShape)
Definition eda_shape.h:176
void SwapShape(EDA_SHAPE *aImage)
std::vector< VECTOR2I > GetRectCorners() const
std::vector< VECTOR2I > m_bezierPoints
Definition eda_shape.h:776
const LINE_ENDING & GetStartEnding() const
Definition eda_shape.h:179
virtual void UpdateHatching() const
virtual void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the three controlling points for an arc.
double GetLength() const
wxString SHAPE_T_asString() const
int GetStartX() const
Definition eda_shape.h:285
double Similarity(const EDA_SHAPE &aOther) const
const VECTOR2I & GetBezierC1() const
Definition eda_shape.h:373
std::optional< BEZIER< double > > ShortenedBezierCurve(int aLineWidth) const
Return the cubic Bezier curve shortened for line endings.
VECTOR2I m_end
Definition eda_shape.h:768
const BOX2I getBoundingBox() 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.
STROKE_PARAMS m_stroke
Definition eda_shape.h:753
const LINE_ENDING & GetEndEnding() const
Definition eda_shape.h:185
FILL_T m_fill
Definition eda_shape.h:757
int GetCornerRadius() const
void SetFillMode(FILL_T aFill)
virtual void SetPolyShape(const SHAPE_POLY_SET &aShape)
Definition eda_shape.h:528
virtual void SetStart(const VECTOR2I &aStart)
Definition eda_shape.h:287
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
int Compare(const EDA_SHAPE *aOther) const
VECTOR2I GetArcMid() const
ENUM_MAP & Map(T aValue, const wxString &aName)
Definition property.h:798
static ENUM_MAP< T > & Instance()
Definition property.h:792
wxPGChoices & Choices()
Definition property.h:843
Class that other classes need to inherit from, in order to be inspectable.
Definition inspectable.h:39
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
std::shared_ptr< wxString > m_text
Definition color4d.h:397
double a
Alpha component.
Definition color4d.h:394
COLOR4D & Desaturate()
Removes color (in HSL model)
Definition color4d.cpp:530
COLOR4D Mix(const COLOR4D &aColor, double aFactor) const
Return a color that is mixed with the input by a factor.
Definition color4d.h:293
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
Definition kiid.h:46
void Plot(PLOTTER *aPlotter, const VECTOR2I &aPoint, const EDA_ANGLE &aTangent, int aLineWidth, void *aData=nullptr) const
Base plotter engine class.
Definition plotter.h:138
virtual void Circle(const VECTOR2I &pos, int diametre, FILL_T fill, int width)=0
virtual void SetDash(int aLineWidth, LINE_STYLE aLineStyle)=0
virtual PLOT_FORMAT GetPlotterType() const =0
Return the effective plot engine in use.
virtual void Rect(const VECTOR2I &p1, const VECTOR2I &p2, FILL_T fill, int width, int aCornerRadius=0)=0
virtual void BezierCurve(const VECTOR2I &aStart, const VECTOR2I &aControl1, const VECTOR2I &aControl2, const VECTOR2I &aEnd, int aTolerance, int aLineThickness)
Generic fallback: Cubic Bezier curve rendered as a polyline.
Definition plotter.cpp:230
bool GetColorMode() const
Definition plotter.h:166
virtual void SetCurrentLineWidth(int width, void *aData=nullptr)=0
Set the line width for the next drawing.
virtual void ThickSegment(const VECTOR2I &start, const VECTOR2I &end, int width, void *aData)
Definition plotter.cpp:442
virtual void PlotPoly(const std::vector< VECTOR2I > &aCornerList, FILL_T aFill, int aWidth, void *aData)=0
Draw a polygon ( filled or not ).
virtual void SetColor(const COLOR4D &color)=0
virtual void Arc(const VECTOR2D &aStart, const VECTOR2D &aMid, const VECTOR2D &aEnd, FILL_T aFill, int aWidth)
Definition plotter.cpp:150
PROPERTY_BASE & SetAvailableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Set a callback function to determine whether an object provides this property.
Definition property.h:275
Provide class metadata.
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
void OverrideAvailability(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName, std::function< bool(INSPECTABLE *)> aFunc)
Sets an override availability functor for a base class property of a given derived class.
void OverrideWriteability(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName, std::function< bool(INSPECTABLE *)> aFunc)
Sets an override writeability functor for a base class property of a given derived class.
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
Holds all the data relating to one schematic.
Definition schematic.h:149
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:170
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
void SetLocked(bool aLocked) override
Definition sch_item.h:262
SCH_RENDER_SETTINGS * getRenderSettings(PLOTTER *aPlotter) const
Definition sch_item.cpp:46
const SYMBOL * GetParentSymbol() const
Definition sch_item.cpp:350
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition sch_item.cpp:302
bool IsLocked() const override
Definition sch_item.cpp:179
virtual bool operator==(const SCH_ITEM &aOther) const
Definition sch_item.cpp:911
bool IsPrivate() const
Definition sch_item.h:259
void SetLayer(SCH_LAYER_ID aLayer)
Definition sch_item.h:354
int GetMaxError() const
Definition sch_item.cpp:996
SCH_ITEM(EDA_ITEM *aParent, KICAD_T aType, int aUnit=0, int aBodyStyle=0)
Definition sch_item.cpp:65
wxString ResolveText(const wxString &aText, const SCH_SHEET_PATH *aPath, int aDepth=0) const
Definition sch_item.cpp:464
virtual int compare(const SCH_ITEM &aOther, int aCompareFlags=~COMPARE_FLAGS::UNIT) const
Provide the draw object specific comparison called by the == and < operators.
Definition sch_item.cpp:935
int GetEffectivePenWidth(const SCH_RENDER_SETTINGS *aSettings) const
SCH_LAYER_ID m_layer
Definition sch_item.h:843
double SimilarityBase(const SCH_ITEM &aItem) const
Calculate the boilerplate similarity for all LIB_ITEMs without preventing the use above of a pure vir...
Definition sch_item.h:403
VECTOR2I TransformCoordinate(const VECTOR2I &aPoint) const
const KIGFX::COLOR4D & GetBackgroundColor() const override
Return current background color settings.
void SetArcOrLine(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the arc from three points, or a two-point polyline when they are collinear.
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
void SetPositionX(int aX)
Definition sch_shape.h:93
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition sch_shape.cpp:73
std::vector< SHAPE * > MakeEffectiveShapes(bool aEdgeOnly=false) const override
Make a set of SHAPE objects representing the SCH_SHAPE.
Definition sch_shape.h:126
void SetFilled(bool aFilled) override
void Move(const VECTOR2I &aOffset) override
Move the item by aMoveVector to a new position.
void UpdateHatching() const override
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition sch_shape.cpp:51
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition sch_shape.cpp:98
void swapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
Definition sch_shape.cpp:90
void Normalize()
double Similarity(const SCH_ITEM &aOther) const override
Return a measure of how likely the other object is to represent the same object.
void Plot(PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_OPTS &aPlotOpts, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aDimmed) override
Plot the item to aPlotter.
SCH_SHAPE(SHAPE_T aShape=SHAPE_T::UNDEFINED, SCH_LAYER_ID aLayer=LAYER_NOTES, int aLineWidth=0, FILL_T aFillType=FILL_T::NO_FILL, KICAD_T aType=SCH_SHAPE_T)
Definition sch_shape.cpp:42
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
void AddPoint(const VECTOR2I &aPosition)
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
bool operator==(const SCH_ITEM &aOther) const override
void SetPositionY(int aY)
Definition sch_shape.h:94
std::vector< int > ViewGetLayers() const override
Return the layers the item is drawn on (which may be more than its "home" layer)
int GetPenWidth() const override
Definition sch_shape.h:56
bool IsEndPoint(const VECTOR2I &aPoint) const override
Test if aPt is an end point of this schematic object.
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition sch_shape.cpp:57
STROKE_PARAMS GetStroke() const override
Definition sch_shape.h:59
int GetPositionX() const
Definition sch_shape.h:91
VECTOR2I GetPosition() const override
Definition sch_shape.h:88
int GetEffectiveWidth() const override
int compare(const SCH_ITEM &aOther, int aCompareFlags=0) const override
Provide the draw object specific comparison called by the == and < operators.
int GetPositionY() const
Definition sch_shape.h:92
int getMaxError() const override
Definition sch_shape.h:162
EDA_ANGLE GetCentralAngle() const
Get the "central angle" of the arc - this is the angle at the point of the "pie slice".
double GetRadius() const
EDA_ANGLE GetStartAngle() const
const VECTOR2I & GetCenter() const
SHAPE_LINE_CHAIN ConvertToPolyline(int aMaxError) const
Build a polyline approximation of the ellipse or arc.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
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.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
Represent a set of closed polygons.
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)
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.
int OutlineCount() const
Return the number of outlines in the set.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
An abstract shape on 2D plane.
Definition shape.h:124
Simple container to manage line stroke parameters.
LINE_STYLE GetLineStyle() const
KIGFX::COLOR4D GetColor() const
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
#define DEFAULT_LINE_WIDTH_MILS
The default line width in mils. (can be changed in preference menu)
#define _(s)
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:450
static constexpr EDA_ANGLE ANGLE_270
Definition eda_angle.h:453
FILL_T
Definition eda_fill.h:29
@ FILLED_WITH_COLOR
Definition eda_fill.h:33
@ NO_FILL
Definition eda_fill.h:30
@ REVERSE_HATCH
Definition eda_fill.h:35
@ HATCH
Definition eda_fill.h:34
@ FILLED_WITH_BG_BODYCOLOR
Definition eda_fill.h:32
@ FILLED_SHAPE
Fill with object color.
Definition eda_fill.h:31
@ CROSS_HATCH
Definition eda_fill.h:36
#define STRUCT_DELETED
flag indication structures to be erased
#define SKIP_STRUCT
flag indicating that the structure should be ignored
#define IS_MOVING
Item being moved.
SHAPE_T
Definition eda_shape.h:54
@ ELLIPSE
Definition eda_shape.h:62
@ SEGMENT
Definition eda_shape.h:56
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
Definition eda_shape.h:57
@ ELLIPSE_ARC
Definition eda_shape.h:63
a few functions useful in geometry calculations.
SCH_LAYER_ID
Eeschema drawing layers.
Definition layer_ids.h:477
@ LAYER_SHAPES_BACKGROUND
Definition layer_ids.h:511
@ LAYER_DEVICE
Definition layer_ids.h:494
@ LAYER_PRIVATE_NOTES
Definition layer_ids.h:496
@ LAYER_DEVICE_BACKGROUND
Definition layer_ids.h:512
@ LAYER_SELECTION_SHADOWS
Definition layer_ids.h:523
This file contains miscellaneous commonly used macros and functions.
#define UNIMPLEMENTED_FOR(type)
Definition macros.h:92
@ LEFT_RIGHT
Flip left to right (around the Y axis)
Definition mirror.h:24
@ TOP_BOTTOM
Flip top to bottom (around the X axis)
Definition mirror.h:25
Message panel definition file.
bool ShapeHitTest(const SHAPE_LINE_CHAIN &aHitter, const SHAPE &aHittee, bool aHitteeContained)
Perform a shape-to-shape hit test.
KICOMMON_API void PackCustomProperties(google::protobuf::RepeatedPtrField< types::CustomProperty > *aOutput, const EDA_ITEM &aItem)
KICOMMON_API void UnpackCustomProperties(const google::protobuf::RepeatedPtrField< types::CustomProperty > &aInput, EDA_ITEM &aItem)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:437
#define _HKI(x)
Definition page_info.cpp:40
#define TYPE_HASH(x)
Macro to generate unique identifier for a type.
Definition property.h:74
#define ENUM_TO_WXANY(type)
Definition property.h:899
@ PT_COORD
Coordinate expressed in distance units (mm/inch)
Definition property.h:65
#define REGISTER_TYPE(x)
Helper macro to map type hashes to names.
static struct SCH_SHAPE_DESC _SCH_SHAPE_DESC
LINE_STYLE
Dashed line types.
VECTOR2I center
const SHAPE_LINE_CHAIN chain
VECTOR2I end
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.
Definition trigo.cpp:227
bool IsStraightArc(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Definition trigo.cpp:549
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition typeinfo.h:70
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708
VECTOR2< double > VECTOR2D
Definition vector2d.h:707