KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_line.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) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 1992-2024 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, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <base_units.h>
26#include <bitmaps.h>
27#include <string_utils.h>
28#include <core/mirror.h>
29#include <sch_painter.h>
30#include <sch_plotter.h>
32#include <sch_line.h>
33#include <sch_edit_frame.h>
35#include <connection_graph.h>
38#include <trigo.h>
39#include <board_item.h>
40#include <api/api_enums.h>
41#include <api/api_utils.h>
42#include <api/schematic/schematic_types.pb.h>
43
44
45SCH_LINE::SCH_LINE( const VECTOR2I& pos, int layer ) :
46 SCH_ITEM( nullptr, SCH_LINE_T )
47{
48 m_start = pos;
49 m_end = pos;
50 m_stroke.SetWidth( 0 );
51 m_stroke.SetLineStyle( LINE_STYLE::DEFAULT );
52 m_stroke.SetColor( COLOR4D::UNSPECIFIED );
53
54 switch( layer )
55 {
56 default: m_layer = LAYER_NOTES; break;
57 case LAYER_WIRE: m_layer = LAYER_WIRE; break;
58 case LAYER_BUS: m_layer = LAYER_BUS; break;
59 }
60
61 if( layer == LAYER_NOTES )
63 else
65
66 if( layer == LAYER_WIRE )
68 else if( layer == LAYER_BUS )
70 else
72
73 m_lastResolvedLineStyle = LINE_STYLE::SOLID;
74 m_lastResolvedColor = COLOR4D::UNSPECIFIED;
75}
76
77
79 SCH_ITEM( aLine )
80{
81 m_start = aLine.m_start;
82 m_end = aLine.m_end;
83 m_stroke = aLine.m_stroke;
86
90
92}
93
94
95void SCH_LINE::Serialize( google::protobuf::Any &aContainer ) const
96{
97 kiapi::schematic::types::Line line;
98
99 line.mutable_id()->set_value( m_Uuid.AsStdString() );
100 kiapi::common::PackVector2( *line.mutable_start(), GetStartPoint() );
101 kiapi::common::PackVector2( *line.mutable_end(), GetEndPoint() );
102 line.set_layer(
103 ToProtoEnum<SCH_LAYER_ID, kiapi::schematic::types::SchematicLayer>( GetLayer() ) );
104
105 aContainer.PackFrom( line );
106}
107
108
109bool SCH_LINE::Deserialize( const google::protobuf::Any &aContainer )
110{
111 kiapi::schematic::types::Line line;
112
113 if( !aContainer.UnpackTo( &line ) )
114 return false;
115
116 const_cast<KIID&>( m_Uuid ) = KIID( line.id().value() );
119 SCH_LAYER_ID layer =
120 FromProtoEnum<SCH_LAYER_ID, kiapi::schematic::types::SchematicLayer>( line.layer() );
121
122 switch( layer )
123 {
124 case LAYER_WIRE:
125 case LAYER_BUS:
126 case LAYER_NOTES:
127 SetLayer( layer );
128 break;
129
130 default:
131 break;
132 }
133
134 return true;
135}
136
137
139{
140 switch( GetLayer() )
141 {
142 case LAYER_WIRE: return _( "Wire" );
143 case LAYER_BUS: return _( "Bus" );
144 default: return _( "Graphic Line" );
145 }
146}
147
148
150{
151 return new SCH_LINE( *this );
152}
153
154
155void SCH_LINE::Move( const VECTOR2I& aOffset )
156{
157 m_start += aOffset;
158 m_end += aOffset;
159}
160
161
162void SCH_LINE::MoveStart( const VECTOR2I& aOffset )
163{
164 m_start += aOffset;
165}
166
167
168void SCH_LINE::MoveEnd( const VECTOR2I& aOffset )
169{
170 m_end += aOffset;
171}
172
173
174#if defined(DEBUG)
175
176void SCH_LINE::Show( int nestLevel, std::ostream& os ) const
177{
178 NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
179 << " layer=\"" << m_layer << '"'
180 << " startIsDangling=\"" << m_startIsDangling
181 << '"' << " endIsDangling=\""
182 << m_endIsDangling << '"' << ">"
183 << " <start" << m_start << "/>"
184 << " <end" << m_end << "/>" << "</"
185 << GetClass().Lower().mb_str() << ">\n";
186}
187
188#endif
189
190
191void SCH_LINE::ViewGetLayers( int aLayers[], int& aCount ) const
192{
193 aCount = 4;
194 aLayers[0] = LAYER_DANGLING;
195 aLayers[1] = m_layer;
196 aLayers[2] = LAYER_SELECTION_SHADOWS;
197 aLayers[3] = LAYER_OP_VOLTAGES;
198}
199
200
201double SCH_LINE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
202{
203 constexpr double HIDE = std::numeric_limits<double>::max();
204 constexpr double SHOW = 0.0;
205
206 if( aLayer == LAYER_OP_VOLTAGES )
207 {
208 if( m_start == m_end )
209 return HIDE;
210
211 int height = std::abs( m_end.y - m_start.y );
212 int width = std::abs( m_end.x - m_start.x );
213
214 // Operating points will be shown only if zoom is appropriate
215 if( height == 0 )
216 return (double) schIUScale.mmToIU( 15 ) / width;
217 else
218 return (double) schIUScale.mmToIU( 5 ) / height;
219 }
220
221 // Other layers are always drawn.
222 return SHOW;
223}
224
225
227{
228 int width = GetPenWidth() / 2;
229
230 int xmin = std::min( m_start.x, m_end.x ) - width;
231 int ymin = std::min( m_start.y, m_end.y ) - width;
232
233 int xmax = std::max( m_start.x, m_end.x ) + width + 1;
234 int ymax = std::max( m_start.y, m_end.y ) + width + 1;
235
236 BOX2I ret( VECTOR2I( xmin, ymin ), VECTOR2I( xmax - xmin, ymax - ymin ) );
237
238 return ret;
239}
240
241
243{
244 return GetLineLength( m_start, m_end );
245}
246
247
248void SCH_LINE::SetLineColor( const COLOR4D& aColor )
249{
250 m_stroke.SetColor( aColor );
252}
253
254
255void SCH_LINE::SetLineColor( const double r, const double g, const double b, const double a )
256{
257 COLOR4D newColor(r, g, b, a);
258
259 if( newColor == COLOR4D::UNSPECIFIED )
260 {
261 m_stroke.SetColor( COLOR4D::UNSPECIFIED );
262 }
263 else
264 {
265 // Eeschema does not allow alpha channel in colors
266 newColor.a = 1.0;
267 m_stroke.SetColor( newColor );
268 }
269}
270
271
273{
274 if( m_stroke.GetColor() != COLOR4D::UNSPECIFIED )
276 else if( !IsConnectable() )
277 m_lastResolvedColor = COLOR4D::UNSPECIFIED;
278 else if( !IsConnectivityDirty() )
279 m_lastResolvedColor = GetEffectiveNetClass()->GetSchematicColor();
280
281 return m_lastResolvedColor;
282}
283
284
285void SCH_LINE::SetLineStyle( const int aStyleId )
286{
287 SetLineStyle( static_cast<LINE_STYLE>( aStyleId ) );
288}
289
290
292{
293 m_stroke.SetLineStyle( aStyle );
295}
296
297
299{
300 if( m_stroke.GetLineStyle() != LINE_STYLE::DEFAULT )
301 return m_stroke.GetLineStyle();
302
303 return LINE_STYLE::SOLID;
304}
305
306
308{
309 if( m_stroke.GetLineStyle() != LINE_STYLE::DEFAULT )
311 else if( !IsConnectable() )
312 m_lastResolvedLineStyle = LINE_STYLE::SOLID;
313 else if( !IsConnectivityDirty() )
315
317}
318
319
320void SCH_LINE::SetLineWidth( const int aSize )
321{
322 m_stroke.SetWidth( aSize );
324}
325
326
328{
329 SCHEMATIC* schematic = Schematic();
330
331 switch ( m_layer )
332 {
333 default:
334 if( m_stroke.GetWidth() > 0 )
335 return m_stroke.GetWidth();
336
337 if( schematic )
338 return schematic->Settings().m_DefaultLineWidth;
339
341
342 case LAYER_WIRE:
343 if( m_stroke.GetWidth() > 0 )
345 else if( !IsConnectivityDirty() )
346 m_lastResolvedWidth = GetEffectiveNetClass()->GetWireWidth();
347
348 return m_lastResolvedWidth;
349
350 case LAYER_BUS:
351 if( m_stroke.GetWidth() > 0 )
353 else if( !IsConnectivityDirty() )
354 m_lastResolvedWidth = GetEffectiveNetClass()->GetBusWidth();
355
356 return m_lastResolvedWidth;
357 }
358}
359
360
361void SCH_LINE::Print( const SCH_RENDER_SETTINGS* aSettings, int aUnit, int aBodyStyle,
362 const VECTOR2I& offset, bool aForceNoFill, bool aDimmed )
363{
364 wxDC* DC = aSettings->GetPrintDC();
366
367 if( color == COLOR4D::UNSPECIFIED )
368 color = aSettings->GetLayerColor( GetLayer() );
369
370 VECTOR2I start = m_start;
371 VECTOR2I end = m_end;
372 LINE_STYLE lineStyle = GetEffectiveLineStyle();
373 int penWidth = GetEffectivePenWidth( aSettings );
374
375 if( lineStyle <= LINE_STYLE::FIRST_TYPE )
376 {
377 GRLine( DC, start.x, start.y, end.x, end.y, penWidth, color );
378 }
379 else
380 {
381 SHAPE_SEGMENT segment( start, end );
382
383 STROKE_PARAMS::Stroke( &segment, lineStyle, penWidth, aSettings,
384 [&]( const VECTOR2I& a, const VECTOR2I& b )
385 {
386 GRLine( DC, a.x, a.y, b.x, b.y, penWidth, color );
387 } );
388 }
389}
390
391
392void SCH_LINE::MirrorVertically( int aCenter )
393{
394 if( m_flags & STARTPOINT )
395 MIRROR( m_start.y, aCenter );
396
397 if( m_flags & ENDPOINT )
398 MIRROR( m_end.y, aCenter );
399}
400
401
403{
404 if( m_flags & STARTPOINT )
405 MIRROR( m_start.x, aCenter );
406
407 if( m_flags & ENDPOINT )
408 MIRROR( m_end.x, aCenter );
409}
410
411
412void SCH_LINE::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
413{
414 if( m_flags & STARTPOINT )
415 RotatePoint( m_start, aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
416
417 if( m_flags & ENDPOINT )
418 RotatePoint( m_end, aCenter, aRotateCCW ? ANGLE_90 : ANGLE_270 );
419}
420
421
422int SCH_LINE::GetAngleFrom( const VECTOR2I& aPoint ) const
423{
424 VECTOR2I vec;
425
426 if( aPoint == m_start )
427 vec = m_end - aPoint;
428 else
429 vec = m_start - aPoint;
430
431 return KiROUND( EDA_ANGLE( vec ).AsDegrees() );
432}
433
434
435int SCH_LINE::GetReverseAngleFrom( const VECTOR2I& aPoint ) const
436{
437 VECTOR2I vec;
438
439 if( aPoint == m_end )
440 vec = m_start - aPoint;
441 else
442 vec = m_end - aPoint;
443
444 return KiROUND( EDA_ANGLE( vec ).AsDegrees() );
445}
446
447
448bool SCH_LINE::IsParallel( const SCH_LINE* aLine ) const
449{
450 wxCHECK_MSG( aLine != nullptr && aLine->Type() == SCH_LINE_T, false,
451 wxT( "Cannot test line segment for overlap." ) );
452
453 VECTOR2I firstSeg = m_end - m_start;
454 VECTOR2I secondSeg = aLine->m_end - aLine->m_start;
455
456 // Use long long here to avoid overflow in calculations
457 return !( (long long) firstSeg.x * secondSeg.y - (long long) firstSeg.y * secondSeg.x );
458}
459
460
461SCH_LINE* SCH_LINE::MergeOverlap( SCH_SCREEN* aScreen, SCH_LINE* aLine, bool aCheckJunctions )
462{
463 auto less =
464 []( const VECTOR2I& lhs, const VECTOR2I& rhs ) -> bool
465 {
466 if( lhs.x == rhs.x )
467 return lhs.y < rhs.y;
468
469 return lhs.x < rhs.x;
470 };
471
472 wxCHECK_MSG( aLine != nullptr && aLine->Type() == SCH_LINE_T, nullptr,
473 wxT( "Cannot test line segment for overlap." ) );
474
475 if( this == aLine || GetLayer() != aLine->GetLayer() )
476 return nullptr;
477
478 VECTOR2I leftmost_start = aLine->m_start;
479 VECTOR2I leftmost_end = aLine->m_end;
480
481 VECTOR2I rightmost_start = m_start;
482 VECTOR2I rightmost_end = m_end;
483
484 // We place the start to the left and below the end of both lines
485 if( leftmost_start != std::min( { leftmost_start, leftmost_end }, less ) )
486 std::swap( leftmost_start, leftmost_end );
487 if( rightmost_start != std::min( { rightmost_start, rightmost_end }, less ) )
488 std::swap( rightmost_start, rightmost_end );
489
490 // - leftmost is the line that starts farthest to the left
491 // - other is the line that is _not_ leftmost
492 // - rightmost is the line that ends farthest to the right. This may or may not be 'other'
493 // as the second line may be completely covered by the first.
494 if( less( rightmost_start, leftmost_start ) )
495 {
496 std::swap( leftmost_start, rightmost_start );
497 std::swap( leftmost_end, rightmost_end );
498 }
499
500 VECTOR2I other_start = rightmost_start;
501 VECTOR2I other_end = rightmost_end;
502
503 if( less( rightmost_end, leftmost_end ) )
504 {
505 rightmost_start = leftmost_start;
506 rightmost_end = leftmost_end;
507 }
508
509 // If we end one before the beginning of the other, no overlap is possible
510 if( less( leftmost_end, other_start ) )
511 {
512 return nullptr;
513 }
514
515 // Search for a common end:
516 if( ( leftmost_start == other_start ) && ( leftmost_end == other_end ) ) // Trivial case
517 {
518 SCH_LINE* ret = new SCH_LINE( *aLine );
519 ret->SetStartPoint( leftmost_start );
520 ret->SetEndPoint( leftmost_end );
521 ret->SetConnectivityDirty( true );
522
523 if( IsSelected() || aLine->IsSelected() )
524 ret->SetSelected();
525
526 return ret;
527 }
528
529 bool colinear = false;
530
531 /* Test alignment: */
532 if( ( leftmost_start.y == leftmost_end.y ) &&
533 ( other_start.y == other_end.y ) ) // Horizontal segment
534 {
535 colinear = ( leftmost_start.y == other_start.y );
536 }
537 else if( ( leftmost_start.x == leftmost_end.x ) &&
538 ( other_start.x == other_end.x ) ) // Vertical segment
539 {
540 colinear = ( leftmost_start.x == other_start.x );
541 }
542 else
543 {
544 // We use long long here to avoid overflow -- it enforces promotion
545 // The slope of the left-most line is dy/dx. Then we check that the slope from the
546 // left most start to the right most start is the same as well as the slope from the
547 // left most start to right most end.
548 long long dx = leftmost_end.x - leftmost_start.x;
549 long long dy = leftmost_end.y - leftmost_start.y;
550 colinear = ( ( ( other_start.y - leftmost_start.y ) * dx ==
551 ( other_start.x - leftmost_start.x ) * dy ) &&
552 ( ( other_end.y - leftmost_start.y ) * dx ==
553 ( other_end.x - leftmost_start.x ) * dy ) );
554 }
555
556 if( !colinear )
557 return nullptr;
558
559 // We either have a true overlap or colinear touching segments. We always want to merge
560 // the former, but the later only get merged if there no junction at the touch point.
561
562 bool touching = leftmost_end == rightmost_start;
563
564 if( touching && aCheckJunctions && aScreen->IsJunction( leftmost_end ) )
565 return nullptr;
566
567 // Make a new segment that merges the 2 segments
568 leftmost_end = rightmost_end;
569
570 SCH_LINE* ret = new SCH_LINE( *aLine );
571 ret->SetStartPoint( leftmost_start );
572 ret->SetEndPoint( leftmost_end );
573 ret->SetConnectivityDirty( true );
574
575 if( IsSelected() || aLine->IsSelected() )
576 ret->SetSelected();
577
578 return ret;
579}
580
581
583{
584 SCH_LINE* newSegment = static_cast<SCH_LINE*>( Duplicate() );
585
586 newSegment->SetStartPoint( aPoint );
587 newSegment->SetConnectivityDirty( true );
588 SetEndPoint( aPoint );
589
590 return newSegment;
591}
592
593
594void SCH_LINE::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
595{
596 if( IsConnectable() )
597 {
598 aItemList.emplace_back( IsBus() ? BUS_END : WIRE_END, this, m_start );
599 aItemList.emplace_back( IsBus() ? BUS_END : WIRE_END, this, m_end );
600 }
601}
602
603
604bool SCH_LINE::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemListByType,
605 std::vector<DANGLING_END_ITEM>& aItemListByPos,
606 const SCH_SHEET_PATH* aPath )
607{
608 if( !IsConnectable() )
609 return false;
610
611 bool previousStartState = m_startIsDangling;
612 bool previousEndState = m_endIsDangling;
613
615
616 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_pos( aItemListByPos, m_start );
617 it < aItemListByPos.end() && it->GetPosition() == m_start; it++ )
618 {
619 DANGLING_END_ITEM& item = *it;
620
621 if( item.GetItem() == this )
622 continue;
623
624 if( ( IsWire() && item.GetType() != BUS_END && item.GetType() != BUS_ENTRY_END )
625 || ( IsBus() && item.GetType() != WIRE_END && item.GetType() != PIN_END ) )
626 {
627 m_startIsDangling = false;
628 break;
629 }
630 }
631
632 for( auto it = DANGLING_END_ITEM_HELPER::get_lower_pos( aItemListByPos, m_end );
633 it < aItemListByPos.end() && it->GetPosition() == m_end; it++ )
634 {
635 DANGLING_END_ITEM& item = *it;
636
637 if( item.GetItem() == this )
638 continue;
639
640 if( ( IsWire() && item.GetType() != BUS_END && item.GetType() != BUS_ENTRY_END )
641 || ( IsBus() && item.GetType() != WIRE_END && item.GetType() != PIN_END ) )
642 {
643 m_endIsDangling = false;
644 break;
645 }
646 }
647
648 // We only use the bus dangling state for automatic line starting, so we don't care if it
649 // has changed or not (and returning true will result in extra work)
650 if( IsBus() )
651 return false;
652
653 return previousStartState != m_startIsDangling || previousEndState != m_endIsDangling;
654}
655
656
658{
659 if( m_layer == LAYER_WIRE || m_layer == LAYER_BUS )
660 return true;
661
662 return false;
663}
664
665
666bool SCH_LINE::CanConnect( const SCH_ITEM* aItem ) const
667{
668 switch( aItem->Type() )
669 {
670 case SCH_NO_CONNECT_T:
671 case SCH_SYMBOL_T:
672 return IsWire();
673
674 case SCH_JUNCTION_T:
675 case SCH_LABEL_T:
677 case SCH_HIER_LABEL_T:
680 case SCH_SHEET_T:
681 case SCH_SHEET_PIN_T:
682 return IsWire() || IsBus();
683
684 default:
685 return m_layer == aItem->GetLayer();
686 }
687}
688
689
691 const SCH_SHEET_PATH* aInstance ) const
692{
693 // Do not compare to ourself.
694 if( aItem == this || !IsConnectable() )
695 return false;
696
697 const SCH_LINE* line = dynamic_cast<const SCH_LINE*>( aItem );
698
699 // Don't compare against a different SCH_ITEM.
700 wxCHECK( line, false );
701
702 if( GetStartPoint() != line->GetStartPoint() )
703 return true;
704
705 return GetEndPoint() != line->GetEndPoint();
706}
707
708
709std::vector<VECTOR2I> SCH_LINE::GetConnectionPoints() const
710{
711 return { m_start, m_end };
712}
713
714
716{
717 switch( aItem->Type() )
718 {
719 case SCH_LINE_T:
720 return IsBus() == static_cast<const SCH_LINE*>( aItem )->IsBus();
721
722 default:
723 return true;
724 }
725}
726
727
728void SCH_LINE::GetSelectedPoints( std::vector<VECTOR2I>& aPoints ) const
729{
730 if( m_flags & STARTPOINT )
731 aPoints.push_back( m_start );
732
733 if( m_flags & ENDPOINT )
734 aPoints.push_back( m_end );
735}
736
737
738wxString SCH_LINE::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
739{
740 wxString txtfmt;
741
742 if( m_start.x == m_end.x )
743 {
744 switch( m_layer )
745 {
746 case LAYER_WIRE: txtfmt = _( "Vertical Wire, length %s" ); break;
747 case LAYER_BUS: txtfmt = _( "Vertical Bus, length %s" ); break;
748 default: txtfmt = _( "Vertical Graphic Line, length %s" ); break;
749 }
750 }
751 else if( m_start.y == m_end.y )
752 {
753 switch( m_layer )
754 {
755 case LAYER_WIRE: txtfmt = _( "Horizontal Wire, length %s" ); break;
756 case LAYER_BUS: txtfmt = _( "Horizontal Bus, length %s" ); break;
757 default: txtfmt = _( "Horizontal Graphic Line, length %s" ); break;
758 }
759 }
760 else
761 {
762 switch( m_layer )
763 {
764 case LAYER_WIRE: txtfmt = _( "Wire, length %s" ); break;
765 case LAYER_BUS: txtfmt = _( "Bus, length %s" ); break;
766 default: txtfmt = _( "Graphic Line, length %s" ); break;
767 }
768 }
769
770 return wxString::Format( txtfmt,
771 aUnitsProvider->MessageTextFromValue( EuclideanNorm( m_start - m_end ) ) );
772}
773
774
776{
777 if( m_layer == LAYER_NOTES )
778 return BITMAPS::add_dashed_line;
779 else if( m_layer == LAYER_WIRE )
780 return BITMAPS::add_line;
781
782 return BITMAPS::add_bus;
783}
784
785
786bool SCH_LINE::operator <( const SCH_ITEM& aItem ) const
787{
788 if( Type() != aItem.Type() )
789 return Type() < aItem.Type();
790
791 const SCH_LINE* line = static_cast<const SCH_LINE*>( &aItem );
792
793 if( GetLayer() != line->GetLayer() )
794 return GetLayer() < line->GetLayer();
795
796 if( GetStartPoint().x != line->GetStartPoint().x )
797 return GetStartPoint().x < line->GetStartPoint().x;
798
799 if( GetStartPoint().y != line->GetStartPoint().y )
800 return GetStartPoint().y < line->GetStartPoint().y;
801
802 if( GetEndPoint().x != line->GetEndPoint().x )
803 return GetEndPoint().x < line->GetEndPoint().x;
804
805 return GetEndPoint().y < line->GetEndPoint().y;
806}
807
808
809bool SCH_LINE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
810{
811 // Performance enhancement for connection-building
812 if( aPosition == m_start || aPosition == m_end )
813 return true;
814
815 if( aAccuracy >= 0 )
816 aAccuracy += GetPenWidth() / 2;
817 else
818 aAccuracy = abs( aAccuracy );
819
820 return TestSegmentHit( aPosition, m_start, m_end, aAccuracy );
821}
822
823
824bool SCH_LINE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
825{
827 return false;
828
829 BOX2I rect = aRect;
830
831 if ( aAccuracy )
832 rect.Inflate( aAccuracy );
833
834 if( aContained )
835 return rect.Contains( m_start ) && rect.Contains( m_end );
836
837 return rect.Intersects( m_start, m_end );
838}
839
840
842{
843 SCH_ITEM::SwapFlags( aItem );
844
845 SCH_LINE* item = (SCH_LINE*) aItem;
846
847 std::swap( m_layer, item->m_layer );
848
849 std::swap( m_start, item->m_start );
850 std::swap( m_end, item->m_end );
851 std::swap( m_startIsDangling, item->m_startIsDangling );
852 std::swap( m_endIsDangling, item->m_endIsDangling );
853 std::swap( m_stroke, item->m_stroke );
854}
855
856
857bool SCH_LINE::doIsConnected( const VECTOR2I& aPosition ) const
858{
859 if( m_layer != LAYER_WIRE && m_layer != LAYER_BUS )
860 return false;
861
862 return IsEndPoint( aPosition );
863}
864
865
866void SCH_LINE::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts,
867 int aUnit, int aBodyStyle, const VECTOR2I& aOffset, bool aDimmed )
868{
869 if( aBackground )
870 return;
871
872 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
873 int penWidth = GetEffectivePenWidth( renderSettings );
875
876 if( color == COLOR4D::UNSPECIFIED )
877 color = renderSettings->GetLayerColor( GetLayer() );
878
879 aPlotter->SetColor( color );
880
881 aPlotter->SetCurrentLineWidth( penWidth );
882 aPlotter->SetDash( penWidth, GetEffectiveLineStyle() );
883
884 aPlotter->MoveTo( m_start );
885 aPlotter->FinishTo( m_end );
886
887 aPlotter->SetDash( penWidth, LINE_STYLE::SOLID );
888
889 // Plot attributes to a hypertext menu
890 std::vector<wxString> properties;
891 BOX2I bbox = GetBoundingBox();
892 bbox.Inflate( penWidth * 3 );
893
894 if( aPlotOpts.m_PDFPropertyPopups )
895 {
896 if( GetLayer() == LAYER_WIRE )
897 {
898 if( SCH_CONNECTION* connection = Connection() )
899 {
900 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
901 _( "Net" ),
902 connection->Name() ) );
903
904 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
905 _( "Resolved netclass" ),
906 GetEffectiveNetClass()->GetName() ) );
907 }
908 }
909 else if( GetLayer() == LAYER_BUS )
910 {
911 if( SCH_CONNECTION* connection = Connection() )
912 {
913 for( const std::shared_ptr<SCH_CONNECTION>& member : connection->Members() )
914 properties.emplace_back( wxT( "!" ) + member->Name() );
915 }
916
917 }
918
919 if( !properties.empty() )
920 aPlotter->HyperlinkMenu( bbox, properties );
921 }
922}
923
924
925void SCH_LINE::SetPosition( const VECTOR2I& aPosition )
926{
927 m_end = m_end - ( m_start - aPosition );
928 m_start = aPosition;
929}
930
931
932void SCH_LINE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
933{
934 wxString msg;
935
936 switch( GetLayer() )
937 {
938 case LAYER_WIRE: msg = _( "Wire" ); break;
939 case LAYER_BUS: msg = _( "Bus" ); break;
940 default: msg = _( "Graphical" ); break;
941 }
942
943 aList.emplace_back( _( "Line Type" ), msg );
944
945 LINE_STYLE lineStyle = GetLineStyle();
946
947 if( GetEffectiveLineStyle() != lineStyle )
948 aList.emplace_back( _( "Line Style" ), _( "from netclass" ) );
949 else
950 m_stroke.GetMsgPanelInfo( aFrame, aList, true, false );
951
952 SCH_CONNECTION* conn = nullptr;
953
954 if( !IsConnectivityDirty() && dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) )
955 conn = Connection();
956
957 if( conn )
958 {
959 conn->AppendInfoToMsgPanel( aList );
960
961 if( !conn->IsBus() )
962 {
963 aList.emplace_back( _( "Resolved Netclass" ),
964 UnescapeString( GetEffectiveNetClass()->GetName() ) );
965 }
966 }
967}
968
969
971{
972 return ( GetLayer() == LAYER_NOTES );
973}
974
975
977{
978 return ( GetLayer() == LAYER_WIRE );
979}
980
981
982bool SCH_LINE::IsBus() const
983{
984 return ( GetLayer() == LAYER_BUS );
985}
986
987
988bool SCH_LINE::operator==( const SCH_ITEM& aOther ) const
989{
990 if( Type() != aOther.Type() )
991 return false;
992
993 const SCH_LINE& other = static_cast<const SCH_LINE&>( aOther );
994
995 if( GetLayer() != other.GetLayer() )
996 return false;
997
998 if( m_start != other.m_start )
999 return false;
1000
1001 if( m_end != other.m_end )
1002 return false;
1003
1004 if( m_stroke.GetWidth() != other.m_stroke.GetWidth() )
1005 return false;
1006
1007 if( m_stroke.GetColor() != other.m_stroke.GetColor() )
1008 return false;
1009
1010 if( m_stroke.GetLineStyle() != other.m_stroke.GetLineStyle() )
1011 return false;
1012
1013 return true;
1014}
1015
1016
1017double SCH_LINE::Similarity( const SCH_ITEM& aOther ) const
1018{
1019 if( m_Uuid == aOther.m_Uuid )
1020 return 1.0;
1021
1022 if( Type() != aOther.Type() )
1023 return 0.0;
1024
1025 const SCH_LINE& other = static_cast<const SCH_LINE&>( aOther );
1026
1027 if( GetLayer() != other.GetLayer() )
1028 return 0.0;
1029
1030 double similarity = 1.0;
1031
1032 if( m_start != other.m_start )
1033 similarity *= 0.9;
1034
1035 if( m_end != other.m_end )
1036 similarity *= 0.9;
1037
1038 if( m_stroke.GetWidth() != other.m_stroke.GetWidth() )
1039 similarity *= 0.9;
1040
1041 if( m_stroke.GetColor() != other.m_stroke.GetColor() )
1042 similarity *= 0.9;
1043
1044 if( m_stroke.GetLineStyle() != other.m_stroke.GetLineStyle() )
1045 similarity *= 0.9;
1046
1047 return similarity;
1048}
1049
1050
1051static struct SCH_LINE_DESC
1052{
1054 {
1056
1057 if( plotDashTypeEnum.Choices().GetCount() == 0 )
1058 {
1059 plotDashTypeEnum.Map( LINE_STYLE::DEFAULT, _HKI( "Default" ) )
1060 .Map( LINE_STYLE::SOLID, _HKI( "Solid" ) )
1061 .Map( LINE_STYLE::DASH, _HKI( "Dashed" ) )
1062 .Map( LINE_STYLE::DOT, _HKI( "Dotted" ) )
1063 .Map( LINE_STYLE::DASHDOT, _HKI( "Dash-Dot" ) )
1064 .Map( LINE_STYLE::DASHDOTDOT, _HKI( "Dash-Dot-Dot" ) );
1065 }
1066
1070
1071 void ( SCH_LINE::*lineStyleSetter )( LINE_STYLE ) = &SCH_LINE::SetLineStyle;
1072
1073 propMgr.AddProperty( new PROPERTY_ENUM<SCH_LINE, LINE_STYLE>( _HKI( "Line Style" ),
1074 lineStyleSetter, &SCH_LINE::GetLineStyle ) );
1075
1076 propMgr.AddProperty( new PROPERTY<SCH_LINE, int>( _HKI( "Line Width" ),
1077 &SCH_LINE::SetLineWidth, &SCH_LINE::GetLineWidth, PROPERTY_DISPLAY::PT_SIZE ) );
1078
1079 propMgr.AddProperty( new PROPERTY<SCH_LINE, COLOR4D>( _HKI( "Color" ),
1081 }
int color
Definition: DXF_plotter.cpp:58
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:294
bool Contains(const Vec &aPoint) const
Definition: box2.h:158
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:541
static std::vector< DANGLING_END_ITEM >::iterator get_lower_pos(std::vector< DANGLING_END_ITEM > &aItemListByPos, const VECTOR2I &aPos)
Definition: sch_item.cpp:589
Helper class used to store the state of schematic items that can be connected to other schematic item...
Definition: sch_item.h:95
DANGLING_END_T GetType() const
Definition: sch_item.h:139
EDA_ITEM * GetItem() const
Definition: sch_item.h:137
The base class for create windows for drawing purpose.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:88
const KIID m_Uuid
Definition: eda_item.h:485
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:100
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:490
bool IsSelected() const
Definition: eda_item.h:109
void SetSelected()
Definition: eda_item.h:118
ENUM_MAP & Map(T aValue, const wxString &aName)
Definition: property.h:669
static ENUM_MAP< T > & Instance()
Definition: property.h:663
wxPGChoices & Choices()
Definition: property.h:712
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
double a
Alpha component.
Definition: color4d.h:395
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
wxDC * GetPrintDC() const
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:68
Definition: kiid.h:49
std::string AsStdString() const
Definition: kiid.cpp:263
Base plotter engine class.
Definition: plotter.h:104
void MoveTo(const VECTOR2I &pos)
Definition: plotter.h:243
virtual void SetDash(int aLineWidth, LINE_STYLE aLineStyle)=0
void FinishTo(const VECTOR2I &pos)
Definition: plotter.h:253
virtual void SetCurrentLineWidth(int width, void *aData=nullptr)=0
Set the line width for the next drawing.
virtual void HyperlinkMenu(const BOX2I &aBox, const std::vector< wxString > &aDestURLs)
Create a clickable hyperlink menu with a rectangular click area.
Definition: plotter.h:464
virtual void SetColor(const COLOR4D &color)=0
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:85
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:87
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
Holds all the data relating to one schematic.
Definition: schematic.h:75
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:289
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
bool IsBus() const
void AppendInfoToMsgPanel(std::vector< MSG_PANEL_ITEM > &aList) const
Adds information about the connection object to aList.
Schematic editor (Eeschema) main window.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:174
SCH_RENDER_SETTINGS * getRenderSettings(PLOTTER *aPlotter) const
Definition: sch_item.h:678
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:145
std::shared_ptr< NETCLASS > GetEffectiveNetClass(const SCH_SHEET_PATH *aSheet=nullptr) const
Definition: sch_item.cpp:245
void SetLayer(SCH_LAYER_ID aLayer)
Definition: sch_item.h:290
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition: sch_item.h:289
void SetConnectivityDirty(bool aDirty=true)
Definition: sch_item.h:520
bool IsConnectivityDirty() const
Definition: sch_item.h:518
void SwapFlags(SCH_ITEM *aItem)
Swap the non-temp and non-edit flags.
Definition: sch_item.cpp:349
SCH_CONNECTION * Connection(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve the connection associated with this object in the given sheet.
Definition: sch_item.cpp:216
int GetEffectivePenWidth(const SCH_RENDER_SETTINGS *aSettings) const
Definition: sch_item.cpp:470
SCH_LAYER_ID m_layer
Definition: sch_item.h:731
SCH_ITEM * Duplicate(bool doClone=false) const
Routine to create a new copy of given item.
Definition: sch_item.cpp:126
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:40
int GetPenWidth() const override
Definition: sch_line.cpp:327
bool doIsConnected(const VECTOR2I &aPosition) const override
Provide the object specific test to see if it is connected to aPosition.
Definition: sch_line.cpp:857
void GetEndPoints(std::vector< DANGLING_END_ITEM > &aItemList) override
Add the schematic item end points to aItemList if the item has end points.
Definition: sch_line.cpp:594
void SetStartPoint(const VECTOR2I &aPosition)
Definition: sch_line.h:136
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: sch_line.cpp:149
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: sch_line.cpp:775
bool UpdateDanglingState(std::vector< DANGLING_END_ITEM > &aItemListByType, std::vector< DANGLING_END_ITEM > &aItemListByPos, const SCH_SHEET_PATH *aPath=nullptr) override
Test the schematic item to aItemList to check if it's dangling state has changed.
Definition: sch_line.cpp:604
bool m_startIsDangling
True if start point is not connected.
Definition: sch_line.h:336
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
Definition: sch_line.cpp:809
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_line.cpp:925
std::vector< VECTOR2I > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
Definition: sch_line.cpp:709
int GetReverseAngleFrom(const VECTOR2I &aPoint) const
Definition: sch_line.cpp:435
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition: sch_line.cpp:201
SCH_LINE(const VECTOR2I &pos=VECTOR2I(0, 0), int layer=LAYER_NOTES)
Definition: sch_line.cpp:45
bool IsWire() const
Return true if the line is a wire.
Definition: sch_line.cpp:976
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_line.cpp:226
void ViewGetLayers(int aLayers[], int &aCount) const override
Return the layers the item is drawn on (which may be more than its "home" layer)
Definition: sch_line.cpp:191
void SetLineColor(const COLOR4D &aColor)
Definition: sch_line.cpp:248
bool CanConnect(const SCH_ITEM *aItem) const override
Definition: sch_line.cpp:666
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider) const override
Return a user-visible description string of this item.
Definition: sch_line.cpp:738
bool IsParallel(const SCH_LINE *aLine) const
Definition: sch_line.cpp:448
void SetLineWidth(const int aSize)
Definition: sch_line.cpp:320
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition: sch_line.cpp:402
int GetAngleFrom(const VECTOR2I &aPoint) const
Definition: sch_line.cpp:422
void GetSelectedPoints(std::vector< VECTOR2I > &aPoints) const
Definition: sch_line.cpp:728
COLOR4D m_lastResolvedColor
Definition: sch_line.h:348
LINE_STYLE GetEffectiveLineStyle() const
Definition: sch_line.cpp:307
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.
Definition: sch_line.cpp:932
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.
Definition: sch_line.cpp:866
wxString m_operatingPoint
Definition: sch_line.h:350
wxString GetClass() const override
Return the class name.
Definition: sch_line.h:62
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_line.cpp:412
VECTOR2I GetEndPoint() const
Definition: sch_line.h:140
VECTOR2I GetStartPoint() const
Definition: sch_line.h:135
bool ConnectionPropagatesTo(const EDA_ITEM *aItem) const override
Return true if this item should propagate connection info to aItem.
Definition: sch_line.cpp:715
LINE_STYLE m_lastResolvedLineStyle
Definition: sch_line.h:346
SCH_LINE * MergeOverlap(SCH_SCREEN *aScreen, SCH_LINE *aLine, bool aCheckJunctions)
Check line against aLine to see if it overlaps and merge if it does.
Definition: sch_line.cpp:461
VECTOR2I m_start
Line start point.
Definition: sch_line.h:338
bool IsBus() const
Return true if the line is a bus.
Definition: sch_line.cpp:982
int m_lastResolvedWidth
Definition: sch_line.h:347
void Print(const SCH_RENDER_SETTINGS *aSettings, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aForceNoFill, bool aDimmed) override
Print an item.
Definition: sch_line.cpp:361
bool HasConnectivityChanges(const SCH_ITEM *aItem, const SCH_SHEET_PATH *aInstance=nullptr) const override
Check if aItem has connectivity changes against this object.
Definition: sch_line.cpp:690
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition: sch_line.cpp:95
void SetLineStyle(const LINE_STYLE aStyle)
Definition: sch_line.cpp:291
VECTOR2I m_end
Line end point.
Definition: sch_line.h:339
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition: sch_line.cpp:155
LINE_STYLE GetLineStyle() const
Definition: sch_line.cpp:298
void MoveEnd(const VECTOR2I &aMoveVector)
Definition: sch_line.cpp:168
STROKE_PARAMS m_stroke
Line stroke properties.
Definition: sch_line.h:341
bool m_endIsDangling
True if end point is not connected.
Definition: sch_line.h:337
void SwapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
Definition: sch_line.cpp:841
bool IsConnectable() const override
Definition: sch_line.cpp:657
wxString GetFriendlyName() const override
Definition: sch_line.cpp:138
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_line.cpp:392
bool operator==(const SCH_ITEM &aOther) const override
Definition: sch_line.cpp:988
bool operator<(const SCH_ITEM &aItem) const override
Definition: sch_line.cpp:786
bool IsEndPoint(const VECTOR2I &aPoint) const
Definition: sch_line.h:89
bool IsGraphicLine() const
Return if the line is a graphic (non electrical line)
Definition: sch_line.cpp:970
int GetLineWidth() const
Definition: sch_line.h:172
COLOR4D GetLineColor() const
Returns COLOR4D::UNSPECIFIED if a custom color hasn't been set for this line.
Definition: sch_line.cpp:272
void MoveStart(const VECTOR2I &aMoveVector)
Definition: sch_line.cpp:162
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition: sch_line.cpp:109
double GetLength() const
Definition: sch_line.cpp:242
SCH_LINE * BreakAt(const VECTOR2I &aPoint)
Break this segment into two at the specified point.
Definition: sch_line.cpp:582
void SetEndPoint(const VECTOR2I &aPosition)
Definition: sch_line.h:141
double Similarity(const SCH_ITEM &aOther) const override
Return a measure of how likely the other object is to represent the same object.
Definition: sch_line.cpp:1017
bool IsJunction(const VECTOR2I &aPosition) const
Test if a junction is required for the items at aPosition on the screen.
Definition: sch_screen.cpp:477
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
int GetWidth() const
Definition: stroke_params.h:91
void SetLineStyle(LINE_STYLE aLineStyle)
Definition: stroke_params.h:95
void SetWidth(int aWidth)
Definition: stroke_params.h:92
void SetColor(const KIGFX::COLOR4D &aColor)
Definition: stroke_params.h:98
void GetMsgPanelInfo(UNITS_PROVIDER *aUnitsProvider, std::vector< MSG_PANEL_ITEM > &aList, bool aIncludeStyle=true, bool aIncludeWidth=true)
LINE_STYLE GetLineStyle() const
Definition: stroke_params.h:94
KIGFX::COLOR4D GetColor() const
Definition: stroke_params.h:97
static void Stroke(const SHAPE *aShape, LINE_STYLE aLineStyle, int aWidth, const KIGFX::RENDER_SETTINGS *aRenderSettings, const std::function< void(const VECTOR2I &a, const VECTOR2I &b)> &aStroker)
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
#define DEFAULT_BUS_WIDTH_MILS
The default noconnect size in mils.
#define DEFAULT_WIRE_WIDTH_MILS
The default bus width in mils. (can be changed in preference menu)
#define DEFAULT_LINE_WIDTH_MILS
The default wire width in mils. (can be changed in preference menu)
#define _HKI(x)
#define _(s)
static constexpr EDA_ANGLE ANGLE_90
Definition: eda_angle.h:437
static constexpr EDA_ANGLE ANGLE_270
Definition: eda_angle.h:440
#define STRUCT_DELETED
flag indication structures to be erased
#define ENDPOINT
ends. (Used to support dragging.)
#define SKIP_STRUCT
flag indicating that the structure should be ignored
#define STARTPOINT
When a line is selected, these flags indicate which.
void GRLine(wxDC *DC, int x1, int y1, int x2, int y2, int width, const COLOR4D &Color, wxPenStyle aStyle)
Definition: gr_basic.cpp:171
SCH_LAYER_ID
Eeschema drawing layers.
Definition: layer_ids.h:353
@ LAYER_DANGLING
Definition: layer_ids.h:381
@ LAYER_WIRE
Definition: layer_ids.h:356
@ LAYER_NOTES
Definition: layer_ids.h:371
@ LAYER_BUS
Definition: layer_ids.h:357
@ LAYER_SELECTION_SHADOWS
Definition: layer_ids.h:395
@ LAYER_OP_VOLTAGES
Definition: layer_ids.h:401
void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
Definition: mirror.h:40
void PackVector2(kiapi::common::types::Vector2 &aOutput, const VECTOR2I aInput)
Definition: api_utils.cpp:69
VECTOR2I UnpackVector2(const types::Vector2 &aInput)
Definition: api_utils.cpp:75
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:424
#define TYPE_HASH(x)
Definition: property.h:71
#define REGISTER_TYPE(x)
Definition: property_mgr.h:371
@ BUS_END
Definition: sch_item.h:79
@ PIN_END
Definition: sch_item.h:81
@ BUS_ENTRY_END
Definition: sch_item.h:83
@ WIRE_END
Definition: sch_item.h:78
static struct SCH_LINE_DESC _SCH_LINE_DESC
wxString UnescapeString(const wxString &aSource)
LINE_STYLE
Dashed line types.
Definition: stroke_params.h:48
constexpr int MilsToIU(int mils) const
Definition: base_units.h:93
constexpr int mmToIU(double mm) const
Definition: base_units.h:88
bool m_PDFPropertyPopups
Definition: sch_plotter.h:91
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.
Definition: trigo.cpp:174
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:228
double GetLineLength(const VECTOR2I &aPointA, const VECTOR2I &aPointB)
Return the length of a line segment defined by aPointA and aPointB.
Definition: trigo.h:194
double EuclideanNorm(const VECTOR2I &vector)
Definition: trigo.h:128
@ SCH_LINE_T
Definition: typeinfo.h:163
@ SCH_NO_CONNECT_T
Definition: typeinfo.h:160
@ SCH_SYMBOL_T
Definition: typeinfo.h:172
@ SCH_DIRECTIVE_LABEL_T
Definition: typeinfo.h:171
@ SCH_LABEL_T
Definition: typeinfo.h:167
@ SCH_SHEET_T
Definition: typeinfo.h:174
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:169
@ SCH_SHEET_PIN_T
Definition: typeinfo.h:173
@ SCH_BUS_WIRE_ENTRY_T
Definition: typeinfo.h:161
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:168
@ SCH_JUNCTION_T
Definition: typeinfo.h:159
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:118
VECTOR2< int > VECTOR2I
Definition: vector2d.h:602