mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-04-21 00:21:25 +00:00
Pcbnew: Enhanced algorithm to calculate board connections:
* A track is seen connected to a pad if the track end is inside the pad shape. * Pads inside pads are now seen connected, if the center of the pad is *inside* the other pad. * this is made to be sure a large copper area is shared by the 2 pads, and to keep algorithm fast.
This commit is contained in:
parent
ccb910eb62
commit
d41b81fc3b
@ -4,6 +4,19 @@ KiCad ChangeLog 2011
|
||||
Please add newer entries at the top, list the date and your name with
|
||||
email address.
|
||||
|
||||
2011-Dec-19, UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
|
||||
================================================================================
|
||||
Pcbnew:
|
||||
Enhanced algorithms to calculate board connections:
|
||||
- A track is seen connected to a pad if the track end is inside the pad shape.
|
||||
- Pads inside pads are now seen connected, if the center of the pad is
|
||||
*inside* the other pad.
|
||||
(this is made to be sure a large copper area is shared by the 2 pads,
|
||||
and to keep algorithm fast).
|
||||
Algorithm to calculate pads connections is still very fast.
|
||||
However some other functions (drag pads, track len calculation ...)
|
||||
still need the track end exactly on the pad position.
|
||||
|
||||
|
||||
2011-Dec-13 UPDATE Dick Hollenbeck <dick@softplc.com>
|
||||
================================================================================
|
||||
|
16
demos/test_pads_inside_pads/test_pads_inside_pads-cache.lib
Normal file
16
demos/test_pads_inside_pads/test_pads_inside_pads-cache.lib
Normal file
@ -0,0 +1,16 @@
|
||||
EESchema-LIBRARY Version 2.3 Date: 19/12/2011 12:55:30
|
||||
#encoding utf-8
|
||||
#
|
||||
# CONN_1
|
||||
#
|
||||
DEF ~CONN_1 P 0 30 N N 1 F N
|
||||
F0 "P" 80 0 40 H V L CNN
|
||||
F1 "CONN_1" 0 55 30 H I C CNN
|
||||
DRAW
|
||||
C 0 0 31 0 1 0 N
|
||||
P 2 0 1 0 -30 0 -50 0 N
|
||||
X 1 1 -150 0 100 R 60 60 1 1 P
|
||||
ENDDRAW
|
||||
ENDDEF
|
||||
#
|
||||
#End Library
|
LOADING design file
31
demos/test_pads_inside_pads/test_pads_inside_pads.cmp
Normal file
31
demos/test_pads_inside_pads/test_pads_inside_pads.cmp
Normal file
@ -0,0 +1,31 @@
|
||||
Cmp-Mod V01 Created by CvPcb (2011-12-09 BZR 3290)-testing date = 11/12/2011 20:34:04
|
||||
|
||||
BeginCmp
|
||||
TimeStamp = /4EDF7CC5;
|
||||
Reference = P1;
|
||||
ValeurCmp = CONN_1;
|
||||
IdModule = 1pin;
|
||||
EndCmp
|
||||
|
||||
BeginCmp
|
||||
TimeStamp = /4EDF7CC0;
|
||||
Reference = P2;
|
||||
ValeurCmp = CONN_1;
|
||||
IdModule = 1pin;
|
||||
EndCmp
|
||||
|
||||
BeginCmp
|
||||
TimeStamp = /4EE5056C;
|
||||
Reference = P3;
|
||||
ValeurCmp = CONN_1;
|
||||
IdModule = 1pin;
|
||||
EndCmp
|
||||
|
||||
BeginCmp
|
||||
TimeStamp = /4EE5056D;
|
||||
Reference = P4;
|
||||
ValeurCmp = CONN_1;
|
||||
IdModule = 1pin;
|
||||
EndCmp
|
||||
|
||||
EndListe
|
25
demos/test_pads_inside_pads/test_pads_inside_pads.net
Normal file
25
demos/test_pads_inside_pads/test_pads_inside_pads.net
Normal file
@ -0,0 +1,25 @@
|
||||
# EESchema Netlist Version 1.1 created 19/12/2011 12:55:28
|
||||
(
|
||||
( /4EE5056D $noname P4 CONN_1 {Lib=CONN_1}
|
||||
( 1 /NET1 )
|
||||
)
|
||||
( /4EE5056C $noname P3 CONN_1 {Lib=CONN_1}
|
||||
( 1 /NET1 )
|
||||
)
|
||||
( /4EDF7CC5 $noname P1 CONN_1 {Lib=CONN_1}
|
||||
( 1 /NET2 )
|
||||
)
|
||||
( /4EDF7CC0 $noname P2 CONN_1 {Lib=CONN_1}
|
||||
( 1 /NET2 )
|
||||
)
|
||||
)
|
||||
*
|
||||
{ Pin List by Nets
|
||||
Net 1 "/NET1" "NET1"
|
||||
P4 1
|
||||
P3 1
|
||||
Net 2 "/NET2" "NET2"
|
||||
P1 1
|
||||
P2 1
|
||||
}
|
||||
#End
|
108
demos/test_pads_inside_pads/test_pads_inside_pads.pro
Normal file
108
demos/test_pads_inside_pads/test_pads_inside_pads.pro
Normal file
@ -0,0 +1,108 @@
|
||||
update=13/12/2011 11:04:14
|
||||
version=1
|
||||
last_client=pcbnew
|
||||
[cvpcb]
|
||||
version=1
|
||||
NetITyp=0
|
||||
NetIExt=.net
|
||||
PkgIExt=.pkg
|
||||
NetDir=
|
||||
LibDir=
|
||||
NetType=0
|
||||
[cvpcb/libraries]
|
||||
EquName1=devcms
|
||||
[eeschema]
|
||||
version=1
|
||||
LibDir=
|
||||
NetFmt=1
|
||||
HPGLSpd=20
|
||||
HPGLDm=15
|
||||
HPGLNum=1
|
||||
offX_A4=0
|
||||
offY_A4=0
|
||||
offX_A3=0
|
||||
offY_A3=0
|
||||
offX_A2=0
|
||||
offY_A2=0
|
||||
offX_A1=0
|
||||
offY_A1=0
|
||||
offX_A0=0
|
||||
offY_A0=0
|
||||
offX_A=0
|
||||
offY_A=0
|
||||
offX_B=0
|
||||
offY_B=0
|
||||
offX_C=0
|
||||
offY_C=0
|
||||
offX_D=0
|
||||
offY_D=0
|
||||
offX_E=0
|
||||
offY_E=0
|
||||
RptD_X=0
|
||||
RptD_Y=100
|
||||
RptLab=1
|
||||
SimCmd=
|
||||
UseNetN=0
|
||||
LabSize=60
|
||||
[eeschema/libraries]
|
||||
LibName1=power
|
||||
LibName2=device
|
||||
LibName3=transistors
|
||||
LibName4=conn
|
||||
LibName5=linear
|
||||
LibName6=regul
|
||||
LibName7=74xx
|
||||
LibName8=cmos4000
|
||||
LibName9=adc-dac
|
||||
LibName10=memory
|
||||
LibName11=xilinx
|
||||
LibName12=special
|
||||
LibName13=microcontrollers
|
||||
LibName14=dsp
|
||||
LibName15=microchip
|
||||
LibName16=analog_switches
|
||||
LibName17=motorola
|
||||
LibName18=texas
|
||||
LibName19=intel
|
||||
LibName20=audio
|
||||
LibName21=interface
|
||||
LibName22=digital-audio
|
||||
LibName23=philips
|
||||
LibName24=display
|
||||
LibName25=cypress
|
||||
LibName26=siliconi
|
||||
LibName27=opto
|
||||
LibName28=atmel
|
||||
LibName29=contrib
|
||||
LibName30=valves
|
||||
[general]
|
||||
version=1
|
||||
[pcbnew]
|
||||
version=1
|
||||
PadDrlX=320
|
||||
PadDimH=600
|
||||
PadDimV=600
|
||||
BoardThickness=630
|
||||
TxtPcbV=800
|
||||
TxtPcbH=600
|
||||
TxtModV=600
|
||||
TxtModH=600
|
||||
TxtModW=120
|
||||
VEgarde=100
|
||||
DrawLar=150
|
||||
EdgeLar=150
|
||||
TxtLar=120
|
||||
MSegLar=150
|
||||
LastNetListRead=
|
||||
[pcbnew/libraries]
|
||||
LibDir=
|
||||
LibName1=sockets
|
||||
LibName2=connect
|
||||
LibName3=discret
|
||||
LibName4=pin_array
|
||||
LibName5=divers
|
||||
LibName6=libcms
|
||||
LibName7=display
|
||||
LibName8=valves
|
||||
LibName9=led
|
||||
LibName10=dip_sockets
|
90
demos/test_pads_inside_pads/test_pads_inside_pads.sch
Normal file
90
demos/test_pads_inside_pads/test_pads_inside_pads.sch
Normal file
@ -0,0 +1,90 @@
|
||||
EESchema Schematic File Version 2 date 19/12/2011 12:55:30
|
||||
LIBS:power
|
||||
LIBS:device
|
||||
LIBS:transistors
|
||||
LIBS:conn
|
||||
LIBS:linear
|
||||
LIBS:regul
|
||||
LIBS:74xx
|
||||
LIBS:cmos4000
|
||||
LIBS:adc-dac
|
||||
LIBS:memory
|
||||
LIBS:xilinx
|
||||
LIBS:special
|
||||
LIBS:microcontrollers
|
||||
LIBS:dsp
|
||||
LIBS:microchip
|
||||
LIBS:analog_switches
|
||||
LIBS:motorola
|
||||
LIBS:texas
|
||||
LIBS:intel
|
||||
LIBS:audio
|
||||
LIBS:interface
|
||||
LIBS:digital-audio
|
||||
LIBS:philips
|
||||
LIBS:display
|
||||
LIBS:cypress
|
||||
LIBS:siliconi
|
||||
LIBS:opto
|
||||
LIBS:atmel
|
||||
LIBS:contrib
|
||||
LIBS:valves
|
||||
EELAYER 25 0
|
||||
EELAYER END
|
||||
$Descr A4 11700 8267
|
||||
encoding utf-8
|
||||
Sheet 1 1
|
||||
Title ""
|
||||
Date "19 dec 2011"
|
||||
Rev ""
|
||||
Comp ""
|
||||
Comment1 ""
|
||||
Comment2 ""
|
||||
Comment3 ""
|
||||
Comment4 ""
|
||||
$EndDescr
|
||||
Wire Wire Line
|
||||
4150 1750 3750 1750
|
||||
Wire Wire Line
|
||||
4150 1450 3750 1450
|
||||
Text Label 3850 1450 0 60 ~ 0
|
||||
NET1
|
||||
$Comp
|
||||
L CONN_1 P4
|
||||
U 1 1 4EE5056D
|
||||
P 4300 1450
|
||||
F 0 "P4" H 4380 1450 40 0000 L CNN
|
||||
F 1 "CONN_1" H 4300 1505 30 0001 C CNN
|
||||
1 4300 1450
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L CONN_1 P3
|
||||
U 1 1 4EE5056C
|
||||
P 3600 1450
|
||||
F 0 "P3" H 3680 1450 40 0000 L CNN
|
||||
F 1 "CONN_1" H 3600 1505 30 0001 C CNN
|
||||
1 3600 1450
|
||||
-1 0 0 1
|
||||
$EndComp
|
||||
$Comp
|
||||
L CONN_1 P1
|
||||
U 1 1 4EDF7CC5
|
||||
P 3600 1750
|
||||
F 0 "P1" H 3680 1750 40 0000 L CNN
|
||||
F 1 "CONN_1" H 3600 1805 30 0001 C CNN
|
||||
1 3600 1750
|
||||
-1 0 0 1
|
||||
$EndComp
|
||||
$Comp
|
||||
L CONN_1 P2
|
||||
U 1 1 4EDF7CC0
|
||||
P 4300 1750
|
||||
F 0 "P2" H 4380 1750 40 0000 L CNN
|
||||
F 1 "CONN_1" H 4300 1805 30 0001 C CNN
|
||||
1 4300 1750
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Text Label 3850 1750 0 60 ~ 0
|
||||
NET2
|
||||
$EndSCHEMATC
|
@ -129,10 +129,9 @@ public:
|
||||
* Function BuildTracksCandidatesList
|
||||
* Fills m_Candidates with all connecting points (track ends or via location)
|
||||
* with tracks from aBegin to aEnd.
|
||||
* if aBegin == NULL, use first track in brd list
|
||||
* if aEnd == NULL, uses all tracks from aBegin in brd list
|
||||
* if aEnd == NULL, uses all tracks from aBegin
|
||||
*/
|
||||
void BuildTracksCandidatesList( TRACK * aBegin = NULL, TRACK * aEnd = NULL);
|
||||
void BuildTracksCandidatesList( TRACK * aBegin, TRACK * aEnd = NULL);
|
||||
|
||||
/**
|
||||
* Function BuildPadsCandidatesList
|
||||
@ -209,15 +208,15 @@ public:
|
||||
|
||||
private:
|
||||
/**
|
||||
* function searchEntryPoint
|
||||
* function searchEntryPointInCandidatesList
|
||||
* Search an item in m_Connected connected to aPoint
|
||||
* note m_Connected containts usually more than one candidate
|
||||
* and searchEntryPoint returns an index to one of these candidates
|
||||
* and searchEntryPointInCandidatesList returns an index to one of these candidates
|
||||
* Others are neightbor of the indexed item.
|
||||
* @param aPoint is the reference coordinates
|
||||
* @return the index of item found or -1 if no candidate
|
||||
*/
|
||||
int searchEntryPoint( const wxPoint & aPoint);
|
||||
int searchEntryPointInCandidatesList( const wxPoint & aPoint);
|
||||
|
||||
/**
|
||||
* Function Merge_SubNets
|
||||
@ -438,10 +437,10 @@ void CONNECTIONS::BuildTracksCandidatesList( TRACK * aBegin, TRACK * aEnd)
|
||||
{
|
||||
m_candidates.clear();
|
||||
|
||||
if( aBegin == NULL )
|
||||
aBegin = m_brd->m_Track;
|
||||
// if( aBegin == NULL )
|
||||
// aBegin = m_brd->m_Track;
|
||||
|
||||
m_firstTrack = aBegin;
|
||||
m_firstTrack = m_lastTrack = aBegin;
|
||||
|
||||
unsigned ii = 0;
|
||||
// Count candidates ( i.e. end points )
|
||||
@ -489,7 +488,7 @@ int CONNECTIONS::SearchConnectedTracks( const TRACK * aTrack )
|
||||
wxPoint position = aTrack->m_Start;
|
||||
for( int kk = 0; kk < 2; kk++ )
|
||||
{
|
||||
int idx = searchEntryPoint( position );
|
||||
int idx = searchEntryPointInCandidatesList( position );
|
||||
if ( idx >= 0 )
|
||||
{
|
||||
// search after:
|
||||
@ -524,7 +523,7 @@ int CONNECTIONS::SearchConnectedTracks( const TRACK * aTrack )
|
||||
return count;
|
||||
}
|
||||
|
||||
int CONNECTIONS::searchEntryPoint( const wxPoint & aPoint)
|
||||
int CONNECTIONS::searchEntryPointInCandidatesList( const wxPoint & aPoint)
|
||||
{
|
||||
// Search the aPoint coordinates in m_Candidates
|
||||
// m_Candidates is sorted by X then Y values, and a fast binary search is used
|
||||
@ -582,6 +581,7 @@ int CONNECTIONS::searchEntryPoint( const wxPoint & aPoint)
|
||||
|
||||
/* Used after a track change (delete a track ou add a track)
|
||||
* Connections to pads are recalculated
|
||||
* Note also aFirstTrack (and aLastTrack ) can be NULL
|
||||
*/
|
||||
void CONNECTIONS::Build_CurrNet_SubNets_Connections( TRACK* aFirstTrack, TRACK* aLastTrack, int aNetcode )
|
||||
{
|
||||
@ -611,6 +611,9 @@ void CONNECTIONS::Build_CurrNet_SubNets_Connections( TRACK* aFirstTrack, TRACK*
|
||||
BuildPadsList( aNetcode );
|
||||
SearchTracksConnectedToPads();
|
||||
|
||||
// Update connections between intersecting pads (no tracks)
|
||||
SearchConnectionsPadsToIntersectingPads();
|
||||
|
||||
// Creates sub nets (clusters) for the current net:
|
||||
Propagate_SubNets();
|
||||
}
|
||||
@ -705,13 +708,54 @@ int CONNECTIONS::Merge_SubNets( int aOldSubNet, int aNewSubNet )
|
||||
*/
|
||||
void CONNECTIONS::Propagate_SubNets()
|
||||
{
|
||||
TRACK* curr_track;
|
||||
int sub_netcode;
|
||||
int sub_netcode = 0;
|
||||
|
||||
curr_track = (TRACK*)m_firstTrack;
|
||||
sub_netcode = 1;
|
||||
curr_track->SetSubNet( sub_netcode );
|
||||
// Examine connections between intersecting pads
|
||||
for( unsigned ii = 0; ii < m_sortedPads.size(); ii++ )
|
||||
{
|
||||
D_PAD * curr_pad = m_sortedPads[ii];
|
||||
for( unsigned jj = 0; jj < curr_pad->m_PadsConnected.size(); jj++ )
|
||||
{
|
||||
D_PAD * pad = curr_pad->m_PadsConnected[jj];
|
||||
if( curr_pad->GetSubNet() )
|
||||
{
|
||||
if( pad->GetSubNet() > 0 )
|
||||
{
|
||||
// The pad is already a cluster member, so we can merge the 2 clusters
|
||||
Merge_PadsSubNets( pad->GetSubNet(), curr_pad->GetSubNet() );
|
||||
}
|
||||
else
|
||||
{
|
||||
// The pad is not yet attached to a cluster,
|
||||
// so we can add this pad to the cluster
|
||||
pad->SetSubNet( curr_pad->GetSubNet() );
|
||||
}
|
||||
}
|
||||
else /* the track segment is not attached to a cluster */
|
||||
{
|
||||
if( pad->GetSubNet() > 0 )
|
||||
{
|
||||
// it is connected to a pad in a cluster, merge this pad
|
||||
curr_pad->SetSubNet( pad->GetSubNet() );
|
||||
}
|
||||
else
|
||||
{
|
||||
// it is connected to a pad not in a cluster,
|
||||
// so we must create a new cluster (only with the 2 pads.
|
||||
sub_netcode++;
|
||||
curr_pad->SetSubNet( sub_netcode );
|
||||
pad->SetSubNet( curr_pad->GetSubNet() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub_netcode++;
|
||||
TRACK* curr_track = (TRACK*)m_firstTrack;
|
||||
if( curr_track )
|
||||
curr_track->SetSubNet( sub_netcode );
|
||||
|
||||
// Examine connections between trcaks and pads
|
||||
for( ; curr_track != NULL; curr_track = curr_track->Next() )
|
||||
{
|
||||
/* First: handling connections to pads */
|
||||
@ -793,6 +837,12 @@ void CONNECTIONS::Propagate_SubNets()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test all connections of the board,
|
||||
* and update subnet variable of pads and tracks
|
||||
* TestForActiveLinksInRatsnest must be called after this function
|
||||
* to update active/inactive ratsnest items status
|
||||
*/
|
||||
void PCB_BASE_FRAME::TestConnections()
|
||||
{
|
||||
// Clear the cluster identifier for all pads
|
||||
@ -806,21 +856,41 @@ void PCB_BASE_FRAME::TestConnections()
|
||||
|
||||
m_Pcb->Test_Connections_To_Copper_Areas();
|
||||
|
||||
// int st = clock(); // For test only, will be removed
|
||||
|
||||
// Test existing connections net by net
|
||||
// note some nets can have no tracks, and pads intersecting
|
||||
// so Build_CurrNet_SubNets_Connections must be called for each net
|
||||
CONNECTIONS connections( m_Pcb );
|
||||
int last_net_tested = 0;
|
||||
int current_net_code = 0;
|
||||
for( TRACK* track = m_Pcb->m_Track; track; )
|
||||
{
|
||||
// At this point, track is the first track of a given net
|
||||
int current_net_code = track->GetNet();
|
||||
current_net_code = track->GetNet();
|
||||
// Get last track of the current net
|
||||
TRACK* lastTrack = track->GetEndNetCode( current_net_code );
|
||||
|
||||
if( current_net_code > 0 ) // do not spend time if net code = 0 ( dummy net )
|
||||
{
|
||||
// Test all previous nets having no tracks
|
||||
for( int net = last_net_tested+1; net < current_net_code; net++ )
|
||||
connections.Build_CurrNet_SubNets_Connections( NULL, NULL, net );
|
||||
|
||||
connections.Build_CurrNet_SubNets_Connections( track, lastTrack, current_net_code );
|
||||
last_net_tested = current_net_code;
|
||||
}
|
||||
|
||||
track = lastTrack->Next(); // this is now the first track of the next net
|
||||
}
|
||||
|
||||
// Test last nets without tracks, if any
|
||||
int netsCount = m_Pcb->GetNetCount();
|
||||
for( int net = last_net_tested+1; net < netsCount; net++ )
|
||||
connections.Build_CurrNet_SubNets_Connections( NULL, NULL, net );
|
||||
|
||||
// wxLogMessage("time %g ms", (double)(clock() - st)*1000.0/CLOCKS_PER_SEC);
|
||||
|
||||
Merge_SubNets_Connected_By_CopperAreas( m_Pcb );
|
||||
|
||||
return;
|
||||
@ -925,7 +995,7 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
|
||||
|
||||
CONNECTIONS connections( m_Pcb );
|
||||
connections.BuildPadsList();
|
||||
connections.BuildTracksCandidatesList();
|
||||
connections.BuildTracksCandidatesList(m_Pcb->m_Track);
|
||||
|
||||
// First pass: build connections between track segments and pads.
|
||||
connections.SearchTracksConnectedToPads();
|
||||
|
Loading…
Reference in New Issue
Block a user