KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_marker.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 (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
27#include <bitmaps.h>
28#include <base_units.h>
29#include <eda_draw_frame.h>
30#include <board.h>
32#include <pcb_marker.h>
33#include <layer_ids.h>
36#include <geometry/shape_null.h>
37#include <widgets/ui_common.h>
38#include <pgm_base.h>
39#include <drc/drc_item.h>
40#include <trigo.h>
41
42
44#define SCALING_FACTOR pcbIUScale.mmToIU( 0.1625 )
45
46
47
48PCB_MARKER::PCB_MARKER( std::shared_ptr<RC_ITEM> aItem, const VECTOR2I& aPosition, int aLayer ) :
49 BOARD_ITEM( nullptr, PCB_MARKER_T, F_Cu ), // parent set during BOARD::Add()
51 m_pathLength( 0 )
52{
53 if( m_rcItem )
54 {
55 m_rcItem->SetParent( this );
56
57 if( aLayer == LAYER_DRAWINGSHEET )
58 {
60 }
61 else
62 {
63 switch( m_rcItem->GetErrorCode() )
64 {
67 break;
68
76 break;
77
78 default:
80 break;
81 }
82
83 SetLayer( ToLAYER_ID( aLayer ) );
84 }
85 }
86
87 m_Pos = aPosition;
88}
89
90
91/* destructor */
93{
94 if( m_rcItem )
95 m_rcItem->SetParent( nullptr );
96}
97
98
100{
101 if( m_rcItem->GetErrorCode() == DRCE_COPPER_SLIVER
102 || m_rcItem->GetErrorCode() == DRCE_GENERIC_WARNING
103 || m_rcItem->GetErrorCode() == DRCE_GENERIC_ERROR )
104 {
105 return wxString::Format( wxT( "%s|%d|%d|%s|%s" ),
106 m_rcItem->GetSettingsKey(),
107 m_Pos.x,
108 m_Pos.y,
109 m_rcItem->GetMainItemID().AsString(),
110 LayerName( m_layer ) );
111 }
112 else if( m_rcItem->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
113 {
114 PCB_LAYER_ID layer = m_layer;
115
116 if( m_layer == UNDEFINED_LAYER )
117 layer = F_Cu;
118
119 return wxString::Format( wxT( "%s|%d|%d|%s|%d|%s|%s" ),
120 m_rcItem->GetSettingsKey(),
121 m_Pos.x,
122 m_Pos.y,
123 LayerName( layer ),
125 m_rcItem->GetMainItemID().AsString(),
126 m_rcItem->GetAuxItemID().AsString() );
127 }
128 else if( m_rcItem->GetErrorCode() == DRCE_STARVED_THERMAL )
129 {
130 return wxString::Format( wxT( "%s|%d|%d|%s|%s|%s" ),
131 m_rcItem->GetSettingsKey(),
132 m_Pos.x,
133 m_Pos.y,
134 m_rcItem->GetMainItemID().AsString(),
135 m_rcItem->GetAuxItemID().AsString(),
136 LayerName( m_layer ) );
137 }
138 else if( m_rcItem->GetErrorCode() == DRCE_UNRESOLVED_VARIABLE
139 && m_rcItem->GetParent()->GetMarkerType() == MARKER_DRAWING_SHEET )
140 {
141 return wxString::Format( wxT( "%s|%d|%d|%s|%s" ),
142 m_rcItem->GetSettingsKey(),
143 m_Pos.x,
144 m_Pos.y,
145 // Drawing sheet KIIDs aren't preserved between runs
146 wxEmptyString,
147 wxEmptyString );
148 }
149 else
150 {
151 return wxString::Format( wxT( "%s|%d|%d|%s|%s" ),
152 m_rcItem->GetSettingsKey(),
153 m_Pos.x,
154 m_Pos.y,
155 m_rcItem->GetMainItemID().AsString(),
156 m_rcItem->GetAuxItemID().AsString() );
157 }
158}
159
160
162{
163 auto getMarkerLayer =
164 []( const wxString& layerName ) -> int
165 {
166 for( int layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
167 {
168 if( LayerName( ToLAYER_ID( layer ) ) == layerName )
169 return layer;
170 }
171
172 return F_Cu;
173 };
174
175 wxArrayString props = wxSplit( data, '|' );
176 int markerLayer = F_Cu;
177 VECTOR2I markerPos( (int) strtol( props[1].c_str(), nullptr, 10 ),
178 (int) strtol( props[2].c_str(), nullptr, 10 ) );
179
180 std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( props[0] );
181
182 if( !drcItem )
183 return nullptr;
184
185 if( drcItem->GetErrorCode() == DRCE_COPPER_SLIVER
186 || drcItem->GetErrorCode() == DRCE_GENERIC_WARNING
187 || drcItem->GetErrorCode() == DRCE_GENERIC_ERROR )
188 {
189 drcItem->SetItems( KIID( props[3] ) );
190 markerLayer = getMarkerLayer( props[4] );
191 }
192 else if( drcItem->GetErrorCode() == DRCE_UNCONNECTED_ITEMS )
193 {
194 // Pre-9.0.4 versions didn't have KIIDs as last two properties to allow sorting stability
195 if( props.size() < 6 )
196 drcItem->SetItems( KIID( props[3] ), KIID( props[4] ) );
197 else
198 drcItem->SetItems( KIID( props[5] ), KIID( props[6] ) );
199 }
200 else if( drcItem->GetErrorCode() == DRCE_STARVED_THERMAL )
201 {
202 drcItem->SetItems( KIID( props[3] ), KIID( props[4] ) );
203
204 // Pre-7.0 versions didn't differentiate between layers
205 if( props.size() == 6 )
206 markerLayer = getMarkerLayer( props[5] );
207 }
208 else if( drcItem->GetErrorCode() == DRCE_UNRESOLVED_VARIABLE
209 && props[3].IsEmpty() && props[4].IsEmpty() )
210 {
211 // Note: caller must load our item pointer with the drawing sheet proxy item
212 markerLayer = LAYER_DRAWINGSHEET;
213 }
214 else
215 {
216 drcItem->SetItems( KIID( props[3] ), KIID( props[4] ) );
217 }
218
219 return new PCB_MARKER( drcItem, markerPos, markerLayer );
220}
221
222
223void PCB_MARKER::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
224{
225 aList.emplace_back( _( "Type" ), _( "Marker" ) );
226 aList.emplace_back( _( "Violation" ), m_rcItem->GetErrorMessage() );
227
228 switch( GetSeverity() )
229 {
231 aList.emplace_back( _( "Severity" ), _( "Ignore" ) );
232 break;
234 aList.emplace_back( _( "Severity" ), _( "Warning" ) );
235 break;
237 aList.emplace_back( _( "Severity" ), _( "Error" ) );
238 break;
239 default:
240 break;
241 }
242
244 {
245 aList.emplace_back( _( "Drawing Sheet" ), wxEmptyString );
246 }
247 else
248 {
249 wxString mainText;
250 wxString auxText;
251 EDA_ITEM* mainItem = aFrame->ResolveItem( m_rcItem->GetMainItemID() );
252 EDA_ITEM* auxItem = aFrame->ResolveItem( m_rcItem->GetAuxItemID() );
253
254 if( mainItem )
255 mainText = mainItem->GetItemDescription( aFrame, true );
256
257 if( auxItem )
258 auxText = auxItem->GetItemDescription( aFrame, true );
259
260 aList.emplace_back( mainText, auxText );
261 }
262
263 if( IsExcluded() )
264 aList.emplace_back( _( "Excluded" ), m_comment );
265}
266
267
268void PCB_MARKER::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
269{
270 // Marker geometry isn't user-editable
271}
272
273
274void PCB_MARKER::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
275{
276 // Marker geometry isn't user-editable
277}
278
279
280std::shared_ptr<SHAPE> PCB_MARKER::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
281{
282 // Markers do not participate in the board geometry space, and therefore have no effective shape.
283 return std::make_shared<SHAPE_NULL>();
284}
285
286
288 int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth ) const
289{
290 // Markers do not participate in the board geometry space, and therefore have no shape.
291};
292
293
294wxString PCB_MARKER::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
295{
296 return wxString::Format( _( "Marker (%s)" ), aFull ? m_rcItem->GetErrorMessage()
297 : m_rcItem->GetErrorText() );
298}
299
300
302{
303 return BITMAPS::drc;
304}
305
306
308{
309 if( IsExcluded() )
311
312 DRC_ITEM* item = static_cast<DRC_ITEM*>( m_rcItem.get() );
313
314 if( item->GetErrorCode() == DRCE_GENERIC_WARNING )
316 else if( item->GetErrorCode() == DRCE_GENERIC_ERROR )
317 return RPT_SEVERITY_ERROR;
318
319 DRC_RULE* rule = item->GetViolatingRule();
320
321 if( rule && rule->m_Severity != RPT_SEVERITY_UNDEFINED )
322 return rule->m_Severity;
323
324 return GetBoard()->GetDesignSettings().GetSeverity( item->GetErrorCode() );
325}
326
327
328std::vector<int> PCB_MARKER::ViewGetLayers() const
329{
331 return {};
332
333 std::vector<int> layers{ 0, LAYER_MARKER_SHADOWS, LAYER_DRC_SHAPES };
334
335 switch( GetSeverity() )
336 {
337 default:
338 case SEVERITY::RPT_SEVERITY_ERROR: layers[0] = LAYER_DRC_ERROR; break;
339 case SEVERITY::RPT_SEVERITY_WARNING: layers[0] = LAYER_DRC_WARNING; break;
341 }
342
343 return layers;
344}
345
346
357
358
360{
361 return ::GetColorSettings( DEFAULT_THEME )->GetColor( GetColorLayer() );
362}
363
364
365void PCB_MARKER::SetZoom( double aZoomFactor ) const
366{
367 SetMarkerScale( SCALING_FACTOR * aZoomFactor );
368}
369
370
371std::vector<PCB_SHAPE> PCB_MARKER::GetShapes() const
372{
373 STROKE_PARAMS hairline( 1.0 ); // Segments of width 1.0 will get drawn as lines by PCB_PAINTER
374 std::vector<PCB_SHAPE> pathShapes;
375
376 if( m_pathStart == m_pathEnd )
377 {
378 // Add a collision 'X'
379 const int len = KiROUND( 2.5 * MarkerScale() );
380
381 PCB_SHAPE s( nullptr, SHAPE_T::SEGMENT );
382 s.SetStroke( hairline );
383
384 s.SetStart( m_pathStart + VECTOR2I( -len, -len ) );
385 s.SetEnd( m_pathStart + VECTOR2I( len, len ) );
386 pathShapes.push_back( s );
387
388 s.SetStart( m_pathStart + VECTOR2I( -len, len ) );
389 s.SetEnd( m_pathStart + VECTOR2I( len, -len ) );
390 pathShapes.push_back( s );
391 }
392 else
393 {
394 // Add the path
395 for( PCB_SHAPE shape : m_pathShapes )
396 {
397 shape.SetStroke( hairline );
398 pathShapes.push_back( std::move( shape ) );
399 }
400
401 // Draw perpendicular begin/end stops
402 if( pathShapes.size() > 0 )
403 {
404 VECTOR2I V1 = pathShapes[0].GetStart() - pathShapes[0].GetEnd();
405 VECTOR2I V2 = pathShapes.back().GetStart() - pathShapes.back().GetEnd();
406 V1 = V1.Perpendicular().Resize( 2.5 * MarkerScale() );
407 V2 = V2.Perpendicular().Resize( 2.5 * MarkerScale() );
408
409 PCB_SHAPE s( nullptr, SHAPE_T::SEGMENT );
410 s.SetStroke( hairline );
411
412 s.SetStart( m_pathStart + V1 );
413 s.SetEnd( m_pathStart - V1 );
414 pathShapes.push_back( s );
415
416 s.SetStart( m_pathEnd + V2 );
417 s.SetEnd( m_pathEnd - V2 );
418 pathShapes.push_back( s );
419 }
420 }
421
422 // Add shaded areas
423 for( PCB_SHAPE shape : m_pathShapes )
424 {
425 shape.SetWidth( 10 * MarkerScale() );
426 pathShapes.push_back( std::move( shape ) );
427 }
428
429 return pathShapes;
430}
431
432
434{
436
437 for( const PCB_SHAPE& s : m_pathShapes )
438 box.Merge( s.GetBoundingBox() );
439
440 return box;
441}
442
443
445{
446 return GetBoundingBox();
447}
448
449
450static struct PCB_MARKER_DESC
451{
453 {
460
461 // Markers cannot be locked and have no user-accessible layer control
462 propMgr.Mask( TYPE_HASH( PCB_MARKER ), TYPE_HASH( BOARD_ITEM ), _HKI( "Layer" ) );
463 propMgr.Mask( TYPE_HASH( PCB_MARKER ), TYPE_HASH( BOARD_ITEM ), _HKI( "Locked" ) );
464 }
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
BITMAPS
A list of all bitmap identifiers.
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:990
SEVERITY GetSeverity(int aDRCErrorCode)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:79
BOARD_ITEM(BOARD_ITEM *aParent, KICAD_T idtype, PCB_LAYER_ID aLayer=F_Cu)
Definition board_item.h:81
PCB_LAYER_ID m_layer
Definition board_item.h:453
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition board_item.h:280
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition board.cpp:1044
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition box2.h:658
DRC_RULE * GetViolatingRule() const
Definition drc_item.h:155
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Definition drc_item.cpp:384
SEVERITY m_Severity
Definition drc_rule.h:131
The base class for create windows for drawing purpose.
virtual EDA_ITEM * ResolveItem(const KIID &aId, bool aAllowNullptrReturn=false) const
Fetch an item by KIID.
virtual wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const
Return a user-visible description string of this item.
Definition eda_item.cpp:144
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:39
void SetStart(const VECTOR2I &aStart)
Definition eda_shape.h:177
void SetEnd(const VECTOR2I &aEnd)
Definition eda_shape.h:219
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:104
Definition kiid.h:49
Marker are mainly used to show a DRC or ERC error or warning.
Definition marker_base.h:49
void SetMarkerScale(int aScale) const
Definition marker_base.h:70
bool IsExcluded() const
Definition marker_base.h:93
wxString m_comment
User supplied comment.
int MarkerScale() const
The scaling factor to convert polygonal shape coordinates to internal units.
Definition marker_base.h:69
VECTOR2I m_Pos
Position of the marker.
@ MARKER_DRAWING_SHEET
Definition marker_base.h:56
void SetMarkerType(enum MARKER_T aMarkerType)
Accessors to set/get marker type (DRC, ERC, or other)
Definition marker_base.h:90
std::shared_ptr< RC_ITEM > m_rcItem
enum MARKER_T GetMarkerType() const
Definition marker_base.h:91
MARKER_BASE(int aScalingFactor, std::shared_ptr< RC_ITEM > aItem, MARKER_T aType=MARKER_UNSPEC)
BOX2I GetBoundingBoxMarker() const
Return the orthogonal, bounding box of this object for display purposes.
void SetZoom(double aZoomFactor) const
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
VECTOR2I m_pathEnd
Definition pcb_marker.h:168
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth) const override
Convert the item shape to a closed polygon.
VECTOR2I m_pathStart
Definition pcb_marker.h:167
std::vector< PCB_SHAPE > GetShapes() const
std::vector< PCB_SHAPE > m_pathShapes
Definition pcb_marker.h:166
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer, FLASHING aFlash=FLASHING::DEFAULT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
std::vector< int > ViewGetLayers() const override
Return the all the layers within the VIEW the object is painted on.
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
SEVERITY GetSeverity() const override
static PCB_MARKER * DeserializeFromString(const wxString &data)
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
wxString SerializeToString() const
GAL_LAYER_ID GetColorLayer() const
PCB_MARKER(std::shared_ptr< RC_ITEM > aItem, const VECTOR2I &aPos, int aLayer=F_Cu)
KIGFX::COLOR4D getColor() const override
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
int m_pathLength
Definition pcb_marker.h:169
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition pcb_shape.h:92
Provide class metadata.Helper macro to map type hashes to names.
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
void Mask(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName)
Sets a base class property as masked in a derived class.
static PROPERTY_MANAGER & Instance()
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
int GetErrorCode() const
Definition rc_item.h:154
Represent a set of closed polygons.
Simple container to manage line stroke parameters.
constexpr VECTOR2< T > Perpendicular() const
Compute the perpendicular vector.
Definition vector2d.h:314
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Definition vector2d.h:385
@ DRCE_FOOTPRINT_FILTERS
Definition drc_item.h:80
@ DRCE_UNCONNECTED_ITEMS
Definition drc_item.h:40
@ DRCE_STARVED_THERMAL
Definition drc_item.h:50
@ DRCE_GENERIC_ERROR
Definition drc_item.h:91
@ DRCE_COPPER_SLIVER
Definition drc_item.h:93
@ DRCE_UNRESOLVED_VARIABLE
Definition drc_item.h:88
@ DRCE_DUPLICATE_FOOTPRINT
Definition drc_item.h:76
@ DRCE_EXTRA_FOOTPRINT
Definition drc_item.h:77
@ DRCE_NET_CONFLICT
Definition drc_item.h:78
@ DRCE_MISSING_FOOTPRINT
Definition drc_item.h:75
@ DRCE_GENERIC_WARNING
Definition drc_item.h:90
@ DRCE_SCHEMATIC_PARITY
Definition drc_item.h:79
#define _(s)
@ SEGMENT
Definition eda_shape.h:45
wxString LayerName(int aLayer)
Returns the default display name for a given layer.
Definition layer_id.cpp:31
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
Definition layer_ids.h:184
GAL_LAYER_ID
GAL layers are "virtual" layers, i.e.
Definition layer_ids.h:228
@ LAYER_DRAWINGSHEET
Sheet frame and title block.
Definition layer_ids.h:278
@ LAYER_DRC_EXCLUSION
Layer for DRC markers which have been individually excluded.
Definition layer_ids.h:304
@ LAYER_DRC_SHAPES
Custom shapes for DRC markers.
Definition layer_ids.h:315
@ LAYER_DRC_WARNING
Layer for DRC markers with #SEVERITY_WARNING.
Definition layer_ids.h:301
@ LAYER_MARKER_SHADOWS
Shadows for DRC markers.
Definition layer_ids.h:305
@ LAYER_DRC_ERROR
Layer for DRC markers with #SEVERITY_ERROR.
Definition layer_ids.h:277
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:60
@ UNDEFINED_LAYER
Definition layer_ids.h:61
@ PCB_LAYER_ID_COUNT
Definition layer_ids.h:171
@ F_Cu
Definition layer_ids.h:64
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition lset.cpp:737
FLIP_DIRECTION
Definition mirror.h:27
#define _HKI(x)
Definition page_info.cpp:44
static struct PCB_MARKER_DESC _PCB_MARKER_DESC
see class PGM_BASE
#define TYPE_HASH(x)
Definition property.h:74
#define REGISTER_TYPE(x)
SEVERITY
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_UNDEFINED
@ RPT_SEVERITY_EXCLUSION
@ RPT_SEVERITY_IGNORE
#define SCALING_FACTOR
Factor to convert the maker unit shape to internal units:
#define DEFAULT_THEME
@ PCB_MARKER_T
class PCB_MARKER, a marker used to show something
Definition typeinfo.h:99
Functions to provide common constants and other functions to assist in making a consistent UI.
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695