diff --git a/include/layers_id_colors_and_visibility.h b/include/layers_id_colors_and_visibility.h index 5df67215be..50aa5fa832 100644 --- a/include/layers_id_colors_and_visibility.h +++ b/include/layers_id_colors_and_visibility.h @@ -239,6 +239,7 @@ enum PCB_VISIBLE PADS_HOLES_VISIBLE, VIAS_HOLES_VISIBLE, + DRC_VISIBLE, ///< drc markers WORKSHEET, ///< worksheet frame GP_OVERLAY, ///< general purpose overlay diff --git a/pcbnew/basepcbframe.cpp b/pcbnew/basepcbframe.cpp index 7adc4ca473..d89094a6fd 100644 --- a/pcbnew/basepcbframe.cpp +++ b/pcbnew/basepcbframe.cpp @@ -75,6 +75,7 @@ static const wxString FastGrid2Entry( wxT( "FastGrid2" ) ); const LAYER_NUM PCB_BASE_FRAME::GAL_LAYER_ORDER[] = { ITEM_GAL_LAYER( GP_OVERLAY ), + ITEM_GAL_LAYER( DRC_VISIBLE ), NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ), DRAW_N, COMMENT_N, ECO1_N, ECO2_N, EDGE_N, UNUSED_LAYER_29, UNUSED_LAYER_30, UNUSED_LAYER_31, @@ -817,6 +818,7 @@ void PCB_BASE_FRAME::LoadSettings() view->SetLayerTarget( ITEM_GAL_LAYER( GP_OVERLAY ), KIGFX::TARGET_OVERLAY ); view->SetLayerTarget( ITEM_GAL_LAYER( RATSNEST_VISIBLE ), KIGFX::TARGET_OVERLAY ); + view->SetLayerTarget( ITEM_GAL_LAYER( DRC_VISIBLE ), KIGFX::TARGET_NONCACHED ); // Apply layer coloring scheme & display options if( view->GetPainter() ) diff --git a/pcbnew/class_marker_pcb.cpp b/pcbnew/class_marker_pcb.cpp index 4e947e07cd..9222698696 100644 --- a/pcbnew/class_marker_pcb.cpp +++ b/pcbnew/class_marker_pcb.cpp @@ -46,7 +46,7 @@ MARKER_PCB::MARKER_PCB( BOARD_ITEM* aParent ) : BOARD_ITEM( aParent, PCB_MARKER_T ), - MARKER_BASE( ) + MARKER_BASE(), m_item( NULL ) { m_Color = WHITE; m_ScalingFactor = SCALING_FACTOR; @@ -57,8 +57,7 @@ MARKER_PCB::MARKER_PCB( int aErrorCode, const wxPoint& aMarkerPos, const wxString& aText, const wxPoint& aPos, const wxString& bText, const wxPoint& bPos ) : BOARD_ITEM( NULL, PCB_MARKER_T ), // parent set during BOARD::Add() - MARKER_BASE( aErrorCode, aMarkerPos, aText, aPos, bText, bPos ) - + MARKER_BASE( aErrorCode, aMarkerPos, aText, aPos, bText, bPos ), m_item( NULL ) { m_Color = WHITE; m_ScalingFactor = SCALING_FACTOR; @@ -67,7 +66,7 @@ MARKER_PCB::MARKER_PCB( int aErrorCode, const wxPoint& aMarkerPos, MARKER_PCB::MARKER_PCB( int aErrorCode, const wxPoint& aMarkerPos, const wxString& aText, const wxPoint& aPos ) : BOARD_ITEM( NULL, PCB_MARKER_T ), // parent set during BOARD::Add() - MARKER_BASE( aErrorCode, aMarkerPos, aText, aPos ) + MARKER_BASE( aErrorCode, aMarkerPos, aText, aPos ), m_item( NULL ) { m_Color = WHITE; m_ScalingFactor = SCALING_FACTOR; @@ -136,3 +135,10 @@ wxString MARKER_PCB::GetSelectMenuText() const return text; } + + +void MARKER_PCB::ViewGetLayers( int aLayers[], int& aCount ) const +{ + aCount = 1; + aLayers[0] = ITEM_GAL_LAYER( DRC_VISIBLE ); +} diff --git a/pcbnew/class_marker_pcb.h b/pcbnew/class_marker_pcb.h index 7728b152c0..1e2c0931cd 100644 --- a/pcbnew/class_marker_pcb.h +++ b/pcbnew/class_marker_pcb.h @@ -64,6 +64,16 @@ public: const wxPoint& GetPosition() const { return m_Pos; } void SetPosition( const wxPoint& aPos ) { m_Pos = aPos; } + void SetItem( const BOARD_ITEM* aItem ) + { + m_item = aItem; + } + + const BOARD_ITEM* GetItem() const + { + return m_item; + } + bool HitTest( const wxPoint& aPosition ) { return HitTestMarker( aPosition ); @@ -77,9 +87,22 @@ public: BITMAP_DEF GetMenuImage() const { return drc_xpm; } + ///> @copydoc VIEW_ITEM::ViewBBox() + virtual const BOX2I ViewBBox() const + { + return GetParent()->ViewBBox(); + } + + ///> @copydoc VIEW_ITEM::ViewGetLayers() + virtual void ViewGetLayers( int aLayers[], int& aCount ) const; + #if defined(DEBUG) void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override #endif + +protected: + ///> Pointer to BOARD_ITEM that causes DRC error. + const BOARD_ITEM* m_item; }; #endif // CLASS_MARKER_PCB_H diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index c10f0537b0..1039fc3492 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include #include @@ -312,6 +314,7 @@ bool DRC::doNetClass( NETCLASS* nc, wxString& msg ) m_currentMarker = fillMarker( DRCE_NETCLASS_CLEARANCE, msg, m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; ret = false; } @@ -327,6 +330,7 @@ bool DRC::doNetClass( NETCLASS* nc, wxString& msg ) m_currentMarker = fillMarker( DRCE_NETCLASS_TRACKWIDTH, msg, m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; ret = false; } @@ -341,6 +345,7 @@ bool DRC::doNetClass( NETCLASS* nc, wxString& msg ) m_currentMarker = fillMarker( DRCE_NETCLASS_VIASIZE, msg, m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; ret = false; } @@ -355,6 +360,7 @@ bool DRC::doNetClass( NETCLASS* nc, wxString& msg ) m_currentMarker = fillMarker( DRCE_NETCLASS_VIADRILLSIZE, msg, m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; ret = false; } @@ -369,6 +375,7 @@ bool DRC::doNetClass( NETCLASS* nc, wxString& msg ) m_currentMarker = fillMarker( DRCE_NETCLASS_uVIASIZE, msg, m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; ret = false; } @@ -383,6 +390,7 @@ bool DRC::doNetClass( NETCLASS* nc, wxString& msg ) m_currentMarker = fillMarker( DRCE_NETCLASS_uVIADRILLSIZE, msg, m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; ret = false; } @@ -447,6 +455,7 @@ void DRC::testPad2Pad() { wxASSERT( m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; } } @@ -493,6 +502,7 @@ void DRC::testTracks( bool aShowProgressBar ) { wxASSERT( m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; } } @@ -554,6 +564,7 @@ void DRC::testZones() m_currentMarker = fillMarker( test_area, DRCE_NON_EXISTANT_NET_FOR_ZONE_OUTLINE, m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; } } @@ -589,6 +600,7 @@ void DRC::testKeepoutAreas() m_currentMarker = fillMarker( segm, NULL, DRCE_TRACK_INSIDE_KEEPOUT, m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; } } @@ -605,6 +617,7 @@ void DRC::testKeepoutAreas() m_currentMarker = fillMarker( segm, NULL, DRCE_VIA_INSIDE_KEEPOUT, m_currentMarker ); m_pcb->Add( m_currentMarker ); + m_mainWindow->GetGalCanvas()->GetView()->Add( m_currentMarker ); m_currentMarker = 0; } } diff --git a/pcbnew/drc_marker_functions.cpp b/pcbnew/drc_marker_functions.cpp index 817d7e17d9..a069acaaa4 100644 --- a/pcbnew/drc_marker_functions.cpp +++ b/pcbnew/drc_marker_functions.cpp @@ -100,12 +100,17 @@ MARKER_PCB* DRC::fillMarker( TRACK* aTrack, BOARD_ITEM* aItem, int aErrorCode, M else { if( aItem ) + { fillMe = new MARKER_PCB( aErrorCode, position, textA, aTrack->GetPosition(), textB, posB ); + fillMe->SetItem( aItem ); + } else + { fillMe = new MARKER_PCB( aErrorCode, position, textA, aTrack->GetPosition() ); + } } return fillMe; @@ -121,9 +126,14 @@ MARKER_PCB* DRC::fillMarker( D_PAD* aPad, D_PAD* bPad, int aErrorCode, MARKER_PC wxPoint posB = bPad->GetPosition(); if( fillMe ) + { fillMe->SetData( aErrorCode, posA, textA, posA, textB, posB ); + } else + { fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA, textB, posB ); + fillMe->SetItem( aPad ); // TODO it has to be checked + } return fillMe; } @@ -136,9 +146,14 @@ MARKER_PCB* DRC::fillMarker( ZONE_CONTAINER* aArea, int aErrorCode, MARKER_PCB* wxPoint posA = aArea->GetPosition(); if( fillMe ) + { fillMe->SetData( aErrorCode, posA, textA, posA ); + } else + { fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA ); + fillMe->SetItem( aArea ); + } return fillMe; } @@ -154,9 +169,14 @@ MARKER_PCB* DRC::fillMarker( const ZONE_CONTAINER* aArea, wxPoint posA = aPos; if( fillMe ) + { fillMe->SetData( aErrorCode, posA, textA, posA ); + } else + { fillMe = new MARKER_PCB( aErrorCode, posA, textA, posA ); + fillMe->SetItem( aArea ); + } return fillMe; } diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 40576eba42..6aa9e54929 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -34,9 +34,8 @@ #include #include #include -#include +#include -#include #include #include @@ -76,6 +75,7 @@ void PCB_RENDER_SETTINGS::ImportLegacyColors( COLORS_DESIGN_SETTINGS* aSettings m_layerColors[NETNAMES_GAL_LAYER( PAD_BK_NETNAMES_VISIBLE )] = COLOR4D( 0.8, 0.8, 0.8, 0.7 ); m_layerColors[ITEM_GAL_LAYER( RATSNEST_VISIBLE )] = COLOR4D( 0.4, 0.4, 0.4, 0.7 ); m_layerColors[ITEM_GAL_LAYER( WORKSHEET )] = COLOR4D( 0.5, 0.0, 0.0, 1.0 ); + m_layerColors[ITEM_GAL_LAYER( DRC_VISIBLE )] = COLOR4D( 1.0, 0.0, 0.0, 1.0 ); // Netnames for copper layers for( LAYER_NUM layer = FIRST_COPPER_LAYER; layer <= LAST_COPPER_LAYER; ++layer ) @@ -246,6 +246,9 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer ) draw( (PCB_TARGET*) aItem ); break; + case PCB_MARKER_T: + draw( (MARKER_PCB*) aItem ); + default: // Painter does not know how to draw the object return false; @@ -863,4 +866,23 @@ void PCB_PAINTER::draw( const PCB_TARGET* aTarget ) } +void PCB_PAINTER::draw( const MARKER_PCB* aMarker ) +{ + const BOARD_ITEM* item = aMarker->GetItem(); + + if( item ) // By default draw an item in a different color + { + Draw( item, ITEM_GAL_LAYER( DRC_VISIBLE ) ); + } + else // If there is no item associated - draw a circle marking the DRC error + { + m_gal->SetStrokeColor( COLOR4D( 1.0, 0.0, 0.0, 1.0 ) ); + m_gal->SetIsFill( false ); + m_gal->SetIsStroke( true ); + m_gal->SetLineWidth( 10000 ); + m_gal->DrawCircle( VECTOR2D( aMarker->GetPosition() ), 200000 ); + } +} + + const double PCB_RENDER_SETTINGS::MAX_FONT_SIZE = Millimeter2iu( 10.0 ); diff --git a/pcbnew/pcb_painter.h b/pcbnew/pcb_painter.h index 10819affdb..efa9cc061b 100644 --- a/pcbnew/pcb_painter.h +++ b/pcbnew/pcb_painter.h @@ -48,6 +48,7 @@ class TEXTE_PCB; class TEXTE_MODULE; class DIMENSION; class PCB_TARGET; +class MARKER_PCB; namespace KIGFX { @@ -169,6 +170,7 @@ protected: void draw( const ZONE_CONTAINER* aZone ); void draw( const DIMENSION* aDimension, int aLayer ); void draw( const PCB_TARGET* aTarget ); + void draw( const MARKER_PCB* aMarker ); }; } // namespace KIGFX diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 1b5c4c5c20..be5896b50e 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -923,7 +923,8 @@ void PCB_EDIT_FRAME::SetTopLayer( LAYER_NUM aLayer ) GetNetnameLayer( aLayer ), ITEM_GAL_LAYER( VIA_THROUGH_VISIBLE ), ITEM_GAL_LAYER( VIAS_HOLES_VISIBLE ), ITEM_GAL_LAYER( PADS_VISIBLE ), ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ), NETNAMES_GAL_LAYER( PADS_NETNAMES_VISIBLE ), - ITEM_GAL_LAYER( GP_OVERLAY ), ITEM_GAL_LAYER( RATSNEST_VISIBLE ), DRAW_N + ITEM_GAL_LAYER( GP_OVERLAY ), ITEM_GAL_LAYER( RATSNEST_VISIBLE ), DRAW_N, + ITEM_GAL_LAYER( DRC_VISIBLE ) }; for( unsigned int i = 0; i < sizeof( layers ) / sizeof( LAYER_NUM ); ++i )