KiCad PCB EDA Suite
Loading...
Searching...
No Matches
ee_grid_helper.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) 2014 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * @author Tomasz Wlostowski <[email protected]>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22#include <functional>
23#include <cmath>
24#include <advanced_config.h>
25#include <macros.h>
27#include <eeschema_settings.h>
28#include <sch_base_frame.h>
29#include <sch_pin.h>
30#include <sch_symbol.h>
32#include <sch_group.h>
33#include <sch_item.h>
34#include <sch_line.h>
35#include <sch_shape.h>
36#include <sch_table.h>
37#include <sch_tablecell.h>
38#include <sch_painter.h>
40#include <snap/snap_inference.h>
41#include <tool/snap_frame.h>
42#include <tool/tool_manager.h>
43#include <sch_tool_base.h>
45#include <trigo.h>
46#include <view/view.h>
47#include "ee_grid_helper.h"
48
49
50namespace
51{
52std::optional<INTERSECTABLE_GEOM> getSchematicIntersectable( const SCH_ITEM& aItem )
53{
54 if( aItem.Type() == SCH_LINE_T )
55 {
56 const SCH_LINE& line = static_cast<const SCH_LINE&>( aItem );
57 return SEG( line.GetStartPoint(), line.GetEndPoint() );
58 }
59
60 if( aItem.Type() != SCH_SHAPE_T )
61 return std::nullopt;
62
63 const SCH_SHAPE& shape = static_cast<const SCH_SHAPE&>( aItem );
64
65 switch( shape.GetShape() )
66 {
67 case SHAPE_T::SEGMENT: return SEG( shape.GetStart(), shape.GetEnd() );
68 case SHAPE_T::CIRCLE: return CIRCLE( shape.GetCenter(), shape.GetRadius() );
69 case SHAPE_T::ARC: return SHAPE_ARC( shape.GetStart(), shape.GetArcMid(), shape.GetEnd(), 0 );
70 case SHAPE_T::RECTANGLE: return BOX2I::ByCorners( shape.GetStart(), shape.GetEnd() );
71 default: return std::nullopt;
72 }
73}
74} // namespace
75
76
81
82
85{
86 if( !m_toolMgr )
87 return;
88
89 KIGFX::VIEW* view = m_toolMgr->GetView();
90
91 m_viewAxis.SetSize( 20000 );
93 m_viewAxis.SetColor( COLOR4D( 0.0, 0.1, 0.4, 0.8 ) );
94 m_viewAxis.SetDrawAtZero( true );
95 view->Add( &m_viewAxis );
96 view->SetVisible( &m_viewAxis, false );
97
99 m_viewSnapPoint.SetColor( COLOR4D( 0.0, 0.1, 0.4, 1.0 ) );
100 m_viewSnapPoint.SetDrawAtZero( true );
101 view->Add( &m_viewSnapPoint );
102 view->SetVisible( &m_viewSnapPoint, false );
103}
104
105
107{
108 if( !m_toolMgr )
109 return;
110
111 KIGFX::VIEW* view = m_toolMgr->GetView();
112
113 view->Remove( &m_viewAxis );
114 view->Remove( &m_viewSnapPoint );
115}
116
117
118void EE_GRID_HELPER::AddConstructionItems( std::vector<SCH_ITEM*> aItems, bool aExtensionOnly, bool aIsPersistent )
119{
120 if( !ADVANCED_CFG::GetCfg().m_EnableExtensionSnaps )
121 return;
122
123 if( !snapInferenceSettings().constructionExtensions )
124 return;
125
126 auto batch = std::make_unique<CONSTRUCTION_MANAGER::CONSTRUCTION_ITEM_BATCH>();
127
128 for( SCH_ITEM* item : aItems )
129 {
130 std::vector<KIGFX::CONSTRUCTION_GEOM::DRAWABLE> drawables;
131 std::optional<SEG> segment;
132
133 if( item->Type() == SCH_LINE_T )
134 {
135 const SCH_LINE& line = static_cast<const SCH_LINE&>( *item );
136 segment = SEG( line.GetStartPoint(), line.GetEndPoint() );
137 }
138 else if( item->Type() == SCH_SHAPE_T )
139 {
140 const SCH_SHAPE& shape = static_cast<const SCH_SHAPE&>( *item );
141
142 if( shape.GetShape() == SHAPE_T::SEGMENT )
143 {
144 segment = SEG( shape.GetStart(), shape.GetEnd() );
145 }
146 else if( shape.GetShape() == SHAPE_T::ARC )
147 {
148 drawables.emplace_back( CIRCLE( shape.GetCenter(), shape.GetRadius() ) );
149 drawables.emplace_back( shape.GetCenter() );
150 }
151 else if( shape.GetShape() == SHAPE_T::CIRCLE )
152 {
153 drawables.emplace_back( shape.GetCenter() );
154 }
155 }
156
157 if( segment )
158 {
159 if( aExtensionOnly )
160 {
161 VECTOR2I direction = segment->B - segment->A;
162 drawables.emplace_back( HALF_LINE( segment->A, segment->A - direction ) );
163 drawables.emplace_back( HALF_LINE( segment->B, segment->B + direction ) );
164 }
165 else
166 {
167 drawables.emplace_back( LINE( *segment ) );
168 }
169
170 if( aIsPersistent )
171 {
172 drawables.emplace_back( segment->A );
173 drawables.emplace_back( segment->B );
174 }
175 }
176
177 std::vector<CONSTRUCTION_MANAGER::CONSTRUCTION_ITEM::DRAWABLE_ENTRY> entries;
178
180 entries.push_back( { std::move( drawable ), 1 } );
181
182 batch->push_back( { CONSTRUCTION_MANAGER::SOURCE::FROM_ITEMS, item, std::move( entries ) } );
183 }
184
185 getSnapManager().GetConstructionManager().ProposeConstructionItems( std::move( batch ), aIsPersistent );
186}
187
188
190{
192
193 if( !m_toolMgr )
194 return settings;
195
196 if( SCH_BASE_FRAME* frame = dynamic_cast<SCH_BASE_FRAME*>( m_toolMgr->GetToolHolder() ) )
197 {
198 // eeconfig() and libeditconfig() are unrelated types, so the editor has to be resolved
199 // first; a plain dynamic_cast silently yields defaults in the symbol editor.
200 if( frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
201 {
202 if( SYMBOL_EDITOR_SETTINGS* cfg = frame->libeditconfig() )
203 settings = cfg->m_SnapInference;
204 }
205 else if( EESCHEMA_SETTINGS* cfg = frame->eeconfig() )
206 {
207 settings = cfg->m_SnapInference;
208 }
209 }
210
211 return settings;
212}
213
214
216{
217 if( aItem.Type() == SCH_SYMBOL_T )
218 return static_cast<const SCH_SYMBOL&>( aItem ).GetBodyAndPinsBoundingBox();
219
220 return aItem.GetBoundingBox();
221}
222
223
224std::vector<std::pair<const SCH_PIN*, VECTOR2I>> EE_GRID_HELPER::layoutPins( SCH_ITEM& aItem )
225{
226 std::vector<std::pair<const SCH_PIN*, VECTOR2I>> pins;
227
228 if( aItem.Type() == SCH_PIN_T )
229 {
230 SCH_PIN& pin = static_cast<SCH_PIN&>( aItem );
231 pins.emplace_back( &pin, pin.GetPosition() );
232 }
233 else if( aItem.Type() == SCH_SYMBOL_T )
234 {
235 // TODO: we don't know what sheet we're on, so we can't pick the correct unit for
236 // that instance of the symbol. For now we check all units and all bodystyles.
237 for( SCH_PIN* pin : static_cast<SCH_SYMBOL&>( aItem ).GetGraphicalPins( ALL_UNITS, ALL_BODY_STYLES ) )
238 pins.emplace_back( pin, pin->GetPosition() );
239 }
240
241 return pins;
242}
243
244
246 const SCH_SELECTION& aItems )
247{
248 clearAnchors();
249
250 // If we're working with any connectable objects, skip non-connectable objects
251 // since they are often off-grid, e.g. text anchors
252 bool hasConnectables = false;
253
254 for( EDA_ITEM* item : aItems )
255 {
256 GRID_HELPER_GRIDS grid = GetItemGrid( static_cast<SCH_ITEM*>( item ) );
257 if( grid == GRID_CONNECTABLE || grid == GRID_WIRES )
258 {
259 hasConnectables = true;
260 break;
261 }
262 }
263
264 for( EDA_ITEM* item : aItems )
265 computeAnchors( static_cast<SCH_ITEM*>( item ), aMousePos, true, !hasConnectables );
266
267 double worldScale = m_toolMgr->GetView()->GetGAL()->GetWorldScale();
268 double lineSnapMinCornerDistance = 50.0 / worldScale;
269
270 ANCHOR* nearestOutline = nearestAnchor( aMousePos, OUTLINE, aGrid );
271 ANCHOR* nearestCorner = nearestAnchor( aMousePos, CORNER, aGrid );
272 ANCHOR* nearestOrigin = nearestAnchor( aMousePos, ORIGIN, aGrid );
273 ANCHOR* best = nullptr;
274 double minDist = std::numeric_limits<double>::max();
275
276 if( nearestOrigin )
277 {
278 minDist = nearestOrigin->Distance( aMousePos );
279 best = nearestOrigin;
280 }
281
282 if( nearestCorner )
283 {
284 double dist = nearestCorner->Distance( aMousePos );
285
286 if( dist < minDist )
287 {
288 minDist = dist;
289 best = nearestCorner;
290 }
291 }
292
293 if( nearestOutline )
294 {
295 double dist = nearestOutline->Distance( aMousePos );
296
297 if( minDist > lineSnapMinCornerDistance && dist < minDist )
298 best = nearestOutline;
299 }
300
301 VECTOR2I ret = best ? best->pos : aMousePos;
302
303 if( best )
304 {
305 std::optional<BOX2I> movingBounds;
306 bool pinEnd = false;
307
308 // A symbol's pin anchors are tagged with the symbol, not the pin, so the grab is
309 // classified against pin geometry rather than against the anchor's item.
310 for( EDA_ITEM* item : aItems )
311 {
312 SCH_ITEM& schematicItem = *static_cast<SCH_ITEM*>( item );
313 BOX2I bounds = layoutBounds( schematicItem );
314
315 if( movingBounds )
316 movingBounds->Merge( bounds );
317 else
318 movingBounds = bounds;
319
320 if( !pinEnd )
321 {
322 std::vector<std::pair<const SCH_PIN*, VECTOR2I>> pins = layoutPins( schematicItem );
323
324 pinEnd = std::any_of( pins.begin(), pins.end(),
325 [&]( const std::pair<const SCH_PIN*, VECTOR2I>& aPin )
326 {
327 return aPin.second == ret;
328 } );
329 }
330 }
331
332 setLayoutReference( ret, movingBounds, pinEnd );
333 }
334 else
335 {
336 setLayoutReference( ret, std::nullopt, false );
337 }
338
339 return ret;
340}
341
342
344{
345 SCH_SELECTION skipItems;
346
347 // No skip item means nothing is moving, which selects the picker snap profile
348 if( aSkip )
349 skipItems.Add( aSkip );
350
351 return ResolveSnap( aOrigin, aGrid, skipItems );
352}
353
354
356 std::optional<VECTOR2I> aMovingReferencePoint )
357{
358 const SNAP_RANGES ranges = computeSnapRanges( canUseGrid() );
359 const double snapScale = ranges.scale;
360 const int snapRange = ranges.range;
361 const int snapIn = ranges.in;
362 const int snapOut = ranges.out;
363
364 const SNAP_INFERENCE_SETTINGS inferenceSettings = snapInferenceSettings();
365
366 const bool constructionEnabled =
368
369 if( !constructionEnabled )
371
372 BOX2I bb( VECTOR2I( aOrigin.x - snapRange / 2, aOrigin.y - snapRange / 2 ), VECTOR2I( snapRange, snapRange ) );
373
374 std::optional<ANCHOR> retained = m_snapItem;
375 clearAnchors();
376
377 const std::set<SCH_ITEM*> visibleItems = queryVisible( bb, aSkip );
378
379 for( SCH_ITEM* item : visibleItems )
380 computeAnchors( item, aOrigin );
381
382 ANCHOR* nearest = nearestAnchor( aOrigin, SNAPPABLE, aGrid );
383 VECTOR2I nearestGrid = Align( aOrigin, aGrid );
384
386 {
387 ad->ClearAnchors();
388 for( const ANCHOR& a : m_anchors )
389 ad->AddAnchor( a.pos );
390
391 ad->SetNearest( nearest ? OPT_VECTOR2I( nearest->pos ) : std::nullopt );
392 m_toolMgr->GetView()->Update( ad, KIGFX::GEOMETRY );
393 }
394
396
398 const VECTOR2D gridSize = GetGridSize( aGrid );
399
400 std::optional<VECTOR2I> guideSnap;
401
402 if( m_enableSnapLine )
403 guideSnap = SnapToConstructionLines( aOrigin, nearestGrid, gridSize, snapRange );
404
405 const auto anchorId = [&]( const ANCHOR& aAnchor )
406 {
407 std::vector<SNAP_TARGET_ID> targets;
408
409 for( const EDA_ITEM* item : aAnchor.items )
410 {
411 if( item )
412 targets.push_back( SnapTargetId( item->m_Uuid ) );
413 }
414
415 SNAP_ID_KIND kind =
417
418 if( targets.empty() )
419 return MakePointSnapId( kind, aAnchor.pos, aAnchor.pointTypes );
420
421 if( targets.size() == 1 )
422 return SNAP_STABLE_ID{ kind, targets.front(), aAnchor.pointTypes, 0 };
423
424 return MakeCompositeSnapId( kind, targets, aAnchor.pointTypes );
425 };
426
427 SNAP_SOURCE_CONTEXT context;
429 context.sourcePoint = aOrigin;
430 context.movingReferencePoint = aMovingReferencePoint;
432
433 for( EDA_ITEM* item : aSkip )
434 {
435 BOX2I bounds = layoutBounds( *static_cast<SCH_ITEM*>( item ) );
436
437 if( context.movingBounds )
438 context.movingBounds->Merge( bounds );
439 else
440 context.movingBounds = bounds;
441 }
442
443 if( aSkip.GetSize() == 1 )
444 {
445 SCH_ITEM* sourceItem = static_cast<SCH_ITEM*>( *aSkip.begin() );
447
450
451 if( sourceItem->Type() == SCH_LINE_T && m_pointEditProfile )
452 {
453 SCH_LINE* line = static_cast<SCH_LINE*>( sourceItem );
454 context.stationarySourceLeg =
455 line->GetStartPoint().SquaredDistance( aOrigin ) > line->GetEndPoint().SquaredDistance( aOrigin )
456 ? line->GetStartPoint()
457 : line->GetEndPoint();
458 }
459 }
460
461 enum class PRESENTATION_KIND
462 {
463 ANCHOR_MARKER,
464 GUIDE
465 };
466
467 struct PRESENTATION
468 {
469 PRESENTATION_KIND kind;
470 std::optional<ANCHOR> anchor;
471 bool proposeConstruction;
472 };
473
475 frame.context = context;
479 frame.trace = snapTraceCallback( context );
480
481 SNAP_INFERENCE_PROVIDER inferenceProvider;
482 SNAP_INFERENCE_PROVIDER tangentProvider;
483 const bool inferenceEnabled = m_enableSnap
484 && ( inferenceSettings.objectGeometry || inferenceSettings.tangentNormal
485 || inferenceSettings.alignmentDistribution );
486
487 // CollectTangentNormal only reads arcs and circles, and only when dragging away from a fixed leg
488 const bool tangentEnabled = inferenceSettings.tangentNormal && context.stationarySourceLeg.has_value();
489
490 if( inferenceEnabled && context.movingItem )
491 {
492 for( size_t i = 0; i < m_stationarySelfSegments.size(); ++i )
493 {
494 SNAP_STABLE_ID id =
495 MakeDerivedSnapId( SNAP_ID_KIND::SELF_SEGMENT, *context.movingItem, static_cast<int>( i ) );
496 context.stationarySelfFeatures.push_back( id );
497
498 if( inferenceSettings.objectGeometry )
499 inferenceProvider.AddPath( { id, m_stationarySelfSegments[i], false } );
500 }
501 }
502
503 emitAngleBranchCandidates( frame.candidates, aOrigin, snapScale );
504
505 if( inferenceEnabled )
506 {
507 for( SCH_ITEM* item : visibleItems )
508 {
509 if( inferenceSettings.objectGeometry || tangentEnabled )
510 {
511 std::optional<INTERSECTABLE_GEOM> geometry = getSchematicIntersectable( *item );
512
513 if( geometry )
514 {
516 static_cast<int>( item->Type() ), 0 };
517 const bool curved = std::holds_alternative<CIRCLE>( *geometry )
518 || std::holds_alternative<SHAPE_ARC>( *geometry );
519
520 if( inferenceSettings.objectGeometry )
521 inferenceProvider.AddPath( { id, *geometry, false } );
522
523 if( tangentEnabled && curved )
524 tangentProvider.AddPath( { std::move( id ), std::move( *geometry ), false } );
525 }
526 }
527
528 if( inferenceSettings.alignmentDistribution )
529 {
530 inferenceProvider.AddBounds( { { SNAP_ID_KIND::ITEM_GEOMETRY, SnapTargetId( item->m_Uuid ),
531 static_cast<int>( item->Type() ), 0 },
532 layoutBounds( *item ),
533 std::nullopt } );
534
535 for( const auto& [pin, position] : layoutPins( *item ) )
536 {
537 inferenceProvider.AddAlignmentPoint(
539 position,
540 SnapTargetId( item->m_Uuid ) } );
541 }
542 }
543 }
544 }
545
546 int constructionIndex = 0;
547
548 if( constructionEnabled )
549 {
550 for( const CONSTRUCTION_MANAGER::CONSTRUCTION_ITEM_BATCH& batch : getSnapManager().GetConstructionItems() )
551 {
552 for( const CONSTRUCTION_MANAGER::CONSTRUCTION_ITEM& item : batch )
553 {
554 SNAP_TARGET_ID target = item.Item ? SnapTargetId( item.Item->m_Uuid ) : SNAP_TARGET_ID{};
555
556 for( const CONSTRUCTION_MANAGER::CONSTRUCTION_ITEM::DRAWABLE_ENTRY& entry : item.Constructions )
557 {
558 SNAP_STABLE_ID id{ SNAP_ID_KIND::CONSTRUCTION, target, constructionIndex++, 0 };
559
560 std::visit(
561 [&]( const auto& drawable )
562 {
563 using DRAWABLE_TYPE = std::decay_t<decltype( drawable )>;
564
565 if constexpr( std::is_same_v<DRAWABLE_TYPE, VECTOR2I> )
566 {
567 frame.candidates.push_back( SNAP_CANDIDATE::Point(
569 drawable, drawable.Distance( aOrigin ) / snapScale ) );
570 }
571 else
572 {
573 inferenceProvider.AddPath( { id, drawable, false, true } );
574 }
575 },
576 entry.Drawable );
577 }
578 }
579 }
580 }
581
582 if( m_enableSnap && ( inferenceSettings.objectGeometry || constructionEnabled ) )
583 {
584 for( SNAP_CANDIDATE& candidate : inferenceProvider.CollectObjectGeometry( context, snapRange ) )
585 frame.candidates.push_back( std::move( candidate ) );
586 }
587
588 if( m_enableSnap && inferenceSettings.tangentNormal && context.stationarySourceLeg )
589 {
590 for( SNAP_CANDIDATE& candidate : tangentProvider.CollectTangentNormal( context, snapRange, true, true ) )
591 {
592 frame.candidates.push_back( std::move( candidate ) );
593 }
594 }
595
596 if( m_enableSnap && inferenceSettings.alignmentDistribution && context.movingBounds )
597 {
598 for( SNAP_CANDIDATE& candidate : inferenceProvider.CollectAlignment( context, snapRange ) )
599 frame.candidates.push_back( std::move( candidate ) );
600
601 for( SNAP_CANDIDATE& candidate : inferenceProvider.CollectEqualSpacing( context, snapRange ) )
602 frame.candidates.push_back( std::move( candidate ) );
603 }
604
605 if( m_enableSnap && retained && retained->Distance( aOrigin ) <= snapOut )
606 {
607 SNAP_STABLE_ID retainedId = anchorId( *retained );
608 frame.retainedId = retainedId;
609 frame.candidates.push_back( SNAP_CANDIDATE::Point( retainedId, SNAP_PRIORITY_TIER::OBJECT,
610 retained->flags & CONSTRUCTED
613 retained->pos, retained->Distance( aOrigin ) / snapScale ) );
614 frame.presentation.emplace( retainedId, PRESENTATION{ PRESENTATION_KIND::ANCHOR_MARKER, *retained, false } );
615 }
616
617 if( m_enableSnap && nearest && nearest->Distance( aOrigin ) <= snapIn && m_skipPoint != nearest->pos )
618 {
619 SNAP_STABLE_ID nearestId = anchorId( *nearest );
621 nearest->flags & CONSTRUCTED
624 nearest->pos, nearest->Distance( aOrigin ) / snapScale ) );
625 frame.presentation.insert_or_assign( nearestId,
626 PRESENTATION{ PRESENTATION_KIND::ANCHOR_MARKER, *nearest, true } );
627 }
628
629 if( guideSnap && m_skipPoint != *guideSnap )
630 {
632 SNAP_CANDIDATE candidate =
634 *guideSnap, guideSnap->Distance( aOrigin ) / snapScale );
635 frame.candidates.push_back( std::move( candidate ) );
636 frame.presentation.emplace( guideId, PRESENTATION{ PRESENTATION_KIND::GUIDE, std::nullopt, false } );
637 }
638
639 emitSelfAndGridCandidates( frame.candidates, context, aOrigin, nearestGrid, snapScale, snapRange, canUseGrid() );
640
641 // Object retention wins because its tier already outranks angle restriction.
642 if( !frame.retainedId && m_retainedAngleBranch )
644
645 SNAP_FRAME_OUTPUT<PRESENTATION> output = ResolveSnapFrame( std::move( frame ) );
646 SNAP_RESULT& result = output.result;
648
649 bool keepConstructionProposal = false;
650
651 if( output.presentation && output.presentation->payload.kind == PRESENTATION_KIND::GUIDE )
652 {
653 snapLineManager.SetSnapLineEnd( result.position );
654 m_toolMgr->GetView()->SetVisible( &m_viewSnapPoint, false );
655 m_snapItem = std::nullopt;
656 }
657 else if( output.presentation && output.presentation->payload.anchor )
658 {
659 const PRESENTATION& presentation = output.presentation->payload;
660 std::vector<SCH_ITEM*> items;
661
662 for( EDA_ITEM* item : presentation.anchor->items )
663 {
664 if( item && item->IsSCH_ITEM() )
665 items.push_back( static_cast<SCH_ITEM*>( item ) );
666 }
667
668 if( presentation.proposeConstruction && constructionEnabled && !items.empty() )
669 {
670 AddConstructionItems( std::move( items ), true, false );
671 keepConstructionProposal = true;
672 }
673
674 m_snapItem = *presentation.anchor;
675 m_viewSnapPoint.SetPosition( result.position );
676 m_viewSnapPoint.SetSnapTypes( m_snapItem->pointTypes );
677 snapLineManager.SetSnapLineOrigin( result.position );
678 snapLineManager.SetSnapLineEnd( std::nullopt );
679
680 if( m_toolMgr->GetView()->IsVisible( &m_viewSnapPoint ) )
681 m_toolMgr->GetView()->Update( &m_viewSnapPoint, KIGFX::GEOMETRY );
682 else
683 m_toolMgr->GetView()->SetVisible( &m_viewSnapPoint, true );
684 }
685 else
686 {
687 m_snapItem = std::nullopt;
688 snapLineManager.SetSnapLineEnd( std::nullopt );
689 m_toolMgr->GetView()->SetVisible( &m_viewSnapPoint, false );
690 }
691
693
694 if( constructionEnabled && !keepConstructionProposal && ADVANCED_CFG::GetCfg().m_ExtensionSnapActivateOnHover )
695 {
696 for( SCH_ITEM* item : visibleItems )
697 {
698 if( item->HitTest( aOrigin, 0 ) )
699 {
700 AddConstructionItems( { item }, true, false );
701 keepConstructionProposal = true;
702 break;
703 }
704 }
705 }
706
707 if( !keepConstructionProposal )
709
710 return result;
711}
712
713
715{
716 if( !m_toolMgr )
717 return GRID_HELPER::GetGridSize( aGrid );
718
719 const GRID_SETTINGS& grid = m_toolMgr->GetSettings()->m_Window.grid;
720 int idx = -1;
721
722 VECTOR2D g = m_toolMgr->GetView()->GetGAL()->GetGridSize();
723
724 if( !grid.overrides_enabled )
725 return g;
726
727 switch( aGrid )
728 {
729 case GRID_CONNECTABLE:
730 if( grid.override_connected )
731 idx = grid.override_connected_idx;
732
733 break;
734
735 case GRID_WIRES:
736 if( grid.override_wires )
737 idx = grid.override_wires_idx;
738
739 break;
740
741 case GRID_TEXT:
742 if( grid.override_text )
743 idx = grid.override_text_idx;
744
745 break;
746
747 case GRID_GRAPHICS:
748 if( grid.override_graphics )
749 idx = grid.override_graphics_idx;
750
751 break;
752
753 default:
754 break;
755 }
756
757 if( idx >= 0 && idx < (int) grid.grids.size() )
758 g = grid.grids[idx].ToDouble( schIUScale );
759
760 return g;
761}
762
763
765{
766 if( !m_snapItem )
767 return nullptr;
768
769 if( m_snapItem->items.empty() )
770 return nullptr;
771
772 return static_cast<SCH_ITEM*>( m_snapItem->items[0] );
773}
774
775
776std::set<SCH_ITEM*> EE_GRID_HELPER::queryVisible( const BOX2I& aArea,
777 const SCH_SELECTION& aSkipList ) const
778{
779 std::set<SCH_ITEM*> items;
780 std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
781
782 EDA_DRAW_FRAME* frame = dynamic_cast<EDA_DRAW_FRAME*>( m_toolMgr->GetToolHolder() );
783 KIGFX::VIEW* view = m_toolMgr->GetView();
784
785 view->SyncLayerVisibilityCache(); // Required for ViewGetLOD() calls.
786 view->Query( aArea, selectedItems );
787
788 for( const KIGFX::VIEW::LAYER_ITEM_PAIR& it : selectedItems )
789 {
790 if( !it.first->IsSCH_ITEM() )
791 continue;
792
793 SCH_ITEM* item = static_cast<SCH_ITEM*>( it.first );
794
795 if( frame && frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
796 {
797 // If we are in the symbol editor, don't use the symbol itself
798 if( item->Type() == LIB_SYMBOL_T )
799 continue;
800 }
801 else
802 {
803 // If we are not in the symbol editor, don't use symbol-editor-private items
804 if( item->IsPrivate() )
805 continue;
806 }
807
808 // The item must be visible and on an active layer
809 if( view->IsVisible( item ) && item->ViewGetLOD( it.second, view ) < view->GetScale() )
810 items.insert( item );
811 }
812
813 for( EDA_ITEM* skipItem : aSkipList )
814 items.erase( static_cast<SCH_ITEM*>( skipItem ) );
815
816 return items;
817}
818
819
821{
822 if( !aItem )
823 return GRID_CURRENT;
824
825 switch( aItem->Type() )
826 {
827 case LIB_SYMBOL_T:
828 case SCH_SYMBOL_T:
829 case SCH_PIN_T:
830 case SCH_SHEET_PIN_T:
831 case SCH_SHEET_T:
832 case SCH_NO_CONNECT_T:
834 case SCH_HIER_LABEL_T:
835 case SCH_LABEL_T:
837 case SCH_RULE_AREA_T:
838 return GRID_CONNECTABLE;
839
840 case SCH_FIELD_T:
841 case SCH_TEXT_T:
842 return GRID_TEXT;
843
844 case SCH_SHAPE_T:
845 // The text box's border lines are what need to be on the graphic grid
846 case SCH_TEXTBOX_T:
847 case SCH_BITMAP_T:
848 return GRID_GRAPHICS;
849
850 case SCH_JUNCTION_T:
851 return GRID_WIRES;
852
853 case SCH_LINE_T:
854 if( static_cast<const SCH_LINE*>( aItem )->IsConnectable() )
855 return GRID_WIRES;
856 else
857 return GRID_GRAPHICS;
858
861 return GRID_WIRES;
862
863 // Groups need to get the grid of their children
864 case SCH_GROUP_T:
865 {
866 const SCH_GROUP* group = static_cast<const SCH_GROUP*>( aItem );
867
868 // Shouldn't happen
869 if( group->GetItems().empty() )
870 return GRID_CURRENT;
871
872 GRID_HELPER_GRIDS grid = GetItemGrid( *group->GetItems().begin() );
873
874 for( EDA_ITEM* item : static_cast<const SCH_GROUP*>( aItem )->GetItems() )
875 {
876 GRID_HELPER_GRIDS itemGrid = GetItemGrid( item );
877
878 if( GetGridSize( itemGrid ) > GetGridSize( grid ) )
879 grid = itemGrid;
880 }
881
882 return grid;
883 }
884
885 default: return GRID_CURRENT;
886 }
887}
888
889
890void EE_GRID_HELPER::computeAnchors( SCH_ITEM* aItem, const VECTOR2I& aRefPos, bool aFrom, bool aIncludeText )
891{
892 bool isGraphicLine = aItem->Type() == SCH_LINE_T && static_cast<SCH_LINE*>( aItem )->IsGraphicLine();
893
894 switch( aItem->Type() )
895 {
896 case SCH_TEXT_T:
897 case SCH_FIELD_T:
898 {
899 if( aIncludeText )
900 addAnchor( aItem->GetPosition(), ORIGIN, aItem );
901
902 break;
903 }
904
905 case SCH_TABLE_T:
906 {
907 if( aIncludeText )
908 {
909 addAnchor( aItem->GetPosition(), SNAPPABLE | CORNER, aItem );
910 addAnchor( static_cast<SCH_TABLE*>( aItem )->GetEnd(), SNAPPABLE | CORNER, aItem );
911 }
912
913 break;
914 }
915
916 case SCH_TEXTBOX_T:
917 case SCH_TABLECELL_T:
918 {
919 if( aIncludeText )
920 {
921 addAnchor( aItem->GetPosition(), SNAPPABLE | CORNER, aItem );
922 addAnchor( static_cast<SCH_SHAPE*>( aItem )->GetEnd(), SNAPPABLE | CORNER, aItem );
923 }
924
925 break;
926 }
927
928 case SCH_SYMBOL_T:
929 case SCH_SHEET_T:
930 addAnchor( aItem->GetPosition(), ORIGIN, aItem );
932
933 case SCH_JUNCTION_T:
934 case SCH_NO_CONNECT_T:
935 case SCH_LINE_T:
936 // Don't add anchors for graphic lines unless we're including text,
937 // they may be on a non-connectable grid
938 if( isGraphicLine && !aIncludeText )
939 break;
940
943 case SCH_HIER_LABEL_T:
944 case SCH_LABEL_T:
947 case SCH_SHEET_PIN_T:
948 {
949 std::vector<VECTOR2I> pts = aItem->GetConnectionPoints();
950
951 for( const VECTOR2I& pt : pts )
952 addAnchor( VECTOR2I( pt ), SNAPPABLE | CORNER, aItem );
953
954 break;
955 }
956 case SCH_PIN_T:
957 {
958 SCH_PIN* pin = static_cast<SCH_PIN*>( aItem );
959 addAnchor( pin->GetPosition(), SNAPPABLE | ORIGIN, aItem );
960 break;
961 }
962
963 case SCH_GROUP_T:
964 for( EDA_ITEM* item : static_cast<SCH_GROUP*>( aItem )->GetItems() )
965 {
966 computeAnchors( static_cast<SCH_ITEM*>( item ), aRefPos, aFrom, aIncludeText );
967 }
968
969 break;
970
971 default:
972 break;
973 }
974
975 // Don't add anchors for graphic lines unless we're including text,
976 // they may be on a non-connectable grid
977 if( aItem->Type() == SCH_LINE_T && ( aIncludeText || !isGraphicLine ) )
978 {
979 SCH_LINE* line = static_cast<SCH_LINE*>( aItem );
980 VECTOR2I pt = Align( aRefPos );
981
982 if( line->GetStartPoint().x == line->GetEndPoint().x )
983 {
984 VECTOR2I possible( line->GetStartPoint().x, pt.y );
985
986 if( TestSegmentHit( possible, line->GetStartPoint(), line->GetEndPoint(), 0 ) )
987 addAnchor( possible, SNAPPABLE | VERTICAL, aItem );
988 }
989 else if( line->GetStartPoint().y == line->GetEndPoint().y )
990 {
991 VECTOR2I possible( pt.x, line->GetStartPoint().y );
992
993 if( TestSegmentHit( possible, line->GetStartPoint(), line->GetEndPoint(), 0 ) )
994 addAnchor( possible, SNAPPABLE | HORIZONTAL, aItem );
995 }
996 }
997}
998
999
1001 GRID_HELPER_GRIDS aGrid )
1002{
1003 double minDist = std::numeric_limits<double>::max();
1004 ANCHOR* best = nullptr;
1005
1006 for( ANCHOR& a : m_anchors )
1007 {
1008 if( ( aFlags & a.flags ) != aFlags )
1009 continue;
1010
1011 // A "virtual" anchor with no real items associated shouldn't be filtered out
1012 if( !a.items.empty() )
1013 {
1014 // Filter using the first item
1015 SCH_ITEM* item = static_cast<SCH_ITEM*>( a.items[0] );
1016
1017 if( aGrid == GRID_CONNECTABLE && !item->IsConnectable() )
1018 continue;
1019 else if( aGrid == GRID_GRAPHICS && item->IsConnectable() )
1020 continue;
1021 }
1022
1023 double dist = a.Distance( aPos );
1024
1025 if( dist < minDist )
1026 {
1027 minDist = dist;
1028 best = &a;
1029 }
1030 }
1031
1032 return best;
1033}
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:130
BOX2< VECTOR2I > BOX2I
Definition box2.h:914
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
static constexpr BOX2< VECTOR2I > ByCorners(const VECTOR2I &aCorner1, const VECTOR2I &aCorner2)
Definition box2.h:67
void ProposeConstructionItems(std::unique_ptr< CONSTRUCTION_ITEM_BATCH > aBatch, bool aIsPersistent)
Add a batch of construction items to the helper.
void CancelProposal()
Cancel outstanding proposals for new geometry.
void Clear()
Clear all construction items.
std::vector< CONSTRUCTION_ITEM > CONSTRUCTION_ITEM_BATCH
bool IsType(FRAME_T aType) 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.
Definition eda_item.h:98
virtual VECTOR2I GetPosition() const
Definition eda_item.h:348
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition eda_item.cpp:270
const KIID m_Uuid
Definition eda_item.h:599
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
int GetRadius() const
SHAPE_T GetShape() const
Definition eda_shape.h:175
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition eda_shape.h:325
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition eda_shape.h:275
VECTOR2I GetArcMid() const
static std::vector< std::pair< const SCH_PIN *, VECTOR2I > > layoutPins(SCH_ITEM &aItem)
Pin connection points the item offers as alignment anchors.
~EE_GRID_HELPER() override
GRID_HELPER_GRIDS GetItemGrid(const EDA_ITEM *aItem) const override
Get the coarsest grid that applies to an item.
VECTOR2I BestDragOrigin(const VECTOR2I &aMousePos, GRID_HELPER_GRIDS aGrid, const SCH_SELECTION &aItems)
std::set< SCH_ITEM * > queryVisible(const BOX2I &aArea, const SCH_SELECTION &aSkipList) const
void AddConstructionItems(std::vector< SCH_ITEM * > aItems, bool aExtensionOnly, bool aIsPersistent)
ANCHOR * nearestAnchor(const VECTOR2I &aPos, int aFlags, GRID_HELPER_GRIDS aGrid)
VECTOR2D GetGridSize(GRID_HELPER_GRIDS aGrid) const override
Return the size of the specified grid.
SCH_ITEM * GetSnapped() const
Function GetSnapped If the EE_GRID_HELPER has highlighted a snap point (target shown),...
SNAP_RESULT ResolveSnap(const VECTOR2I &aOrigin, GRID_HELPER_GRIDS aGrid, SCH_ITEM *aSkip)
SNAP_INFERENCE_SETTINGS snapInferenceSettings() const
Snap inference settings for whichever editor owns this helper.
void computeAnchors(SCH_ITEM *aItem, const VECTOR2I &aRefPos, bool aFrom=false, bool aIncludeText=false)
Insert the local anchor points in to the grid helper for the specified schematic item,...
static BOX2I layoutBounds(const SCH_ITEM &aItem)
Bounds a layout relation should align to.
void retainAcceptedSnaps(const SNAP_RESULT &aResult)
Record which snaps the resolver accepted so they can be re-biased on the next resolve,...
std::optional< VECTOR2I > SnapToConstructionLines(const VECTOR2I &aPoint, const VECTOR2I &aNearestGrid, const VECTOR2D &aGrid, double aSnapRange) const
void addAnchor(const VECTOR2I &aPos, int aFlags, EDA_ITEM *aItem, int aPointTypes=POINT_TYPE::PT_NONE)
SNAP_MANAGER & getSnapManager()
VECTOR2I m_skipPoint
SNAP_RANGES computeSnapRanges(bool aClampToVisibleGrid) const
Compute the snap thresholds.
void emitAngleBranchCandidates(std::vector< SNAP_CANDIDATE > &aCandidates, const VECTOR2I &aOrigin, double aSnapScale) const
Emit the angle-restriction snap candidates (the two branches bracketing the cursor angle) into the cu...
void showConstructionGeometry(bool aShow)
SNAP_RESOLVER::FEASIBILITY_CALLBACK m_feasibilityCallback
std::vector< SEG > m_stationarySelfSegments
TOOL_MANAGER * m_toolMgr
virtual VECTOR2D GetGridSize(GRID_HELPER_GRIDS aGrid) const
Return the size of the specified grid.
SNAP_RESOLVER::TRACE_CALLBACK snapTraceCallback(const SNAP_SOURCE_CONTEXT &aContext) const
bool m_enableSnapLine
bool m_enableSnap
bool canUseGrid() const
Check whether it is possible to use the grid – this depends both on local grid helper settings and gl...
std::optional< SNAP_STABLE_ID > m_retainedAngleBranch
void clearAnchors()
std::optional< ANCHOR > m_snapItem
SNAP_REFERENCE_PREFERENCE m_layoutReferencePreference
KIGFX::ANCHOR_DEBUG * enableAndGetAnchorDebug()
Enable the anchor debug if permitted and return it.
KIGFX::SNAP_INDICATOR m_viewSnapPoint
virtual VECTOR2I Align(const VECTOR2I &aPoint, GRID_HELPER_GRIDS aGrid) const
KIGFX::ORIGIN_VIEWITEM m_viewAxis
bool m_pointEditProfile
std::vector< SNAP_STABLE_ID > m_stickySnapIds
void setLayoutReference(const VECTOR2I &aPoint, const std::optional< BOX2I > &aBounds, bool aAnchorPoint)
Record the classified drag reference and trace it.
void emitSelfAndGridCandidates(std::vector< SNAP_CANDIDATE > &aCandidates, const SNAP_SOURCE_CONTEXT &aContext, const VECTOR2I &aOrigin, const VECTOR2I &aNearestGrid, double aSnapScale, int aSnapRange, bool aUseGrid) const
Emit the point editor's unchanged self-geometry and the independent grid axes.
void applySnapResultGuides(const SNAP_RESULT &aResult)
std::vector< ANCHOR > m_anchors
View item to draw debug items for anchors.
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
std::variant< SEG, LINE, HALF_LINE, CIRCLE, SHAPE_ARC, VECTOR2I > DRAWABLE
bool IsSCH_ITEM() const
Definition view_item.h:97
virtual double ViewGetLOD(int aLayer, const VIEW *aView) const
Return the level of detail (LOD) of the item.
Definition view_item.h:151
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:63
double GetScale() const
Definition view.h:283
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Add a VIEW_ITEM to the view.
Definition view.cpp:297
virtual void Remove(VIEW_ITEM *aItem)
Remove a VIEW_ITEM from the view.
Definition view.cpp:412
int Query(const BOX2I &aRect, std::vector< LAYER_ITEM_PAIR > &aResult) const
Find all visible items that touch or are within the rectangle aRect.
Definition view.cpp:501
void SyncLayerVisibilityCache()
Definition view.cpp:1957
std::pair< VIEW_ITEM *, int > LAYER_ITEM_PAIR
Definition view.h:67
bool IsVisible(const VIEW_ITEM *aItem) const
Return information if the item is visible (or not).
Definition view.cpp:1862
void SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Set the item visibility.
Definition view.cpp:1813
A shim class between EDA_DRAW_FRAME and several derived classes: SYMBOL_EDIT_FRAME,...
A set of SCH_ITEMs (i.e., without duplicates).
Definition sch_group.h:48
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:170
virtual bool IsConnectable() const
Definition sch_item.h:545
bool IsPrivate() const
Definition sch_item.h:259
virtual std::vector< VECTOR2I > GetConnectionPoints() const
Add all the connection points for this item to aPoints.
Definition sch_item.h:558
Segment description base class to describe items which have 2 end points (track, wire,...
Definition sch_line.h:39
VECTOR2I GetEndPoint() const
Definition sch_line.h:145
VECTOR2I GetStartPoint() const
Definition sch_line.h:136
VECTOR2I GetCenter() const
Definition sch_shape.h:94
Schematic symbol object.
Definition sch_symbol.h:73
Definition seg.h:38
virtual void Add(EDA_ITEM *aItem)
A null aItem is ignored; the selection never holds null members.
Definition selection.cpp:38
ITER begin()
Definition selection.h:75
virtual unsigned int GetSize() const override
Return the number of stored items.
Definition selection.h:104
bool Empty() const
Checks if there is anything selected.
Definition selection.h:114
std::vector< SNAP_CANDIDATE > CollectObjectGeometry(const SNAP_SOURCE_CONTEXT &aContext, int aRadius) const
std::vector< SNAP_CANDIDATE > CollectEqualSpacing(const SNAP_SOURCE_CONTEXT &aContext, int aRadius) const
void AddBounds(SNAP_OBJECT_BOUNDS aBounds)
std::vector< SNAP_CANDIDATE > CollectTangentNormal(const SNAP_SOURCE_CONTEXT &aContext, int aRadius, bool aTangentEnabled, bool aNormalEnabled) const
void AddPath(SNAP_OBJECT_PATH aPath)
void AddAlignmentPoint(SNAP_ALIGNMENT_POINT aPoint)
std::vector< SNAP_CANDIDATE > CollectAlignment(const SNAP_SOURCE_CONTEXT &aContext, int aRadius) const
void SetSnapLineOrigin(const VECTOR2I &aOrigin)
The snap point is a special point that is located at the last point the cursor snapped to.
void SetSnapLineEnd(const OPT_VECTOR2I &aSnapPoint)
Set the end point of the snap line.
SNAP_LINE_MANAGER & GetSnapLineManager()
CONSTRUCTION_MANAGER & GetConstructionManager()
Master controller class:
constexpr extended_type SquaredDistance(const VECTOR2< T > &aVector) const
Compute the squared distance between two vectors.
Definition vector2d.h:582
@ SEGMENT
Definition eda_shape.h:56
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
Definition eda_shape.h:57
@ FRAME_SCH_SYMBOL_EDITOR
Definition frame_type.h:31
static KIGFX::CONSTRUCTION_GEOM::DRAWABLE drawable(const GRAPHIC_EDIT_GEOMETRY &aGeometry)
SNAP_TARGET_ID SnapTargetId(const KIID &aId)
The snap identity of a document item.
Definition grid_helper.h:49
GRID_HELPER_GRIDS
Definition grid_helper.h:55
@ GRID_TEXT
Definition grid_helper.h:62
@ GRID_CURRENT
Definition grid_helper.h:57
@ GRID_GRAPHICS
Definition grid_helper.h:63
@ GRID_CONNECTABLE
Definition grid_helper.h:59
@ GRID_WIRES
Definition grid_helper.h:60
bool m_EnableExtensionSnaps
Enable snap anchors based on item line extensions.
@ LAYER_SCHEMATIC_ANCHOR
Definition layer_ids.h:522
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 ...
Definition macros.h:79
@ GEOMETRY
Position or shape has changed.
Definition view_item.h:51
Class to handle a set of SCH_ITEMs.
std::optional< VECTOR2I > OPT_VECTOR2I
Definition seg.h:35
SNAP_FRAME_OUTPUT< Payload > ResolveSnapFrame(SNAP_FRAME_INPUT< Payload > aInput)
Definition snap_frame.h:60
SNAP_STABLE_ID MakePointSnapId(SNAP_ID_KIND aKind, const VECTOR2I &aPoint, int aFeatureIndex=0)
SNAP_STABLE_ID MakeCompositeSnapId(SNAP_ID_KIND aKind, const std::vector< SNAP_TARGET_ID > &aTargets, int aFeatureIndex=0)
SNAP_STABLE_ID MakeDerivedSnapId(SNAP_ID_KIND aKind, const SNAP_STABLE_ID &aSource, int aFeatureIndex=0, int aSolutionBranch=0)
SNAP_ID_KIND
std::array< uint8_t, 16 > SNAP_TARGET_ID
KIGFX::CONSTRUCTION_GEOM::DRAWABLE Drawable
Items to be used for the construction of "virtual" anchors, for example, when snapping to a point inv...
double Distance(const VECTOR2I &aP) const
World-space snap thresholds derived from the screen-space snap radius.
int range
Snap radius, optionally clamped to the visible grid.
int in
Distance at which a candidate is picked up.
double scale
SNAP_SCREEN_RADIUS in world units.
int out
Distance at which a held candidate is released.
double rankingHysteresis
Resolver ranking stickiness, as a fraction of the radius.
static SNAP_CANDIDATE Point(SNAP_STABLE_ID aId, SNAP_PRIORITY_TIER aPriority, SNAP_CANDIDATE_SUBTYPE aSubtype, const VECTOR2I &aPoint, double aResidual)
std::optional< SNAP_STABLE_ID > retainedId
Definition snap_frame.h:34
SNAP_RESOLVER::TRACE_CALLBACK trace
Definition snap_frame.h:39
SNAP_RESOLVER::FEASIBILITY_CALLBACK feasibility
Definition snap_frame.h:38
std::map< SNAP_STABLE_ID, Payload > presentation
Definition snap_frame.h:35
SNAP_SOURCE_CONTEXT context
Definition snap_frame.h:32
std::vector< SNAP_CANDIDATE > candidates
Definition snap_frame.h:33
double rankingHysteresis
Definition snap_frame.h:37
std::vector< SNAP_STABLE_ID > stickyIds
Definition snap_frame.h:36
std::optional< SNAP_FRAME_PRESENTATION< Payload > > presentation
Definition snap_frame.h:55
SNAP_RESULT result
Definition snap_frame.h:54
std::optional< VECTOR2I > stationarySourceLeg
std::optional< BOX2I > movingBounds
std::optional< VECTOR2I > movingReferencePoint
std::optional< SNAP_STABLE_ID > movingItem
std::vector< SNAP_STABLE_ID > stationarySelfFeatures
SNAP_EDITOR_PROFILE profile
SNAP_REFERENCE_PREFERENCE referencePreference
#define ALL_UNITS
Definition symbol.h:150
#define ALL_BODY_STYLES
Definition symbol.h:151
KIBIS_PIN * pin
wxString result
Test unit parsing edge cases and error handling.
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:173
@ SCH_GROUP_T
Definition typeinfo.h:169
@ SCH_TABLE_T
Definition typeinfo.h:161
@ SCH_LINE_T
Definition typeinfo.h:159
@ LIB_SYMBOL_T
Definition typeinfo.h:144
@ SCH_NO_CONNECT_T
Definition typeinfo.h:156
@ SCH_SYMBOL_T
Definition typeinfo.h:168
@ SCH_TABLECELL_T
Definition typeinfo.h:162
@ SCH_FIELD_T
Definition typeinfo.h:146
@ SCH_DIRECTIVE_LABEL_T
Definition typeinfo.h:167
@ SCH_LABEL_T
Definition typeinfo.h:163
@ SCH_SHEET_T
Definition typeinfo.h:171
@ SCH_SHAPE_T
Definition typeinfo.h:145
@ SCH_RULE_AREA_T
Definition typeinfo.h:166
@ SCH_HIER_LABEL_T
Definition typeinfo.h:165
@ SCH_BUS_BUS_ENTRY_T
Definition typeinfo.h:158
@ SCH_SHEET_PIN_T
Definition typeinfo.h:170
@ SCH_TEXT_T
Definition typeinfo.h:147
@ SCH_BUS_WIRE_ENTRY_T
Definition typeinfo.h:157
@ SCH_BITMAP_T
Definition typeinfo.h:160
@ SCH_TEXTBOX_T
Definition typeinfo.h:148
@ SCH_GLOBAL_LABEL_T
Definition typeinfo.h:164
@ SCH_JUNCTION_T
Definition typeinfo.h:155
@ SCH_PIN_T
Definition typeinfo.h:149
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708
VECTOR2< double > VECTOR2D
Definition vector2d.h:707