GAL show markers for zone outlines gap test
Moved a DRC function (BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines) from BOARD class to DRC (DRC::TestZoneToZoneOutline). Added BOARD_COMMITs to handle marker visibility updates. Fixes: lp:1619124 * https://bugs.launchpad.net/kicad/+bug/1619124
This commit is contained in:
parent
693c8bce40
commit
9b5dc5c215
|
@ -1121,21 +1121,6 @@ public:
|
|||
ZONE_CONTAINER* area_ref,
|
||||
ZONE_CONTAINER* area_to_combine );
|
||||
|
||||
/**
|
||||
* Function Test_Drc_Areas_Outlines_To_Areas_Outlines
|
||||
* tests area outlines for DRC:
|
||||
* Tests areas inside other areas.
|
||||
* Tests areas too close.
|
||||
*
|
||||
* @param aArea_To_Examine: area to compare with other areas, or if NULL then
|
||||
* all areas are compared to all others.
|
||||
* @param aCreate_Markers: if true create DRC markers. False: do not creates anything
|
||||
* @return errors count
|
||||
*/
|
||||
int Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_Examine,
|
||||
bool aCreate_Markers );
|
||||
|
||||
|
||||
/**
|
||||
* Function GetViaByPosition
|
||||
* finds the first via at \a aPosition on \a aLayer.
|
||||
|
|
169
pcbnew/drc.cpp
169
pcbnew/drc.cpp
|
@ -41,6 +41,7 @@
|
|||
#include <class_draw_panel_gal.h>
|
||||
#include <view/view.h>
|
||||
#include <geometry/seg.h>
|
||||
#include <math_for_graphics.h>
|
||||
|
||||
#include <connectivity_data.h>
|
||||
#include <connectivity_algo.h>
|
||||
|
@ -89,13 +90,15 @@ void DRC::ShowDRCDialog( wxWindow* aParent )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void DRC::addMarkerToPcb( MARKER_PCB* aMarker )
|
||||
{
|
||||
BOARD_COMMIT commit ( m_pcbEditorFrame );
|
||||
BOARD_COMMIT commit( m_pcbEditorFrame );
|
||||
commit.Add( aMarker );
|
||||
commit.Push( wxEmptyString, false );
|
||||
}
|
||||
|
||||
|
||||
void DRC::DestroyDRCDialog( int aReason )
|
||||
{
|
||||
if( m_drcDialog )
|
||||
|
@ -176,6 +179,168 @@ int DRC::Drc( TRACK* aRefSegm, TRACK* aList )
|
|||
}
|
||||
|
||||
|
||||
int DRC::TestZoneToZoneOutline( ZONE_CONTAINER* aZone, bool aCreateMarkers )
|
||||
{
|
||||
BOARD* board = m_pcbEditorFrame->GetBoard();
|
||||
BOARD_COMMIT commit( m_pcbEditorFrame );
|
||||
int nerrors = 0;
|
||||
|
||||
// iterate through all areas
|
||||
for( int ia = 0; ia < board->GetAreaCount(); ia++ )
|
||||
{
|
||||
ZONE_CONTAINER* zoneRef = board->GetArea( ia );
|
||||
SHAPE_POLY_SET refSmoothedPoly;
|
||||
|
||||
zoneRef->BuildSmoothedPoly( refSmoothedPoly );
|
||||
|
||||
if( !zoneRef->IsOnCopperLayer() )
|
||||
continue;
|
||||
|
||||
// When testing only a single area, skip all others
|
||||
if( aZone && ( aZone != zoneRef) )
|
||||
continue;
|
||||
|
||||
for( int ia2 = 0; ia2 < board->GetAreaCount(); ia2++ )
|
||||
{
|
||||
ZONE_CONTAINER* zoneToTest = board->GetArea( ia2 );
|
||||
SHAPE_POLY_SET testSmoothedPoly;
|
||||
|
||||
zoneToTest->BuildSmoothedPoly( testSmoothedPoly );
|
||||
|
||||
if( zoneRef == zoneToTest )
|
||||
continue;
|
||||
|
||||
// test for same layer
|
||||
if( zoneRef->GetLayer() != zoneToTest->GetLayer() )
|
||||
continue;
|
||||
|
||||
// Test for same net
|
||||
if( zoneRef->GetNetCode() == zoneToTest->GetNetCode() && zoneRef->GetNetCode() >= 0 )
|
||||
continue;
|
||||
|
||||
// test for different priorities
|
||||
if( zoneRef->GetPriority() != zoneToTest->GetPriority() )
|
||||
continue;
|
||||
|
||||
// test for different types
|
||||
if( zoneRef->GetIsKeepout() != zoneToTest->GetIsKeepout() )
|
||||
continue;
|
||||
|
||||
// Examine a candidate zone: compare zoneToTest to zoneRef
|
||||
|
||||
// Get clearance used in zone to zone test. The policy used to
|
||||
// obtain that value is now part of the zone object itself by way of
|
||||
// ZONE_CONTAINER::GetClearance().
|
||||
int zone2zoneClearance = zoneRef->GetClearance( zoneToTest );
|
||||
|
||||
// Keepout areas have no clearance, so set zone2zoneClearance to 1
|
||||
// ( zone2zoneClearance = 0 can create problems in test functions)
|
||||
if( zoneRef->GetIsKeepout() )
|
||||
zone2zoneClearance = 1;
|
||||
|
||||
// test for some corners of zoneRef inside zoneToTest
|
||||
for( auto iterator = refSmoothedPoly.IterateWithHoles(); iterator; iterator++ )
|
||||
{
|
||||
VECTOR2I currentVertex = *iterator;
|
||||
|
||||
if( testSmoothedPoly.Contains( currentVertex ) )
|
||||
{
|
||||
// COPPERAREA_COPPERAREA error: copper area ref corner inside copper area
|
||||
if( aCreateMarkers )
|
||||
{
|
||||
wxPoint pt( currentVertex.x, currentVertex.y );
|
||||
wxString msg1 = zoneRef->GetSelectMenuText();
|
||||
wxString msg2 = zoneToTest->GetSelectMenuText();
|
||||
MARKER_PCB* marker = new MARKER_PCB( COPPERAREA_INSIDE_COPPERAREA,
|
||||
pt, msg1, pt, msg2, pt );
|
||||
commit.Add( marker );
|
||||
}
|
||||
|
||||
nerrors++;
|
||||
}
|
||||
}
|
||||
|
||||
// test for some corners of zoneToTest inside zoneRef
|
||||
for( auto iterator = testSmoothedPoly.IterateWithHoles(); iterator; iterator++ )
|
||||
{
|
||||
VECTOR2I currentVertex = *iterator;
|
||||
|
||||
if( refSmoothedPoly.Contains( currentVertex ) )
|
||||
{
|
||||
// COPPERAREA_COPPERAREA error: copper area corner inside copper area ref
|
||||
if( aCreateMarkers )
|
||||
{
|
||||
wxPoint pt( currentVertex.x, currentVertex.y );
|
||||
wxString msg1 = zoneToTest->GetSelectMenuText();
|
||||
wxString msg2 = zoneRef->GetSelectMenuText();
|
||||
MARKER_PCB* marker = new MARKER_PCB( COPPERAREA_INSIDE_COPPERAREA,
|
||||
pt, msg1, pt, msg2, pt );
|
||||
commit.Add( marker );
|
||||
}
|
||||
|
||||
nerrors++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Iterate through all the segments of refSmoothedPoly
|
||||
for( auto refIt = refSmoothedPoly.IterateSegmentsWithHoles(); refIt; refIt++ )
|
||||
{
|
||||
// Build ref segment
|
||||
SEG refSegment = *refIt;
|
||||
|
||||
// Iterate through all the segments in testSmoothedPoly
|
||||
for( auto testIt = testSmoothedPoly.IterateSegmentsWithHoles(); testIt; testIt++ )
|
||||
{
|
||||
// Build test segment
|
||||
SEG testSegment = *testIt;
|
||||
wxPoint pt;
|
||||
|
||||
int ax1, ay1, ax2, ay2;
|
||||
ax1 = refSegment.A.x;
|
||||
ay1 = refSegment.A.y;
|
||||
ax2 = refSegment.B.x;
|
||||
ay2 = refSegment.B.y;
|
||||
|
||||
int bx1, by1, bx2, by2;
|
||||
bx1 = testSegment.A.x;
|
||||
by1 = testSegment.A.y;
|
||||
bx2 = testSegment.B.x;
|
||||
by2 = testSegment.B.y;
|
||||
|
||||
int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2,
|
||||
0,
|
||||
ax1, ay1, ax2, ay2,
|
||||
0,
|
||||
zone2zoneClearance,
|
||||
&pt.x, &pt.y );
|
||||
|
||||
if( d < zone2zoneClearance )
|
||||
{
|
||||
// COPPERAREA_COPPERAREA error : intersect or too close
|
||||
if( aCreateMarkers )
|
||||
{
|
||||
wxString msg1 = zoneRef->GetSelectMenuText();
|
||||
wxString msg2 = zoneToTest->GetSelectMenuText();
|
||||
MARKER_PCB* marker = new MARKER_PCB( COPPERAREA_CLOSE_TO_COPPERAREA,
|
||||
pt, msg1, pt, msg2, pt );
|
||||
commit.Add( marker );
|
||||
}
|
||||
|
||||
nerrors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( aCreateMarkers )
|
||||
commit.Push( wxEmptyString, false );
|
||||
|
||||
return nerrors;
|
||||
}
|
||||
|
||||
|
||||
int DRC::Drc( ZONE_CONTAINER* aArea, int aCornerIndex )
|
||||
{
|
||||
updatePointers();
|
||||
|
@ -609,7 +774,7 @@ void DRC::testZones()
|
|||
}
|
||||
|
||||
// Test copper areas outlines, and create markers when needed
|
||||
m_pcb->Test_Drc_Areas_Outlines_To_Areas_Outlines( NULL, true );
|
||||
TestZoneToZoneOutline( NULL, true );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -458,6 +458,15 @@ public:
|
|||
return doTrackKeepoutDrc( aRefSeg ) ? OK_DRC : BAD_DRC;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
* @return Errors count
|
||||
*/
|
||||
int TestZoneToZoneOutline( ZONE_CONTAINER* aZone, bool aCreateMarkers );
|
||||
|
||||
/**
|
||||
* Function ShowDRCDialog
|
||||
|
|
|
@ -167,8 +167,10 @@ void PCB_EDIT_FRAME::duplicateZone( wxDC* aDC, ZONE_CONTAINER* aZone )
|
|||
GetBoard()->RedrawAreasOutlines( m_canvas, aDC, GR_OR, newZone->GetLayer() );
|
||||
GetBoard()->RedrawFilledAreas( m_canvas, aDC, GR_OR, newZone->GetLayer() );
|
||||
|
||||
DRC drc( this );
|
||||
|
||||
if( GetBoard()->GetAreaIndex( newZone ) >= 0
|
||||
&& GetBoard()->Test_Drc_Areas_Outlines_To_Areas_Outlines( newZone, true ) )
|
||||
&& drc.TestZoneToZoneOutline( newZone, true ) )
|
||||
{
|
||||
DisplayInfoMessage( this, _( "Warning: The new zone fails DRC" ) );
|
||||
}
|
||||
|
@ -367,7 +369,8 @@ void PCB_EDIT_FRAME::End_Move_Zone_Corner_Or_Outlines( wxDC* DC, ZONE_CONTAINER*
|
|||
SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED);
|
||||
s_PickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
|
||||
|
||||
int error_count = GetBoard()->Test_Drc_Areas_Outlines_To_Areas_Outlines( aZone, true );
|
||||
DRC drc( this );
|
||||
int error_count = drc.TestZoneToZoneOutline( aZone, true );
|
||||
|
||||
if( error_count )
|
||||
{
|
||||
|
@ -425,7 +428,8 @@ void PCB_EDIT_FRAME::Remove_Zone_Corner( wxDC* DC, ZONE_CONTAINER* aZone )
|
|||
if( ii < 0 )
|
||||
aZone = NULL; // aZone does not exist anymore, after combining zones
|
||||
|
||||
int error_count = GetBoard()->Test_Drc_Areas_Outlines_To_Areas_Outlines( aZone, true );
|
||||
DRC drc( this );
|
||||
int error_count = drc.TestZoneToZoneOutline( aZone, true );
|
||||
|
||||
if( error_count )
|
||||
{
|
||||
|
@ -811,7 +815,8 @@ bool PCB_EDIT_FRAME::End_Zone( wxDC* DC )
|
|||
if( ii < 0 )
|
||||
zone = NULL; // was removed by combining zones
|
||||
|
||||
int error_count = GetBoard()->Test_Drc_Areas_Outlines_To_Areas_Outlines( zone, true );
|
||||
DRC drc( this );
|
||||
int error_count = drc.TestZoneToZoneOutline( zone, true );
|
||||
|
||||
if( error_count )
|
||||
{
|
||||
|
|
|
@ -284,175 +284,6 @@ bool BOARD::CombineAreas( PICKED_ITEMS_LIST* aDeletedList, ZONE_CONTAINER* area_
|
|||
}
|
||||
|
||||
|
||||
int BOARD::Test_Drc_Areas_Outlines_To_Areas_Outlines( ZONE_CONTAINER* aArea_To_Examine,
|
||||
bool aCreate_Markers )
|
||||
{
|
||||
int nerrors = 0;
|
||||
|
||||
// iterate through all areas
|
||||
for( int ia = 0; ia < GetAreaCount(); ia++ )
|
||||
{
|
||||
ZONE_CONTAINER* Area_Ref = GetArea( ia );
|
||||
SHAPE_POLY_SET refSmoothedPoly;
|
||||
|
||||
Area_Ref->BuildSmoothedPoly( refSmoothedPoly );
|
||||
|
||||
if( !Area_Ref->IsOnCopperLayer() )
|
||||
continue;
|
||||
|
||||
// When testing only a single area, skip all others
|
||||
if( aArea_To_Examine && (aArea_To_Examine != Area_Ref) )
|
||||
continue;
|
||||
|
||||
for( int ia2 = 0; ia2 < GetAreaCount(); ia2++ )
|
||||
{
|
||||
ZONE_CONTAINER* area_to_test = GetArea( ia2 );
|
||||
SHAPE_POLY_SET testSmoothedPoly;
|
||||
|
||||
area_to_test->BuildSmoothedPoly( testSmoothedPoly );
|
||||
|
||||
if( Area_Ref == area_to_test )
|
||||
continue;
|
||||
|
||||
// test for same layer
|
||||
if( Area_Ref->GetLayer() != area_to_test->GetLayer() )
|
||||
continue;
|
||||
|
||||
// Test for same net
|
||||
if( Area_Ref->GetNetCode() == area_to_test->GetNetCode() && Area_Ref->GetNetCode() >= 0 )
|
||||
continue;
|
||||
|
||||
// test for different priorities
|
||||
if( Area_Ref->GetPriority() != area_to_test->GetPriority() )
|
||||
continue;
|
||||
|
||||
// test for different types
|
||||
if( Area_Ref->GetIsKeepout() != area_to_test->GetIsKeepout() )
|
||||
continue;
|
||||
|
||||
// Examine a candidate zone: compare area_to_test to Area_Ref
|
||||
|
||||
// Get clearance used in zone to zone test. The policy used to
|
||||
// obtain that value is now part of the zone object itself by way of
|
||||
// ZONE_CONTAINER::GetClearance().
|
||||
int zone2zoneClearance = Area_Ref->GetClearance( area_to_test );
|
||||
|
||||
// Keepout areas have no clearance, so set zone2zoneClearance to 1
|
||||
// ( zone2zoneClearance = 0 can create problems in test functions)
|
||||
if( Area_Ref->GetIsKeepout() )
|
||||
zone2zoneClearance = 1;
|
||||
|
||||
// test for some corners of Area_Ref inside area_to_test
|
||||
for( auto iterator = refSmoothedPoly.IterateWithHoles(); iterator; iterator++ )
|
||||
{
|
||||
VECTOR2I currentVertex = *iterator;
|
||||
|
||||
if( testSmoothedPoly.Contains( currentVertex ) )
|
||||
{
|
||||
// COPPERAREA_COPPERAREA error: copper area ref corner inside copper area
|
||||
if( aCreate_Markers )
|
||||
{
|
||||
int x = currentVertex.x;
|
||||
int y = currentVertex.y;
|
||||
|
||||
wxString msg1 = Area_Ref->GetSelectMenuText();
|
||||
wxString msg2 = area_to_test->GetSelectMenuText();
|
||||
MARKER_PCB* marker = new MARKER_PCB( COPPERAREA_INSIDE_COPPERAREA,
|
||||
wxPoint( x, y ),
|
||||
msg1, wxPoint( x, y ),
|
||||
msg2, wxPoint( x, y ) );
|
||||
Add( marker );
|
||||
}
|
||||
|
||||
nerrors++;
|
||||
}
|
||||
}
|
||||
|
||||
// test for some corners of area_to_test inside Area_Ref
|
||||
for( auto iterator = testSmoothedPoly.IterateWithHoles(); iterator; iterator++ )
|
||||
{
|
||||
VECTOR2I currentVertex = *iterator;
|
||||
|
||||
if( refSmoothedPoly.Contains( currentVertex ) )
|
||||
{
|
||||
// COPPERAREA_COPPERAREA error: copper area corner inside copper area ref
|
||||
if( aCreate_Markers )
|
||||
{
|
||||
int x = currentVertex.x;
|
||||
int y = currentVertex.y;
|
||||
|
||||
wxString msg1 = area_to_test->GetSelectMenuText();
|
||||
wxString msg2 = Area_Ref->GetSelectMenuText();
|
||||
MARKER_PCB* marker = new MARKER_PCB( COPPERAREA_INSIDE_COPPERAREA,
|
||||
wxPoint( x, y ),
|
||||
msg1, wxPoint( x, y ),
|
||||
msg2, wxPoint( x, y ) );
|
||||
Add( marker );
|
||||
}
|
||||
|
||||
nerrors++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Iterate through all the segments of refSmoothedPoly
|
||||
for( auto refIt = refSmoothedPoly.IterateSegmentsWithHoles(); refIt; refIt++ )
|
||||
{
|
||||
// Build ref segment
|
||||
SEG refSegment = *refIt;
|
||||
|
||||
// Iterate through all the segments in testSmoothedPoly
|
||||
for( auto testIt = testSmoothedPoly.IterateSegmentsWithHoles(); testIt; testIt++ )
|
||||
{
|
||||
// Build test segment
|
||||
SEG testSegment = *testIt;
|
||||
|
||||
int x, y;
|
||||
|
||||
int ax1, ay1, ax2, ay2;
|
||||
ax1 = refSegment.A.x;
|
||||
ay1 = refSegment.A.y;
|
||||
ax2 = refSegment.B.x;
|
||||
ay2 = refSegment.B.y;
|
||||
|
||||
int bx1, by1, bx2, by2;
|
||||
bx1 = testSegment.A.x;
|
||||
by1 = testSegment.A.y;
|
||||
bx2 = testSegment.B.x;
|
||||
by2 = testSegment.B.y;
|
||||
|
||||
int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2,
|
||||
0,
|
||||
ax1, ay1, ax2, ay2,
|
||||
0,
|
||||
zone2zoneClearance,
|
||||
&x, &y );
|
||||
|
||||
if( d < zone2zoneClearance )
|
||||
{
|
||||
// COPPERAREA_COPPERAREA error : intersect or too close
|
||||
if( aCreate_Markers )
|
||||
{
|
||||
wxString msg1 = Area_Ref->GetSelectMenuText();
|
||||
wxString msg2 = area_to_test->GetSelectMenuText();
|
||||
MARKER_PCB* marker = new MARKER_PCB( COPPERAREA_CLOSE_TO_COPPERAREA,
|
||||
wxPoint( x, y ),
|
||||
msg1, wxPoint( x, y ),
|
||||
msg2, wxPoint( x, y ) );
|
||||
Add( marker );
|
||||
}
|
||||
|
||||
nerrors++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nerrors;
|
||||
}
|
||||
|
||||
|
||||
bool DRC::doEdgeZoneDrc( ZONE_CONTAINER* aArea, int aCornerIndex )
|
||||
{
|
||||
if( !aArea->IsOnCopperLayer() ) // Cannot have a Drc error if not on copper layer
|
||||
|
|
Loading…
Reference in New Issue