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 )
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
459 GRAPH_NODE( GRAPH_NODE::TYPE aType, CREEP_SHAPE* aParent, VECTOR2I aPos = VECTOR2I() )
460 : m_parent( aParent ), m_pos( aPos ), m_type( aType )
461 {
462 m_node_conns = {};
463 m_virtual = false;
464 m_connectDirectly = true;
465 m_net = -1;
466 };
467
469
470
472 std::set<std::shared_ptr<GRAPH_CONNECTION>> m_node_conns;
474
475 // Virtual nodes are connected with a 0 weight connection to equivalent net ( same net or netclass )
478 int m_net;
479
481};
482
488{
489public:
490 GRAPH_CONNECTION( std::shared_ptr<GRAPH_NODE>& aN1, std::shared_ptr<GRAPH_NODE>& aN2,
491 const PATH_CONNECTION& aPc ) : n1( aN1 ), n2( aN2 )
492 {
493 m_path = aPc;
494 m_forceStraightLine = false;
495 };
496
497 std::vector<PCB_SHAPE> GetShapes();
498
499 std::shared_ptr<GRAPH_NODE> n1;
500 std::shared_ptr<GRAPH_NODE> n2;
503};
504
505
511{
512public:
514 {
515 m_pos = aPos;
516 m_type = CREEP_SHAPE::TYPE::POINT;
517 }
518
519 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
520 double aMaxSquaredWeight ) const override;
521
522 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
523 double aMaxSquaredWeight ) const override;
524
525 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
526 double aMaxSquaredWeight ) const override;
527
528 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
529 double aMaxSquaredWeight ) const override
530 {
531 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
532 };
533
534 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
535 double aMaxSquaredWeight ) const override
536 {
537 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
538 }
539
540 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_ARC& aS2, double aMaxWeight,
541 double aMaxSquaredWeight ) const override
542 {
543 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
544 };
545
546
547 void ConnectChildren( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
548 CREEPAGE_GRAPH& aG ) const override;
549};
550
556{
557public:
558 BE_SHAPE_CIRCLE( VECTOR2I aPos = VECTOR2I( 0, 0 ), int aRadius = 0 ) : BE_SHAPE()
559 {
560 m_pos = aPos;
561 m_radius = aRadius;
562 m_type = CREEP_SHAPE::TYPE::CIRCLE;
563 }
564
565 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
566 double aMaxSquaredWeight ) const override
567 {
568 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
569 };
570
571 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
572 double aMaxSquaredWeight ) const override;
573
574 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
575 double aMaxSquaredWeight ) const override;
576
577 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& aS2, double aMaxWeight,
578 double aMaxSquaredWeight ) const override
579 {
580 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
581 };
582
583 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_CIRCLE& aS2, double aMaxWeight,
584 double aMaxSquaredWeight ) const override
585 {
586 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
587 };
588
589
590 int GetRadius() const override { return m_radius; }
591
592 void ConnectChildren( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
593 CREEPAGE_GRAPH& aG ) const override;
594
595 void ShortenChildDueToGV( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
596 CREEPAGE_GRAPH& aG, double aNormalWeight ) const;
597
598
599protected:
601};
602
608{
609public:
610 BE_SHAPE_ARC( VECTOR2I aPos, int aRadius, EDA_ANGLE aStartAngle, EDA_ANGLE aEndAngle,
611 VECTOR2D aStartPoint, VECTOR2D aEndPoint ) :
612 BE_SHAPE_CIRCLE( aPos, aRadius ),
613 m_startAngle( aStartAngle ), m_endAngle( aEndAngle ),
614 m_startPoint( aStartPoint ), m_endPoint( aEndPoint )
615 {
616 m_type = CREEP_SHAPE::TYPE::ARC;
617 }
618
619 void ConnectChildren( std::shared_ptr<GRAPH_NODE>& a1, std::shared_ptr<GRAPH_NODE>& a2,
620 CREEPAGE_GRAPH& aG ) const override;
621
622
623 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_POINT& aS2, double aMaxWeight,
624 double aMaxSquaredWeight ) const override
625 {
626 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
627 };
628 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_CIRCLE& aS2, double aMaxWeight,
629 double aMaxSquaredWeight ) const override
630 {
631 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
632 };
633 std::vector<PATH_CONNECTION> Paths( const BE_SHAPE_ARC& aS2, double aMaxWeight,
634 double aMaxSquaredWeight ) const override;
635
636 std::vector<PATH_CONNECTION> Paths( const CU_SHAPE_SEGMENT& 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 CU_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 CU_SHAPE_ARC& aS2, double aMaxWeight,
647 double aMaxSquaredWeight ) const override
648 {
649 return ReversePaths( aS2.Paths( *this, aMaxWeight, aMaxSquaredWeight ) );
650 };
651
652
653 EDA_ANGLE GetStartAngle() const override { return m_startAngle; }
654 EDA_ANGLE GetEndAngle() const override { return m_endAngle; }
655 int GetRadius() const override { return m_radius; }
656
657
658 VECTOR2I GetStartPoint() const override { return m_startPoint; }
659 VECTOR2I GetEndPoint() const override { return m_endPoint; }
661 {
662 EDA_ANGLE angle( aPoint - m_pos );
663
664 while( angle < m_startAngle )
665 angle += ANGLE_360;
666 while( angle > m_endAngle + ANGLE_360 )
667 angle -= ANGLE_360;
668
669 return angle;
670 }
671
672 std::pair<bool, bool> IsThereATangentPassingThroughPoint( const BE_SHAPE_POINT aPoint ) const;
673
674protected:
679};
680
681
687{
688public:
689 CREEPAGE_GRAPH( BOARD& aBoard ) : m_board( aBoard )
690 {
691 m_boardOutline = nullptr;
693 m_creepageTarget = -1;
695 };
696
698 {
699 for( CREEP_SHAPE* cs : m_shapeCollection )
700 if( cs )
701 {
702 delete cs;
703 cs = nullptr;
704 }
705 };
706
707
709 void TransformCreepShapesToNodes(std::vector<CREEP_SHAPE*>& aShapes);
711
712 // Add a node to the graph. If an equivalent node exists, returns the pointer of the existing node instead
713 std::shared_ptr<GRAPH_NODE> AddNode( GRAPH_NODE::TYPE aType, CREEP_SHAPE* aParent = nullptr,
714 VECTOR2I aPos = VECTOR2I() );
715
716 std::shared_ptr<GRAPH_NODE> AddNodeVirtual();
717
718 std::shared_ptr<GRAPH_CONNECTION> AddConnection( std::shared_ptr<GRAPH_NODE>& aN1,
719 std::shared_ptr<GRAPH_NODE>& aN2,
720 const PATH_CONNECTION& aPc );
721
722 std::shared_ptr<GRAPH_CONNECTION> AddConnection( std::shared_ptr<GRAPH_NODE>& aN1,
723 std::shared_ptr<GRAPH_NODE>& aN2 );
724
725 std::shared_ptr<GRAPH_NODE> FindNode( GRAPH_NODE::TYPE aType, CREEP_SHAPE* aParent,
726 VECTOR2I aPos );
727
728 void RemoveConnection( std::shared_ptr<GRAPH_CONNECTION>, bool aDelete = false );
729
730 void Trim( double aWeightLimit );
731
732 void Addshape( const SHAPE& aShape, std::shared_ptr<GRAPH_NODE>& aConnectTo,
733 BOARD_ITEM* aParent = nullptr );
734
735 double Solve( std::shared_ptr<GRAPH_NODE>& aFrom, std::shared_ptr<GRAPH_NODE>& aTo,
736 std::vector<std::shared_ptr<GRAPH_CONNECTION>>& aResult );
737
738 void GeneratePaths( double aMaxWeight, PCB_LAYER_ID aLayer, bool aClearance );
739
740 std::shared_ptr<GRAPH_NODE> AddNetElements( int aNetCode, PCB_LAYER_ID aLayer,
741 int aMaxCreepage );
742
743 void SetTarget( double aTarget );
744 double GetTarget() { return m_creepageTarget; };
745
746
748 {
749 std::size_t operator()(const std::shared_ptr<GRAPH_NODE>& node) const
750 {
751 return hash_val(node->m_type, node->m_parent, node->m_pos.x, node->m_pos.y);
752 }
753 };
754
756 {
757 bool operator()(const std::shared_ptr<GRAPH_NODE>& lhs, const std::shared_ptr<GRAPH_NODE>& rhs) const
758 {
759 return lhs->m_type == rhs->m_type && lhs->m_parent == rhs->m_parent && lhs->m_pos == rhs->m_pos;
760 }
761 };
762
764 std::vector<BOARD_ITEM*> m_boardEdge;
766 std::vector<std::shared_ptr<GRAPH_NODE>> m_nodes;
767 std::vector<std::shared_ptr<GRAPH_CONNECTION>> m_connections;
768 std::vector<CREEP_SHAPE*> m_shapeCollection;
769
770 // This is a duplicate of m_nodes, but it is used to quickly find a node rather than iterating through m_nodes
771 std::unordered_set<std::shared_ptr<GRAPH_NODE>, GraphNodeHash, GraphNodeEqual> m_nodeset;
772
774
775private:
778};
779
780
781#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:295
const TRACKS & Tracks() const
Definition: board.h:334
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)
void RemoveConnection(std::shared_ptr< GRAPH_CONNECTION >, bool aDelete=false)
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 > AddNode(GRAPH_NODE::TYPE aType, CREEP_SHAPE *aParent=nullptr, VECTOR2I aPos=VECTOR2I())
std::shared_ptr< GRAPH_NODE > AddNodeVirtual()
void TransformCreepShapesToNodes(std::vector< CREEP_SHAPE * > &aShapes)
void Trim(double aWeightLimit)
SHAPE_POLY_SET * m_boardOutline
std::shared_ptr< GRAPH_NODE > FindNode(GRAPH_NODE::TYPE aType, CREEP_SHAPE *aParent, VECTOR2I aPos)
void GeneratePaths(double aMaxWeight, PCB_LAYER_ID aLayer, bool aClearance)
std::vector< BOARD_ITEM * > m_boardEdge
double m_creepageTargetSquared
std::unordered_set< std::shared_ptr< GRAPH_NODE >, GraphNodeHash, GraphNodeEqual > m_nodeset
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)
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
Definition: seg.h:42
bool Intersects(const SEG &aSeg) const
Definition: seg.cpp:248
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:407
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)
Test if a path is valid.
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695