Build out PADSTACK::Compare().

Also add angle to PCB_BARCODE::Compare().
This commit is contained in:
Jeff Young
2026-01-31 15:13:29 +00:00
parent 30d77f11de
commit 0959b553d1
3 changed files with 175 additions and 4 deletions
+167 -4
View File
@@ -1350,13 +1350,60 @@ std::optional<bool> PADSTACK::IsFilled() const
}
#define TEST( a, b ) { if( a != b ) return a - b; }
int PADSTACK::Compare( const PADSTACK* aLeft, const PADSTACK* aRight )
{
// TODO: Implement full comparison
if( aLeft == aRight )
return 0;
int diff;
return 1;
TEST( (int) aLeft->m_mode, (int) aRight->m_mode );
if( aLeft->m_layerSet != aRight->m_layerSet )
return aLeft->m_layerSet.Seq() < aRight->m_layerSet.Seq();
if( ( diff = aLeft->m_customName.Cmp( aRight->m_customName ) ) != 0 )
return diff;
TEST( aLeft->m_orientation.AsTenthsOfADegree(), aRight->m_orientation.AsTenthsOfADegree() );
if( ( diff = aLeft->m_frontMaskProps.Compare( aRight->m_frontMaskProps ) ) != 0 )
return diff;
if( ( diff = aLeft->m_backMaskProps.Compare( aRight->m_backMaskProps ) ) != 0 )
return diff;
TEST( (int) aLeft->m_unconnectedLayerMode, (int) aRight->m_unconnectedLayerMode );
TEST( (int) aLeft->m_customShapeInZoneMode, (int) aRight->m_customShapeInZoneMode );
if( ( diff = aLeft->m_drill.Compare( aRight->m_drill ) ) != 0 )
return diff;
if( ( diff = aLeft->m_secondaryDrill.Compare( aRight->m_secondaryDrill ) ) != 0 )
return diff;
if( ( diff = aLeft->m_tertiaryDrill.Compare( aRight->m_tertiaryDrill ) ) != 0 )
return diff;
if( ( diff = aLeft->m_frontPostMachining.Compare( aRight->m_frontPostMachining ) ) != 0 )
return diff;
if( ( diff = aLeft->m_backPostMachining.Compare( aRight->m_backPostMachining ) ) != 0 )
return diff;
aLeft->ForEachUniqueLayer(
[&]( PCB_LAYER_ID aLayer )
{
if( diff != 0 ) // we want to return the first non-matching layer
return;
diff = aLeft->CopperLayer( aLayer ).Compare( aRight->CopperLayer( aLayer ) );
} );
if( diff != 0 )
return diff;
return 0;
}
@@ -1423,6 +1470,30 @@ bool PADSTACK::SHAPE_PROPS::operator==( const SHAPE_PROPS& aOther ) const
}
int PADSTACK::SHAPE_PROPS::Compare( const PADSTACK::SHAPE_PROPS& aOther ) const
{
TEST( (int) shape, (int) aOther.shape );
TEST( (int) anchor_shape, (int) aOther.anchor_shape );
TEST( size.x, aOther.size.x );
if( shape != PAD_SHAPE::CIRCLE && ( shape != PAD_SHAPE::CUSTOM || anchor_shape != PAD_SHAPE::CIRCLE ) )
TEST( size.y, aOther.size.y );
TEST( offset.x, aOther.offset.x );
TEST( offset.y, aOther.offset.y );
if( abs( round_rect_radius_ratio - aOther.round_rect_radius_ratio ) > 0.0001 )
return round_rect_radius_ratio > aOther.round_rect_radius_ratio ? 1 : -1;
if( abs( chamfered_rect_ratio - aOther.chamfered_rect_ratio ) > 0.0001 )
return chamfered_rect_ratio > aOther.chamfered_rect_ratio ? 1 : -1;
TEST( chamfered_rect_positions, aOther.chamfered_rect_positions );
return 0;
}
bool PADSTACK::COPPER_LAYER_PROPS::operator==( const COPPER_LAYER_PROPS& aOther ) const
{
if( !( shape == aOther.shape ) ) return false;
@@ -1440,6 +1511,49 @@ bool PADSTACK::COPPER_LAYER_PROPS::operator==( const COPPER_LAYER_PROPS& aOther
}
#define TEST_OPT( a, b, v ) \
{ \
if( a.has_value() != b.has_value() ) \
return a.has_value() - b.has_value(); \
if( (int) a.value_or( v ) - (int) b.value_or( v ) != 0 ) \
return (int) a.value_or( v ) - (int) b.value_or( v ); \
}
#define TEST_OPT_ANGLE( a, b, v ) \
{ \
if( a.has_value() != b.has_value() ) \
return a.has_value() - b.has_value(); \
if( abs( a.value_or( v ).AsDegrees() - b.value_or( v ).AsDegrees() ) > 0.001 ) \
return a.value_or( v ).AsDegrees() > b.value_or( v ).AsDegrees() ? 1 : -1; \
}
int PADSTACK::COPPER_LAYER_PROPS::Compare( const PADSTACK::COPPER_LAYER_PROPS& aOther ) const
{
int diff;
if( ( diff = shape.Compare( aOther.shape ) ) != 0 )
return diff;
TEST_OPT( zone_connection, aOther.zone_connection, ZONE_CONNECTION::NONE );
TEST_OPT( thermal_spoke_width, aOther.thermal_spoke_width, 0 );
TEST_OPT_ANGLE( thermal_spoke_angle, aOther.thermal_spoke_angle, ANGLE_0 );
TEST_OPT( thermal_gap, aOther.thermal_gap, 0 );
TEST_OPT( clearance, aOther.clearance, 0 );
if( ( diff = (int) custom_shapes.size() - (int) aOther.custom_shapes.size() ) != 0 )
return diff;
for( int ii = 0; ii < (int) custom_shapes.size(); ++ii )
{
if( ( diff = custom_shapes[ii]->Compare( aOther.custom_shapes[ii].get() ) ) != 0 )
return diff;
}
return 0;
}
bool PADSTACK::MASK_LAYER_PROPS::operator==( const MASK_LAYER_PROPS& aOther ) const
{
return solder_mask_margin == aOther.solder_mask_margin &&
@@ -1452,6 +1566,25 @@ bool PADSTACK::MASK_LAYER_PROPS::operator==( const MASK_LAYER_PROPS& aOther ) co
}
int PADSTACK::MASK_LAYER_PROPS::Compare( const MASK_LAYER_PROPS& aOther ) const
{
TEST_OPT( solder_mask_margin, aOther.solder_mask_margin, 0 );
TEST_OPT( solder_paste_margin, aOther.solder_paste_margin, 0 );
if( solder_paste_margin_ratio.has_value() != aOther.solder_paste_margin_ratio.has_value() )
return solder_paste_margin_ratio.has_value() - aOther.solder_paste_margin_ratio.has_value();
if( abs( solder_paste_margin_ratio.value_or( 0.0 ) - aOther.solder_paste_margin_ratio.value_or( 0.0 ) ) > 0.0001 )
return solder_paste_margin_ratio.value_or( 0.0 ) > aOther.solder_paste_margin_ratio.value_or( 0.0 ) ? 1 : -1;
TEST_OPT( has_solder_mask, aOther.has_solder_mask, false );
TEST_OPT( has_solder_paste, aOther.has_solder_paste, false );
TEST_OPT( has_covering, aOther.has_covering, false );
TEST_OPT( has_plugging, aOther.has_plugging, false );
return 0;
}
bool PADSTACK::DRILL_PROPS::operator==( const DRILL_PROPS& aOther ) const
{
return size == aOther.size &&
@@ -1463,6 +1596,25 @@ bool PADSTACK::DRILL_PROPS::operator==( const DRILL_PROPS& aOther ) const
}
int PADSTACK::DRILL_PROPS::Compare( const DRILL_PROPS& aOther ) const
{
TEST( (int) shape, (int) aOther.shape );
TEST( size.x, aOther.size.x );
if( shape != PAD_DRILL_SHAPE::CIRCLE )
TEST( size.y, aOther.size.y );
TEST( (int) start, (int) aOther.start );
TEST( (int) end, (int) aOther.end );
TEST_OPT( is_filled, aOther.is_filled, false );
TEST_OPT( is_capped, aOther.is_capped, false );
return 0;
}
bool PADSTACK::POST_MACHINING_PROPS::operator==( const POST_MACHINING_PROPS& aOther ) const
{
return mode == aOther.mode &&
@@ -1472,6 +1624,17 @@ bool PADSTACK::POST_MACHINING_PROPS::operator==( const POST_MACHINING_PROPS& aOt
}
int PADSTACK::POST_MACHINING_PROPS::Compare( const PADSTACK::POST_MACHINING_PROPS& aOther ) const
{
TEST_OPT( mode, aOther.mode, PAD_DRILL_POST_MACHINING_MODE::UNKNOWN );
TEST( size, aOther.size );
TEST( depth, aOther.depth );
TEST( angle, aOther.angle );
return 0;
}
void PADSTACK::SetMode( MODE aMode )
{
m_mode = aMode;