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 #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 ) bool DRC_ENGINE::HasRulesForConstraintType( DRC_CONSTRAINT_T constraintID )
{ {
//drc_dbg(10,"hascorrect id %d size %d\n", ruleID, m_ruleMap[ruleID]->sortedRules.size( ) ); //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; 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 ) if( current > worst )
{ {
worst = current; worst = current;
aConstraint = constraint; aConstraint = c->constraint;
} }
} }
} }

View File

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

View File

@ -86,7 +86,7 @@ PAD::PAD( FOOTPRINT* parent ) :
SetSubRatsnest( 0 ); // used in ratsnest calculations SetSubRatsnest( 0 ); // used in ratsnest calculations
m_shapesDirty = true; SetDirty();
m_effectiveBoundingRadius = 0; m_effectiveBoundingRadius = 0;
m_removeUnconnectedLayer = false; m_removeUnconnectedLayer = false;
m_keepTopBottomLayer = true; m_keepTopBottomLayer = true;
@ -262,7 +262,7 @@ void PAD::SetRoundRectRadiusRatio( double aRadiusScale )
{ {
m_roundedCornerScale = std::max( 0.0, std::min( aRadiusScale, 0.5 ) ); 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_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 ) if( m_polyDirty )
BuildEffectiveShapes( aLayer ); BuildEffectivePolygon();
return m_effectivePolygon; return m_effectivePolygon;
} }
@ -303,8 +303,8 @@ const SHAPE_SEGMENT* PAD::GetEffectiveHoleShape() const
int PAD::GetBoundingRadius() const int PAD::GetBoundingRadius() const
{ {
if( m_shapesDirty ) if( m_polyDirty )
BuildEffectiveShapes( UNDEFINED_LAYER ); BuildEffectivePolygon();
return m_effectiveBoundingRadius; 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(); BOX2I bbox = m_effectiveShape->BBox();
m_effectiveBoundingBox = EDA_RECT( (wxPoint) bbox.GetPosition(), m_effectiveBoundingBox = EDA_RECT( (wxPoint) bbox.GetPosition(),
wxSize( bbox.GetWidth(), bbox.GetHeight() ) ); 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 const EDA_RECT PAD::GetBoundingBox() const
{ {
if( m_shapesDirty ) if( m_shapesDirty )
@ -522,7 +539,7 @@ void PAD::SetDrawCoord()
RotatePoint( &m_pos.x, &m_pos.y, angle ); RotatePoint( &m_pos.x, &m_pos.y, angle );
m_pos += parentFootprint->GetPosition(); m_pos += parentFootprint->GetPosition();
m_shapesDirty = true; SetDirty();
} }
@ -548,7 +565,7 @@ void PAD::SetAttribute( PAD_ATTR_T aAttribute )
if( aAttribute == PAD_ATTRIB_SMD ) if( aAttribute == PAD_ATTRIB_SMD )
m_drill = wxSize( 0, 0 ); m_drill = wxSize( 0, 0 );
m_shapesDirty = true; SetDirty();
} }
@ -556,7 +573,7 @@ void PAD::SetProperty( PAD_PROP_T aProperty )
{ {
m_property = aProperty; m_property = aProperty;
m_shapesDirty = true; SetDirty();
} }
@ -565,7 +582,7 @@ void PAD::SetOrientation( double aAngle )
NORMALIZE_ANGLE_POS( aAngle ); NORMALIZE_ANGLE_POS( aAngle );
m_orient = 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 // Flip the basic shapes, in custom pads
FlipPrimitives( aFlipLeftRight ); FlipPrimitives( aFlipLeftRight );
m_shapesDirty = true; SetDirty();
} }
@ -633,7 +650,7 @@ void PAD::FlipPrimitives( bool aFlipLeftRight )
for( std::shared_ptr<PCB_SHAPE>& primitive : m_editPrimitives ) for( std::shared_ptr<PCB_SHAPE>& primitive : m_editPrimitives )
primitive->Flip( wxPoint( 0, 0 ), aFlipLeftRight ); primitive->Flip( wxPoint( 0, 0 ), aFlipLeftRight );
m_shapesDirty = true; SetDirty();
} }
@ -1040,7 +1057,7 @@ void PAD::Rotate( const wxPoint& aRotCentre, double aAngle )
SetLocalCoord(); SetLocalCoord();
m_shapesDirty = true; SetDirty();
} }
@ -1357,7 +1374,7 @@ void PAD::ImportSettingsFrom( const PAD& aMasterPad )
ReplacePrimitives( aMasterPad.GetPrimitives() ); ReplacePrimitives( aMasterPad.GetPrimitives() );
SetAnchorPadShape( aMasterPad.GetAnchorPadShape() ); SetAnchorPadShape( aMasterPad.GetAnchorPadShape() );
m_shapesDirty = true; SetDirty();
} }

