KiCad PCB EDA Suite
Loading...
Searching...
No Matches
drc_creepage_utils.h
Go to the documentation of this file.
1/*
2 * Copyright The KiCad Developers.
3 * Copyright (C) 2024 Fabien Corona f.corona<at>laposte.net
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, you may find one here:
17 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18 * or you may search the http://www.gnu.org website for the version 2 license,
19 * or you may write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23
24#pragma once
25
26#include <unordered_set>
27
28#include <common.h>
29#include <macros.h>
31#include <footprint.h>
32#include <pad.h>
33#include <pcb_track.h>
34#include <pcb_shape.h>
35#include <zone.h>
36#include <advanced_config.h>
37#include <geometry/shape_rect.h>
38#include <geometry/seg.h>
40#include <drc/drc_item.h>
41#include <drc/drc_rule.h>
42#include <board.h>
43
44
46
47
48extern bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
49 const std::vector<BOARD_ITEM*>& aBe,
50 const std::vector<const BOARD_ITEM*>& aDontTestAgainst,
51 int aMinGrooveWidth );
52
54{
57 double weight = -1;
58 bool m_show = true;
59
62
63
68 bool isValid( const BOARD& aBoard, PCB_LAYER_ID aLayer,
69 const std::vector<BOARD_ITEM*>& aBoardEdges,
70 const std::vector<const BOARD_ITEM*>& aIgnoreForTest, SHAPE_POLY_SET* aOutline,
71 const std::pair<bool, bool>& aTestLocalConcavity, int aMinGrooveWidth ) const
72 {
73 if( !aOutline )
74 return true; // We keep the segment if there is a problem
75
76 if( !SegmentIntersectsBoard( a1, a2, aBoardEdges, aIgnoreForTest, aMinGrooveWidth ) )
77 return false;
78
79 // The mid point should be inside the board.
80 // Tolerance of 100nm.
81
82 VECTOR2I midPoint = ( a1 + a2 ) / 2;
83 int tolerance = 100;
84
85 if( !( aOutline->Contains( midPoint, -1, tolerance )
86 || aOutline->PointOnEdge( midPoint, tolerance ) ) )
87 return false;
88
89 if( false && ( aTestLocalConcavity.first || aTestLocalConcavity.second ) )
90 {
91 // Test for local concavity. If it is localy convex, then it will not be a path of interest.
92
93 double extendLine = 1000; // extend line by 1000nm
94 // In some cases, the projected point could be on the board edge
95 // In such cases, we wan to keep the line.
96 // We inflate the polygon to get a small margin for computation/rounding error.
97 // We might keep some unnecessary lines, but it's better than loosing the important ones.
98 double extendPoly = 100; // extend polygon by 10 nm
99
100 VECTOR2D a( double( a1.x ), double( a1.y ) );
101 VECTOR2D b( double( a2.x ), double( a2.y ) );
102
103 VECTOR2D dir( b - a );
104 dir = dir * ( extendLine / dir.SquaredEuclideanNorm() );
105
106 SHAPE_POLY_SET outline2 = *aOutline;
107 outline2.Inflate( extendPoly, CORNER_STRATEGY::ROUND_ALL_CORNERS, 3 );
108
109 if( aTestLocalConcavity.first && !aOutline->Contains( a - dir, -1, 0 ) )
110 return false;
111
112 if( aTestLocalConcavity.second && !aOutline->Contains( b + dir, -1, 0 ) )
113 return false;
114 }
115
116 SEG segPath( a1, a2 );
117
118 if( aLayer != Edge_Cuts )
119 {
120 for( PCB_TRACK* track : aBoard.Tracks() )
121 {
122 if( !track )
123 continue;
124
125 if( track->Type() == KICAD_T::PCB_TRACE_T && track->IsOnLayer( aLayer ) )
126 {
127 std::shared_ptr<SHAPE> sh = track->GetEffectiveShape();
128
129 if( sh && sh->Type() == SHAPE_TYPE::SH_SEGMENT )
130 {
131 SEG segTrack( track->GetStart(), track->GetEnd() );
132
133 if( segPath.Intersects( segTrack ) )
134 return false;
135 }
136 }
137 }
138 }
139 return true;
140 }
141};
142
143
144class GRAPH_CONNECTION;
145class GRAPH_NODE;
146class CREEPAGE_GRAPH;
147class CREEP_SHAPE;
148class BE_SHAPE;
149class BE_SHAPE_POINT;
150class BE_SHAPE_ARC;
151class BE_SHAPE_CIRCLE;
152class CU_SHAPE;
153class CU_SHAPE_SEGMENT;
154class CU_SHAPE_CIRCLE;
155class CU_SHAPE_ARC;
156
162{
163public:
164 enum class TYPE
165 {
170 };
171
173 {
174 m_conductive = false;
175 m_parent = nullptr;
176 m_pos = VECTOR2I( 0, 0 );
177 m_type = CREEP_SHAPE::TYPE::UNDEFINED;
178 };
179
180 virtual ~CREEP_SHAPE() {}
181
182 virtual int GetRadius() const { return 0; };
183 virtual EDA_ANGLE GetStartAngle() const { return EDA_ANGLE( 0 ); };
184 virtual EDA_ANGLE GetEndAngle() const { return EDA_ANGLE( 0 ); };
185 virtual VECTOR2I GetStartPoint() const { return VECTOR2I( 0, 0 ); };
186 virtual VECTOR2I GetEndPoint() const { return VECTOR2I( 0, 0 ); };
187 VECTOR2I GetPos() const { return m_pos; };
188 CREEP_SHAPE::TYPE GetType() const { return m_type; };
189 const BOARD_ITEM* GetParent() const { return m_parent; };
190 void SetParent( BOARD_ITEM* aParent ) { m_parent = aParent; };
191
192 virtual void ConnectChildren( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
193 CREEPAGE_GRAPH& aG ) const;
194
195 std::vector<PATH_CONNECTION> ReversePaths( const std::vector<PATH_CONNECTION>& aV ) const
196 {
197 std::vector<PATH_CONNECTION> r;
198 r.reserve( aV.size() );
199
200 for( const auto& pc : aV )
201 {
202 r.emplace_back( pc );
203 std::swap( r.back().a1, r.back().a2 );
204 }
205
206 return r;
207 }
208
209 std::vector<PATH_CONNECTION> Paths( const CREEP_SHAPE& aS2, double aMaxWeight,
210 double aMaxSquaredWeight ) const
211 {
212 std::vector<PATH_CONNECTION> a;
213 return a;
214 };
215
216 virtual std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
217 double aMaxSquaredWeight ) const
218 {
219 std::vector<PATH_CONNECTION> a;
220 return a;
221 };
222
223 virtual std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
224 double aMaxSquaredWeight ) const
225 {
226 std::vector<PATH_CONNECTION> a;
227 return a;
228 };
229
230 virtual std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
231 double aMaxSquaredWeight ) const
232 {
233 std::vector<PATH_CONNECTION> a;
234 return a;
235 };
236
237 virtual std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
238 double aMaxSquaredWeight ) const
239 {
240 std::vector<PATH_CONNECTION> a;
241 return a;
242 };
243
244 virtual std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
245 double aMaxSquaredWeight ) const
246 {
247 std::vector<PATH_CONNECTION> a;
248 return a;
249 };
250
251 virtual std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_ARC& aS2, double aMaxWeight,
252 double aMaxSquaredWeight ) const
253 {
254 std::vector<PATH_CONNECTION> a;
255 return a;
256 };
257
258 //virtual std::vector<PATH_CONNECTION> GetPathsCuToBe( CREEP_SHAPE* aShape ) const{ std::vector<PATH_CONNECTION> a; return a;};
259 bool IsConductive() { return m_conductive; };
260
261protected:
266};
267
268
273class CU_SHAPE : public CREEP_SHAPE
274{
275public:
278 {
279 m_conductive = true;
280 };
281};
282
287class BE_SHAPE : public CREEP_SHAPE
288{
289public:
292 {
293 m_conductive = false;
294 };
295};
296
302{
303public:
304 CU_SHAPE_SEGMENT( VECTOR2I aStart, VECTOR2I aEnd, double aWidth = 0 ) :
305 CU_SHAPE()
306 {
307 m_start = aStart;
308 m_end = aEnd;
309 m_width = aWidth;
310 }
311
312 VECTOR2I GetStart() const { return m_start; };
313 VECTOR2I GetEnd() const { return m_end; };
314 double GetWidth() const { return m_width; };
315
316 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
317 double aMaxSquaredWeight ) const override;
318 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
319 double aMaxSquaredWeight ) const override;
320 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
321 double aMaxSquaredWeight ) const override;
322 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
323 double aMaxSquaredWeight ) const override;
324 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
325 double aMaxSquaredWeight ) const override;
326 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_ARC& aS2, double aMaxWeight,
327 double aMaxSquaredWeight ) const override;
328
329
330private:
333 double m_width = 0;
334};
335
341{
342public:
343 CU_SHAPE_CIRCLE( VECTOR2I aPos, double aRadius = 0 ) :
344 CU_SHAPE()
345 {
346 m_pos = aPos;
347 m_radius = aRadius;
348 }
349
350 VECTOR2I GetPos() const { return m_pos; };
351 int GetRadius() const override { return m_radius; };
352
353 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
354 double aMaxSquaredWeight ) const override;
355 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
356 double aMaxSquaredWeight ) const override;
357 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
358 double aMaxSquaredWeight ) const override;
359 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
360 double aMaxSquaredWeight ) const override
361 {
362 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
363 };
364
365 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
366 double aMaxSquaredWeight ) const override;
367 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_ARC& aS2, double aMaxWeight,
368 double aMaxSquaredWeight ) const override;
369
370protected:
372 double m_radius = 1;
373};
374
380{
381public:
382 CU_SHAPE_ARC( VECTOR2I aPos, double aRadius, EDA_ANGLE aStartAngle, EDA_ANGLE aEndAngle,
383 VECTOR2D aStartPoint, VECTOR2D aEndPoint ) :
384 CU_SHAPE_CIRCLE( aPos, aRadius ),
385 m_startAngle( aStartAngle ),
386 m_endAngle( aEndAngle ),
387 m_startPoint( aStartPoint ),
388 m_endPoint( aEndPoint )
389 {
390 m_type = CREEP_SHAPE::TYPE::ARC;
391 m_width = 0;
392 }
393
394 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
395 double aMaxSquaredWeight ) const override;
396
397 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
398 double aMaxSquaredWeight ) const override;
399
400 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
401 double aMaxSquaredWeight ) const override;
402
403 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
404 double aMaxSquaredWeight ) const override
405 {
406 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
407 };
408
409 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
410 double aMaxSquaredWeight ) const override
411 {
412 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
413 };
414
415 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_ARC& aS2, double aMaxWeight,
416 double aMaxSquaredWeight ) const override;
417
418 EDA_ANGLE GetStartAngle() const override { return m_startAngle; }
419 EDA_ANGLE GetEndAngle() const override { return m_endAngle; }
420 int GetRadius() const override { return m_radius; }
421
422 VECTOR2I GetStartPoint() const override { return m_startPoint; }
423 VECTOR2I GetEndPoint() const override { return m_endPoint; }
424
426 {
427 EDA_ANGLE angle( aPoint - m_pos );
428
429 while( angle < GetStartAngle() )
430 angle += ANGLE_360;
431
432 while( angle > GetEndAngle() + ANGLE_360 )
433 angle -= ANGLE_360;
434
435 return angle;
436 }
437
438 double GetWidth() const { return m_width; };
439 void SetWidth( double aW ) { m_width = aW; };
440
441private:
447};
448
454{
455public:
464
465 GRAPH_NODE( GRAPH_NODE::TYPE aType, CREEP_SHAPE* aParent, const VECTOR2I& aPos = VECTOR2I() ) :
466 m_parent( aParent ),
467 m_pos( aPos ),
468 m_type( aType )
469 {
470 m_node_conns = {};
471 m_virtual = false;
472 m_connectDirectly = true;
473 m_net = -1;
474 };
475
477
478public:
480 std::set<std::shared_ptr<GRAPH_CONNECTION>> m_node_conns;
482
483 // Virtual nodes are connected with a 0 weight connection to equivalent net ( same net or netclass )
486 int m_net;
487
489};
490
496{
497public:
498 GRAPH_CONNECTION( std::shared_ptr<GRAPH_NODE>& aN1, std::shared_ptr<GRAPH_NODE>& aN2,
499 const PATH_CONNECTION& aPc ) :
500 n1( aN1 ),
501 n2( aN2 )
502 {
503 m_path = aPc;
504 m_forceStraightLine = false;
505 };
506
507 void GetShapes( std::vector<PCB_SHAPE>& aShapes );
508
509public:
510 std::shared_ptr<GRAPH_NODE> n1;
511 std::shared_ptr<GRAPH_NODE> n2;
514};
515
516
522{
523public:
525 BE_SHAPE()
526 {
527 m_pos = aPos;
528 m_type = CREEP_SHAPE::TYPE::POINT;
529 }
530
531 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
532 double aMaxSquaredWeight ) const override;
533
534 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
535 double aMaxSquaredWeight ) const override;
536
537 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
538 double aMaxSquaredWeight ) const override;
539
540 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
541 double aMaxSquaredWeight ) const override
542 {
543 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
544 };
545
546 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
547 double aMaxSquaredWeight ) const override
548 {
549 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
550 }
551
552 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_ARC& aS2, double aMaxWeight,
553 double aMaxSquaredWeight ) const override
554 {
555 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
556 };
557
558
559 void ConnectChildren( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
560 CREEPAGE_GRAPH& aG ) const override;
561};
562
568{
569public:
570 BE_SHAPE_CIRCLE( VECTOR2I aPos = VECTOR2I( 0, 0 ), int aRadius = 0 ) :
571 BE_SHAPE()
572 {
573 m_pos = aPos;
574 m_radius = aRadius;
575 m_type = CREEP_SHAPE::TYPE::CIRCLE;
576 }
577
578 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
579 double aMaxSquaredWeight ) const override
580 {
581 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
582 };
583
584 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
585 double aMaxSquaredWeight ) const override;
586
587 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
588 double aMaxSquaredWeight ) const override;
589
590 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
591 double aMaxSquaredWeight ) const override
592 {
593 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
594 };
595
596 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
597 double aMaxSquaredWeight ) const override
598 {
599 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
600 };
601
602
603 int GetRadius() const override { return m_radius; }
604
605 void ConnectChildren( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
606 CREEPAGE_GRAPH& aG ) const override;
607
608 void ShortenChildDueToGV( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
609 CREEPAGE_GRAPH& aG, double aNormalWeight ) const;
610
611
612protected:
614};
615
621{
622public:
623 BE_SHAPE_ARC( VECTOR2I aPos, int aRadius, EDA_ANGLE aStartAngle, EDA_ANGLE aEndAngle,
624 VECTOR2D aStartPoint, VECTOR2D aEndPoint ) :
625 BE_SHAPE_CIRCLE( aPos, aRadius ),
626 m_startAngle( aStartAngle ), m_endAngle( aEndAngle ),
627 m_startPoint( aStartPoint ), m_endPoint( aEndPoint )
628 {
629 m_type = CREEP_SHAPE::TYPE::ARC;
630 }
631
632 void ConnectChildren( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
633 CREEPAGE_GRAPH& aG ) const override;
634
635
636 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
637 double aMaxSquaredWeight ) const override
638 {
639 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
640 };
641 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
642 double aMaxSquaredWeight ) const override
643 {
644 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
645 };
646 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
647 double aMaxSquaredWeight ) const override;
648
649 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
650 double aMaxSquaredWeight ) const override
651 {
652 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
653 };
654 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
655 double aMaxSquaredWeight ) const override
656 {
657 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
658 };
659 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_ARC& aS2, double aMaxWeight,
660 double aMaxSquaredWeight ) const override
661 {
662 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
663 };
664
665 EDA_ANGLE GetStartAngle() const override { return m_startAngle; }
666 EDA_ANGLE GetEndAngle() const override { return m_endAngle; }
667 int GetRadius() const override { return m_radius; }
668
669 VECTOR2I GetStartPoint() const override { return m_startPoint; }
670 VECTOR2I GetEndPoint() const override { return m_endPoint; }
672 {
673 EDA_ANGLE angle( aPoint - m_pos );
674
675 while( angle < m_startAngle )
676 angle += ANGLE_360;
677 while( angle > m_endAngle + ANGLE_360 )
678 angle -= ANGLE_360;
679
680 return angle;
681 }
682
683 std::pair<bool, bool> IsThereATangentPassingThroughPoint( const BE_SHAPE_POINT aPoint ) const;
684
685protected:
690};
691
692
698{
699public:
701 m_board( aBoard )
702 {
703 m_boardOutline = nullptr;
705 m_creepageTarget = -1;
707 };
708
710 {
711 for( CREEP_SHAPE* cs : m_shapeCollection )
712 {
713 if( cs )
714 {
715 delete cs;
716 cs = nullptr;
717 }
718 }
719
720 // Clear out the circular shared pointer references
721 for( std::shared_ptr<GRAPH_NODE>& n : m_nodes )
722 {
723 if( n )
724 {
725 n->m_node_conns.clear();
726 n = nullptr;
727 }
728 }
729
730 for( std::shared_ptr<GRAPH_CONNECTION>& c : m_connections )
731 {
732 if( c )
733 c = nullptr;
734 }
735 };
736
738 void TransformCreepShapesToNodes(std::vector<CREEP_SHAPE*>& aShapes);
740
741 // Add a node to the graph. If an equivalent node exists, returns the pointer of the existing node instead
742 std::shared_ptr<GRAPH_NODE> AddNode( GRAPH_NODE::TYPE aType, CREEP_SHAPE* aParent = nullptr,
743 const VECTOR2I& aPos = VECTOR2I() );
744
745 std::shared_ptr<GRAPH_NODE> AddNodeVirtual();
746
747 std::shared_ptr<GRAPH_CONNECTION> AddConnection( std::shared_ptr<GRAPH_NODE>& aN1,
748 std::shared_ptr<GRAPH_NODE>& aN2,
749 const PATH_CONNECTION& aPc );
750
751 std::shared_ptr<GRAPH_CONNECTION> AddConnection( std::shared_ptr<GRAPH_NODE>& aN1,
752 std::shared_ptr<GRAPH_NODE>& aN2 );
753
754 std::shared_ptr<GRAPH_NODE> FindNode( GRAPH_NODE::TYPE aType, CREEP_SHAPE* aParent,
755 const VECTOR2I& aPos );
756
757 void RemoveConnection( const std::shared_ptr<GRAPH_CONNECTION>&, bool aDelete = false );
758
759 void Trim( double aWeightLimit );
760
761 void Addshape( const SHAPE& aShape, std::shared_ptr<GRAPH_NODE>& aConnectTo,
762 BOARD_ITEM* aParent = nullptr );
763
764 double Solve( std::shared_ptr<GRAPH_NODE>& aFrom, std::shared_ptr<GRAPH_NODE>& aTo,
765 std::vector<std::shared_ptr<GRAPH_CONNECTION>>& aResult );
766
767 void GeneratePaths( double aMaxWeight, PCB_LAYER_ID aLayer );
768
769 std::shared_ptr<GRAPH_NODE> AddNetElements( int aNetCode, PCB_LAYER_ID aLayer, int aMaxCreepage );
770
771 void SetTarget( double aTarget );
772 double GetTarget() { return m_creepageTarget; };
773
775 {
776 std::size_t operator()(const std::shared_ptr<GRAPH_NODE>& node) const
777 {
778 return hash_val(node->m_type, node->m_parent, node->m_pos.x, node->m_pos.y);
779 }
780 };
781
783 {
784 bool operator()(const std::shared_ptr<GRAPH_NODE>& lhs, const std::shared_ptr<GRAPH_NODE>& rhs) const
785 {
786 return lhs->m_type == rhs->m_type && lhs->m_parent == rhs->m_parent && lhs->m_pos == rhs->m_pos;
787 }
788 };
789
790public:
792 std::vector<BOARD_ITEM*> m_boardEdge;
794 std::vector<std::shared_ptr<GRAPH_NODE>> m_nodes;
795 std::vector<std::shared_ptr<GRAPH_CONNECTION>> m_connections;
796 std::vector<CREEP_SHAPE*> m_shapeCollection;
797
798 // This is a duplicate of m_nodes, but it is used to quickly find a node rather than iterating through m_nodes
799 std::unordered_set<std::shared_ptr<GRAPH_NODE>, GraphNodeHash, GraphNodeEqual> m_nodeset;
800
802
803private:
806};
807
Creepage: a board edge arc.
std::pair< bool, bool > IsThereATangentPassingThroughPoint(const BE_SHAPE_POINT aPoint) const
EDA_ANGLE GetStartAngle() const override
int GetRadius() const override
BE_SHAPE_ARC(VECTOR2I aPos, int aRadius, EDA_ANGLE aStartAngle, EDA_ANGLE aEndAngle, VECTOR2D aStartPoint, VECTOR2D aEndPoint)
std::vector< PATH_CONNECTION > Paths(const CU_SHAPE_ARC &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
VECTOR2I GetStartPoint() const override
std::vector< PATH_CONNECTION > Paths(const BE_SHAPE_POINT &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
void ConnectChildren(std::shared_ptr< GRAPH_NODE > &a1, std::shared_ptr< GRAPH_NODE > &a2, CREEPAGE_GRAPH &aG) const override
EDA_ANGLE GetEndAngle() const override
std::vector< PATH_CONNECTION > Paths(const CU_SHAPE_SEGMENT &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
std::vector< PATH_CONNECTION > Paths(const BE_SHAPE_CIRCLE &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
std::vector< PATH_CONNECTION > Paths(const CU_SHAPE_CIRCLE &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
VECTOR2I GetEndPoint() const override
EDA_ANGLE AngleBetweenStartAndEnd(const VECTOR2I aPoint) const
Creepage: a board edge circle.
int GetRadius() const override
BE_SHAPE_CIRCLE(VECTOR2I aPos=VECTOR2I(0, 0), int aRadius=0)
void ShortenChildDueToGV(std::shared_ptr< GRAPH_NODE > &a1, std::shared_ptr< GRAPH_NODE > &a2, CREEPAGE_GRAPH &aG, double aNormalWeight) const
std::vector< PATH_CONNECTION > Paths(const CU_SHAPE_CIRCLE &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
std::vector< PATH_CONNECTION > Paths(const CU_SHAPE_SEGMENT &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
std::vector< PATH_CONNECTION > Paths(const BE_SHAPE_POINT &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
void ConnectChildren(std::shared_ptr< GRAPH_NODE > &a1, std::shared_ptr< GRAPH_NODE > &a2, CREEPAGE_GRAPH &aG) const override
Creepage: a board edge point.
BE_SHAPE_POINT(VECTOR2I aPos)
void ConnectChildren(std::shared_ptr< GRAPH_NODE > &a1, std::shared_ptr< GRAPH_NODE > &a2, CREEPAGE_GRAPH &aG) const override
std::vector< PATH_CONNECTION > Paths(const CU_SHAPE_ARC &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
std::vector< PATH_CONNECTION > Paths(const CU_SHAPE_SEGMENT &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
std::vector< PATH_CONNECTION > Paths(const BE_SHAPE_POINT &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
std::vector< PATH_CONNECTION > Paths(const CU_SHAPE_CIRCLE &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
Creepage: a board edge shape.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:79
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:317
const TRACKS & Tracks() const
Definition board.h:356
A graph with nodes and connections for creepage calculation.
std::shared_ptr< GRAPH_NODE > AddNode(GRAPH_NODE::TYPE aType, CREEP_SHAPE *aParent=nullptr, const VECTOR2I &aPos=VECTOR2I())
std::shared_ptr< GRAPH_CONNECTION > AddConnection(std::shared_ptr< GRAPH_NODE > &aN1, std::shared_ptr< GRAPH_NODE > &aN2, const PATH_CONNECTION &aPc)
void SetTarget(double aTarget)
double Solve(std::shared_ptr< GRAPH_NODE > &aFrom, std::shared_ptr< GRAPH_NODE > &aTo, std::vector< std::shared_ptr< GRAPH_CONNECTION > > &aResult)
void Addshape(const SHAPE &aShape, std::shared_ptr< GRAPH_NODE > &aConnectTo, BOARD_ITEM *aParent=nullptr)
std::vector< CREEP_SHAPE * > m_shapeCollection
CREEPAGE_GRAPH(BOARD &aBoard)
std::shared_ptr< GRAPH_NODE > AddNodeVirtual()
void TransformCreepShapesToNodes(std::vector< CREEP_SHAPE * > &aShapes)
void Trim(double aWeightLimit)
SHAPE_POLY_SET * m_boardOutline
std::vector< BOARD_ITEM * > m_boardEdge
std::unordered_set< std::shared_ptr< GRAPH_NODE >, GraphNodeHash, GraphNodeEqual > m_nodeset
void GeneratePaths(double aMaxWeight, PCB_LAYER_ID aLayer)
std::vector< std::shared_ptr< GRAPH_NODE > > m_nodes
std::vector< std::shared_ptr< GRAPH_CONNECTION > > m_connections
std::shared_ptr< GRAPH_NODE > AddNetElements(int aNetCode, PCB_LAYER_ID aLayer, int aMaxCreepage)
void RemoveConnection(const std::shared_ptr< GRAPH_CONNECTION > &, bool aDelete=false)
std::shared_ptr< GRAPH_NODE > FindNode(GRAPH_NODE::TYPE aType, CREEP_SHAPE *aParent, const VECTOR2I &aPos)
A class used to represent the shapes for creepage calculation.
VECTOR2I GetPos() const
virtual VECTOR2I GetStartPoint() const
virtual std::vector< PATH_CONNECTION > Paths(const BE_SHAPE_POINT &aS2, double aMaxWeight, double aMaxSquaredWeight) const
virtual std::vector< PATH_CONNECTION > Paths(const BE_SHAPE_ARC &aS2, double aMaxWeight, double aMaxSquaredWeight) const
CREEP_SHAPE::TYPE GetType() const
std::vector< PATH_CONNECTION > Paths(const CREEP_SHAPE &aS2, double aMaxWeight, double aMaxSquaredWeight) const
virtual EDA_ANGLE GetEndAngle() const
void SetParent(BOARD_ITEM *aParent)
CREEP_SHAPE::TYPE m_type
virtual std::vector< PATH_CONNECTION > Paths(const CU_SHAPE_ARC &aS2, double aMaxWeight, double aMaxSquaredWeight) const
virtual std::vector< PATH_CONNECTION > Paths(const BE_SHAPE_CIRCLE &aS2, double aMaxWeight, double aMaxSquaredWeight) const
virtual ~CREEP_SHAPE()
virtual int GetRadius() const
const BOARD_ITEM * GetParent() const
virtual void ConnectChildren(std::shared_ptr< GRAPH_NODE > &a1, std::shared_ptr< GRAPH_NODE > &a2, CREEPAGE_GRAPH &aG) const
BOARD_ITEM * m_parent
virtual std::vector< PATH_CONNECTION > Paths(const CU_SHAPE_CIRCLE &aS2, double aMaxWeight, double aMaxSquaredWeight) const
virtual EDA_ANGLE GetStartAngle() const
virtual VECTOR2I GetEndPoint() const
virtual std::vector< PATH_CONNECTION > Paths(const CU_SHAPE_SEGMENT &aS2, double aMaxWeight, double aMaxSquaredWeight) const
std::vector< PATH_CONNECTION > ReversePaths(const std::vector< PATH_CONNECTION > &aV) const
Creepage: a conductive arc.
VECTOR2I GetStartPoint() const override
void SetWidth(double aW)
EDA_ANGLE AngleBetweenStartAndEnd(const VECTOR2I aPoint) const
VECTOR2I GetEndPoint() const override
std::vector< PATH_CONNECTION > Paths(const CU_SHAPE_CIRCLE &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
EDA_ANGLE GetStartAngle() const override
double GetWidth() const
CU_SHAPE_ARC(VECTOR2I aPos, double aRadius, EDA_ANGLE aStartAngle, EDA_ANGLE aEndAngle, VECTOR2D aStartPoint, VECTOR2D aEndPoint)
int GetRadius() const override
EDA_ANGLE GetEndAngle() const override
std::vector< PATH_CONNECTION > Paths(const CU_SHAPE_SEGMENT &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
std::vector< PATH_CONNECTION > Paths(const BE_SHAPE_POINT &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
Creepage: a conductive circle.
int GetRadius() const override
std::vector< PATH_CONNECTION > Paths(const CU_SHAPE_SEGMENT &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
VECTOR2I GetPos() const
CU_SHAPE_CIRCLE(VECTOR2I aPos, double aRadius=0)
std::vector< PATH_CONNECTION > Paths(const BE_SHAPE_POINT &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
Creepage: a conductive segment.
std::vector< PATH_CONNECTION > Paths(const BE_SHAPE_POINT &aS2, double aMaxWeight, double aMaxSquaredWeight) const override
VECTOR2I GetStart() const
double GetWidth() const
VECTOR2I GetEnd() const
CU_SHAPE_SEGMENT(VECTOR2I aStart, VECTOR2I aEnd, double aWidth=0)
Creepage: a conductive shape.
a connection in a
std::shared_ptr< GRAPH_NODE > n2
PATH_CONNECTION m_path
void GetShapes(std::vector< PCB_SHAPE > &aShapes)
std::shared_ptr< GRAPH_NODE > n1
GRAPH_CONNECTION(std::shared_ptr< GRAPH_NODE > &aN1, std::shared_ptr< GRAPH_NODE > &aN2, const PATH_CONNECTION &aPc)
CREEP_SHAPE * m_parent
std::set< std::shared_ptr< GRAPH_CONNECTION > > m_node_conns
GRAPH_NODE(GRAPH_NODE::TYPE aType, CREEP_SHAPE *aParent, const VECTOR2I &aPos=VECTOR2I())
GRAPH_NODE::TYPE m_type
Definition seg.h:42
bool Intersects(const SEG &aSeg) const
Definition seg.cpp:431
Represent a set of closed polygons.
void Inflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, bool aSimplify=false)
Perform outline inflation/deflation.
bool PointOnEdge(const VECTOR2I &aP, int aAccuracy=0) const
Check if point aP lies on an edge or vertex of some of the outlines or holes.
bool Contains(const VECTOR2I &aP, int aSubpolyIndex=-1, int aAccuracy=0, bool aUseBBoxCaches=false) const
Return true if a given subpolygon contains the point aP.
An abstract shape on 2D plane.
Definition shape.h:126
constexpr extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
Definition vector2d.h:307
The common library.
@ ROUND_ALL_CORNERS
All angles are rounded.
bool SegmentIntersectsBoard(const VECTOR2I &aP1, const VECTOR2I &aP2, const std::vector< BOARD_ITEM * > &aBe, const std::vector< const BOARD_ITEM * > &aDontTestAgainst, int aMinGrooveWidth)
static constexpr EDA_ANGLE ANGLE_360
Definition eda_angle.h:417
static constexpr std::size_t hash_val(const Types &... args)
Definition hash.h:51
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:60
@ Edge_Cuts
Definition layer_ids.h:112
This file contains miscellaneous commonly used macros and functions.
@ SH_SEGMENT
line segment
Definition shape.h:48
bool operator()(const std::shared_ptr< GRAPH_NODE > &lhs, const std::shared_ptr< GRAPH_NODE > &rhs) const
std::size_t operator()(const std::shared_ptr< GRAPH_NODE > &node) const
bool isValid(const BOARD &aBoard, PCB_LAYER_ID aLayer, const std::vector< BOARD_ITEM * > &aBoardEdges, const std::vector< const BOARD_ITEM * > &aIgnoreForTest, SHAPE_POLY_SET *aOutline, const std::pair< bool, bool > &aTestLocalConcavity, int aMinGrooveWidth) const
Test if a path is valid.
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition typeinfo.h:96
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695
VECTOR2< double > VECTOR2D
Definition vector2d.h:694