mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-04-11 14:59:50 +00:00
Consolidation of Component Class implementation
- Moves functionality to FOOTPRINT class from BOARD_ITEM - Renames DRC property from ComponentClass to Component_Class - Adds DRC checks QA for A.Component_Class and a.hasComponentClass('x')
This commit is contained in:
parent
43c3cd57eb
commit
db072a524c
include
pcbnew
qa
@ -37,7 +37,6 @@
|
||||
class BOARD;
|
||||
class BOARD_DESIGN_SETTINGS;
|
||||
class BOARD_ITEM_CONTAINER;
|
||||
class COMPONENT_CLASS;
|
||||
class SHAPE_POLY_SET;
|
||||
class SHAPE_SEGMENT;
|
||||
class PCB_BASE_FRAME;
|
||||
@ -81,7 +80,7 @@ class BOARD_ITEM : public EDA_ITEM
|
||||
public:
|
||||
BOARD_ITEM( BOARD_ITEM* aParent, KICAD_T idtype, PCB_LAYER_ID aLayer = F_Cu ) :
|
||||
EDA_ITEM( aParent, idtype, false, true ), m_layer( aLayer ), m_isKnockout( false ),
|
||||
m_isLocked( false ), m_group( nullptr ), m_componentClass( nullptr )
|
||||
m_isLocked( false ), m_group( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
@ -425,12 +424,6 @@ public:
|
||||
bool operator() ( const BOARD_ITEM* a, const BOARD_ITEM* b ) const;
|
||||
};
|
||||
|
||||
void SetComponentClass( const COMPONENT_CLASS* aClass ) { m_componentClass = aClass; }
|
||||
|
||||
const COMPONENT_CLASS* GetComponentClass() const { return m_componentClass; }
|
||||
|
||||
wxString GetComponentClassAsString() const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Return a string (to be shown to the user) describing a layer mask.
|
||||
@ -446,8 +439,6 @@ protected:
|
||||
bool m_isLocked;
|
||||
|
||||
PCB_GROUP* m_group;
|
||||
|
||||
const COMPONENT_CLASS* m_componentClass;
|
||||
};
|
||||
|
||||
#ifndef SWIG
|
||||
|
@ -380,17 +380,6 @@ wxString BOARD_ITEM::GetParentAsString() const
|
||||
}
|
||||
|
||||
|
||||
wxString BOARD_ITEM::GetComponentClassAsString() const
|
||||
{
|
||||
if( m_componentClass )
|
||||
{
|
||||
return m_componentClass->GetFullName();
|
||||
}
|
||||
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
|
||||
static struct BOARD_ITEM_DESC
|
||||
{
|
||||
BOARD_ITEM_DESC()
|
||||
@ -430,13 +419,6 @@ static struct BOARD_ITEM_DESC
|
||||
BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( aItem );
|
||||
return item && item->GetBoard() && !item->GetBoard()->IsFootprintHolder();
|
||||
} );
|
||||
|
||||
// Used only in DRC engine
|
||||
propMgr.AddProperty( new PROPERTY<BOARD_ITEM, wxString>(
|
||||
_HKI( "ComponentClass" ), NO_SETTER( BOARD_ITEM, wxString ),
|
||||
&BOARD_ITEM::GetComponentClassAsString ) )
|
||||
.SetIsHiddenFromLibraryEditors()
|
||||
.SetIsHiddenFromPropertiesManager();
|
||||
}
|
||||
} _BOARD_ITEM_DESC;
|
||||
|
||||
|
@ -70,7 +70,8 @@ FOOTPRINT::FOOTPRINT( BOARD* parent ) :
|
||||
m_boundingBoxCacheTimeStamp( 0 ),
|
||||
m_textExcludedBBoxCacheTimeStamp( 0 ),
|
||||
m_hullCacheTimeStamp( 0 ),
|
||||
m_initial_comments( nullptr )
|
||||
m_initial_comments( nullptr ),
|
||||
m_componentClass( nullptr )
|
||||
{
|
||||
m_attributes = 0;
|
||||
m_layer = F_Cu;
|
||||
@ -138,6 +139,8 @@ FOOTPRINT::FOOTPRINT( const FOOTPRINT& aFootprint ) :
|
||||
m_netTiePadGroups = aFootprint.m_netTiePadGroups;
|
||||
m_fileFormatVersionAtLoad = aFootprint.m_fileFormatVersionAtLoad;
|
||||
|
||||
m_componentClass = aFootprint.m_componentClass;
|
||||
|
||||
std::map<BOARD_ITEM*, BOARD_ITEM*> ptrMap;
|
||||
|
||||
// Copy fields
|
||||
@ -708,6 +711,8 @@ FOOTPRINT& FOOTPRINT::operator=( FOOTPRINT&& aOther )
|
||||
m_zoneConnection = aOther.m_zoneConnection;
|
||||
m_netTiePadGroups = aOther.m_netTiePadGroups;
|
||||
|
||||
m_componentClass = aOther.m_componentClass;
|
||||
|
||||
// Move the fields
|
||||
m_fields.clear();
|
||||
|
||||
@ -800,6 +805,8 @@ FOOTPRINT& FOOTPRINT::operator=( const FOOTPRINT& aOther )
|
||||
m_zoneConnection = aOther.m_zoneConnection;
|
||||
m_netTiePadGroups = aOther.m_netTiePadGroups;
|
||||
|
||||
m_componentClass = aOther.m_componentClass;
|
||||
|
||||
std::map<BOARD_ITEM*, BOARD_ITEM*> ptrMap;
|
||||
|
||||
// Copy fields
|
||||
@ -3781,6 +3788,17 @@ void FOOTPRINT::EmbedFonts()
|
||||
}
|
||||
|
||||
|
||||
wxString FOOTPRINT::GetComponentClassAsString() const
|
||||
{
|
||||
if( m_componentClass )
|
||||
{
|
||||
return m_componentClass->GetFullName();
|
||||
}
|
||||
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
|
||||
static struct FOOTPRINT_DESC
|
||||
{
|
||||
FOOTPRINT_DESC()
|
||||
@ -3846,6 +3864,13 @@ static struct FOOTPRINT_DESC
|
||||
NO_SETTER( FOOTPRINT, wxString ), &FOOTPRINT::GetKeywords ),
|
||||
groupFields );
|
||||
|
||||
// Used only in DRC engine
|
||||
propMgr.AddProperty( new PROPERTY<FOOTPRINT, wxString>(
|
||||
_HKI( "Component Class" ), NO_SETTER( FOOTPRINT, wxString ),
|
||||
&FOOTPRINT::GetComponentClassAsString ) )
|
||||
.SetIsHiddenFromLibraryEditors()
|
||||
.SetIsHiddenFromPropertiesManager();
|
||||
|
||||
const wxString groupAttributes = _HKI( "Attributes" );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<FOOTPRINT, bool>( _HKI( "Not in Schematic" ),
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <board_item_container.h>
|
||||
#include <board_item.h>
|
||||
#include <collectors.h>
|
||||
#include <component_class_manager.h>
|
||||
#include <embedded_files.h>
|
||||
#include <layer_ids.h> // ALL_LAYERS definition.
|
||||
#include <lset.h>
|
||||
@ -993,6 +994,13 @@ public:
|
||||
|
||||
double Similarity( const BOARD_ITEM& aOther ) const override;
|
||||
|
||||
void SetComponentClass( const COMPONENT_CLASS* aClass ) { m_componentClass = aClass; }
|
||||
|
||||
const COMPONENT_CLASS* GetComponentClass() const { return m_componentClass; }
|
||||
|
||||
wxString GetComponentClassAsString() const;
|
||||
|
||||
|
||||
bool operator==( const BOARD_ITEM& aOther ) const override;
|
||||
bool operator==( const FOOTPRINT& aOther ) const;
|
||||
|
||||
@ -1087,6 +1095,8 @@ private:
|
||||
mutable HASH_128 m_courtyard_cache_front_hash;
|
||||
mutable HASH_128 m_courtyard_cache_back_hash;
|
||||
mutable std::mutex m_courtyard_cache_mutex;
|
||||
|
||||
const COMPONENT_CLASS* m_componentClass;
|
||||
};
|
||||
|
||||
#endif // FOOTPRINT_H
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <board.h>
|
||||
#include <footprint.h>
|
||||
#include <lset.h>
|
||||
#include <board_connected_item.h>
|
||||
#include <pcbexpr_evaluator.h>
|
||||
@ -169,13 +170,15 @@ class PCBEXPR_COMPONENT_CLASS_VALUE : public LIBEVAL::VALUE
|
||||
{
|
||||
public:
|
||||
PCBEXPR_COMPONENT_CLASS_VALUE( BOARD_ITEM* aItem ) :
|
||||
LIBEVAL::VALUE( wxEmptyString ), m_item( aItem ){};
|
||||
LIBEVAL::VALUE( wxEmptyString ), m_item( dynamic_cast<FOOTPRINT*>( aItem ) )
|
||||
{};
|
||||
|
||||
const wxString& AsString() const override
|
||||
{
|
||||
const COMPONENT_CLASS* compClass = m_item->GetComponentClass();
|
||||
if( !m_item )
|
||||
return LIBEVAL::VALUE::AsString();
|
||||
|
||||
if( compClass )
|
||||
if( const COMPONENT_CLASS* compClass = m_item->GetComponentClass() )
|
||||
{
|
||||
const_cast<PCBEXPR_COMPONENT_CLASS_VALUE*>( this )->Set( compClass->GetFullName() );
|
||||
}
|
||||
@ -188,6 +191,9 @@ public:
|
||||
if( const PCBEXPR_COMPONENT_CLASS_VALUE* bValue =
|
||||
dynamic_cast<const PCBEXPR_COMPONENT_CLASS_VALUE*>( b ) )
|
||||
{
|
||||
if( !m_item || !bValue->m_item )
|
||||
return LIBEVAL::VALUE::EqualTo( aCtx, b );
|
||||
|
||||
const COMPONENT_CLASS* aClass = m_item->GetComponentClass();
|
||||
const COMPONENT_CLASS* bClass = bValue->m_item->GetComponentClass();
|
||||
|
||||
@ -206,6 +212,9 @@ public:
|
||||
if( const PCBEXPR_COMPONENT_CLASS_VALUE* bValue =
|
||||
dynamic_cast<const PCBEXPR_COMPONENT_CLASS_VALUE*>( b ) )
|
||||
{
|
||||
if( !m_item || !bValue->m_item )
|
||||
return LIBEVAL::VALUE::EqualTo( aCtx, b );
|
||||
|
||||
const COMPONENT_CLASS* aClass = m_item->GetComponentClass();
|
||||
const COMPONENT_CLASS* bClass = bValue->m_item->GetComponentClass();
|
||||
|
||||
@ -220,7 +229,7 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
BOARD_ITEM* m_item;
|
||||
FOOTPRINT* m_item;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1234,8 +1234,12 @@ static void hasComponentClassFunc( LIBEVAL::CONTEXT* aCtx, void* self )
|
||||
result->SetDeferredEval(
|
||||
[item, arg]() -> double
|
||||
{
|
||||
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( item );
|
||||
const COMPONENT_CLASS* compClass = boardItem->GetComponentClass();
|
||||
FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( item );
|
||||
|
||||
if( !footprint )
|
||||
return 0.0;
|
||||
|
||||
const COMPONENT_CLASS* compClass = footprint->GetComponentClass();
|
||||
|
||||
if( compClass && compClass->ContainsClassName( arg->AsString() ) )
|
||||
return 1.0;
|
||||
|
25
qa/data/pcbnew/component_classes_drc.kicad_dru
Normal file
25
qa/data/pcbnew/component_classes_drc.kicad_dru
Normal file
@ -0,0 +1,25 @@
|
||||
(version 1)
|
||||
(rule Rule1
|
||||
(condition "A.intersectsArea('AREA1') && A.Type == 'Footprint'")
|
||||
(constraint assertion "A.Component_Class == 'CLASS1'")
|
||||
)
|
||||
|
||||
(rule Rule2
|
||||
(condition "A.intersectsArea('AREA3') && A.Type == 'Footprint'")
|
||||
(constraint assertion "A.Component_Class != 'CLASS1'")
|
||||
)
|
||||
|
||||
(rule Rule3
|
||||
(condition "A.intersectsArea('AREA2') && A.Type == 'Footprint'")
|
||||
(constraint assertion "A.Component_Class == 'CLASS2,CLASS3'")
|
||||
)
|
||||
|
||||
(rule Rule4
|
||||
(condition "A.intersectsArea('AREA4') && A.Type == 'Footprint'")
|
||||
(constraint assertion "A.hasComponentClass('CLASS3')")
|
||||
)
|
||||
|
||||
(rule Rule5
|
||||
(condition "A.intersectsArea('AREA4') && A.Type == 'Footprint'")
|
||||
(constraint assertion "A.hasComponentClass('CLASS4')")
|
||||
)
|
qa/data/pcbnew/component_classes_drc.kicad_pcb
Normal file
LOADING design file
626
qa/data/pcbnew/component_classes_drc.kicad_pro
Normal file
626
qa/data/pcbnew/component_classes_drc.kicad_pro
Normal file
@ -0,0 +1,626 @@
|
||||
{
|
||||
"board": {
|
||||
"3dviewports": [],
|
||||
"design_settings": {
|
||||
"defaults": {
|
||||
"apply_defaults_to_fp_fields": false,
|
||||
"apply_defaults_to_fp_shapes": false,
|
||||
"apply_defaults_to_fp_text": false,
|
||||
"board_outline_line_width": 0.05,
|
||||
"copper_line_width": 0.2,
|
||||
"copper_text_italic": false,
|
||||
"copper_text_size_h": 1.5,
|
||||
"copper_text_size_v": 1.5,
|
||||
"copper_text_thickness": 0.3,
|
||||
"copper_text_upright": false,
|
||||
"courtyard_line_width": 0.05,
|
||||
"dimension_precision": 4,
|
||||
"dimension_units": 3,
|
||||
"dimensions": {
|
||||
"arrow_length": 1270000,
|
||||
"extension_offset": 500000,
|
||||
"keep_text_aligned": true,
|
||||
"suppress_zeroes": false,
|
||||
"text_position": 0,
|
||||
"units_format": 1
|
||||
},
|
||||
"fab_line_width": 0.1,
|
||||
"fab_text_italic": false,
|
||||
"fab_text_size_h": 1.0,
|
||||
"fab_text_size_v": 1.0,
|
||||
"fab_text_thickness": 0.15,
|
||||
"fab_text_upright": false,
|
||||
"other_line_width": 0.1,
|
||||
"other_text_italic": false,
|
||||
"other_text_size_h": 1.0,
|
||||
"other_text_size_v": 1.0,
|
||||
"other_text_thickness": 0.15,
|
||||
"other_text_upright": false,
|
||||
"pads": {
|
||||
"drill": 0.8,
|
||||
"height": 1.27,
|
||||
"width": 2.54
|
||||
},
|
||||
"silk_line_width": 0.1,
|
||||
"silk_text_italic": false,
|
||||
"silk_text_size_h": 1.0,
|
||||
"silk_text_size_v": 1.0,
|
||||
"silk_text_thickness": 0.1,
|
||||
"silk_text_upright": false,
|
||||
"zones": {
|
||||
"min_clearance": 0.0
|
||||
}
|
||||
},
|
||||
"diff_pair_dimensions": [],
|
||||
"drc_exclusions": [],
|
||||
"meta": {
|
||||
"version": 2
|
||||
},
|
||||
"rule_severities": {
|
||||
"annular_width": "error",
|
||||
"clearance": "error",
|
||||
"connection_width": "warning",
|
||||
"copper_edge_clearance": "error",
|
||||
"copper_sliver": "warning",
|
||||
"courtyards_overlap": "error",
|
||||
"creepage": "error",
|
||||
"diff_pair_gap_out_of_range": "error",
|
||||
"diff_pair_uncoupled_length_too_long": "error",
|
||||
"drill_out_of_range": "error",
|
||||
"duplicate_footprints": "warning",
|
||||
"extra_footprint": "warning",
|
||||
"footprint": "error",
|
||||
"footprint_filters_mismatch": "ignore",
|
||||
"footprint_symbol_mismatch": "warning",
|
||||
"footprint_type_mismatch": "ignore",
|
||||
"hole_clearance": "error",
|
||||
"hole_to_hole": "warning",
|
||||
"holes_co_located": "warning",
|
||||
"invalid_outline": "error",
|
||||
"isolated_copper": "warning",
|
||||
"item_on_disabled_layer": "error",
|
||||
"items_not_allowed": "error",
|
||||
"length_out_of_range": "error",
|
||||
"lib_footprint_issues": "warning",
|
||||
"lib_footprint_mismatch": "warning",
|
||||
"malformed_courtyard": "error",
|
||||
"microvia_drill_out_of_range": "error",
|
||||
"missing_courtyard": "ignore",
|
||||
"missing_footprint": "warning",
|
||||
"net_conflict": "warning",
|
||||
"npth_inside_courtyard": "ignore",
|
||||
"padstack": "warning",
|
||||
"pth_inside_courtyard": "ignore",
|
||||
"shorting_items": "error",
|
||||
"silk_edge_clearance": "warning",
|
||||
"silk_over_copper": "warning",
|
||||
"silk_overlap": "warning",
|
||||
"skew_out_of_range": "error",
|
||||
"solder_mask_bridge": "error",
|
||||
"starved_thermal": "error",
|
||||
"text_height": "warning",
|
||||
"text_thickness": "warning",
|
||||
"through_hole_pad_without_hole": "error",
|
||||
"too_many_vias": "error",
|
||||
"track_angle": "error",
|
||||
"track_dangling": "warning",
|
||||
"track_segment_length": "error",
|
||||
"track_width": "error",
|
||||
"tracks_crossing": "error",
|
||||
"unconnected_items": "error",
|
||||
"unresolved_variable": "error",
|
||||
"via_dangling": "warning",
|
||||
"zones_intersect": "error"
|
||||
},
|
||||
"rules": {
|
||||
"max_error": 0.005,
|
||||
"min_clearance": 0.0,
|
||||
"min_connection": 0.0,
|
||||
"min_copper_edge_clearance": 0.5,
|
||||
"min_groove_width": 0.0,
|
||||
"min_hole_clearance": 0.25,
|
||||
"min_hole_to_hole": 0.25,
|
||||
"min_microvia_diameter": 0.2,
|
||||
"min_microvia_drill": 0.1,
|
||||
"min_resolved_spokes": 2,
|
||||
"min_silk_clearance": 0.0,
|
||||
"min_text_height": 0.8,
|
||||
"min_text_thickness": 0.08,
|
||||
"min_through_hole_diameter": 0.3,
|
||||
"min_track_width": 0.0,
|
||||
"min_via_annular_width": 0.1,
|
||||
"min_via_diameter": 0.5,
|
||||
"solder_mask_to_copper_clearance": 0.0,
|
||||
"use_height_for_length_calcs": true
|
||||
},
|
||||
"teardrop_options": [
|
||||
{
|
||||
"td_onpthpad": true,
|
||||
"td_onroundshapesonly": false,
|
||||
"td_onsmdpad": true,
|
||||
"td_ontrackend": false,
|
||||
"td_onvia": true
|
||||
}
|
||||
],
|
||||
"teardrop_parameters": [
|
||||
{
|
||||
"td_allow_use_two_tracks": true,
|
||||
"td_curve_segcount": 0,
|
||||
"td_height_ratio": 1.0,
|
||||
"td_length_ratio": 0.5,
|
||||
"td_maxheight": 2.0,
|
||||
"td_maxlen": 1.0,
|
||||
"td_on_pad_in_zone": false,
|
||||
"td_target_name": "td_round_shape",
|
||||
"td_width_to_size_filter_ratio": 0.9
|
||||
},
|
||||
{
|
||||
"td_allow_use_two_tracks": true,
|
||||
"td_curve_segcount": 0,
|
||||
"td_height_ratio": 1.0,
|
||||
"td_length_ratio": 0.5,
|
||||
"td_maxheight": 2.0,
|
||||
"td_maxlen": 1.0,
|
||||
"td_on_pad_in_zone": false,
|
||||
"td_target_name": "td_rect_shape",
|
||||
"td_width_to_size_filter_ratio": 0.9
|
||||
},
|
||||
{
|
||||
"td_allow_use_two_tracks": true,
|
||||
"td_curve_segcount": 0,
|
||||
"td_height_ratio": 1.0,
|
||||
"td_length_ratio": 0.5,
|
||||
"td_maxheight": 2.0,
|
||||
"td_maxlen": 1.0,
|
||||
"td_on_pad_in_zone": false,
|
||||
"td_target_name": "td_track_end",
|
||||
"td_width_to_size_filter_ratio": 0.9
|
||||
}
|
||||
],
|
||||
"track_widths": [],
|
||||
"tuning_pattern_settings": {
|
||||
"diff_pair_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 1.0
|
||||
},
|
||||
"diff_pair_skew_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 0.6
|
||||
},
|
||||
"single_track_defaults": {
|
||||
"corner_radius_percentage": 80,
|
||||
"corner_style": 1,
|
||||
"max_amplitude": 1.0,
|
||||
"min_amplitude": 0.2,
|
||||
"single_sided": false,
|
||||
"spacing": 0.6
|
||||
}
|
||||
},
|
||||
"via_dimensions": [],
|
||||
"zones_allow_external_fillets": false
|
||||
},
|
||||
"ipc2581": {
|
||||
"dist": "",
|
||||
"distpn": "",
|
||||
"internal_id": "",
|
||||
"mfg": "",
|
||||
"mpn": ""
|
||||
},
|
||||
"layer_pairs": [],
|
||||
"layer_presets": [],
|
||||
"viewports": []
|
||||
},
|
||||
"boards": [],
|
||||
"cvpcb": {
|
||||
"equivalence_files": []
|
||||
},
|
||||
"erc": {
|
||||
"erc_exclusions": [],
|
||||
"meta": {
|
||||
"version": 0
|
||||
},
|
||||
"pin_map": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
]
|
||||
],
|
||||
"rule_severities": {
|
||||
"bus_definition_conflict": "error",
|
||||
"bus_entry_needed": "error",
|
||||
"bus_to_bus_conflict": "error",
|
||||
"bus_to_net_conflict": "error",
|
||||
"different_unit_footprint": "error",
|
||||
"different_unit_net": "error",
|
||||
"duplicate_reference": "error",
|
||||
"duplicate_sheet_names": "error",
|
||||
"endpoint_off_grid": "warning",
|
||||
"extra_units": "error",
|
||||
"footprint_filter": "ignore",
|
||||
"footprint_link_issues": "warning",
|
||||
"four_way_junction": "ignore",
|
||||
"global_label_dangling": "warning",
|
||||
"hier_label_mismatch": "error",
|
||||
"label_multiple_wires": "warning",
|
||||
"lib_symbol_issues": "warning",
|
||||
"lib_symbol_mismatch": "warning",
|
||||
"missing_bidi_pin": "warning",
|
||||
"missing_input_pin": "warning",
|
||||
"missing_power_pin": "error",
|
||||
"missing_unit": "warning",
|
||||
"multiple_net_names": "warning",
|
||||
"net_not_bus_member": "warning",
|
||||
"no_connect_connected": "warning",
|
||||
"no_connect_dangling": "warning",
|
||||
"pin_not_connected": "error",
|
||||
"pin_not_driven": "error",
|
||||
"pin_to_pin": "warning",
|
||||
"power_pin_not_driven": "error",
|
||||
"same_local_global_label": "warning",
|
||||
"similar_label_and_power": "warning",
|
||||
"similar_labels": "warning",
|
||||
"similar_power": "warning",
|
||||
"simulation_model_issue": "ignore",
|
||||
"single_global_label": "ignore",
|
||||
"unannotated": "error",
|
||||
"unconnected_wire_endpoint": "warning",
|
||||
"unit_value_mismatch": "error",
|
||||
"unresolved_variable": "error",
|
||||
"wire_dangling": "error"
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"pinned_footprint_libs": [],
|
||||
"pinned_symbol_libs": []
|
||||
},
|
||||
"meta": {
|
||||
"filename": "component_classes_drc.kicad_pro",
|
||||
"version": 1
|
||||
},
|
||||
"net_settings": {
|
||||
"classes": [
|
||||
{
|
||||
"bus_width": 12,
|
||||
"clearance": 0.2,
|
||||
"diff_pair_gap": 0.25,
|
||||
"diff_pair_via_gap": 0.25,
|
||||
"diff_pair_width": 0.2,
|
||||
"line_style": 0,
|
||||
"microvia_diameter": 0.3,
|
||||
"microvia_drill": 0.1,
|
||||
"name": "Default",
|
||||
"pcb_color": "rgba(0, 0, 0, 0.000)",
|
||||
"priority": -1,
|
||||
"schematic_color": "rgba(0, 0, 0, 0.000)",
|
||||
"track_width": 0.2,
|
||||
"via_diameter": 0.6,
|
||||
"via_drill": 0.3,
|
||||
"wire_width": 6
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"version": 4
|
||||
},
|
||||
"net_colors": null,
|
||||
"netclass_assignments": null,
|
||||
"netclass_patterns": []
|
||||
},
|
||||
"pcbnew": {
|
||||
"last_paths": {
|
||||
"gencad": "",
|
||||
"idf": "",
|
||||
"netlist": "",
|
||||
"plot": "",
|
||||
"pos_files": "",
|
||||
"specctra_dsn": "",
|
||||
"step": "",
|
||||
"svg": "",
|
||||
"vrml": ""
|
||||
},
|
||||
"page_layout_descr_file": ""
|
||||
},
|
||||
"schematic": {
|
||||
"annotate_start_num": 0,
|
||||
"bom_export_filename": "${PROJECTNAME}.csv",
|
||||
"bom_fmt_presets": [],
|
||||
"bom_fmt_settings": {
|
||||
"field_delimiter": ",",
|
||||
"keep_line_breaks": false,
|
||||
"keep_tabs": false,
|
||||
"name": "CSV",
|
||||
"ref_delimiter": ",",
|
||||
"ref_range_delimiter": "",
|
||||
"string_delimiter": "\""
|
||||
},
|
||||
"bom_presets": [],
|
||||
"bom_settings": {
|
||||
"exclude_dnp": false,
|
||||
"fields_ordered": [
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Reference",
|
||||
"name": "Reference",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Qty",
|
||||
"name": "${QUANTITY}",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "Value",
|
||||
"name": "Value",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "DNP",
|
||||
"name": "${DNP}",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "Exclude from BOM",
|
||||
"name": "${EXCLUDE_FROM_BOM}",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "Exclude from Board",
|
||||
"name": "${EXCLUDE_FROM_BOARD}",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": true,
|
||||
"label": "Footprint",
|
||||
"name": "Footprint",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Datasheet",
|
||||
"name": "Datasheet",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "Description",
|
||||
"name": "Description",
|
||||
"show": false
|
||||
},
|
||||
{
|
||||
"group_by": false,
|
||||
"label": "#",
|
||||
"name": "${ITEM_NUMBER}",
|
||||
"show": false
|
||||
}
|
||||
],
|
||||
"filter_string": "",
|
||||
"group_symbols": true,
|
||||
"include_excluded_from_bom": true,
|
||||
"name": "",
|
||||
"sort_asc": true,
|
||||
"sort_field": "Reference"
|
||||
},
|
||||
"connection_grid_size": 50.0,
|
||||
"drawing": {
|
||||
"dashed_lines_dash_length_ratio": 12.0,
|
||||
"dashed_lines_gap_length_ratio": 3.0,
|
||||
"default_line_thickness": 6.0,
|
||||
"default_text_size": 50.0,
|
||||
"field_names": [],
|
||||
"intersheets_ref_own_page": false,
|
||||
"intersheets_ref_prefix": "",
|
||||
"intersheets_ref_short": false,
|
||||
"intersheets_ref_show": false,
|
||||
"intersheets_ref_suffix": "",
|
||||
"junction_size_choice": 3,
|
||||
"label_size_ratio": 0.375,
|
||||
"operating_point_overlay_i_precision": 3,
|
||||
"operating_point_overlay_i_range": "~A",
|
||||
"operating_point_overlay_v_precision": 3,
|
||||
"operating_point_overlay_v_range": "~V",
|
||||
"overbar_offset_ratio": 1.23,
|
||||
"pin_symbol_size": 25.0,
|
||||
"text_offset_ratio": 0.15
|
||||
},
|
||||
"legacy_lib_dir": "",
|
||||
"legacy_lib_list": [],
|
||||
"meta": {
|
||||
"version": 1
|
||||
},
|
||||
"net_format_name": "",
|
||||
"page_layout_descr_file": "",
|
||||
"plot_directory": "",
|
||||
"space_save_all_events": true,
|
||||
"spice_current_sheet_as_root": false,
|
||||
"spice_external_command": "spice \"%I\"",
|
||||
"spice_model_current_sheet_as_root": true,
|
||||
"spice_save_all_currents": false,
|
||||
"spice_save_all_dissipations": false,
|
||||
"spice_save_all_voltages": false,
|
||||
"subpart_first_id": 65,
|
||||
"subpart_id_separator": 0
|
||||
},
|
||||
"sheets": [
|
||||
[
|
||||
"beda2468-90ac-47a7-b798-9955b432c0a3",
|
||||
"Root"
|
||||
]
|
||||
],
|
||||
"text_variables": {}
|
||||
}
|
qa/data/pcbnew/component_classes_drc.kicad_sch
Normal file
LOADING design file
@ -61,6 +61,7 @@ set( QA_PCBNEW_SRCS
|
||||
drc/test_solder_mask_bridging.cpp
|
||||
drc/test_drc_multi_netclasses.cpp
|
||||
drc/test_drc_skew.cpp
|
||||
drc/test_drc_component_classes.cpp
|
||||
|
||||
pcb_io/altium/test_altium_rule_transformer.cpp
|
||||
pcb_io/altium/test_altium_pcblib_import.cpp
|
||||
|
107
qa/tests/pcbnew/drc/test_drc_component_classes.cpp
Normal file
107
qa/tests/pcbnew/drc/test_drc_component_classes.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <qa_utils/wx_utils/unit_test_utils.h>
|
||||
#include <pcbnew_utils/board_test_utils.h>
|
||||
#include <board.h>
|
||||
#include <board_design_settings.h>
|
||||
#include <drc/drc_item.h>
|
||||
#include <settings/settings_manager.h>
|
||||
|
||||
|
||||
struct DRC_REGRESSION_TEST_FIXTURE
|
||||
{
|
||||
DRC_REGRESSION_TEST_FIXTURE() :
|
||||
m_settingsManager( true /* headless */ )
|
||||
{ }
|
||||
|
||||
SETTINGS_MANAGER m_settingsManager;
|
||||
std::unique_ptr<BOARD> m_board;
|
||||
};
|
||||
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE( DRCComponentClasses, DRC_REGRESSION_TEST_FIXTURE )
|
||||
{
|
||||
// Check for minimum copper connection errors
|
||||
|
||||
std::vector<std::pair<wxString, int>> tests =
|
||||
{
|
||||
{ "component_classes_drc", 2 }
|
||||
};
|
||||
|
||||
for( const std::pair<wxString, int>& test : tests )
|
||||
{
|
||||
KI_TEST::LoadBoard( m_settingsManager, test.first, m_board );
|
||||
KI_TEST::FillZones( m_board.get() );
|
||||
|
||||
std::vector<DRC_ITEM> violations;
|
||||
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
|
||||
|
||||
// Disable DRC tests not useful or not handled in this testcase
|
||||
bds.m_DRCSeverities[ DRCE_INVALID_OUTLINE ] = SEVERITY::RPT_SEVERITY_IGNORE;
|
||||
bds.m_DRCSeverities[ DRCE_UNCONNECTED_ITEMS ] = SEVERITY::RPT_SEVERITY_IGNORE;
|
||||
bds.m_DRCSeverities[ DRCE_COPPER_SLIVER ] = SEVERITY::RPT_SEVERITY_IGNORE;
|
||||
bds.m_DRCSeverities[ DRCE_STARVED_THERMAL ] = SEVERITY::RPT_SEVERITY_IGNORE;
|
||||
bds.m_DRCSeverities[ DRCE_DRILL_OUT_OF_RANGE ] = SEVERITY::RPT_SEVERITY_IGNORE;
|
||||
bds.m_DRCSeverities[ DRCE_VIA_DIAMETER ] = SEVERITY::RPT_SEVERITY_IGNORE;
|
||||
// These DRC tests are not useful and do not work because they need a footprint library
|
||||
// associated to the board
|
||||
bds.m_DRCSeverities[ DRCE_LIB_FOOTPRINT_ISSUES ] = SEVERITY::RPT_SEVERITY_IGNORE;
|
||||
bds.m_DRCSeverities[ DRCE_LIB_FOOTPRINT_MISMATCH ] = SEVERITY::RPT_SEVERITY_IGNORE;
|
||||
bds.m_DRCSeverities[ DRCE_UNCONNECTED_ITEMS ] = SEVERITY::RPT_SEVERITY_IGNORE;
|
||||
|
||||
// Ensure that our desired error is fired
|
||||
bds.m_DRCSeverities[ DRCE_ASSERTION_FAILURE ] = SEVERITY::RPT_SEVERITY_ERROR;
|
||||
|
||||
bds.m_DRCEngine->SetViolationHandler(
|
||||
[&]( const std::shared_ptr<DRC_ITEM>& aItem, VECTOR2I aPos, int aLayer )
|
||||
{
|
||||
if( bds.GetSeverity( aItem->GetErrorCode() ) == SEVERITY::RPT_SEVERITY_ERROR )
|
||||
violations.push_back( *aItem );
|
||||
} );
|
||||
|
||||
bds.m_DRCEngine->RunTests( EDA_UNITS::MILLIMETRES, true, false );
|
||||
|
||||
if( violations.size() == test.second )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( 1, 1 ); // quiet "did not check any assertions" warning
|
||||
BOOST_TEST_MESSAGE( wxString::Format( "DRC component classes: %s, passed", test.first ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
UNITS_PROVIDER unitsProvider( pcbIUScale, EDA_UNITS::INCHES );
|
||||
|
||||
std::map<KIID, EDA_ITEM*> itemMap;
|
||||
m_board->FillItemMap( itemMap );
|
||||
|
||||
for( const DRC_ITEM& item : violations )
|
||||
{
|
||||
BOOST_TEST_MESSAGE( item.ShowReport( &unitsProvider, RPT_SEVERITY_ERROR,
|
||||
itemMap ) );
|
||||
}
|
||||
|
||||
BOOST_ERROR( wxString::Format( "DRC component classes: %s, failed (violations found %d expected %d)",
|
||||
test.first, (int)violations.size(), test.second ) );
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user