View File

@ -153,7 +153,7 @@ public:
void SetShape( PAD_SHAPE_T aShape ) void SetShape( PAD_SHAPE_T aShape )
{ {
m_padShape = aShape; m_padShape = aShape;
m_shapesDirty = true; SetDirty();
} }
/** /**
@ -164,7 +164,7 @@ public:
void SetPosition( const wxPoint& aPos ) override void SetPosition( const wxPoint& aPos ) override
{ {
m_pos = aPos; m_pos = aPos;
m_shapesDirty = true; SetDirty();
} }
wxPoint GetPosition() const override { return m_pos; } wxPoint GetPosition() const override { return m_pos; }
@ -203,7 +203,7 @@ public:
void SetAnchorPadShape( PAD_SHAPE_T aShape ) void SetAnchorPadShape( PAD_SHAPE_T aShape )
{ {
m_anchorPadShape = ( aShape == PAD_SHAPE_RECT ) ? PAD_SHAPE_RECT : PAD_SHAPE_CIRCLE; 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; return ( GetLayerSet() & LSET::AllCuMask() ) != 0;
} }
void SetY( int y ) { m_pos.y = y; m_shapesDirty = true; } void SetY( int y ) { m_pos.y = y; SetDirty(); }
void SetX( int x ) { m_pos.x = x; m_shapesDirty = true; } void SetX( int x ) { m_pos.x = x; SetDirty(); }
void SetPos0( const wxPoint& aPos ) { m_pos0 = aPos; } void SetPos0( const wxPoint& aPos ) { m_pos0 = aPos; }
const wxPoint& GetPos0() const { return m_pos0; } const wxPoint& GetPos0() const { return m_pos0; }
@ -225,24 +225,24 @@ public:
void SetY0( int y ) { m_pos0.y = y; } void SetY0( int y ) { m_pos0.y = y; }
void SetX0( int x ) { m_pos0.x = x; } 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; } 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; } 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; } 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; } 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; } 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; } 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; } 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; } const wxPoint& GetOffset() const { return m_offset; }
wxPoint GetCenter() const override { return GetPosition(); } wxPoint GetCenter() const override { return GetPosition(); }
@ -341,8 +341,16 @@ public:
void SetDrillShape( PAD_DRILL_SHAPE_T aShape ) { m_drillShape = aShape; m_shapesDirty = true; } void SetDrillShape( PAD_DRILL_SHAPE_T aShape ) { m_drillShape = aShape; m_shapesDirty = true; }
PAD_DRILL_SHAPE_T GetDrillShape() const { return m_drillShape; } PAD_DRILL_SHAPE_T GetDrillShape() const { return m_drillShape; }
bool IsDirty() const { return m_shapesDirty; } bool IsDirty() const
void SetDirty() { m_shapesDirty = true; } {
return m_shapesDirty || m_polyDirty;
}
void SetDirty()
{
m_shapesDirty = true;
m_polyDirty = true;
}
void SetLayerSet( LSET aLayers ) override { m_layerMask = aLayers; } void SetLayerSet( LSET aLayers ) override { m_layerMask = aLayers; }
LSET GetLayerSet() const override { return m_layerMask; } LSET GetLayerSet() const override { return m_layerMask; }
@ -402,7 +410,7 @@ public:
// @copydoc BOARD_ITEM::GetEffectiveShape // @copydoc BOARD_ITEM::GetEffectiveShape
virtual std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer = UNDEFINED_LAYER ) const override; 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 * Function GetEffectiveHoleShape
@ -597,7 +605,7 @@ public:
{ {
m_pos += aMoveVector; m_pos += aMoveVector;
SetLocalCoord(); SetLocalCoord();
m_shapesDirty = true; SetDirty();
} }
void Rotate( const wxPoint& aRotCentre, double aAngle ) override; void Rotate( const wxPoint& aRotCentre, double aAngle ) override;
@ -634,6 +642,7 @@ public:
* the dirty bit. * the dirty bit.
*/ */
void BuildEffectiveShapes( PCB_LAYER_ID aLayer ) const; void BuildEffectiveShapes( PCB_LAYER_ID aLayer ) const;
void BuildEffectivePolygon() const;
virtual void ViewGetLayers( int aLayers[], int& aCount ) const override; 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) // Must be set to true to force rebuild shapes to draw (after geometry change for instance)
mutable bool m_shapesDirty; mutable bool m_shapesDirty;
mutable std::mutex m_shapesBuildingLock; mutable std::mutex m_shapesBuildingLock;
mutable int m_effectiveBoundingRadius;
mutable EDA_RECT m_effectiveBoundingBox; mutable EDA_RECT m_effectiveBoundingBox;
mutable std::shared_ptr<SHAPE_COMPOUND> m_effectiveShape; mutable std::shared_ptr<SHAPE_COMPOUND> m_effectiveShape;
mutable std::shared_ptr<SHAPE_SEGMENT> m_effectiveHoleShape; 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 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: * 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->SetPolyPoints( aPoly );
item->SetWidth( aThickness ); item->SetWidth( aThickness );
m_editPrimitives.emplace_back( item ); 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->SetEnd( aEnd );
item->SetWidth( aThickness ); item->SetWidth( aThickness );
m_editPrimitives.emplace_back( item ); 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->SetAngle( aArcAngle );
item->SetWidth( aThickness ); item->SetWidth( aThickness );
m_editPrimitives.emplace_back( item ); 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->SetBezControl2( aCtrl2 );
item->SetWidth( aThickness ); item->SetWidth( aThickness );
m_editPrimitives.emplace_back( item ); 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->SetEnd( wxPoint( aCenter.x + aRadius, aCenter.y ) );
item->SetWidth( aThickness ); item->SetWidth( aThickness );
m_editPrimitives.emplace_back( item ); 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->SetEnd( aEnd );
item->SetWidth( aThickness ); item->SetWidth( aThickness );
m_editPrimitives.emplace_back( item ); 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() ) if( aPrimitivesList.size() )
AppendPrimitives( aPrimitivesList ); 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 ) for( const std::shared_ptr<PCB_SHAPE>& prim : aPrimitivesList )
AddPrimitive( new PCB_SHAPE( *prim ) ); 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_editPrimitives.emplace_back( aPrimitive );
m_shapesDirty = true; SetDirty();
} }
@ -171,7 +171,7 @@ void PAD::DeletePrimitivesList()
{ {
m_editPrimitives.clear(); 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 ) for( ; fwd_it != m_nodes.end(); ++fwd_it )
{ {
auto nodeB = *fwd_it; const std::shared_ptr<CN_ANCHOR>& nodeB = *fwd_it;
if( nodeB->GetNoLine() ) if( nodeB->GetNoLine() )
continue; 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 /// Step 3: using the same starting point, check points backwards for closer points
for( ; rev_it != m_nodes.rend(); ++rev_it ) for( ; rev_it != m_nodes.rend(); ++rev_it )
{ {
auto nodeB = *rev_it; const std::shared_ptr<CN_ANCHOR>& nodeB = *rev_it;
if( nodeB->GetNoLine() ) if( nodeB->GetNoLine() )
continue; continue;

View File

@ -421,7 +421,9 @@ int PCB_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
//move cursor prediction //move cursor prediction
if( !modifier_enabled && !dragAlwaysSelects && !m_selection.Empty() if( !modifier_enabled && !dragAlwaysSelects && !m_selection.Empty()
&& evt->HasPosition() && selectionContains( evt->Position() ) ) && evt->HasPosition() && selectionContains( evt->Position() ) )
{
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::MOVING ); m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::MOVING );
}
else else
{ {
if( m_additive ) if( m_additive )
@ -2204,13 +2206,18 @@ bool PCB_SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const
const unsigned GRIP_MARGIN = 20; const unsigned GRIP_MARGIN = 20;
VECTOR2I margin = getView()->ToWorld( VECTOR2I( GRIP_MARGIN, GRIP_MARGIN ), false ); 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 GENERAL_COLLECTORS_GUIDE guide = getCollectorsGuide();
for( EDA_ITEM* item : m_selection ) GENERAL_COLLECTOR collector;
{
BOX2I itemBox = item->ViewBBox();
itemBox.Inflate( margin.x, margin.y ); // Give some margin for gripping an item
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; return true;
} }

View File

@ -547,7 +547,12 @@ double TRACK::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
const BOX2I TRACK::ViewBBox() const const BOX2I TRACK::ViewBBox() const
{ {
BOX2I bbox = GetBoundingBox(); BOX2I bbox = GetBoundingBox();
bbox.Inflate( 2 * GetOwnClearance( GetLayer() ) );
BOARD* board = GetBoard();
if( board )
bbox.Inflate( 2 * board->GetDesignSettings().GetBiggestClearanceValue() );
return bbox; 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() ) for( PAD* pad : footprint->Pads() )
{ {
if( pad->IsDirty() ) if( pad->IsDirty() )
{
pad->BuildEffectiveShapes( UNDEFINED_LAYER ); pad->BuildEffectiveShapes( UNDEFINED_LAYER );
pad->BuildEffectivePolygon();
}
} }
for( ZONE* zone : footprint->Zones() ) for( ZONE* zone : footprint->Zones() )