Add asserts to flush out incorrect uses of GetLayer().

This commit is contained in:
Jeff Young 2022-02-18 10:12:11 +00:00
parent 233f86e8cf
commit 5efa354f0f
7 changed files with 147 additions and 197 deletions

View File

@ -376,7 +376,7 @@ SEARCH_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData )
break;
case FP_TEXT::TEXT_is_DIVERS:
if( !m_Guide->IsLayerVisible( layer ) && m_Guide->IgnoreNonVisibleLayers() )
if( !m_Guide->IsLayerVisible( layer ) )
goto exit;
break;
@ -466,145 +466,144 @@ SEARCH_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* testItem, void* testData )
}
}
if( item->IsOnLayer( m_Guide->GetPreferredLayer() ) || m_Guide->IgnorePreferredLayer() )
if( ( item->IsOnLayer( m_Guide->GetPreferredLayer() ) )
&& ( !item->IsLocked() || !m_Guide->IgnoreLockedItems() ) )
{
PCB_LAYER_ID layer = item->GetLayer();
// footprints and their subcomponents: reference, value and pads are not sensitive
// to the layer visibility controls. They all have their own separate visibility
// controls for vias, GetLayer() has no meaning, but IsOnLayer() works fine. User
// text in a footprint *is* sensitive to layer visibility but that was already handled.
if( via || footprint || pad || m_Guide->IsLayerVisible( layer )
|| !m_Guide->IgnoreNonVisibleLayers() )
int accuracy = KiROUND( 5 * m_Guide->OnePixelInIU() );
if( zone )
{
if( !m_Guide->IsLayerLocked( layer ) || !m_Guide->IgnoreLockedLayers() )
if( zone->HitTestForCorner( m_refPos, accuracy * 2 )
|| zone->HitTestForEdge( m_refPos, accuracy ) )
{
if( !item->IsLocked() || !m_Guide->IgnoreLockedItems() )
Append( item );
goto exit;
}
else if( !m_Guide->IgnoreZoneFills() )
{
for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
{
int accuracy = KiROUND( 5 * m_Guide->OnePixelInIU() );
if( m_Guide->IsLayerVisible( layer )
&& zone->HitTestFilledArea( layer, m_refPos ) )
{
Append( item );
goto exit;
}
}
}
}
else if( footprint )
{
if( footprint->HitTest( m_refPos, accuracy )
&& footprint->HitTestAccurate( m_refPos, accuracy ) )
{
Append( item );
goto exit;
}
}
else if( pad || via )
{
if( item->HitTest( m_refPos, accuracy ) )
{
Append( item );
goto exit;
}
}
else
{
PCB_LAYER_ID layer = item->GetLayer();
if( zone )
{
bool testFill = !m_Guide->IgnoreZoneFills();
if( m_Guide->IsLayerVisible( layer ) )
{
if( dimension )
{
// Dimensions feel particularly hard to select, probably due to their
// noisy shape making it feel like they should have a larger boundary.
accuracy = KiROUND( accuracy * 1.5 );
}
if( zone->HitTestForCorner( m_refPos, accuracy * 2 )
|| zone->HitTestForEdge( m_refPos, accuracy )
|| ( testFill && zone->HitTestFilledArea( layer, m_refPos ) ) )
{
Append( item );
goto exit;
}
}
else if( item->Type() == PCB_FOOTPRINT_T )
{
if( footprint->HitTest( m_refPos, accuracy )
&& footprint->HitTestAccurate( m_refPos, accuracy ) )
{
Append( item );
goto exit;
}
}
else if( shape )
{
if( shape->HitTest( m_refPos, accuracy ) )
{
Append( shape );
goto exit;
}
}
else if( dimension )
{
// Dimensions feel particularly hard to select, probably due to their
// noisy shape making it feel like they should have a larger boundary.
if( dimension->HitTest( m_refPos, KiROUND( accuracy * 1.5 ) ) )
{
Append( dimension );
goto exit;
}
}
else
{
if( item->HitTest( m_refPos, accuracy ) )
{
Append( item );
goto exit;
}
}
if( item->HitTest( m_refPos, accuracy ) )
{
Append( item );
goto exit;
}
}
}
}
if( m_Guide->IncludeSecondary() )
if( m_Guide->IncludeSecondary()
&& ( !item->IsLocked() || !m_Guide->IgnoreLockedItems() ) )
{
// for now, "secondary" means "tolerate any layer". It has
// no effect on other criteria, since there is a separate "ignore" control for
// those in the COLLECTORS_GUIDE
PCB_LAYER_ID layer = item->GetLayer();
// for now, "secondary" means "tolerate any visible layer". It has no effect on other
// criteria, since there is a separate "ignore" control for those in the COLLECTORS_GUIDE
// footprints and their subcomponents: reference, value and pads are not sensitive
// to the layer visibility controls. They all have their own separate visibility
// controls for vias, GetLayer() has no meaning, but IsOnLayer() works fine. User
// text in a footprint *is* sensitive to layer visibility but that was already handled.
if( via || footprint || pad || zone || m_Guide->IsLayerVisible( layer )
|| !m_Guide->IgnoreNonVisibleLayers() )
int accuracy = KiROUND( 5 * m_Guide->OnePixelInIU() );
if( zone )
{
if( !m_Guide->IsLayerLocked( layer ) || !m_Guide->IgnoreLockedLayers() )
if( zone->HitTestForCorner( m_refPos, accuracy * 2 )
|| zone->HitTestForEdge( m_refPos, accuracy ) )
{
if( !item->IsLocked() || !m_Guide->IgnoreLockedItems() )
Append2nd( item );
goto exit;
}
else if( !m_Guide->IgnoreZoneFills() )
{
for( PCB_LAYER_ID layer : zone->GetLayerSet().Seq() )
{
int accuracy = KiROUND( 5 * m_Guide->OnePixelInIU() );
if( m_Guide->IsLayerVisible( layer )
&& zone->HitTestFilledArea( layer, m_refPos ) )
{
Append2nd( item );
goto exit;
}
}
}
}
else if( item->Type() == PCB_FOOTPRINT_T )
{
if( footprint->HitTest( m_refPos, accuracy )
&& footprint->HitTestAccurate( m_refPos, accuracy ) )
{
Append2nd( item );
goto exit;
}
}
else if( pad || via )
{
if( item->HitTest( m_refPos, accuracy ) )
{
Append2nd( item );
goto exit;
}
}
else
{
PCB_LAYER_ID layer = item->GetLayer();
if( zone )
{
bool testFill = !m_Guide->IgnoreZoneFills();
if( m_Guide->IsLayerVisible( layer ) )
{
if( dimension )
{
// Dimensions feel particularly hard to select, probably due to their
// noisy shape making it feel like they should have a larger boundary.
accuracy = KiROUND( accuracy * 1.5 );
}
if( zone->HitTestForCorner( m_refPos, accuracy * 2 )
|| zone->HitTestForEdge( m_refPos, accuracy )
|| ( testFill && zone->HitTestFilledArea( layer, m_refPos ) ) )
{
Append2nd( item );
goto exit;
}
}
else if( item->Type() == PCB_FOOTPRINT_T )
{
if( footprint->HitTest( m_refPos, accuracy )
&& footprint->HitTestAccurate( m_refPos, accuracy ) )
{
Append2nd( item );
goto exit;
}
}
else if( shape )
{
if( shape->HitTest( m_refPos, accuracy ) )
{
Append2nd( shape );
goto exit;
}
}
else if( dimension )
{
// Dimensions feels particularly hard to select, probably due to their
// noisy shape making it feel like they should have a larger boundary.
if( dimension->HitTest( m_refPos, KiROUND( accuracy * 1.5 ) ) )
{
Append2nd( dimension );
goto exit;
}
}
else
{
if( item->HitTest( m_refPos, 0 ) )
{
Append2nd( item );
goto exit;
}
}
if( item->HitTest( m_refPos, accuracy ) )
{
Append2nd( item );
goto exit;
}
}
}

View File

@ -62,38 +62,16 @@ class COLLECTORS_GUIDE
public:
virtual ~COLLECTORS_GUIDE() {}
/**
* @return true if the given layer is locked, else false.
*/
virtual bool IsLayerLocked( PCB_LAYER_ID layer ) const = 0;
/**
* @return true if the given layer is visible, else false.
*/
virtual bool IsLayerVisible( PCB_LAYER_ID layer ) const = 0;
/**
* @return true if should ignore locked layers, else false.
*/
virtual bool IgnoreLockedLayers() const = 0;
/**
* @return true if should ignore non-visible layers, else false.
*/
virtual bool IgnoreNonVisibleLayers() const = 0;
/**
* @return the preferred layer for HitTest()ing.
*/
virtual PCB_LAYER_ID GetPreferredLayer() const = 0;
/**
* Provide wildcard behavior regarding the preferred layer.
*
* @return true if should ignore preferred layer, else false.
*/
virtual bool IgnorePreferredLayer() const = 0;
/**
* @return true if should ignore locked items, else false.
*/
@ -392,10 +370,7 @@ public:
VECTOR2I one( 1, 1 );
m_preferredLayer = aPreferredLayer;
m_ignorePreferredLayer = false;
m_visibleLayers = aVisibleLayerMask;
m_ignoreLockedLayers = true;
m_ignoreNonVisibleLayers = true;
m_ignoreLockedItems = false;
#if defined(USE_MATCH_LAYER)
@ -426,19 +401,6 @@ public:
m_onePixelInIU = abs( aView->ToWorld( one, false ).x );
}
/**
* @return true if the given layer is locked, else false.
*/
bool IsLayerLocked( PCB_LAYER_ID aLayerId ) const override
{
return m_lockedLayers[aLayerId];
}
void SetLayerLocked( PCB_LAYER_ID aLayerId, bool isLocked )
{
m_lockedLayers.set( aLayerId, isLocked );
}
/**
* @return true if the given layer is visible, else false.
*/
@ -452,32 +414,12 @@ public:
}
void SetLayerVisibleBits( LSET aLayerBits ) { m_visibleLayers = aLayerBits; }
/**
* @return true if should ignore locked layers, else false.
*/
bool IgnoreLockedLayers() const override { return m_ignoreLockedLayers; }
void SetIgnoreLockedLayers( bool ignore ) { m_ignoreLockedLayers = ignore; }
/**
* @return true if should ignore non-visible layers, else false.
*/
bool IgnoreNonVisibleLayers() const override { return m_ignoreNonVisibleLayers; }
void SetIgnoreNonVisibleLayers( bool ignore ) { m_ignoreLockedLayers = ignore; }
/**
* @return int - the preferred layer for HitTest()ing.
*/
PCB_LAYER_ID GetPreferredLayer() const override { return m_preferredLayer; }
void SetPreferredLayer( PCB_LAYER_ID aLayer ) { m_preferredLayer = aLayer; }
/**
* Provide wildcard behavior regarding the preferred layer.
*
* @return true if should ignore preferred layer, else false.
*/
bool IgnorePreferredLayer() const override { return m_ignorePreferredLayer; }
void SetIgnorePreferredLayer( bool ignore ) { m_ignorePreferredLayer = ignore; }
/**
* @return true if should ignore locked items, else false.
*/
@ -575,13 +517,8 @@ private:
// a carrier object and its functions are what is used, and data only indirectly.
PCB_LAYER_ID m_preferredLayer;
bool m_ignorePreferredLayer;
LSET m_lockedLayers; ///< bit-mapped layer locked bits
bool m_ignoreLockedLayers;
LSET m_visibleLayers; ///< bit-mapped layer visible bits
bool m_ignoreNonVisibleLayers;
bool m_ignoreLockedItems;
bool m_includeSecondary;

