Performance enhancements.

This commit is contained in:
Jeff Young 2021-01-08 00:26:32 +00:00
parent c3eb8dccda
commit 3fd128a75b
9 changed files with 126 additions and 98 deletions

View File

@ -1103,20 +1103,6 @@ DRC_CONSTRAINT DRC_ENGINE::GetWorstGlobalConstraint( DRC_CONSTRAINT_T ruleID )
#endif
std::vector<DRC_CONSTRAINT> DRC_ENGINE::QueryConstraintsById( DRC_CONSTRAINT_T constraintID )
{
std::vector<DRC_CONSTRAINT> rv;
if( m_constraintMap.count( constraintID ) )
{
for ( DRC_ENGINE_CONSTRAINT* c : *m_constraintMap[constraintID] )
rv.push_back( c->constraint );
}
return rv;
}
bool DRC_ENGINE::HasRulesForConstraintType( DRC_CONSTRAINT_T constraintID )
{
//drc_dbg(10,"hascorrect id %d size %d\n", ruleID, m_ruleMap[ruleID]->sortedRules.size( ) );
@ -1131,16 +1117,16 @@ bool DRC_ENGINE::QueryWorstConstraint( DRC_CONSTRAINT_T aConstraintId, DRC_CONST
{
int worst = 0;
for( const DRC_CONSTRAINT& constraint : QueryConstraintsById( aConstraintId ) )
if( m_constraintMap.count( aConstraintId ) )
{
if( constraint.GetValue().HasMin() )
for( DRC_ENGINE_CONSTRAINT* c : *m_constraintMap[aConstraintId] )
{
int current = constraint.GetValue().Min();
int current = c->constraint.GetValue().Min();
if( current > worst )
{
worst = current;
aConstraint = constraint;
aConstraint = c->constraint;
}
}
}

View File

@ -145,8 +145,6 @@ public:
PCB_LAYER_ID aLayer = UNDEFINED_LAYER,
REPORTER* aReporter = nullptr );
std::vector<DRC_CONSTRAINT> QueryConstraintsById( DRC_CONSTRAINT_T ruleID );
bool HasRulesForConstraintType( DRC_CONSTRAINT_T constraintID );
EDA_UNITS UserUnits() const { return m_userUnits; }

View File

@ -86,7 +86,7 @@ PAD::PAD( FOOTPRINT* parent ) :
SetSubRatsnest( 0 ); // used in ratsnest calculations
m_shapesDirty = true;
SetDirty();
m_effectiveBoundingRadius = 0;
m_removeUnconnectedLayer = false;
m_keepTopBottomLayer = true;
@ -262,7 +262,7 @@ void PAD::SetRoundRectRadiusRatio( double aRadiusScale )
{
m_roundedCornerScale = std::max( 0.0, std::min( aRadiusScale, 0.5 ) );
m_shapesDirty = true;
SetDirty();
}
@ -270,14 +270,14 @@ void PAD::SetChamferRectRatio( double aChamferScale )
{
m_chamferScale = std::max( 0.0, std::min( aChamferScale, 0.5 ) );
m_shapesDirty = true;
SetDirty();
}
const std::shared_ptr<SHAPE_POLY_SET>& PAD::GetEffectivePolygon( PCB_LAYER_ID aLayer ) const
const std::shared_ptr<SHAPE_POLY_SET>& PAD::GetEffectivePolygon() const
{
if( m_shapesDirty )
BuildEffectiveShapes( aLayer );
if( m_polyDirty )
BuildEffectivePolygon();
return m_effectivePolygon;
}
@ -303,8 +303,8 @@ const SHAPE_SEGMENT* PAD::GetEffectiveHoleShape() const
int PAD::GetBoundingRadius() const
{
if( m_shapesDirty )
BuildEffectiveShapes( UNDEFINED_LAYER );
if( m_polyDirty )
BuildEffectivePolygon();
return m_effectiveBoundingRadius;
}
@ -453,31 +453,6 @@ void PAD::BuildEffectiveShapes( PCB_LAYER_ID aLayer ) const
}
}
// Polygon
//
m_effectivePolygon = std::make_shared<SHAPE_POLY_SET>();
TransformShapeWithClearanceToPolygon( *m_effectivePolygon, aLayer, 0, maxError, ERROR_INSIDE );
// Bounding box and radius
//
// PADSTACKS TODO: these will both need to cycle through all layers to get the largest
// values....
//
m_effectiveBoundingRadius = 0;
for( int cnt = 0; cnt < m_effectivePolygon->OutlineCount(); ++cnt )
{
const SHAPE_LINE_CHAIN& poly = m_effectivePolygon->COutline( cnt );
for( int ii = 0; ii < poly.PointCount(); ++ii )
{
int dist = KiROUND( ( poly.CPoint( ii ) - m_pos ).EuclideanNorm() );
m_effectiveBoundingRadius = std::max( m_effectiveBoundingRadius, dist );
}
}
m_effectiveBoundingRadius += 1;
BOX2I bbox = m_effectiveShape->BBox();
m_effectiveBoundingBox = EDA_RECT( (wxPoint) bbox.GetPosition(),
wxSize( bbox.GetWidth(), bbox.GetHeight() ) );
@ -499,6 +474,48 @@ void PAD::BuildEffectiveShapes( PCB_LAYER_ID aLayer ) const
}
void PAD::BuildEffectivePolygon() const
{
std::lock_guard<std::mutex> RAII_lock( m_polyBuildingLock );
// If we had to wait for the lock then we were probably waiting for someone else to
// finish rebuilding the shapes. So check to see if they're clean now.
if( !m_polyDirty )
return;
BOARD* board = GetBoard();
int maxError = board ? board->GetDesignSettings().m_MaxError : ARC_HIGH_DEF;
// Polygon
//
m_effectivePolygon = std::make_shared<SHAPE_POLY_SET>();
TransformShapeWithClearanceToPolygon( *m_effectivePolygon, UNDEFINED_LAYER, 0, maxError,
ERROR_INSIDE );
// Bounding radius
//
// PADSTACKS TODO: these will both need to cycle through all layers to get the largest
// values....
//
m_effectiveBoundingRadius = 0;
for( int cnt = 0; cnt < m_effectivePolygon->OutlineCount(); ++cnt )
{
const SHAPE_LINE_CHAIN& poly = m_effectivePolygon->COutline( cnt );
for( int ii = 0; ii < poly.PointCount(); ++ii )
{
int dist = KiROUND( ( poly.CPoint( ii ) - m_pos ).EuclideanNorm() );
m_effectiveBoundingRadius = std::max( m_effectiveBoundingRadius, dist );
}
}
// All done
//
m_polyDirty = false;
}
const EDA_RECT PAD::GetBoundingBox() const
{
if( m_shapesDirty )
@ -522,7 +539,7 @@ void PAD::SetDrawCoord()
RotatePoint( &m_pos.x, &m_pos.y, angle );
m_pos += parentFootprint->GetPosition();
m_shapesDirty = true;
SetDirty();
}
@ -548,7 +565,7 @@ void PAD::SetAttribute( PAD_ATTR_T aAttribute )
if( aAttribute == PAD_ATTRIB_SMD )
m_drill = wxSize( 0, 0 );
m_shapesDirty = true;
SetDirty();
}
@ -556,7 +573,7 @@ void PAD::SetProperty( PAD_PROP_T aProperty )
{
m_property = aProperty;
m_shapesDirty = true;
SetDirty();
}
@ -565,7 +582,7 @@ void PAD::SetOrientation( double aAngle )
NORMALIZE_ANGLE_POS( aAngle );
m_orient = aAngle;
m_shapesDirty = true;
SetDirty();
}
@ -623,7 +640,7 @@ void PAD::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
// Flip the basic shapes, in custom pads
FlipPrimitives( aFlipLeftRight );
m_shapesDirty = true;
SetDirty();
}
@ -633,7 +650,7 @@ void PAD::FlipPrimitives( bool aFlipLeftRight )
for( std::shared_ptr<PCB_SHAPE>& primitive : m_editPrimitives )
primitive->Flip( wxPoint( 0, 0 ), aFlipLeftRight );
m_shapesDirty = true;
SetDirty();
}
@ -1040,7 +1057,7 @@ void PAD::Rotate( const wxPoint& aRotCentre, double aAngle )
SetLocalCoord();
m_shapesDirty = true;
SetDirty();
}
@ -1357,7 +1374,7 @@ void PAD::ImportSettingsFrom( const PAD& aMasterPad )
ReplacePrimitives( aMasterPad.GetPrimitives() );
SetAnchorPadShape( aMasterPad.GetAnchorPadShape() );
m_shapesDirty = true;
SetDirty();
}

