Pcbnew, On line DRC in legacy canvas: Fix broken Drc test during track and zone creation or edition.

It was broken by commit c78171d01f.
During creation, the Drc must only display a error message, and do not create markers.
Markers are created only during a full board DRC test.
commit c78171d01f replaced this behavior by a incorrect one (create markers and do not show error messages)
This commit is contained in:
jean-pierre charras 2018-06-04 10:44:25 +02:00
parent 27c9c6ceed
commit 0b8cf93888
8 changed files with 107 additions and 34 deletions

View File

@ -96,11 +96,22 @@ void DRC::ShowDRCDialog( wxWindow* aParent )
void DRC::addMarkerToPcb( MARKER_PCB* aMarker )
{
// In legacy routing mode, do not add markers to the board.
// only shows the drc error message
if( m_drcInLegacyRoutingMode )
{
m_pcbEditorFrame->SetMsgPanel( aMarker );
delete aMarker;
m_currentMarker = nullptr;
}
else
{
BOARD_COMMIT commit( m_pcbEditorFrame );
commit.Add( aMarker );
commit.Push( wxEmptyString, false, false );
}
}
void DRC::DestroyDRCDialog( int aReason )
@ -126,6 +137,7 @@ DRC::DRC( PCB_EDIT_FRAME* aPcbWindow )
m_drcDialog = NULL;
// establish initial values for everything:
m_drcInLegacyRoutingMode = false;
m_doPad2PadTest = true; // enable pad to pad clearance tests
m_doUnconnectedTest = true; // enable unconnected tests
m_doZonesTest = true; // enable zone to items clearance tests
@ -160,15 +172,23 @@ DRC::~DRC()
}
int DRC::Drc( TRACK* aRefSegm, TRACK* aList )
int DRC::DrcOnCreatingTrack( TRACK* aRefSegm, TRACK* aList )
{
updatePointers();
// Set right options for this on line drc
int drc_state = m_drcInLegacyRoutingMode;
m_drcInLegacyRoutingMode = true;
int rpt_state = m_reportAllTrackErrors;
m_reportAllTrackErrors = false;
if( !doTrackDrc( aRefSegm, aList, true ) )
{
if( m_currentMarker )
m_pcbEditorFrame->SetMsgPanel( m_currentMarker );
m_drcInLegacyRoutingMode = drc_state;
m_reportAllTrackErrors = rpt_state;
return BAD_DRC;
}
@ -177,9 +197,15 @@ int DRC::Drc( TRACK* aRefSegm, TRACK* aList )
wxASSERT( m_currentMarker );
m_pcbEditorFrame->SetMsgPanel( m_currentMarker );
delete m_currentMarker;
m_currentMarker = nullptr;
m_drcInLegacyRoutingMode = drc_state;
m_reportAllTrackErrors = rpt_state;
return BAD_DRC;
}
m_drcInLegacyRoutingMode = drc_state;
m_reportAllTrackErrors = rpt_state;
return OK_DRC;
}
@ -345,17 +371,29 @@ int DRC::TestZoneToZoneOutline( ZONE_CONTAINER* aZone, bool aCreateMarkers )
}
int DRC::Drc( ZONE_CONTAINER* aArea, int aCornerIndex )
int DRC::DrcOnCreatingZone( ZONE_CONTAINER* aArea, int aCornerIndex )
{
updatePointers();
// Set right options for this on line drc
int drc_state = m_drcInLegacyRoutingMode;
m_drcInLegacyRoutingMode = true;
int rpt_state = m_reportAllTrackErrors;
m_reportAllTrackErrors = false;
if( !doEdgeZoneDrc( aArea, aCornerIndex ) )
{
wxASSERT( m_currentMarker );
m_pcbEditorFrame->SetMsgPanel( m_currentMarker );
delete m_currentMarker;
m_currentMarker = nullptr;
m_drcInLegacyRoutingMode = drc_state;
m_reportAllTrackErrors = rpt_state;
return BAD_DRC;
}
m_drcInLegacyRoutingMode = drc_state;
m_reportAllTrackErrors = rpt_state;
return OK_DRC;
}

View File