View File

@ -200,6 +200,14 @@ bool PAD::IsFlipped() const
}
PCB_LAYER_ID PAD::GetLayer() const
{
wxFAIL_MSG( wxT( "Pads exist on multiple layers. GetLayer() has no meaning." ) );
return BOARD_ITEM::GetLayer();
}
bool PAD::FlashLayer( LSET aLayers ) const
{
for( auto layer : aLayers.Seq() )
@ -958,7 +966,7 @@ void PAD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>&
}
wxString source;
int clearance = GetOwnClearance( GetLayer(), &source );
int clearance = GetOwnClearance( UNDEFINED_LAYER, &source );
if( !source.IsEmpty() )
{

View File

@ -585,6 +585,8 @@ public:
*/
bool FlashLayer( int aLayer ) const;
PCB_LAYER_ID GetLayer() const override;
/**
* Check to see if the pad should be flashed to any of the layers in the set.
*

View File

@ -2324,9 +2324,11 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili
// If the footprint has no items except the reference and value fields, include the
// footprint in the selections.
if( footprint->GraphicalItems().empty()
&& footprint->Pads().empty()
&& footprint->Zones().empty() )
&& footprint->Pads().empty()
&& footprint->Zones().empty() )
{
return true;
}
for( const BOARD_ITEM* item : footprint->GraphicalItems() )
{
@ -2505,7 +2507,7 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili
break;
}
return aItem->ViewGetLOD( aItem->GetLayer(), view() ) < view()->GetScale();
return true;
}

View File

@ -205,10 +205,21 @@ VECTOR2I ZONE::GetPosition() const
PCB_LAYER_ID ZONE::GetLayer() const
{
wxFAIL_MSG( wxT( "Zones exist on multiple layers. GetLayer() has no meaning." ) );
return BOARD_ITEM::GetLayer();
}
PCB_LAYER_ID ZONE::GetFirstLayer() const
{
if( m_layerSet.size() )
return m_layerSet.UIOrder()[0];
else
return UNDEFINED_LAYER;
}
bool ZONE::IsOnCopperLayer() const
{
return ( m_layerSet & LSET::AllCuMask() ).count() > 0;
@ -226,8 +237,6 @@ bool ZONE::CommonLayerExists( const LSET aLayerSet ) const
void ZONE::SetLayer( PCB_LAYER_ID aLayer )
{
SetLayerSet( LSET( aLayer ) );
m_layer = aLayer;
}
@ -255,14 +264,6 @@ void ZONE::SetLayerSet( LSET aLayerSet )
}
m_layerSet = aLayerSet;
// Set the single layer parameter. For zones that can be on many layers, this parameter
// is arbitrary at best, but some code still uses it.
// Priority is F_Cu then B_Cu then to the first selected layer
m_layer = aLayerSet.Seq()[0];
if( m_layer != F_Cu && aLayerSet[B_Cu] )
m_layer = B_Cu;
}
@ -589,7 +590,7 @@ void ZONE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>&
aList.emplace_back( _( "Filled Area" ), msg );
wxString source;
int clearance = GetOwnClearance( GetLayer(), &source );
int clearance = GetOwnClearance( UNDEFINED_LAYER, &source );
if( !source.IsEmpty() )
{
@ -647,12 +648,8 @@ void ZONE::Rotate( const VECTOR2I& aCentre, const EDA_ANGLE& aAngle )
void ZONE::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
{
Mirror( aCentre, aFlipLeftRight );
int copperLayerCount = GetBoard()->GetCopperLayerCount();
if( GetIsRuleArea() )
SetLayerSet( FlipLayerMask( GetLayerSet(), copperLayerCount ) );
else
SetLayer( FlipLayer( GetLayer(), copperLayerCount ) );
SetLayerSet( FlipLayerMask( GetLayerSet(), GetBoard()->GetCopperLayerCount() ) );
}
@ -854,7 +851,7 @@ void ZONE::HatchBorder()
int hatch_line_len = m_borderHatchPitch;
// To have a better look, give a slope depending on the layer
int layer = GetLayer();
int layer = GetLayerSet().Seq()[0];
int slope_flag = (layer & 1) ? 1 : -1; // 1 or -1
double slope = 0.707106 * slope_flag; // 45 degrees slope
int max_a, min_a;
@ -1181,7 +1178,9 @@ void ZONE::TransformSmoothedOutlineToPolygon( SHAPE_POLY_SET& aCornerBuffer, int
{
// Creates the zone outline polygon (with holes if any)
SHAPE_POLY_SET polybuffer;
BuildSmoothedPoly( polybuffer, GetLayer(), aBoardOutline );
// TODO: using GetFirstLayer() means it only works for single-layer zones....
BuildSmoothedPoly( polybuffer, GetFirstLayer(), aBoardOutline );
// Calculate the polygon with clearance
// holes are linked to the main outline, so only one polygon is created.

View File

@ -183,6 +183,9 @@ public:
virtual PCB_LAYER_ID GetLayer() const override;
// Return the first layer in GUI sequence.
PCB_LAYER_ID GetFirstLayer() const;
virtual bool IsOnLayer( PCB_LAYER_ID ) const override;
virtual void ViewGetLayers( int aLayers[], int& aCount ) const override;