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#ifndef _DRC_CREEPAGE_UTILS_H
25#define _DRC_CREEPAGE_UTILS_H
26
27#include <unordered_set>
28
29#include <common.h>
30#include <macros.h>
32#include <footprint.h>
33#include <pad.h>
34#include <pcb_track.h>
35#include <pcb_shape.h>
36#include <zone.h>
37#include <advanced_config.h>
38#include <geometry/shape_rect.h>
39#include <geometry/seg.h>
41#include <drc/drc_item.h>
42#include <drc/drc_rule.h>
43#include <board.h>
44
45
47
48
49extern bool SegmentIntersectsBoard( const VECTOR2I& aP1, const VECTOR2I& aP2,
50 const std::vector<BOARD_ITEM*>& aBe,
51 const std::vector<const BOARD_ITEM*>& aDontTestAgainst,
52 int aMinGrooveWidth );
53
55{
58 double weight = -1;
59 bool m_show = true;
60
63
64
69 bool isValid( const BOARD& aBoard, PCB_LAYER_ID aLayer,
70 const std::vector<BOARD_ITEM*>& aBoardEdges,
71 const std::vector<const BOARD_ITEM*>& aIgnoreForTest, SHAPE_POLY_SET* aOutline,
72 const std::pair<bool, bool>& aTestLocalConcavity, int aMinGrooveWidth ) const
73 {
74 if( !aOutline )
75 return true; // We keep the segment if there is a problem
76
77 if( !SegmentIntersectsBoard( a1, a2, aBoardEdges, aIgnoreForTest, aMinGrooveWidth ) )
78 return false;
79
80 // The mid point should be inside the board.
81 // Tolerance of 100nm.
82
83 VECTOR2I midPoint = ( a1 + a2 ) / 2;
84 int tolerance = 100;
85
86 if( !( aOutline->Contains( midPoint, -1, tolerance )
87 || aOutline->PointOnEdge( midPoint, tolerance ) ) )
88 return false;
89
90 if( false && ( aTestLocalConcavity.first || aTestLocalConcavity.second ) )
91 {
92 // Test for local concavity. If it is localy convex, then it will not be a path of interest.
93
94 double extendLine = 1000; // extend line by 1000nm
95 // In some cases, the projected point could be on the board edge
96 // In such cases, we wan to keep the line.
97 // We inflate the polygon to get a small margin for computation/rounding error.
98 // We might keep some unnecessary lines, but it's better than loosing the important ones.
99 double extendPoly = 100; // extend polygon by 10 nm
100
101 VECTOR2D a( double( a1.x ), double( a1.y ) );
102 VECTOR2D b( double( a2.x ), double( a2.y ) );
103
104 VECTOR2D dir( b - a );
105 dir = dir * ( extendLine / dir.SquaredEuclideanNorm() );
106
107 SHAPE_POLY_SET outline2 = *aOutline;
108 outline2.Inflate( extendPoly, CORNER_STRATEGY::ROUND_ALL_CORNERS, 3 );
109
110 if( aTestLocalConcavity.first && !aOutline->Contains( a - dir, -1, 0 ) )
111 return false;
112
113 if( aTestLocalConcavity.second && !aOutline->Contains( b + dir, -1, 0 ) )
114 return false;
115 }
116
117 SEG segPath( a1, a2 );
118
119 if( aLayer != Edge_Cuts )
120 {
121 for( PCB_TRACK* track : aBoard.Tracks() )
122 {
123 if( !track )
124 continue;
125
126 if( track->Type() == KICAD_T::PCB_TRACE_T && track->IsOnLayer( aLayer ) )
127 {
128 std::shared_ptr<SHAPE> sh = track->GetEffectiveShape();
129
130 if( sh && sh->Type() == SHAPE_TYPE::SH_SEGMENT )
131 {
132 SEG segTrack( track->GetStart(), track->GetEnd() );
133
134 if( segPath.Intersects( segTrack ) )
135 return false;
136 }
137 }
138 }
139 }
140 return true;
141 }
142};
143
144
145class GRAPH_CONNECTION;
146class GRAPH_NODE;
147class CREEPAGE_GRAPH;
148class CREEP_SHAPE;
149class BE_SHAPE;
150class BE_SHAPE_POINT;
151class BE_SHAPE_ARC;
152class BE_SHAPE_CIRCLE;
153class CU_SHAPE;
154class CU_SHAPE_SEGMENT;
155class CU_SHAPE_CIRCLE;
156class CU_SHAPE_ARC;
157
163{
164public:
165 enum class TYPE
166 {
167 UNDEFINED = 0,
168 POINT,
169 CIRCLE,
170 ARC
171 };
172
174 {
175 m_conductive = false;
176 m_parent = nullptr;
177 m_pos = VECTOR2I( 0, 0 );
178 m_type = CREEP_SHAPE::TYPE::UNDEFINED;
179 };
180
181 virtual ~CREEP_SHAPE() {}
182
183
184 virtual int GetRadius() const { return 0; };
185 virtual EDA_ANGLE GetStartAngle() const { return EDA_ANGLE( 0 ); };
186 virtual EDA_ANGLE GetEndAngle() const { return EDA_ANGLE( 0 ); };
187 virtual VECTOR2I GetStartPoint() const { return VECTOR2I( 0, 0 ); };
188 virtual VECTOR2I GetEndPoint() const { return VECTOR2I( 0, 0 ); };
189 VECTOR2I GetPos() const { return m_pos; };
190 CREEP_SHAPE::TYPE GetType() const { return m_type; };
191 const BOARD_ITEM* GetParent() const { return m_parent; };
192 void SetParent( BOARD_ITEM* aParent ) { m_parent = aParent; };
193
194 virtual void ConnectChildren( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
195 CREEPAGE_GRAPH& aG ) const;
196
197 std::vector<PATH_CONNECTION> ReversePaths( const std::vector<PATH_CONNECTION>& aV ) const
198 {
199 std::vector<PATH_CONNECTION> r;
200 r.reserve( aV.size() );
201
202 for( const auto& pc : aV )
203 {
204 r.emplace_back( pc );
205 std::swap( r.back().a1, r.back().a2 );
206 }
207
208 return r;
209 }
210
211 std::vector<PATH_CONNECTION> Paths( const CREEP_SHAPE& aS2, double aMaxWeight,
212 double aMaxSquaredWeight ) const
213 {
214 std::vector<PATH_CONNECTION> a;
215 return a;
216 };
217
218 virtual std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
219 double aMaxSquaredWeight ) const
220 {
221 std::vector<PATH_CONNECTION> a;
222 return a;
223 };
224
225 virtual std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
226 double aMaxSquaredWeight ) const
227 {
228 std::vector<PATH_CONNECTION> a;
229 return a;
230 };
231
232 virtual std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
233 double aMaxSquaredWeight ) const
234 {
235 std::vector<PATH_CONNECTION> a;
236 return a;
237 };
238
239 virtual std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
240 double aMaxSquaredWeight ) const
241 {
242 std::vector<PATH_CONNECTION> a;
243 return a;
244 };
245
246 virtual std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
247 double aMaxSquaredWeight ) const
248 {
249 std::vector<PATH_CONNECTION> a;
250 return a;
251 };
252
253 virtual std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_ARC& aS2, double aMaxWeight,
254 double aMaxSquaredWeight ) const
255 {
256 std::vector<PATH_CONNECTION> a;
257 return a;
258 };
259
260 //virtual std::vector<PATH_CONNECTION> GetPathsCuToBe( CREEP_SHAPE* aShape ) const{ std::vector<PATH_CONNECTION> a; return a;};
261 bool IsConductive() { return m_conductive; };
262
263
264protected:
269};
270
271
276class CU_SHAPE : public CREEP_SHAPE
277{
278public:
280};
281
286class BE_SHAPE : public CREEP_SHAPE
287{
288public:
290};
291
297{
298public:
299 CU_SHAPE_SEGMENT( VECTOR2I aStart, VECTOR2I aEnd, double aWidth = 0 ) : CU_SHAPE()
300 {
301 m_start = aStart;
302 m_end = aEnd;
303 m_width = aWidth;
304 }
305
306 VECTOR2I GetStart() const { return m_start; };
307 VECTOR2I GetEnd() const { return m_end; };
308 double GetWidth() const { return m_width; };
309
310 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
311 double aMaxSquaredWeight ) const override;
312 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
313 double aMaxSquaredWeight ) const override;
314 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
315 double aMaxSquaredWeight ) const override;
316 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
317 double aMaxSquaredWeight ) const override;
318 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
319 double aMaxSquaredWeight ) const override;
320 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_ARC& aS2, double aMaxWeight,
321 double aMaxSquaredWeight ) const override;
322
323
324private:
327 double m_width = 0;
328};
329
335{
336public:
337 CU_SHAPE_CIRCLE( VECTOR2I aPos, double aRadius = 0 ) : CU_SHAPE()
338 {
339 m_pos = aPos;
340 m_radius = aRadius;
341 }
342
343 VECTOR2I GetPos() const { return m_pos; };
344 int GetRadius() const override { return m_radius; };
345
346 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
347 double aMaxSquaredWeight ) const override;
348 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
349 double aMaxSquaredWeight ) const override;
350 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
351 double aMaxSquaredWeight ) const override;
352 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
353 double aMaxSquaredWeight ) const override
354 {
355 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
356 };
357
358 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
359 double aMaxSquaredWeight ) const override;
360 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_ARC& aS2, double aMaxWeight,
361 double aMaxSquaredWeight ) const override;
362
363protected:
365 double m_radius = 1;
366};
367
373{
374public:
375 CU_SHAPE_ARC( VECTOR2I aPos, double aRadius, EDA_ANGLE aStartAngle, EDA_ANGLE aEndAngle,
376 VECTOR2D aStartPoint, VECTOR2D aEndPoint ) :
377 CU_SHAPE_CIRCLE( aPos, aRadius ),
378 m_startAngle( aStartAngle ), m_endAngle( aEndAngle ),
379 m_startPoint( aStartPoint ), m_endPoint( aEndPoint )
380 {
381 m_type = CREEP_SHAPE::TYPE::ARC;
382 m_width = 0;
383 }
384
385 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
386 double aMaxSquaredWeight ) const override;
387
388 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
389 double aMaxSquaredWeight ) const override;
390
391 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
392 double aMaxSquaredWeight ) const override;
393
394 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
395 double aMaxSquaredWeight ) const override
396 {
397 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
398 };
399
400 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
401 double aMaxSquaredWeight ) const override
402 {
403 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
404 };
405
406 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_ARC& aS2, double aMaxWeight,
407 double aMaxSquaredWeight ) const override;
408
409
410 EDA_ANGLE GetStartAngle() const override { return m_startAngle; }
411 EDA_ANGLE GetEndAngle() const override { return m_endAngle; }
412 int GetRadius() const override { return m_radius; }
413
414
415 VECTOR2I GetStartPoint() const override { return m_startPoint; }
416 VECTOR2I GetEndPoint() const override { return m_endPoint; }
417
419 {
420 EDA_ANGLE angle( aPoint - m_pos );
421
422 while( angle < GetStartAngle() )
423 angle += ANGLE_360;
424
425 while( angle > GetEndAngle() + ANGLE_360 )
426 angle -= ANGLE_360;
427
428 return angle;
429 }
430
431 double GetWidth() const { return m_width; };
432 void SetWidth( double aW ) { m_width = aW; };
433
434private:
440};
441
447{
448public:
449 enum TYPE
450 {
451
452 POINT = 0,
456 VIRTUAL
457 };
458
460 m_parent( aParent ),
461 m_pos( aPos ),
462 m_type( aType )
463 {
464 m_node_conns = {};
465 m_virtual = false;
466 m_connectDirectly = true;
467 m_net = -1;
468 };
469
471
472
474 std::set<std::shared_ptr<GRAPH_CONNECTION>> m_node_conns;
476
477 // Virtual nodes are connected with a 0 weight connection to equivalent net ( same net or netclass )
480 int m_net;
481
483};
484
490{
491public:
492 GRAPH_CONNECTION( std::shared_ptr<GRAPH_NODE>& aN1, std::shared_ptr<GRAPH_NODE>& aN2,
493 const PATH_CONNECTION& aPc ) :
494 n1( aN1 ),
495 n2( aN2 )
496 {
497 m_path = aPc;
498 m_forceStraightLine = false;
499 };
500
501 std::vector<PCB_SHAPE> GetShapes();
502
503 std::shared_ptr<GRAPH_NODE> n1;
504 std::shared_ptr<GRAPH_NODE> n2;
507};
508
509
515{
516public:
518 BE_SHAPE()
519 {
520 m_pos = aPos;
521 m_type = CREEP_SHAPE::TYPE::POINT;
522 }
523
524 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
525 double aMaxSquaredWeight ) const override;
526
527 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
528 double aMaxSquaredWeight ) const override;
529
530 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
531 double aMaxSquaredWeight ) const override;
532
533 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
534 double aMaxSquaredWeight ) const override
535 {
536 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
537 };
538
539 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
540 double aMaxSquaredWeight ) const override
541 {
542 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
543 }
544
545 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_ARC& aS2, double aMaxWeight,
546 double aMaxSquaredWeight ) const override
547 {
548 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
549 };
550
551
552 void ConnectChildren( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
553 CREEPAGE_GRAPH& aG ) const override;
554};
555
561{
562public:
563 BE_SHAPE_CIRCLE( VECTOR2I aPos = VECTOR2I( 0, 0 ), int aRadius = 0 ) :
564 BE_SHAPE()
565 {
566 m_pos = aPos;
567 m_radius = aRadius;
568 m_type = CREEP_SHAPE::TYPE::CIRCLE;
569 }
570
571 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
572 double aMaxSquaredWeight ) const override
573 {
574 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
575 };
576
577 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
578 double aMaxSquaredWeight ) const override;
579
580 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
581 double aMaxSquaredWeight ) const override;
582
583 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
584 double aMaxSquaredWeight ) const override
585 {
586 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
587 };
588
589 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
590 double aMaxSquaredWeight ) const override
591 {
592 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
593 };
594
595
596 int GetRadius() const override { return m_radius; }
597
598 void ConnectChildren( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
599 CREEPAGE_GRAPH& aG ) const override;
600
601 void ShortenChildDueToGV( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
602 CREEPAGE_GRAPH& aG, double aNormalWeight ) const;
603
604
605protected:
607};
608
614{
615public:
616 BE_SHAPE_ARC( VECTOR2I aPos, int aRadius, EDA_ANGLE aStartAngle, EDA_ANGLE aEndAngle,
617 VECTOR2D aStartPoint, VECTOR2D aEndPoint ) :
618 BE_SHAPE_CIRCLE( aPos, aRadius ),
619 m_startAngle( aStartAngle ), m_endAngle( aEndAngle ),
620 m_startPoint( aStartPoint ), m_endPoint( aEndPoint )
621 {
622 m_type = CREEP_SHAPE::TYPE::ARC;
623 }
624
625 void ConnectChildren( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
626 CREEPAGE_GRAPH& aG ) const override;
627
628
629 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
630 double aMaxSquaredWeight ) const override
631 {
632 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
633 };
634 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
635 double aMaxSquaredWeight ) const override
636 {
637 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
638 };
639 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
640 double aMaxSquaredWeight ) const override;
641
642 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
643 double aMaxSquaredWeight ) const override
644 {
645 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
646 };
647 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
648 double aMaxSquaredWeight ) const override
649 {
650 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
651 };
652 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_ARC& aS2, double aMaxWeight,
653 double aMaxSquaredWeight ) const override
654 {
655 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
656 };
657
658
659 EDA_ANGLE GetStartAngle() const override { return m_startAngle; }
660 EDA_ANGLE GetEndAngle() const override { return m_endAngle; }
661 int GetRadius() const override { return m_radius; }
662
663
664 VECTOR2I GetStartPoint() const override { return m_startPoint; }
665 VECTOR2I GetEndPoint() const override { return m_endPoint; }
667 {
668 EDA_ANGLE angle( aPoint - m_pos );
669
670 while( angle < m_startAngle )
671 angle += ANGLE_360;
672 while( angle > m_endAngle + ANGLE_360 )
673 angle -= ANGLE_360;
674
675 return angle;
676 }
677
678 std::pair<bool, bool> IsThereATangentPassingThroughPoint( const BE_SHAPE_POINT aPoint ) const;
679
680protected:
685};
686
687
693{
694public:
696 m_board( aBoard )
697 {
698 m_boardOutline = nullptr;
700 m_creepageTarget = -1;
702 };
703
705 {
706 for( CREEP_SHAPE* cs : m_shapeCollection )
707 {
708 if( cs )
709 {
710 delete cs;
711 cs = nullptr;
712 }
713 }
714
715 // Clear out the circular shared pointer references
716 for( std::shared_ptr<GRAPH_NODE>& n : m_nodes )
717 {
718 if( n )
719 {
720 n->m_node_conns.clear();
721 n = nullptr;
722 }
723 }
724
725 for( std::shared_ptr<GRAPH_CONNECTION>& c : m_connections )
726 {
727 if( c )
728 c = nullptr;
729 }
730 };
731
732
734 void TransformCreepShapesToNodes(std::vector<CREEP_SHAPE*>& aShapes);
736
737 // Add a node to the graph. If an equivalent node exists, returns the pointer of the existing node instead
738 std::shared_ptr<GRAPH_NODE> AddNode( GRAPH_NODE::TYPE aType, CREEP_SHAPE* aParent = nullptr,
739 const VECTOR2I& aPos = VECTOR2I() );
740
741 std::shared_ptr<GRAPH_NODE> AddNodeVirtual();
742
743 std::shared_ptr<GRAPH_CONNECTION> AddConnection( std::shared_ptr<GRAPH_NODE>& aN1,
744 std::shared_ptr<GRAPH_NODE>& aN2,
745 const PATH_CONNECTION& aPc );
746
747 std::shared_ptr<GRAPH_CONNECTION> AddConnection( std::shared_ptr<GRAPH_NODE>& aN1,
748 std::shared_ptr<GRAPH_NODE>& aN2 );
749
750 std::shared_ptr<GRAPH_NODE> FindNode( GRAPH_NODE::TYPE aType, CREEP_SHAPE* aParent,
751 const VECTOR2I& aPos );
752
753 void RemoveConnection( const std::shared_ptr<GRAPH_CONNECTION>&, bool aDelete = false );
754
755 void Trim( double aWeightLimit );
756
757 void Addshape( const SHAPE& aShape, std::shared_ptr<GRAPH_NODE>& aConnectTo,
758 BOARD_ITEM* aParent = nullptr );
759
760 double Solve( std::shared_ptr<GRAPH_NODE>& aFrom, std::shared_ptr<GRAPH_NODE>& aTo,
761 std::vector<std::shared_ptr<GRAPH_CONNECTION>>& aResult );
762
763 void GeneratePaths( double aMaxWeight, PCB_LAYER_ID aLayer );
764
765 std::shared_ptr<GRAPH_NODE> AddNetElements( int aNetCode, PCB_LAYER_ID aLayer, int aMaxCreepage );
766
767 void SetTarget( double aTarget );
768 double GetTarget() { return m_creepageTarget; };
769
770
772 {
773 std::size_t operator()(const std::shared_ptr<GRAPH_NODE>& node) const
774 {
775 return hash_val(node->m_type, node->m_parent, node->m_pos.x, node->m_pos.y);
776 }
777 };
778
780 {
781 bool operator()(const std::shared_ptr<GRAPH_NODE>& lhs, const std::shared_ptr<GRAPH_NODE>& rhs) const
782 {
783 return lhs->m_type == rhs->m_type && lhs->m_parent == rhs->m_parent && lhs->m_pos == rhs->m_pos;
784 }
785 };
786
788 std::vector<BOARD_ITEM*> m_boardEdge;
790 std::vector<std::shared_ptr<GRAPH_NODE>> m_nodes;
791 std::vector<std::shared_ptr<GRAPH_CONNECTION>> m_connections;
792 std::vector<CREEP_SHAPE*> m_shapeCollection;
793
794 // This is a duplicate of m_nodes, but it is used to quickly find a node rather than iterating through m_nodes
795 std::unordered_set<std::shared_ptr<GRAPH_NODE>, GraphNodeHash, GraphNodeEqual> m_nodeset;
796
798
799private:
802};
803
804
805#endif
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
EDA_ANGLE m_endAngle
VECTOR2I GetStartPoint() const override
EDA_ANGLE m_startAngle
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
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
double m_creepageTargetSquared
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
EDA_ANGLE m_startAngle
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
EDA_ANGLE m_endAngle
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.
std::vector< PCB_SHAPE > GetShapes()
std::shared_ptr< GRAPH_NODE > n2
PATH_CONNECTION m_path
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::TYPE m_type
GRAPH_NODE(GRAPH_NODE::TYPE aType, CREEP_SHAPE *aParent, VECTOR2I aPos=VECTOR2I())
Definition: seg.h:42
bool Intersects(const SEG &aSeg) const
Definition: seg.cpp:433
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.
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.
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.
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695