@ -183,6 +183,14 @@ private:
bool m_abortDRC;
bool m_drcInProgress;
/**
* in legacy canvas, when creating a track, the drc test must only display the
* error message, and do not create a DRC marker.
* if m_drcInLegacyRoutingMode it true only the message will be displayed
* m_drcInLegacyRoutingMode = false is the normal Drc mode
*/
bool m_drcInLegacyRoutingMode;
/* In DRC functions, many calculations are using coordinates relative
* to the position of the segment under test (segm to segm DRC, segm to pad DRC
* Next variables store coordinates relative to the start point of this segment
@ -419,33 +427,36 @@ public:
~DRC();
/**
* Function Drc
* tests the current segment and returns the result and displays the error
* in the status panel only if one exists.
* No marker created or added to the board. Must be used only during track
* creation in legacy canvas
* @param aRefSeg The current segment to test.
* @param aList The track list to test (usually m_Pcb->m_Track)
* @return int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK
*/
int Drc( TRACK* aRefSeg, TRACK* aList );
int DrcOnCreatingTrack( TRACK* aRefSeg, TRACK* aList );
/**
* Function Drc
* tests the outline segment starting at CornerIndex and returns the result and displays
* the error in the status panel only if one exists.
* Test Edge inside other areas
* Test Edge too close other areas
* No marker created or added to the board. Must be used only during zone
* creation in legacy canvas
* @param aArea The area parent which contains the corner.
* @param aCornerIndex The starting point of the segment to test.
* @return int - BAD_DRC (1) if DRC error or OK_DRC (0) if OK
*/
int Drc( ZONE_CONTAINER* aArea, int aCornerIndex );
int DrcOnCreatingZone( ZONE_CONTAINER* aArea, int aCornerIndex );
/*
/**
* Tests whether distance between zones complies with the DRC rules.
*
* @param aZone: zone to compare with other zones, or if NULL then
* all zones are compared to all others.
* @param aCreateMarkers: if true create DRC markers. False: do not creates anything
* @param aCreateMarkers: if true create DRC markers.
* False: do not create markers. only fing drc errors
* @return Errors count
*/
int TestZoneToZoneOutline( ZONE_CONTAINER* aZone, bool aCreateMarkers );
@ -505,6 +516,7 @@ public:
m_doFootprintOverlapping = aCourtyardTest;
m_doNoCourtyardDefined = aCourtyardMissingTest;
m_refillZones = aRefillZones;
m_drcInLegacyRoutingMode = false;
m_reportAllTrackErrors = aReportAllTrackErrors;
}
@ -529,7 +541,6 @@ public:
{
return m_currentMarker;
}
};

View File

@ -146,6 +146,19 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
std::vector<MARKER_PCB*> markers;
auto commitMarkers = [&]()
{
// In legacy routing mode, do not add markers to the board.
// only shows the drc error message
if( m_drcInLegacyRoutingMode )
{
while( markers.size() > 0 )
{
m_pcbEditorFrame->SetMsgPanel( markers.back() );
delete markers.back();
markers.pop_back();
}
}
else
{
BOARD_COMMIT commit( m_pcbEditorFrame );
@ -153,6 +166,7 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
commit.Add( marker );
commit.Push( wxEmptyString, false, false );
}
};
// Returns false if we should return false from call site, or true to continue

View File

@ -120,7 +120,7 @@ bool PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK* aTrackItem,
int diagdrc = OK_DRC;
if( Settings().m_legacyDrcOn )
diagdrc = m_drc->Drc( aTrackItem, GetBoard()->m_Track );
diagdrc = m_drc->DrcOnCreatingTrack( aTrackItem, GetBoard()->m_Track );
if( diagdrc == OK_DRC )
change_ok = true;

View File

