KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_drc_violation_layers_issue24941.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
24
26#include <board.h>
27#include <pcb_shape.h>
28#include <pcb_track.h>
29#include <zone.h>
30#include <pcb_marker.h>
31#include <drc/drc_item.h>
32
34{
35 DRC_VIOLATION_LAYERS_FIXTURE() { m_board = std::make_unique<BOARD>(); }
36
37 std::unique_ptr<BOARD> m_board;
38};
39
40
41// Issue 24941: clicking a board edge clearance violation must focus Edge.Cuts,
42// not the copper layer the marker sits on
44{
45 PCB_SHAPE* edge = new PCB_SHAPE( m_board.get(), SHAPE_T::SEGMENT );
46 edge->SetLayer( Edge_Cuts );
47 edge->SetStart( VECTOR2I( 0, 0 ) );
48 edge->SetEnd( VECTOR2I( 1000000, 0 ) );
49 m_board->Add( edge );
50
51 PCB_TRACK* track = new PCB_TRACK( m_board.get() );
52 track->SetLayer( F_Cu );
53 track->SetStart( VECTOR2I( 0, 100000 ) );
54 track->SetEnd( VECTOR2I( 1000000, 100000 ) );
55 m_board->Add( track );
56
57 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_EDGE_CLEARANCE );
58 drcItem->SetItems( edge->m_Uuid, track->m_Uuid );
59
60 // The edge clearance provider stamps the marker with the copper item's layer
61 PCB_MARKER* marker = new PCB_MARKER( drcItem, VECTOR2I( 0, 100000 ), F_Cu );
62 m_board->Add( marker );
63
64 PCB_LAYER_ID principalLayer;
65 LSET violationLayers;
66
67 DRC_ITEM::GetViolationLayers( m_board.get(), drcItem, marker, principalLayer, violationLayers );
68
69 BOOST_CHECK_EQUAL( static_cast<int>( principalLayer ), static_cast<int>( Edge_Cuts ) );
70}
71
72
73// Guard for the original fix: for a violation on a multi-layer item the marker
74// layer must win over the first layer of the item's layer set
76{
77 ZONE* zone = new ZONE( m_board.get() );
78 zone->SetLayerSet( LSET( { F_Cu, B_Cu } ) );
79 m_board->Add( zone );
80
81 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_CONNECTION_WIDTH );
82 drcItem->SetItems( zone->m_Uuid );
83
84 // The narrow neck is on B.Cu, the provider marks it there
85 PCB_MARKER* marker = new PCB_MARKER( drcItem, VECTOR2I( 0, 0 ), B_Cu );
86 m_board->Add( marker );
87
88 PCB_LAYER_ID principalLayer;
89 LSET violationLayers;
90
91 DRC_ITEM::GetViolationLayers( m_board.get(), drcItem, marker, principalLayer, violationLayers );
92
93 BOOST_CHECK_EQUAL( static_cast<int>( principalLayer ), static_cast<int>( B_Cu ) );
94}
95
96
97// Without a marker the layer comes from intersecting the items' layer sets
99{
100 PCB_TRACK* track1 = new PCB_TRACK( m_board.get() );
101 track1->SetLayer( B_Cu );
102 track1->SetStart( VECTOR2I( 0, 0 ) );
103 track1->SetEnd( VECTOR2I( 1000000, 0 ) );
104 m_board->Add( track1 );
105
106 PCB_TRACK* track2 = new PCB_TRACK( m_board.get() );
107 track2->SetLayer( B_Cu );
108 track2->SetStart( VECTOR2I( 0, 100000 ) );
109 track2->SetEnd( VECTOR2I( 1000000, 100000 ) );
110 m_board->Add( track2 );
111
112 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_CLEARANCE );
113 drcItem->SetItems( track1->m_Uuid, track2->m_Uuid );
114
115 PCB_LAYER_ID principalLayer;
116 LSET violationLayers;
117
118 DRC_ITEM::GetViolationLayers( m_board.get(), drcItem, nullptr, principalLayer, violationLayers );
119
120 BOOST_CHECK_EQUAL( static_cast<int>( principalLayer ), static_cast<int>( B_Cu ) );
121 BOOST_CHECK( violationLayers.test( B_Cu ) );
122}
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
static void GetViolationLayers(BOARD *aBoard, const std::shared_ptr< RC_ITEM > &aItem, PCB_MARKER *aMarker, PCB_LAYER_ID &aPrincipalLayer, LSET &aViolationLayers)
Work out which layer to focus on and which layers a violation involves.
Definition drc_item.cpp:545
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Definition drc_item.cpp:418
const KIID m_Uuid
Definition eda_item.h:531
LSET is a set of PCB_LAYER_IDs.
Definition lset.h:37
void SetEnd(const VECTOR2I &aEnd) override
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
void SetStart(const VECTOR2I &aStart) override
void SetEnd(const VECTOR2I &aEnd)
Definition pcb_track.h:89
void SetStart(const VECTOR2I &aStart)
Definition pcb_track.h:92
Handle a list of polygons defining a copper zone.
Definition zone.h:70
void SetLayerSet(const LSET &aLayerSet) override
Definition zone.cpp:644
@ DRCE_EDGE_CLEARANCE
Definition drc_item.h:44
@ DRCE_CLEARANCE
Definition drc_item.h:41
@ DRCE_CONNECTION_WIDTH
Definition drc_item.h:57
@ SEGMENT
Definition eda_shape.h:46
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
@ Edge_Cuts
Definition layer_ids.h:108
@ B_Cu
Definition layer_ids.h:61
@ F_Cu
Definition layer_ids.h:60
BOOST_FIXTURE_TEST_CASE(EdgeClearanceFocusesEdgeCuts, DRC_VIOLATION_LAYERS_FIXTURE)
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683