KiCad PCB EDA Suite
Loading...
Searching...
No Matches
teardrop.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2021 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include "teardrop/teardrop.h"
26
27#include <confirm.h>
28
30#include <pcb_track.h>
31#include <pad.h>
32#include <zone_filler.h>
33#include <board_commit.h>
34
36#include <drc/drc_rtree.h>
39#include <bezier_curves.h>
40
41#include <wx/log.h>
42
43// The first priority level of a teardrop area (arbitrary value)
44#define MAGIC_TEARDROP_ZONE_ID 30000
45
46
48 m_board( aBoard ),
49 m_toolManager( aToolManager )
50{
51 m_prmsList = m_board->GetDesignSettings().GetTeadropParamsList();
52 m_tolerance = 0;
53}
54
55
57 std::vector<VECTOR2I>& aPoints, PCB_TRACK* aTrack,
58 BOARD_ITEM* aCandidate ) const
59{
60 ZONE* teardrop = new ZONE( m_board );
61
62 // Create a deterministic UUID from the track and candidate UUIDs so that teardrops
63 // maintain stable ordering in the output file across save/load cycles.
64 teardrop->SetUuidDirect( KIID::Combine( aTrack->m_Uuid, aCandidate->m_Uuid ) );
65
66 // teardrop settings are the last zone settings used by a zone dialog.
67 // override them by default.
69
70 // Add zone properties (priority will be fixed later)
71 teardrop->SetTeardropAreaType( aTeardropVariant == TD_TYPE_PADVIA ? TEARDROP_TYPE::TD_VIAPAD
73 teardrop->SetLayer( aTrack->GetLayer() );
74 teardrop->SetNetCode( aTrack->GetNetCode() );
75 teardrop->SetLocalClearance( 0 );
76 teardrop->SetMinThickness( pcbIUScale.mmToIU( 0.0254 ) ); // The minimum zone thickness
78 teardrop->SetIsFilled( false );
81
82 SHAPE_POLY_SET* outline = teardrop->Outline();
83 outline->NewOutline();
84
85 for( const VECTOR2I& pt: aPoints )
86 outline->Append( pt.x, pt.y );
87
88 // Until we know better (ie: pay for a potentially very expensive zone refill), the teardrop
89 // fill is the same as its outline.
90 teardrop->SetFilledPolysList( aTrack->GetLayer(), *teardrop->Outline() );
91 teardrop->SetIsFilled( true );
92
93 // Used in priority calculations:
94 teardrop->CalculateFilledArea();
95
96 return teardrop;
97}
98
99
101 std::vector<VECTOR2I>& aPoints, PCB_TRACK* aTrack,
102 BOARD_ITEM* aCandidate ) const
103{
104 ZONE* teardrop = new ZONE( m_board );
105
106 // Create a deterministic UUID from the track and candidate UUIDs, then increment it
107 // to differentiate from the copper teardrop zone.
108 KIID maskUuid = KIID::Combine( aTrack->m_Uuid, aCandidate->m_Uuid );
109 maskUuid.Increment();
110 teardrop->SetUuidDirect( maskUuid );
111
112 teardrop->SetTeardropAreaType( aTeardropVariant == TD_TYPE_PADVIA ? TEARDROP_TYPE::TD_VIAPAD
114 teardrop->SetLayer( aTrack->GetLayer() == F_Cu ? F_Mask : B_Mask );
115 teardrop->SetMinThickness( pcbIUScale.mmToIU( 0.0254 ) ); // The minimum zone thickness
116 teardrop->SetIsFilled( false );
119
120 SHAPE_POLY_SET* outline = teardrop->Outline();
121 outline->NewOutline();
122
123 for( const VECTOR2I& pt: aPoints )
124 outline->Append( pt.x, pt.y );
125
126 if( int expansion = aTrack->GetSolderMaskExpansion() )
127 {
128 // The zone-min-thickness deflate/reinflate is going to round corners, so it's more
129 // efficient to allow acute corners on the solder mask expansion here, and delegate the
130 // rounding to the deflate/reinflate.
131 teardrop->SetMinThickness( std::max( teardrop->GetMinThickness(), expansion ) );
132
134 m_board->GetDesignSettings().m_MaxError );
135 }
136
137 // Until we know better (ie: pay for a potentially very expensive zone refill), the teardrop
138 // fill is the same as its outline.
139 teardrop->SetFilledPolysList( teardrop->GetLayer(), *teardrop->Outline() );
140 teardrop->SetIsFilled( true );
141
142 return teardrop;
143}
144
145
147 TEARDROP_VARIANT aTeardropVariant,
148 std::vector<VECTOR2I>& aPoints,
149 PCB_TRACK* aTrack, BOARD_ITEM* aCandidate )
150{
151 ZONE* new_teardrop = createTeardrop( aTeardropVariant, aPoints, aTrack, aCandidate );
152 m_board->Add( new_teardrop, ADD_MODE::BULK_INSERT );
153 m_createdTdList.push_back( new_teardrop );
154
155 aCommit.Added( new_teardrop );
156
157 if( aTrack->HasSolderMask() && IsExternalCopperLayer( aTrack->GetLayer() ) )
158 {
159 ZONE* new_teardrop_mask = createTeardropMask( aTeardropVariant, aPoints, aTrack, aCandidate );
160 m_board->Add( new_teardrop_mask, ADD_MODE::BULK_INSERT );
161 aCommit.Added( new_teardrop_mask );
162 }
163}
164
165
167 const TEARDROP_PARAMETERS& aParams,
168 TEARDROP_MANAGER::TEARDROP_VARIANT aTeardropVariant,
169 PCB_TRACK* aTrack, BOARD_ITEM* aCandidate,
170 const VECTOR2I& aPos )
171{
172 std::vector<VECTOR2I> points;
173
174 if( computeTeardropPolygon( aParams, points, aTrack, aCandidate, aPos ) )
175 {
176 createAndAddTeardropWithMask( aCommit, aTeardropVariant, points, aTrack, aCandidate );
177 return true;
178 }
179
180 return false;
181}
182
183
185 const std::vector<BOARD_ITEM*>* dirtyPadsAndVias,
186 const std::set<PCB_TRACK*>* dirtyTracks )
187{
188 std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_board->GetConnectivity();
189
190 auto isStale =
191 [&]( ZONE* zone )
192 {
193 std::vector<PAD*> connectedPads;
194 std::vector<PCB_VIA*> connectedVias;
195
196 connectivity->GetConnectedPadsAndVias( zone, &connectedPads, &connectedVias );
197
198 for( PAD* pad : connectedPads )
199 {
200 if( alg::contains( *dirtyPadsAndVias, pad ) )
201 return true;
202 }
203
204 for( PCB_VIA* via : connectedVias )
205 {
206 if( alg::contains( *dirtyPadsAndVias, via ) )
207 return true;
208 }
209
210 for( PCB_TRACK* track : connectivity->GetConnectedTracks( zone ) )
211 {
212 if( alg::contains( *dirtyTracks, track ) )
213 return true;
214 }
215
216 return false;
217 };
218
219 for( ZONE* zone : m_board->Zones() )
220 {
221 if( zone->IsTeardropArea() && isStale( zone ) )
222 zone->SetFlags( STRUCT_DELETED );
223 }
224
225 m_board->BulkRemoveStaleTeardrops( aCommit );
226}
227
228
230 const std::vector<BOARD_ITEM*>* dirtyPadsAndVias,
231 const std::set<PCB_TRACK*>* dirtyTracks,
232 bool aForceFullUpdate )
233{
234 if( m_board->LegacyTeardrops() )
235 return;
236
237 // Init parameters:
238 m_tolerance = pcbIUScale.mmToIU( 0.01 );
239
241
242 // Old teardrops must be removed, to ensure a clean teardrop rebuild
243 if( aForceFullUpdate )
244 {
245 for( ZONE* zone : m_board->Zones() )
246 {
247 if( zone->IsTeardropArea() )
248 zone->SetFlags( STRUCT_DELETED );
249 }
250
251 m_board->BulkRemoveStaleTeardrops( aCommit );
252 }
253
254 std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_board->GetConnectivity();
255
256 for( PCB_TRACK* track : m_board->Tracks() )
257 {
258 if( ! ( track->Type() == PCB_TRACE_T || track->Type() == PCB_ARC_T ) )
259 continue;
260
261 std::vector<PAD*> connectedPads;
262 std::vector<PCB_VIA*> connectedVias;
263
264 connectivity->GetConnectedPadsAndVias( track, &connectedPads, &connectedVias );
265
266 bool forceUpdate = aForceFullUpdate || dirtyTracks->contains( track );
267
268 for( PAD* pad : connectedPads )
269 {
270 if( !forceUpdate && !alg::contains( *dirtyPadsAndVias, pad ) )
271 continue;
272
273 TEARDROP_PARAMETERS& tdParams = pad->GetTeardropParams();
274 VECTOR2I padSize = pad->GetSize( track->GetLayer() );
275 int annularWidth = std::min( padSize.x, padSize.y );
276
277 if( !tdParams.m_Enabled )
278 continue;
279
280 // Ensure a teardrop shape can be built: track width must be < teardrop width and
281 // filter width
282 if( track->GetWidth() >= tdParams.m_TdMaxWidth
283 || track->GetWidth() >= annularWidth * tdParams.m_BestWidthRatio
284 || track->GetWidth() >= annularWidth * tdParams.m_WidthtoSizeFilterRatio )
285 {
286 continue;
287 }
288
289 bool startHitsPad = pad->HitTest( track->GetStart(), 0, track->GetLayer() );
290 bool endHitsPad = pad->HitTest( track->GetEnd(), 0, track->GetLayer() );
291
292 // The track is entirely inside the pad; cannot create a teardrop
293 if( startHitsPad && endHitsPad )
294 continue;
295
296 // Only count segments that substantively emerge from the pad copper. A track
297 // whose centerline grazes the pad edge exits by less than its own width; such a
298 // segment is effectively covered and using it mis-orients the teardrop axis
299 // along the tangent instead of the track's real entry direction.
300 if( startHitsPad != endHitsPad
301 && computeEmergingTrackLength( track, pad, track->GetLayer() ) < track->GetWidth() )
302 {
303 continue;
304 }
305
306 // Skip case where pad and the track are within a copper zone with the same net
307 // (and the pad can be connected to the zone)
308 if( !tdParams.m_TdOnPadsInZones && areItemsInSameZone( pad, track ) )
309 continue;
310
311 tryCreateTrackTeardrop( aCommit, tdParams, TEARDROP_MANAGER::TD_TYPE_PADVIA, track, pad, pad->GetPosition() );
312
313 // A track can be connected to pad when just crossing it. So we can create 2 teardrops,
314 // one from pad to track start point and the other to track end point.
315 // However this is acceptable only if the pad position is inside the track.
316 // Otherwise the 2 teardrop shapes can be strange (and of course incorrect
317 if( !startHitsPad && !endHitsPad && track->HitTest( pad->GetPosition() ) )
318 {
319 PCB_TRACK reversed( *track );
320 reversed.SetStart( track->GetEnd() );
321 reversed.SetEnd( pad->GetPosition() );
322 tryCreateTrackTeardrop( aCommit, tdParams, TEARDROP_MANAGER::TD_TYPE_PADVIA, &reversed, pad, pad->GetPosition() );
323 reversed.SetStart( track->GetStart() );
324 tryCreateTrackTeardrop( aCommit, tdParams, TEARDROP_MANAGER::TD_TYPE_PADVIA, &reversed, pad, pad->GetPosition() );
325 }
326 }
327
328 for( PCB_VIA* via : connectedVias )
329 {
330 if( !forceUpdate && !alg::contains( *dirtyPadsAndVias, via ) )
331 continue;
332
333 TEARDROP_PARAMETERS tdParams = via->GetTeardropParams();
334 int annularWidth = via->GetWidth( track->GetLayer() );
335
336 if( !tdParams.m_Enabled )
337 continue;
338
339 // Ensure a teardrop shape can be built: track width must be < teardrop width and
340 // filter width
341 if( track->GetWidth() >= tdParams.m_TdMaxWidth
342 || track->GetWidth() >= annularWidth * tdParams.m_BestWidthRatio
343 || track->GetWidth() >= annularWidth * tdParams.m_WidthtoSizeFilterRatio )
344 {
345 continue;
346 }
347
348 bool startHitsVia = via->HitTest( track->GetStart() );
349 bool endHitsVia = via->HitTest( track->GetEnd() );
350
351 // The track is entirely inside the via; cannot create a teardrop
352 if( startHitsVia && endHitsVia )
353 continue;
354
355 // Only count segments that substantively emerge from the via copper. A track
356 // that grazes the via edge tangentially emerges by less than its own width and
357 // should not anchor a teardrop: its direction misrepresents the real track entry.
358 if( startHitsVia != endHitsVia
359 && computeEmergingTrackLength( track, via, track->GetLayer() ) < track->GetWidth() )
360 {
361 continue;
362 }
363
365 via->GetPosition() );
366
367 // A track can be connected to via when just crossing it. So we can create 2 teardrops,
368 // one from via to track start point and the other to track end point.
369 // However this is acceptable only if the via position is inside the track.
370 // Otherwise the 2 teardrop shapes can be strange (and of course incorrect
371 if( !startHitsVia && !endHitsVia && track->HitTest( via->GetPosition() ) )
372 {
373 PCB_TRACK reversed( *track );
374 reversed.SetStart( track->GetEnd() );
375 reversed.SetEnd( via->GetPosition() );
376 tryCreateTrackTeardrop( aCommit, tdParams, TEARDROP_MANAGER::TD_TYPE_PADVIA, &reversed, via, via->GetPosition() );
377 reversed.SetStart( track->GetStart() );
378 tryCreateTrackTeardrop( aCommit, tdParams, TEARDROP_MANAGER::TD_TYPE_PADVIA, &reversed, via, via->GetPosition() );
379 }
380 }
381 }
382
383 if( ( aForceFullUpdate || !dirtyTracks->empty() )
384 && m_prmsList->GetParameters( TARGET_TRACK )->m_Enabled )
385 {
386 AddTeardropsOnTracks( aCommit, dirtyTracks, aForceFullUpdate );
387 }
388
389 // Now set priority of teardrops now all teardrops are added
391}
392
393
395{
396 for( ZONE* zone : m_board->Zones() )
397 {
398 if( zone->IsTeardropArea() && zone->GetTeardropAreaType() == TEARDROP_TYPE::TD_TRACKEND )
399 zone->SetFlags( STRUCT_DELETED );
400 }
401
402 m_board->BulkRemoveStaleTeardrops( aCommit );
403}
404
405
407{
408 // Note: a teardrop area is on only one layer, so using GetFirstLayer() is OK
409 // to know the zone layer of a teardrop
410
411 int priority_base = MAGIC_TEARDROP_ZONE_ID;
412
413 // The sort function to sort by increasing copper layers. Group by layers.
414 // For same layers sort by decreasing areas
415 struct
416 {
417 bool operator()(ZONE* a, ZONE* b) const
418 {
419 if( a->GetFirstLayer() == b->GetFirstLayer() )
420 {
421 if( a->GetOutlineArea() != b->GetOutlineArea() )
422 return a->GetOutlineArea() > b->GetOutlineArea();
423 return a->m_Uuid < b->m_Uuid; // stable tiebreak
424 }
425 return a->GetFirstLayer() < b->GetFirstLayer();
426
427 }
428 } compareLess;
429
430 for( ZONE* td: m_createdTdList )
431 td->CalculateOutlineArea();
432
433 std::sort( m_createdTdList.begin(), m_createdTdList.end(), compareLess );
434
435 int curr_layer = -1;
436
437 for( ZONE* td: m_createdTdList )
438 {
439 if( td->GetFirstLayer() != curr_layer )
440 {
441 curr_layer = td->GetFirstLayer();
442 priority_base = MAGIC_TEARDROP_ZONE_ID;
443 }
444
445 td->SetAssignedPriority( priority_base++ );
446 }
447}
448
449
451 const std::set<PCB_TRACK*>* aTracks,
452 bool aForceFullUpdate )
453{
454 std::shared_ptr<CONNECTIVITY_DATA> connectivity = m_board->GetConnectivity();
455 TEARDROP_PARAMETERS params = *m_prmsList->GetParameters( TARGET_TRACK );
456
457 // Explore groups (a group is a set of tracks on the same layer and the same net):
458 for( auto& grp : m_trackLookupList.GetBuffer() )
459 {
460 int layer, netcode;
461 TRACK_BUFFER::GetNetcodeAndLayerFromIndex( grp.first, &layer, &netcode );
462
463 std::vector<PCB_TRACK*>* sublist = grp.second;
464
465 if( sublist->size() <= 1 ) // We need at least 2 track segments
466 continue;
467
468 // The sort function to sort by increasing track widths
469 struct
470 {
471 bool operator()(PCB_TRACK* a, PCB_TRACK* b) const
472 { return a->GetWidth() < b->GetWidth(); }
473 } compareLess;
474
475 std::sort( sublist->begin(), sublist->end(), compareLess );
476 int min_width = sublist->front()->GetWidth();
477 int max_width = sublist->back()->GetWidth();
478
479 // Skip groups having the same track thickness
480 if( max_width == min_width )
481 continue;
482
483 for( unsigned ii = 0; ii < sublist->size()-1; ii++ )
484 {
485 PCB_TRACK* track = (*sublist)[ii];
486 int track_len = (int) track->GetLength();
487 bool track_needs_update = aForceFullUpdate || alg::contains( *aTracks, track );
488 min_width = track->GetWidth();
489
490 // to avoid creating a teardrop between 2 tracks having similar widths give a threshold
491 params.m_WidthtoSizeFilterRatio = std::max( params.m_WidthtoSizeFilterRatio, 0.1 );
492 const double th = 1.0 / params.m_WidthtoSizeFilterRatio;
493 min_width = KiROUND( min_width * th );
494
495 for( unsigned jj = ii+1; jj < sublist->size(); jj++ )
496 {
497 // Search candidates with thickness > curr thickness
498 PCB_TRACK* candidate = (*sublist)[jj];
499
500 if( min_width >= candidate->GetWidth() )
501 continue;
502
503 // Cannot build a teardrop on a too short track segment.
504 // The min len is > candidate radius
505 if( track_len <= candidate->GetWidth() /2 )
506 continue;
507
508 // Now test end to end connection:
509 EDA_ITEM_FLAGS match_points; // to return the end point EDA_ITEM_FLAGS:
510 // 0, STARTPOINT, ENDPOINT
511
512 VECTOR2I pos = candidate->GetStart();
513 match_points = track->IsPointOnEnds( pos, m_tolerance );
514
515 if( !match_points )
516 {
517 pos = candidate->GetEnd();
518 match_points = track->IsPointOnEnds( pos, m_tolerance );
519 }
520
521 if( !match_points )
522 continue;
523
524 if( !track_needs_update && alg::contains( *aTracks, candidate ) )
525 continue;
526
527 // Pads/vias have priority for teardrops; ensure there isn't one at our position
528 bool existingPadOrVia = false;
529 std::vector<PAD*> connectedPads;
530 std::vector<PCB_VIA*> connectedVias;
531
532 connectivity->GetConnectedPadsAndVias( track, &connectedPads, &connectedVias );
533
534 for( PAD* pad : connectedPads )
535 {
536 if( pad->HitTest( pos ) )
537 existingPadOrVia = true;
538 }
539
540 for( PCB_VIA* via : connectedVias )
541 {
542 if( via->HitTest( pos ) )
543 existingPadOrVia = true;
544 }
545
546 if( existingPadOrVia )
547 continue;
548
549 tryCreateTrackTeardrop( aCommit, params, TEARDROP_MANAGER::TD_TYPE_TRACKEND, track, candidate, pos );
550 }
551 }
552 }
553}
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:125
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:990
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
void SetUuidDirect(const KIID &aUuid)
Raw UUID assignment.
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:323
COMMIT & Added(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Notify observers that aItem has been added.
Definition commit.h:84
const KIID m_Uuid
Definition eda_item.h:528
Definition kiid.h:48
static KIID Combine(const KIID &aFirst, const KIID &aSecond)
Creates a deterministic KIID from two input KIIDs by XORing their underlying UUIDs.
Definition kiid.cpp:286
void Increment()
Generates a deterministic replacement for a given ID.
Definition kiid.cpp:271
Definition pad.h:55
int GetSolderMaskExpansion() const
virtual double GetLength() const
Get the length of the track using the hypotenuse calculation.
void SetEnd(const VECTOR2I &aEnd)
Definition pcb_track.h:93
bool HasSolderMask() const
Definition pcb_track.h:121
void SetStart(const VECTOR2I &aStart)
Definition pcb_track.h:96
const VECTOR2I & GetStart() const
Definition pcb_track.h:97
const VECTOR2I & GetEnd() const
Definition pcb_track.h:94
EDA_ITEM_FLAGS IsPointOnEnds(const VECTOR2I &point, int min_dist=0) const
Return STARTPOINT if point if near (dist = min_dist) start point, ENDPOINT if point if near (dist = m...
virtual int GetWidth() const
Definition pcb_track.h:91
Represent a set of closed polygons.
void Inflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, bool aSimplify=false)
Perform outline inflation/deflation.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
int NewOutline()
Creates a new empty polygon in the set and returns its index.
BOARD * m_board
Definition teardrop.h:279
ZONE * createTeardropMask(TEARDROP_VARIANT aTeardropVariant, std::vector< VECTOR2I > &aPoints, PCB_TRACK *aTrack, BOARD_ITEM *aCandidate) const
Definition teardrop.cpp:100
static int GetWidth(BOARD_ITEM *aItem, PCB_LAYER_ID aLayer)
bool computeTeardropPolygon(const TEARDROP_PARAMETERS &aParams, std::vector< VECTOR2I > &aCorners, PCB_TRACK *aTrack, BOARD_ITEM *aOther, const VECTOR2I &aOtherPos) const
Compute all teardrop points of the polygon shape.
TEARDROP_MANAGER(BOARD *aBoard, TOOL_MANAGER *aToolManager)
Definition teardrop.cpp:47
void createAndAddTeardropWithMask(BOARD_COMMIT &aCommit, TEARDROP_VARIANT aTeardropVariant, std::vector< VECTOR2I > &aPoints, PCB_TRACK *aTrack, BOARD_ITEM *aCandidate)
Creates and adds a teardrop with optional mask to the board.
Definition teardrop.cpp:146
void UpdateTeardrops(BOARD_COMMIT &aCommit, const std::vector< BOARD_ITEM * > *dirtyPadsAndVias, const std::set< PCB_TRACK * > *dirtyTracks, bool aForceFullUpdate=false)
Update teardrops on a list of items.
Definition teardrop.cpp:229
void setTeardropPriorities()
Set priority of created teardrops.
Definition teardrop.cpp:406
void AddTeardropsOnTracks(BOARD_COMMIT &aCommit, const std::set< PCB_TRACK * > *aTracks, bool aForceFullUpdate=false)
Add teardrop on tracks of different sizes connected by their end.
Definition teardrop.cpp:450
bool tryCreateTrackTeardrop(BOARD_COMMIT &aCommit, const TEARDROP_PARAMETERS &aParams, TEARDROP_VARIANT aTeardropVariant, PCB_TRACK *aTrack, BOARD_ITEM *aCandidate, const VECTOR2I &aPos)
Attempts to create a track-to-track teardrop.
Definition teardrop.cpp:166
TRACK_BUFFER m_trackLookupList
Definition teardrop.h:284
TEARDROP_PARAMETERS_LIST * m_prmsList
Definition teardrop.h:281
std::vector< ZONE * > m_createdTdList
Definition teardrop.h:285
void DeleteTrackToTrackTeardrops(BOARD_COMMIT &aCommit)
Definition teardrop.cpp:394
bool areItemsInSameZone(BOARD_ITEM *aPadOrVia, PCB_TRACK *aTrack) const
friend class TEARDROP_PARAMETERS
Definition teardrop.h:95
void RemoveTeardrops(BOARD_COMMIT &aCommit, const std::vector< BOARD_ITEM * > *dirtyPadsAndVias, const std::set< PCB_TRACK * > *dirtyTracks)
Remove teardrops connected to any dirty pads, vias or tracks.
Definition teardrop.cpp:184
TOOL_MANAGER * m_toolManager
Definition teardrop.h:280
int computeEmergingTrackLength(PCB_TRACK *aTrack, BOARD_ITEM *aOther, PCB_LAYER_ID aLayer) const
Return the length of the portion of aTrack that lies outside aOther's copper shape on aLayer.
ZONE * createTeardrop(TEARDROP_VARIANT aTeardropVariant, std::vector< VECTOR2I > &aPoints, PCB_TRACK *aTrack, BOARD_ITEM *aCandidate) const
Creates a teardrop (a ZONE item) from its polygonal shape, track netcode and layer.
Definition teardrop.cpp:56
double m_BestWidthRatio
The height of a teardrop as ratio between height and size of pad/via.
int m_TdMaxWidth
max allowed height for teardrops in IU. <= 0 to disable
double m_WidthtoSizeFilterRatio
The ratio (H/D) between the via/pad size and the track width max value to create a teardrop 1....
bool m_TdOnPadsInZones
A filter to exclude pads inside zone fills.
bool m_Enabled
Flag to enable teardrops.
Master controller class:
static void GetNetcodeAndLayerFromIndex(int aIdx, int *aLayer, int *aNetcode)
Definition teardrop.h:61
void ExportSetting(ZONE &aTarget, bool aFullExport=true) const
Function ExportSetting copy settings to a given zone.
static const ZONE_SETTINGS & GetDefaultSettings()
Handle a list of polygons defining a copper zone.
Definition zone.h:74
double GetOutlineArea()
This area is cached from the most recent call to CalculateOutlineArea().
Definition zone.h:276
void SetLocalClearance(std::optional< int > aClearance)
Definition zone.h:187
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aBorderHatchStyle, int aBorderHatchPitch, bool aRebuilBorderdHatch)
Set all hatch parameters for the zone.
Definition zone.cpp:1280
void SetMinThickness(int aMinThickness)
Definition zone.h:303
virtual PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition zone.cpp:501
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
Definition zone.cpp:550
SHAPE_POLY_SET * Outline()
Definition zone.h:336
void SetFilledPolysList(PCB_LAYER_ID aLayer, const SHAPE_POLY_SET &aPolysList)
Set the list of filled polygons.
Definition zone.h:631
int GetMinThickness() const
Definition zone.h:302
void SetIsFilled(bool isFilled)
Definition zone.h:294
double CalculateFilledArea()
Compute the area currently occupied by the zone fill.
Definition zone.cpp:1599
void SetPadConnection(ZONE_CONNECTION aPadConnection)
Definition zone.h:300
void SetTeardropAreaType(TEARDROP_TYPE aType)
Set the type of teardrop if the zone is a teardrop area for non teardrop area, the type must be TEARD...
Definition zone.h:697
void SetIslandRemovalMode(ISLAND_REMOVAL_MODE aRemove)
Definition zone.h:739
PCB_LAYER_ID GetFirstLayer() const
Definition zone.cpp:523
This file is part of the common library.
@ ALLOW_ACUTE_CORNERS
just inflate the polygon. Acute angles create spikes
#define STRUCT_DELETED
flag indication structures to be erased
std::uint32_t EDA_ITEM_FLAGS
bool IsExternalCopperLayer(int aLayerId)
Test whether a layer is an external (F_Cu or B_Cu) copper layer.
Definition layer_ids.h:690
@ B_Mask
Definition layer_ids.h:98
@ F_Mask
Definition layer_ids.h:97
@ F_Cu
Definition layer_ids.h:64
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition kicad_algo.h:100
#define MAGIC_TEARDROP_ZONE_ID
Definition teardrop.cpp:44
@ TARGET_TRACK
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition typeinfo.h:95
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition typeinfo.h:93
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:687
@ FULL
pads are covered by copper
Definition zones.h:51