Performance enhancements.
This commit is contained in:
parent
c3eb8dccda
commit
3fd128a75b
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
48
pcbnew/pad.h
48
pcbnew/pad.h
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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() )
|
||||
|
|
Loading…
Reference in New Issue