Cache pad bounding boxes for performance.

Also allows us to return to a LOD test for pad numbers which treats
round and square pads the same.
This commit is contained in:
Jeff Young 2020-07-01 16:23:59 +01:00
parent 3b764d6357
commit 424d551054
3 changed files with 14 additions and 72 deletions

View File

@ -334,10 +334,17 @@ void D_PAD::BuildEffectiveShapes() const
add( poly ); add( poly );
} }
// Bounding radius // Bounding box and radius
// //
m_effectiveBoundingRadius = calcBoundingRadius(); m_effectiveBoundingRadius = calcBoundingRadius();
for( const std::shared_ptr<SHAPE>& shape : m_effectiveShapes )
{
BOX2I r = shape->BBox();
m_effectiveBoundingBox.Merge( EDA_RECT( (wxPoint) r.GetOrigin(),
wxSize( r.GetWidth(), r.GetHeight() ) ) );
}
// Hole shape // Hole shape
// //
wxSize half_size = m_Drill / 2; wxSize half_size = m_Drill / 2;
@ -357,15 +364,10 @@ void D_PAD::BuildEffectiveShapes() const
const EDA_RECT D_PAD::GetBoundingBox() const const EDA_RECT D_PAD::GetBoundingBox() const
{ {
EDA_RECT bbox; if( m_shapesDirty )
BuildEffectiveShapes();
for( const std::shared_ptr<SHAPE>& shape : GetEffectiveShapes() ) return m_effectiveBoundingBox;
{
BOX2I r = shape->BBox();
bbox.Merge( EDA_RECT( (wxPoint) r.GetOrigin(), wxSize( r.GetWidth(), r.GetHeight() ) ) );
}
return bbox;
} }
@ -1098,14 +1100,14 @@ unsigned int D_PAD::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
// Netnames will be shown only if zoom is appropriate // Netnames will be shown only if zoom is appropriate
if( IsNetnameLayer( aLayer ) ) if( IsNetnameLayer( aLayer ) )
{ {
int divisor = GetBoundingRadius(); int divisor = std::min( GetBoundingBox().GetWidth(), GetBoundingBox().GetHeight() );
// Pad sizes can be zero briefly when someone is typing a number like "0.5" // Pad sizes can be zero briefly when someone is typing a number like "0.5"
// in the pad properties dialog // in the pad properties dialog
if( divisor == 0 ) if( divisor == 0 )
return HIDE; return HIDE;
return ( Millimeter2iu( 10 ) / divisor ); return ( Millimeter2iu( 5 ) / divisor );
} }
// Other layers are shown without any conditions // Other layers are shown without any conditions

View File

@ -620,6 +620,7 @@ private:
mutable bool m_shapesDirty; mutable bool m_shapesDirty;
mutable int m_effectiveBoundingRadius; mutable int m_effectiveBoundingRadius;
mutable EDA_RECT m_effectiveBoundingBox;
mutable std::vector<std::shared_ptr<SHAPE>> m_effectiveShapes; mutable std::vector<std::shared_ptr<SHAPE>> m_effectiveShapes;
mutable std::shared_ptr<SHAPE_SEGMENT> m_effectiveHoleShape; mutable std::shared_ptr<SHAPE_SEGMENT> m_effectiveHoleShape;

View File

@ -24,77 +24,16 @@
*/ */
#include <fctsys.h> #include <fctsys.h>
#include <pcb_edit_frame.h>
#include <trigo.h> #include <trigo.h>
#include <pcbnew.h>
#include <drc/drc.h> #include <drc/drc.h>
#include <class_board.h> #include <class_board.h>
#include <class_module.h>
#include <class_track.h> #include <class_track.h>
#include <class_zone.h>
#include <class_drawsegment.h> #include <class_drawsegment.h>
#include <class_marker_pcb.h> #include <class_marker_pcb.h>
#include <math_for_graphics.h> #include <math_for_graphics.h>
#include <geometry/polygon_test_point_inside.h> #include <geometry/polygon_test_point_inside.h>
#include <convert_basic_shapes_to_polygon.h> #include <convert_basic_shapes_to_polygon.h>
#include <board_commit.h>
#include <math/util.h> // for KiROUND
#include <geometry/shape_rect.h> #include <geometry/shape_rect.h>
#include <macros.h>
/**
* compare 2 convex polygons and return true if distance > aDist (if no error DRC)
* i.e if for each edge of the first polygon distance from each edge of the other polygon
* is >= aDist
*/
bool poly2polyDRC( wxPoint* aTref, int aTrefCount, wxPoint* aTtest, int aTtestCount,
int aAllowedDist, int* actualDist )
{
/* Test if one polygon is contained in the other and thus the polygon overlap.
* This case is not covered by the following check if one polygone is
* completely contained in the other (because edges don't intersect)!
*/
if( TestPointInsidePolygon( aTref, aTrefCount, aTtest[0] ) )
{
*actualDist = 0;
return false;
}
if( TestPointInsidePolygon( aTtest, aTtestCount, aTref[0] ) )
{
*actualDist = 0;
return false;
}
for( int ii = 0, jj = aTrefCount - 1; ii < aTrefCount; jj = ii, ii++ )
{
// for all edges in aTref
for( int kk = 0, ll = aTtestCount - 1; kk < aTtestCount; ll = kk, kk++ )
{
// for all edges in aTtest
double d;
int intersect = TestForIntersectionOfStraightLineSegments(
aTref[ii].x, aTref[ii].y, aTref[jj].x, aTref[jj].y,
aTtest[kk].x, aTtest[kk].y, aTtest[ll].x, aTtest[ll].y,
nullptr, nullptr, &d );
if( intersect )
{
*actualDist = 0;
return false;
}
if( d < aAllowedDist )
{
*actualDist = KiROUND( d );
return false;
}
}
}
return true;
}
/* /*