@ -75,14 +75,15 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC )
// Is the current segment Ok (no DRC error) ?
if( Settings().m_legacyDrcOn )
{
if( BAD_DRC==m_drc->Drc( g_CurrentTrackSegment, GetBoard()->m_Track ) )
if( BAD_DRC==m_drc->DrcOnCreatingTrack( g_CurrentTrackSegment, GetBoard()->m_Track ) )
// DRC error, the change layer is not made
return false;
// Handle 2 segments.
if( Settings().m_legacyUseTwoSegmentTracks && g_CurrentTrackSegment->Back() )
{
if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment->Back(), GetBoard()->m_Track ) )
if( BAD_DRC == m_drc->DrcOnCreatingTrack( g_CurrentTrackSegment->Back(),
GetBoard()->m_Track ) )
return false;
}
}
@ -153,7 +154,8 @@ bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC )
break;
}
if( Settings().m_legacyDrcOn && BAD_DRC == m_drc->Drc( via, GetBoard()->m_Track ) )
if( Settings().m_legacyDrcOn &&
BAD_DRC == m_drc->DrcOnCreatingTrack( via, GetBoard()->m_Track ) )
{
// DRC fault: the Via cannot be placed here ...
delete via;

View File

@ -214,7 +214,7 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
if( Settings().m_legacyDrcOn )
{
if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment, GetBoard()->m_Track ) )
if( BAD_DRC == m_drc->DrcOnCreatingTrack( g_CurrentTrackSegment, GetBoard()->m_Track ) )
{
return g_CurrentTrackSegment;
}
@ -225,13 +225,14 @@ TRACK* PCB_EDIT_FRAME::Begin_Route( TRACK* aTrack, wxDC* aDC )
// Test for a D.R.C. error:
if( Settings().m_legacyDrcOn )
{
if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment, GetBoard()->m_Track ) )
if( BAD_DRC == m_drc->DrcOnCreatingTrack( g_CurrentTrackSegment, GetBoard()->m_Track ) )
return NULL;
// We must handle 2 segments
if( Settings().m_legacyUseTwoSegmentTracks && g_CurrentTrackSegment->Back() )
{
if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment->Back(), GetBoard()->m_Track ) )
if( BAD_DRC == m_drc->DrcOnCreatingTrack( g_CurrentTrackSegment->Back(),
GetBoard()->m_Track ) )
return NULL;
}
}
@ -355,7 +356,8 @@ bool PCB_EDIT_FRAME::Add45DegreeSegment( wxDC* aDC )
else
newTrack->SetEnd( wxPoint(newTrack->GetEnd().x - segm_step_45, newTrack->GetEnd().y) );
if( Settings().m_legacyDrcOn && BAD_DRC == m_drc->Drc( curTrack, GetBoard()->m_Track ) )
if( Settings().m_legacyDrcOn &&
BAD_DRC == m_drc->DrcOnCreatingTrack( curTrack, GetBoard()->m_Track ) )
{
delete newTrack;
return false;
@ -390,7 +392,8 @@ bool PCB_EDIT_FRAME::Add45DegreeSegment( wxDC* aDC )
else
newTrack->SetEnd( wxPoint(newTrack->GetEnd().x, newTrack->GetEnd().y - segm_step_45) );
if( Settings().m_legacyDrcOn && BAD_DRC==m_drc->Drc( newTrack, GetBoard()->m_Track ) )
if( Settings().m_legacyDrcOn &&
BAD_DRC == m_drc->DrcOnCreatingTrack( newTrack, GetBoard()->m_Track ) )
{
delete newTrack;
return false;
@ -414,7 +417,8 @@ bool PCB_EDIT_FRAME::End_Route( TRACK* aTrack, wxDC* aDC )
if( aTrack == NULL )
return false;
if( Settings().m_legacyDrcOn && BAD_DRC == m_drc->Drc( g_CurrentTrackSegment, GetBoard()->m_Track ) )
if( Settings().m_legacyDrcOn &&
BAD_DRC == m_drc->DrcOnCreatingTrack( g_CurrentTrackSegment, GetBoard()->m_Track ) )
return false;
// Saving the coordinate of end point of the trace

View File

@ -803,15 +803,15 @@ bool PCB_EDIT_FRAME::PlaceDraggedOrMovedTrackSegment( TRACK* Track, wxDC* DC )
// DRC control:
if( Settings().m_legacyDrcOn )
{
errdrc = m_drc->Drc( Track, GetBoard()->m_Track );
errdrc = m_drc->DrcOnCreatingTrack( Track, GetBoard()->m_Track );
if( errdrc == BAD_DRC )
return false;
// Redraw the dragged segments
// Test the dragged segments
for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
{
errdrc = m_drc->Drc( g_DragSegmentList[ii].m_Track, GetBoard()->m_Track );
errdrc = m_drc->DrcOnCreatingTrack( g_DragSegmentList[ii].m_Track, GetBoard()->m_Track );
if( errdrc == BAD_DRC )
return false;

View File

@ -687,7 +687,8 @@ int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC )
// Add the duplicate corner:
zone->AppendCorner( GetCrossHairPosition(), -1, true );
if( Settings().m_legacyDrcOn && (m_drc->Drc( zone, 0 ) == BAD_DRC) && zone->IsOnCopperLayer() )
if( Settings().m_legacyDrcOn && (m_drc->DrcOnCreatingZone( zone, 0 ) == BAD_DRC)
&& zone->IsOnCopperLayer() )
{
zone->ClearFlags();
zone->RemoveAllContours();
@ -712,7 +713,8 @@ int PCB_EDIT_FRAME::Begin_Zone( wxDC* DC )
// by Show_New_Edge_While_Move_Mouse
if( zone->GetCornerPosition( ii - 1 ) != zone->GetCornerPosition( ii ) )
{
if( !Settings().m_legacyDrcOn || !zone->IsOnCopperLayer() || ( m_drc->Drc( zone, ii - 1 ) == OK_DRC ) )
if( !Settings().m_legacyDrcOn || !zone->IsOnCopperLayer()
|| ( m_drc->DrcOnCreatingZone( zone, ii - 1 ) == OK_DRC ) )
{
// Ok, we can add a new corner
if( m_canvas->IsMouseCaptured() )
@ -756,10 +758,12 @@ bool PCB_EDIT_FRAME::End_Zone( wxDC* DC )
int icorner = zone->GetNumCorners() - 1;
if( zone->IsOnCopperLayer() )
{
if( Settings().m_legacyDrcOn && m_drc->Drc( zone, icorner - 1 ) == BAD_DRC ) // we can't validate last edge
if( Settings().m_legacyDrcOn &&
m_drc->DrcOnCreatingZone( zone, icorner - 1 ) == BAD_DRC ) // we can't validate last edge
return false;
if( Settings().m_legacyDrcOn && m_drc->Drc( zone, icorner ) == BAD_DRC ) // we can't validate the closing edge
if( Settings().m_legacyDrcOn &&
m_drc->DrcOnCreatingZone( zone, icorner ) == BAD_DRC ) // we can't validate the closing edge
{
DisplayErrorMessage( this,
_( "DRC error: closing this area creates a DRC error with another area" ) );