Pcbnew: trace length calculations:
fix incorrect calculation when a small segment at the end of the track was inside a pad: it was not taken in account. Fix also the len die values not always taken in account (references to pads at end of track not always stored) This is a partial fix of bug 1628585.
This commit is contained in:
parent
9fdcba8229
commit
038f8713ce
|
@ -2001,8 +2001,86 @@ TRACK* BOARD::MarkTrace( TRACK* aTrace, int* aCount,
|
||||||
if( firstTrack == NULL )
|
if( firstTrack == NULL )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
// First step: calculate the track length and find the pads (when exist)
|
||||||
|
// at each end of the trace.
|
||||||
double full_len = 0;
|
double full_len = 0;
|
||||||
double lenPadToDie = 0;
|
double lenPadToDie = 0;
|
||||||
|
// Because we have a track (a set of track segments between 2 nodes),
|
||||||
|
// only 2 pads (maximum) will be taken in account:
|
||||||
|
// that are on each end of the track, if any.
|
||||||
|
// keep trace of them, to know the die length and the track length ibside each pad.
|
||||||
|
D_PAD* s_pad = NULL; // the pad on one end of the trace
|
||||||
|
D_PAD* e_pad = NULL; // the pad on the other end of the trace
|
||||||
|
int dist_fromstart = INT_MAX;
|
||||||
|
int dist_fromend = INT_MAX;
|
||||||
|
|
||||||
|
for( TRACK* track = firstTrack; track; track = track->Next() )
|
||||||
|
{
|
||||||
|
if( !track->GetState( BUSY ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
layer_set = track->GetLayerSet();
|
||||||
|
D_PAD * pad_on_start = GetPad( track->GetStart(), layer_set );
|
||||||
|
D_PAD * pad_on_end = GetPad( track->GetEnd(), layer_set );
|
||||||
|
|
||||||
|
// a segment fully inside a pad does not contribute to the track len
|
||||||
|
// (an other track end inside this pad will contribute to this lenght)
|
||||||
|
if( pad_on_start && ( pad_on_start == pad_on_end ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
full_len += track->GetLength();
|
||||||
|
|
||||||
|
if( pad_on_start == NULL && pad_on_end == NULL )
|
||||||
|
// This most of time the case
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// At this point, we can have one track end on a pad, or the 2 track ends on
|
||||||
|
// 2 different pads.
|
||||||
|
// We don't know what pad (s_pad or e_pad) must be used to store the
|
||||||
|
// start point and the end point of the track, so if a pad is already set,
|
||||||
|
// use the other
|
||||||
|
if( pad_on_start )
|
||||||
|
{
|
||||||
|
SEG segm( track->GetStart(), pad_on_start->GetPosition() );
|
||||||
|
int dist = segm.Length();
|
||||||
|
|
||||||
|
if( s_pad == NULL )
|
||||||
|
{
|
||||||
|
dist_fromstart = dist;
|
||||||
|
s_pad = pad_on_start;
|
||||||
|
}
|
||||||
|
else if( e_pad == NULL )
|
||||||
|
{
|
||||||
|
dist_fromend = dist;
|
||||||
|
e_pad = pad_on_start;
|
||||||
|
}
|
||||||
|
else // Should not occur, at least for basic pads
|
||||||
|
{
|
||||||
|
// wxLogMessage( "BOARD::MarkTrace: multiple pad_on_start" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pad_on_end )
|
||||||
|
{
|
||||||
|
SEG segm( track->GetEnd(), pad_on_end->GetPosition() );
|
||||||
|
int dist = segm.Length();
|
||||||
|
|
||||||
|
if( s_pad == NULL )
|
||||||
|
{
|
||||||
|
dist_fromstart = dist;
|
||||||
|
s_pad = pad_on_end;
|
||||||
|
}
|
||||||
|
else if( e_pad == NULL )
|
||||||
|
{
|
||||||
|
dist_fromend = dist;
|
||||||
|
e_pad = pad_on_end;
|
||||||
|
}
|
||||||
|
else // Should not occur, at least for basic pads
|
||||||
|
{
|
||||||
|
// wxLogMessage( "BOARD::MarkTrace: multiple pad_on_end" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( aReorder )
|
if( aReorder )
|
||||||
{
|
{
|
||||||
|
@ -2025,25 +2103,6 @@ TRACK* BOARD::MarkTrace( TRACK* aTrace, int* aCount,
|
||||||
track->UnLink();
|
track->UnLink();
|
||||||
list->Insert( track, firstTrack->Next() );
|
list->Insert( track, firstTrack->Next() );
|
||||||
|
|
||||||
if( aTraceLength )
|
|
||||||
full_len += track->GetLength();
|
|
||||||
|
|
||||||
if( aPadToDieLength ) // Add now length die.
|
|
||||||
{
|
|
||||||
// In fact only 2 pads (maximum) will be taken in account:
|
|
||||||
// that are on each end of the track, if any
|
|
||||||
if( track->GetState( BEGIN_ONPAD ) )
|
|
||||||
{
|
|
||||||
D_PAD* pad = (D_PAD *) track->start;
|
|
||||||
lenPadToDie += (double) pad->GetPadToDieLength();
|
|
||||||
}
|
|
||||||
|
|
||||||
if( track->GetState( END_ONPAD ) )
|
|
||||||
{
|
|
||||||
D_PAD* pad = (D_PAD *) track->end;
|
|
||||||
lenPadToDie += (double) pad->GetPadToDieLength();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2057,28 +2116,24 @@ TRACK* BOARD::MarkTrace( TRACK* aTrace, int* aCount,
|
||||||
{
|
{
|
||||||
busy_count++;
|
busy_count++;
|
||||||
track->SetState( BUSY, false );
|
track->SetState( BUSY, false );
|
||||||
full_len += track->GetLength();
|
|
||||||
|
|
||||||
// Add now length die.
|
|
||||||
// In fact only 2 pads (maximum) will be taken in account:
|
|
||||||
// that are on each end of the track, if any
|
|
||||||
if( track->GetState( BEGIN_ONPAD ) )
|
|
||||||
{
|
|
||||||
D_PAD* pad = (D_PAD *) track->start;
|
|
||||||
lenPadToDie += (double) pad->GetPadToDieLength();
|
|
||||||
}
|
|
||||||
|
|
||||||
if( track->GetState( END_ONPAD ) )
|
|
||||||
{
|
|
||||||
D_PAD* pad = (D_PAD *) track->end;
|
|
||||||
lenPadToDie += (double) pad->GetPadToDieLength();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DBG( printf( "%s: busy_count:%d\n", __func__, busy_count ); )
|
DBG( printf( "%s: busy_count:%d\n", __func__, busy_count ); )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( s_pad )
|
||||||
|
{
|
||||||
|
full_len += dist_fromstart;
|
||||||
|
lenPadToDie += (double) s_pad->GetPadToDieLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( e_pad )
|
||||||
|
{
|
||||||
|
full_len += dist_fromend;
|
||||||
|
lenPadToDie += (double) e_pad->GetPadToDieLength();
|
||||||
|
}
|
||||||
|
|
||||||
if( aTraceLength )
|
if( aTraceLength )
|
||||||
*aTraceLength = full_len;
|
*aTraceLength = full_len;
|
||||||
|
|
||||||
|
|
|
@ -1289,12 +1289,12 @@ public:
|
||||||
*
|
*
|
||||||
* @param aTrace The segment within a list of trace segments to test.
|
* @param aTrace The segment within a list of trace segments to test.
|
||||||
* @param aCount A pointer to an integer where to return the number of
|
* @param aCount A pointer to an integer where to return the number of
|
||||||
* marked segments.
|
* marked segments (can be NULL).
|
||||||
* @param aTraceLength A pointer to an double where to return the length of the
|
* @param aTraceLength A pointer to an double where to return the length of the
|
||||||
* trace.
|
* trace (can be NULL).
|
||||||
* @param aInPackageLength A pointer to an double where to return the extra lengths inside
|
* @param aInPackageLength A pointer to an double where to return the extra lengths inside
|
||||||
* integrated circuits from the pads connected to this track to the
|
* integrated circuits from the pads connected to this track to the
|
||||||
* die (if any).
|
* die (if any) (can be NULL).
|
||||||
* @param aReorder true for reorder the interesting segments (useful for
|
* @param aReorder true for reorder the interesting segments (useful for
|
||||||
* track edition/deletion) in this case the flag BUSY is
|
* track edition/deletion) in this case the flag BUSY is
|
||||||
* set (the user is responsible of flag clearing). False
|
* set (the user is responsible of flag clearing). False
|
||||||
|
@ -1378,7 +1378,7 @@ public:
|
||||||
* segment start position if the return value is not NULL.
|
* segment start position if the return value is not NULL.
|
||||||
* @param aSegment The trace segment to create the lock point on.
|
* @param aSegment The trace segment to create the lock point on.
|
||||||
* @param aList The pick list to add the created items to.
|
* @param aList The pick list to add the created items to.
|
||||||
* @return NULL if no new point was created or a pointer to a TRACK ojbect of the
|
* @return NULL if no new point was created or a pointer to a TRACK object of the
|
||||||
* created segment. If \a aSegment points to a via the exact value of \a
|
* created segment. If \a aSegment points to a via the exact value of \a
|
||||||
* aPosition and a pointer to the via are returned.
|
* aPosition and a pointer to the via are returned.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
// Polygon calculations can use fast mode or force strickly simple polygons after calculations
|
// Polygon calculations can use fast mode or force strickly simple polygons after calculations
|
||||||
// Forcing strickly simple polygons is time consuming, and we have not see issues in fast mode
|
// Forcing strickly simple polygons is time consuming, and we have not see issues in fast mode
|
||||||
// so we use fast mode
|
// so we use fast mode
|
||||||
|
// (choice is SHAPE_POLY_SET::PM_STRICTLY_SIMPLE or SHAPE_POLY_SET::PM_FAST)
|
||||||
#define POLY_CALC_MODE SHAPE_POLY_SET::PM_FAST
|
#define POLY_CALC_MODE SHAPE_POLY_SET::PM_FAST
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
Loading…
Reference in New Issue