View File

@ -153,7 +153,7 @@ public:
void SetShape( PAD_SHAPE_T aShape )
{
m_padShape = aShape;
m_shapesDirty = true;
SetDirty();
}
/**
@ -164,7 +164,7 @@ public:
void SetPosition( const wxPoint& aPos ) override
{
m_pos = aPos;
m_shapesDirty = true;
SetDirty();
}
wxPoint GetPosition() const override { return m_pos; }
@ -203,7 +203,7 @@ public:
void SetAnchorPadShape( PAD_SHAPE_T aShape )
{
m_anchorPadShape = ( aShape == PAD_SHAPE_RECT ) ? PAD_SHAPE_RECT : PAD_SHAPE_CIRCLE;
m_shapesDirty = true;
SetDirty();
}
/**
@ -216,8 +216,8 @@ public:
return ( GetLayerSet() & LSET::AllCuMask() ) != 0;
}
void SetY( int y ) { m_pos.y = y; m_shapesDirty = true; }
void SetX( int x ) { m_pos.x = x; m_shapesDirty = true; }
void SetY( int y ) { m_pos.y = y; SetDirty(); }
void SetX( int x ) { m_pos.x = x; SetDirty(); }
void SetPos0( const wxPoint& aPos ) { m_pos0 = aPos; }
const wxPoint& GetPos0() const { return m_pos0; }
@ -225,24 +225,24 @@ public:
void SetY0( int y ) { m_pos0.y = y; }
void SetX0( int x ) { m_pos0.x = x; }
void SetSize( const wxSize& aSize ) { m_size = aSize; m_shapesDirty = true; }
void SetSize( const wxSize& aSize ) { m_size = aSize; SetDirty(); }
const wxSize& GetSize() const { return m_size; }
void SetSizeX( const int aX ) { m_size.x = aX; m_shapesDirty = true; }
void SetSizeX( const int aX ) { m_size.x = aX; SetDirty(); }
const int GetSizeX() const { return m_size.x; }
void SetSizeY( const int aY ) { m_size.y = aY; m_shapesDirty = true; }
void SetSizeY( const int aY ) { m_size.y = aY; SetDirty(); }
const int GetSizeY() const { return m_size.y; }
void SetDelta( const wxSize& aSize ) { m_deltaSize = aSize; m_shapesDirty = true; }
void SetDelta( const wxSize& aSize ) { m_deltaSize = aSize; SetDirty(); }
const wxSize& GetDelta() const { return m_deltaSize; }
void SetDrillSize( const wxSize& aSize ) { m_drill = aSize; m_shapesDirty = true; }
void SetDrillSize( const wxSize& aSize ) { m_drill = aSize; SetDirty(); }
const wxSize& GetDrillSize() const { return m_drill; }
void SetDrillSizeX( const int aX ) { m_drill.x = aX; m_shapesDirty = true; }
void SetDrillSizeX( const int aX ) { m_drill.x = aX; SetDirty(); }
const int GetDrillSizeX() const { return m_drill.x; }
void SetDrillSizeY( const int aY ) { m_drill.y = aY; m_shapesDirty = true; }
void SetDrillSizeY( const int aY ) { m_drill.y = aY; SetDirty(); }
const int GetDrillSizeY() const { return m_drill.y; }
void SetOffset( const wxPoint& aOffset ) { m_offset = aOffset; m_shapesDirty = true; }
void SetOffset( const wxPoint& aOffset ) { m_offset = aOffset; SetDirty(); }
const wxPoint& GetOffset() const { return m_offset; }
wxPoint GetCenter() const override { return GetPosition(); }
@ -341,8 +341,16 @@ public:
void SetDrillShape( PAD_DRILL_SHAPE_T aShape ) { m_drillShape = aShape; m_shapesDirty = true; }
PAD_DRILL_SHAPE_T GetDrillShape() const { return m_drillShape; }
bool IsDirty() const { return m_shapesDirty; }
void SetDirty() { m_shapesDirty = true; }
bool IsDirty() const
{
return m_shapesDirty || m_polyDirty;
}
void SetDirty()
{
m_shapesDirty = true;
m_polyDirty = true;
}
void SetLayerSet( LSET aLayers ) override { m_layerMask = aLayers; }
LSET GetLayerSet() const override { return m_layerMask; }
@ -402,7 +410,7 @@ public:
// @copydoc BOARD_ITEM::GetEffectiveShape
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const override;
const std::shared_ptr<SHAPE_POLY_SET>& GetEffectivePolygon( PCB_LAYER_ID = UNDEFINED_LAYER ) const;
const std::shared_ptr<SHAPE_POLY_SET>& GetEffectivePolygon() const;
/**
* Function GetEffectiveHoleShape
@ -597,7 +605,7 @@ public:
{
m_pos += aMoveVector;
SetLocalCoord();
m_shapesDirty = true;
SetDirty();
}
void Rotate( const wxPoint& aRotCentre, double aAngle ) override;
@ -634,6 +642,7 @@ public:
* the dirty bit.
*/
void BuildEffectiveShapes( PCB_LAYER_ID aLayer ) const;
void BuildEffectivePolygon() const;
virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;
@ -670,11 +679,14 @@ private:
// Must be set to true to force rebuild shapes to draw (after geometry change for instance)
mutable bool m_shapesDirty;
mutable std::mutex m_shapesBuildingLock;
mutable int m_effectiveBoundingRadius;
mutable EDA_RECT m_effectiveBoundingBox;
mutable std::shared_ptr<SHAPE_COMPOUND> m_effectiveShape;
mutable std::shared_ptr<SHAPE_SEGMENT> m_effectiveHoleShape;
mutable bool m_polyDirty;
mutable std::mutex m_polyBuildingLock;
mutable std::shared_ptr<SHAPE_POLY_SET> m_effectivePolygon;
mutable int m_effectiveBoundingRadius;
/*
* How to build the custom shape in zone, to create the clearance area:

View File

@ -60,7 +60,7 @@ void PAD::AddPrimitivePoly( const std::vector<wxPoint>& aPoly, int aThickness, b
item->SetPolyPoints( aPoly );
item->SetWidth( aThickness );
m_editPrimitives.emplace_back( item );
m_shapesDirty = true;
SetDirty();
}
@ -73,7 +73,7 @@ void PAD::AddPrimitiveSegment( const wxPoint& aStart, const wxPoint& aEnd, int a
item->SetEnd( aEnd );
item->SetWidth( aThickness );
m_editPrimitives.emplace_back( item );
m_shapesDirty = true;
SetDirty();
}
@ -88,7 +88,7 @@ void PAD::AddPrimitiveArc( const wxPoint& aCenter, const wxPoint& aStart, int aA
item->SetAngle( aArcAngle );
item->SetWidth( aThickness );
m_editPrimitives.emplace_back( item );
m_shapesDirty = true;
SetDirty();
}
@ -104,7 +104,7 @@ void PAD::AddPrimitiveCurve( const wxPoint& aStart, const wxPoint& aEnd, const w
item->SetBezControl2( aCtrl2 );
item->SetWidth( aThickness );
m_editPrimitives.emplace_back( item );
m_shapesDirty = true;
SetDirty();
}
@ -117,7 +117,7 @@ void PAD::AddPrimitiveCircle( const wxPoint& aCenter, int aRadius, int aThicknes
item->SetEnd( wxPoint( aCenter.x + aRadius, aCenter.y ) );
item->SetWidth( aThickness );
m_editPrimitives.emplace_back( item );
m_shapesDirty = true;
SetDirty();
}
@ -131,7 +131,7 @@ void PAD::AddPrimitiveRect( const wxPoint& aStart, const wxPoint& aEnd, int aThi
item->SetEnd( aEnd );
item->SetWidth( aThickness );
m_editPrimitives.emplace_back( item );
m_shapesDirty = true;
SetDirty();
}
@ -144,7 +144,7 @@ void PAD::ReplacePrimitives( const std::vector<std::shared_ptr<PCB_SHAPE>>& aPri
if( aPrimitivesList.size() )
AppendPrimitives( aPrimitivesList );
m_shapesDirty = true;
SetDirty();
}
@ -154,7 +154,7 @@ void PAD::AppendPrimitives( const std::vector<std::shared_ptr<PCB_SHAPE>>& aPrim
for( const std::shared_ptr<PCB_SHAPE>& prim : aPrimitivesList )
AddPrimitive( new PCB_SHAPE( *prim ) );
m_shapesDirty = true;
SetDirty();
}
@ -162,7 +162,7 @@ void PAD::AddPrimitive( PCB_SHAPE* aPrimitive )
{
m_editPrimitives.emplace_back( aPrimitive );
m_shapesDirty = true;
SetDirty();
}
@ -171,7 +171,7 @@ void PAD::DeletePrimitivesList()
{
m_editPrimitives.clear();
m_shapesDirty = true;
SetDirty();
}

View File

@ -428,7 +428,7 @@ bool RN_NET::NearestBicoloredPair( const RN_NET& aOtherNet, CN_ANCHOR_PTR& aNode
for( ; fwd_it != m_nodes.end(); ++fwd_it )
{
auto nodeB = *fwd_it;
const std::shared_ptr<CN_ANCHOR>& nodeB = *fwd_it;
if( nodeB->GetNoLine() )
continue;
@ -446,7 +446,7 @@ bool RN_NET::NearestBicoloredPair( const RN_NET& aOtherNet, CN_ANCHOR_PTR& aNode
/// Step 3: using the same starting point, check points backwards for closer points
for( ; rev_it != m_nodes.rend(); ++rev_it )
{
auto nodeB = *rev_it;
const std::shared_ptr<CN_ANCHOR>& nodeB = *rev_it;
if( nodeB->GetNoLine() )
continue;

View File

@ -421,7 +421,9 @@ int PCB_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
//move cursor prediction
if( !modifier_enabled && !dragAlwaysSelects && !m_selection.Empty()
&& evt->HasPosition() && selectionContains( evt->Position() ) )
{
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::MOVING );
}
else
{
if( m_additive )
@ -2204,13 +2206,18 @@ bool PCB_SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const
const unsigned GRIP_MARGIN = 20;
VECTOR2I margin = getView()->ToWorld( VECTOR2I( GRIP_MARGIN, GRIP_MARGIN ), false );
// Check if the point is located within any of the currently selected items bounding boxes
for( EDA_ITEM* item : m_selection )
{
BOX2I itemBox = item->ViewBBox();
itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
GENERAL_COLLECTORS_GUIDE guide = getCollectorsGuide();
GENERAL_COLLECTOR collector;
if( itemBox.Contains( aPoint ) )
collector.Collect( board(), m_isFootprintEditor ? GENERAL_COLLECTOR::FootprintItems
: GENERAL_COLLECTOR::AllBoardItems,
(wxPoint) aPoint, guide );
for( int i = collector.GetCount() - 1; i >= 0; --i )
{
BOARD_ITEM* item = collector[i];
if( item->IsSelected() && item->HitTest( (wxPoint) aPoint, margin.x ) )
return true;
}

View File

@ -547,7 +547,12 @@ double TRACK::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
const BOX2I TRACK::ViewBBox() const
{
BOX2I bbox = GetBoundingBox();
bbox.Inflate( 2 * GetOwnClearance( GetLayer() ) );
BOARD* board = GetBoard();
if( board )
bbox.Inflate( 2 * board->GetDesignSettings().GetBiggestClearanceValue() );
return bbox;
}

View File

@ -126,7 +126,10 @@ bool ZONE_FILLER::Fill( std::vector<ZONE*>& aZones, bool aCheck, wxWindow* aPare
for( PAD* pad : footprint->Pads() )
{
if( pad->IsDirty() )
{
pad->BuildEffectiveShapes( UNDEFINED_LAYER );
pad->BuildEffectivePolygon();
}
}
for( ZONE* zone : footprint->Zones() )