Add some distances to a few DRC errors.
This commit is contained in:
parent
e14e3faed6
commit
32db9eb0f1
|
@ -48,8 +48,7 @@ PANEL_SETUP_SEVERITIES::PANEL_SETUP_SEVERITIES( PAGED_DIALOG* aParent, RC_ITEM&
|
|||
|
||||
for( int errorCode = m_firstErrorCode; errorCode <= m_lastErrorCode; ++errorCode )
|
||||
{
|
||||
aDummyItem.SetErrorCode( errorCode );
|
||||
wxString msg = aDummyItem.GetErrorText();
|
||||
wxString msg = aDummyItem.GetErrorText( errorCode );
|
||||
|
||||
// When msg is empty, for some reason, the current errorCode is not supported
|
||||
// by the RC_ITEM aDummyItem.
|
||||
|
|
|
@ -33,6 +33,15 @@
|
|||
#define WX_DATAVIEW_WINDOW_PADDING 6
|
||||
|
||||
|
||||
wxString RC_ITEM::GetErrorMessage() const
|
||||
{
|
||||
if( m_errorMessage.IsEmpty() )
|
||||
return GetErrorText( m_errorCode );
|
||||
else
|
||||
return m_errorMessage;
|
||||
}
|
||||
|
||||
|
||||
wxString RC_ITEM::ShowCoord( EDA_UNITS aUnits, const wxPoint& aPos )
|
||||
{
|
||||
return wxString::Format( "@(%s, %s)",
|
||||
|
@ -52,13 +61,11 @@ wxString RC_ITEM::ShowReport( EDA_UNITS aUnits, const std::map<KIID, EDA_ITEM*>&
|
|||
if( m_auxItemUuid != niluuid )
|
||||
auxItem = aItemMap.at( m_auxItemUuid );
|
||||
|
||||
wxString msg = m_errorMessage.IsEmpty() ? GetErrorText() : m_errorMessage;
|
||||
|
||||
if( mainItem && auxItem )
|
||||
{
|
||||
return wxString::Format( wxT( "ErrType(%d): %s\n %s: %s\n %s: %s\n" ),
|
||||
m_errorCode,
|
||||
msg,
|
||||
GetErrorCode(),
|
||||
GetErrorMessage(),
|
||||
ShowCoord( aUnits, mainItem->GetPosition() ),
|
||||
mainItem->GetSelectMenuText( aUnits ),
|
||||
ShowCoord( aUnits, auxItem->GetPosition() ),
|
||||
|
@ -67,16 +74,16 @@ wxString RC_ITEM::ShowReport( EDA_UNITS aUnits, const std::map<KIID, EDA_ITEM*>&
|
|||
else if( mainItem )
|
||||
{
|
||||
return wxString::Format( wxT( "ErrType(%d): %s\n %s: %s\n" ),
|
||||
m_errorCode,
|
||||
msg,
|
||||
GetErrorCode(),
|
||||
GetErrorMessage(),
|
||||
ShowCoord( aUnits, mainItem->GetPosition() ),
|
||||
mainItem->GetSelectMenuText( aUnits ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return wxString::Format( wxT( "ErrType(%d): %s\n" ),
|
||||
m_errorCode,
|
||||
msg );
|
||||
GetErrorCode(),
|
||||
GetErrorMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,7 +261,7 @@ void RC_TREE_MODEL::GetValue( wxVariant& aVariant,
|
|||
excluded ? _( "Excluded " ) : wxString( "" ),
|
||||
error ? _( "Error: " ) : _( "Warning: " ) );
|
||||
|
||||
aVariant = prefix + rcItem->GetErrorText();
|
||||
aVariant = prefix + rcItem->GetErrorMessage();
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -140,9 +140,15 @@ public:
|
|||
|
||||
/**
|
||||
* Function GetErrorText
|
||||
* returns the string form of a drc error code.
|
||||
* returns the string form of a RC error code
|
||||
*/
|
||||
virtual wxString GetErrorText() const = 0;
|
||||
virtual wxString GetErrorText( int aCode = -1 ) const = 0;
|
||||
|
||||
/**
|
||||
* Function GetErrorMessage
|
||||
* returns the error message of a RC_ITEM
|
||||
*/
|
||||
virtual wxString GetErrorMessage() const;
|
||||
|
||||
/**
|
||||
* Function ShowCoord
|
||||
|
|
|
@ -394,6 +394,7 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent )
|
|||
RC_ITEM* rcItem = node->m_RcItem;
|
||||
wxString listName;
|
||||
wxMenu menu;
|
||||
wxString msg;
|
||||
|
||||
switch( GetSeverity( rcItem->GetErrorCode() ) )
|
||||
{
|
||||
|
@ -417,20 +418,23 @@ void DIALOG_ERC::OnERCItemRClick( wxDataViewEvent& aEvent )
|
|||
|
||||
if( GetSeverity( rcItem->GetErrorCode() ) == RPT_SEVERITY_WARNING )
|
||||
{
|
||||
menu.Append( 3, wxString::Format( _( "Change severity to Error for all '%s' violations" ),
|
||||
rcItem->GetErrorText(),
|
||||
_( "Violation severities can also be edited in the Board Setup... dialog" ) ) );
|
||||
msg.Printf( _( "Change severity to Error for all '%s' violations" ),
|
||||
rcItem->GetErrorText( rcItem->GetErrorCode() ),
|
||||
_( "Violation severities can also be edited in the Board Setup... dialog" ) );
|
||||
menu.Append( 3, msg );
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.Append( 4, wxString::Format( _( "Change severity to Warning for all '%s' violations" ),
|
||||
rcItem->GetErrorText(),
|
||||
_( "Violation severities can also be edited in the Board Setup... dialog" ) ) );
|
||||
msg.Printf( _( "Change severity to Warning for all '%s' violations" ),
|
||||
rcItem->GetErrorText( rcItem->GetErrorCode() ),
|
||||
_( "Violation severities can also be edited in the Board Setup... dialog" ) );
|
||||
menu.Append( 4, msg );
|
||||
}
|
||||
|
||||
menu.Append( 5, wxString::Format( _( "Ignore all '%s' violations" ),
|
||||
rcItem->GetErrorText() ),
|
||||
_( "Violations will not be checked or reported" ) );
|
||||
msg.Printf( _( "Ignore all '%s' violations" ),
|
||||
rcItem->GetErrorText( rcItem->GetErrorCode() ),
|
||||
_( "Violations will not be checked or reported" ) );
|
||||
menu.Append( 5, msg );
|
||||
|
||||
menu.AppendSeparator();
|
||||
|
||||
|
|
|
@ -30,8 +30,11 @@
|
|||
#include <erc_item.h>
|
||||
|
||||
|
||||
wxString ERC_ITEM::GetErrorText() const
|
||||
wxString ERC_ITEM::GetErrorText( int aErrorCode ) const
|
||||
{
|
||||
if( aErrorCode < 0 )
|
||||
aErrorCode = m_errorCode;
|
||||
|
||||
switch( m_errorCode )
|
||||
{
|
||||
case ERCE_UNSPECIFIED:
|
||||
|
|
|
@ -37,9 +37,9 @@ public:
|
|||
|
||||
/**
|
||||
* Function GetErrorText
|
||||
* returns the string form of a drc error code.
|
||||
* returns the string form of an erc error code.
|
||||
*/
|
||||
wxString GetErrorText() const override;
|
||||
wxString GetErrorText( int aErrorCode = -1 ) const override;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ void SCH_MARKER::Print( RENDER_SETTINGS* aSettings, const wxPoint& aOffset )
|
|||
|
||||
bool SCH_MARKER::Matches( wxFindReplaceData& aSearchData, void* aAuxData )
|
||||
{
|
||||
return SCH_ITEM::Matches( m_rcItem->GetErrorText(), aSearchData );
|
||||
return SCH_ITEM::Matches( m_rcItem->GetErrorMessage(), aSearchData );
|
||||
}
|
||||
|
||||
|
||||
|
@ -130,7 +130,7 @@ const EDA_RECT SCH_MARKER::GetBoundingBox() const
|
|||
void SCH_MARKER::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, MSG_PANEL_ITEMS& aList )
|
||||
{
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Electronics Rule Check Error" ),
|
||||
m_rcItem->GetErrorText(), DARKRED ) );
|
||||
m_rcItem->GetErrorMessage(), DARKRED ) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ bool MARKER_PCB::IsOnLayer( PCB_LAYER_ID aLayer ) const
|
|||
void MARKER_PCB::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
|
||||
{
|
||||
aList.emplace_back( _( "Type" ), _( "Marker" ), DARKCYAN );
|
||||
aList.emplace_back( _( "Violation" ), m_rcItem->GetErrorText(), RED );
|
||||
aList.emplace_back( _( "Violation" ), m_rcItem->GetErrorMessage(), RED );
|
||||
|
||||
wxString mainText;
|
||||
wxString auxText;
|
||||
|
@ -140,7 +140,10 @@ void MARKER_PCB::Flip(const wxPoint& aCentre, bool aFlipLeftRight )
|
|||
|
||||
wxString MARKER_PCB::GetSelectMenuText( EDA_UNITS aUnits ) const
|
||||
{
|
||||
return wxString::Format( _( "Marker (%s)" ), m_rcItem->GetErrorText() );
|
||||
// m_rcItem->GetErrorMessage() could be used instead, but is probably too long
|
||||
// for menu duty.
|
||||
return wxString::Format( _( "Marker (%s)" ),
|
||||
m_rcItem->GetErrorText( m_rcItem->GetErrorCode() ) );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ public:
|
|||
|
||||
bool Matches( wxFindReplaceData& aSearchData, void* aAuxData ) override
|
||||
{
|
||||
return BOARD_ITEM::Matches( m_rcItem->GetErrorText(), aSearchData );
|
||||
return BOARD_ITEM::Matches( m_rcItem->GetErrorMessage(), aSearchData );
|
||||
}
|
||||
|
||||
wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
|
||||
|
|
|
@ -285,6 +285,7 @@ void DIALOG_DRC::OnDRCItemRClick( wxDataViewEvent& aEvent )
|
|||
RC_ITEM* rcItem = node->m_RcItem;
|
||||
wxString listName;
|
||||
wxMenu menu;
|
||||
wxString msg;
|
||||
|
||||
switch( m_BrdSettings.m_DRCSeverities[ rcItem->GetErrorCode() ] )
|
||||
{
|
||||
|
@ -308,20 +309,23 @@ void DIALOG_DRC::OnDRCItemRClick( wxDataViewEvent& aEvent )
|
|||
|
||||
if( m_BrdSettings.m_DRCSeverities[ rcItem->GetErrorCode() ] == RPT_SEVERITY_WARNING )
|
||||
{
|
||||
menu.Append( 3, wxString::Format( _( "Change severity to Error for all '%s' violations" ),
|
||||
rcItem->GetErrorText(),
|
||||
_( "Violation severities can also be edited in the Board Setup... dialog" ) ) );
|
||||
msg.Printf( _( "Change severity to Error for all '%s' violations" ),
|
||||
rcItem->GetErrorText( rcItem->GetErrorCode() ),
|
||||
_( "Violation severities can also be edited in the Board Setup... dialog" ) );
|
||||
menu.Append( 3, msg );
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.Append( 4, wxString::Format( _( "Change severity to Warning for all '%s' violations" ),
|
||||
rcItem->GetErrorText(),
|
||||
_( "Violation severities can also be edited in the Board Setup... dialog" ) ) );
|
||||
msg.Printf( _( "Change severity to Warning for all '%s' violations" ),
|
||||
rcItem->GetErrorText( rcItem->GetErrorCode() ),
|
||||
_( "Violation severities can also be edited in the Board Setup... dialog" ) );
|
||||
menu.Append( 4, msg );
|
||||
}
|
||||
|
||||
menu.Append( 5, wxString::Format( _( "Ignore all '%s' violations" ),
|
||||
rcItem->GetErrorText() ),
|
||||
_( "Violations will not be checked or reported" ) );
|
||||
msg.Printf( _( "Ignore all '%s' violations" ),
|
||||
rcItem->GetErrorText( rcItem->GetErrorCode() ),
|
||||
_( "Violations will not be checked or reported" ) );
|
||||
menu.Append( 5, msg );
|
||||
|
||||
menu.AppendSeparator();
|
||||
|
||||
|
|
|
@ -696,6 +696,7 @@ void DRC::testDrilledHoles()
|
|||
|
||||
std::vector<DRILLED_HOLE> holes;
|
||||
DRILLED_HOLE hole;
|
||||
wxString msg;
|
||||
|
||||
for( MODULE* mod : m_pcb->Modules() )
|
||||
{
|
||||
|
@ -735,10 +736,18 @@ void DRC::testDrilledHoles()
|
|||
if( checkHole.m_location == refHole.m_location )
|
||||
continue;
|
||||
|
||||
if( KiROUND( GetLineLength( checkHole.m_location, refHole.m_location ) )
|
||||
< checkHole.m_drillRadius + refHole.m_drillRadius + holeToHoleMin )
|
||||
int actual = KiROUND( GetLineLength( checkHole.m_location, refHole.m_location ) );
|
||||
actual = std::max( 0, actual - checkHole.m_drillRadius - refHole.m_drillRadius );
|
||||
|
||||
if( actual < holeToHoleMin )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_DRILLED_HOLES_TOO_CLOSE );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( " (minimum %s; actual %s)" ),
|
||||
MessageTextFromValue( userUnits(), holeToHoleMin, true ),
|
||||
MessageTextFromValue( userUnits(), actual, true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetItems( refHole.m_owner, checkHole.m_owner );
|
||||
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, refHole.m_location );
|
||||
|
@ -1319,7 +1328,10 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_li
|
|||
|
||||
for( D_PAD** pad_list = aStart; pad_list<aEnd; ++pad_list )
|
||||
{
|
||||
D_PAD* pad = *pad_list;
|
||||
D_PAD* pad = *pad_list;
|
||||
int allowed;
|
||||
int actual;
|
||||
wxString msg;
|
||||
|
||||
if( pad == aRefPad )
|
||||
continue;
|
||||
|
@ -1363,9 +1375,15 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_li
|
|||
PAD_SHAPE_OVAL : PAD_SHAPE_CIRCLE );
|
||||
dummypad.SetOrientation( pad->GetOrientation() );
|
||||
|
||||
if( !checkClearancePadToPad( aRefPad, &dummypad ) )
|
||||
if( !checkClearancePadToPad( aRefPad, &dummypad, &allowed, &actual ) )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_HOLE_NEAR_PAD );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( "(minimum %s; actual %s)" ),
|
||||
MessageTextFromValue( userUnits(), allowed, true ),
|
||||
MessageTextFromValue( userUnits(), actual, true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetItems( pad, aRefPad );
|
||||
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, pad->GetPosition() );
|
||||
|
@ -1382,9 +1400,15 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_li
|
|||
PAD_SHAPE_OVAL : PAD_SHAPE_CIRCLE );
|
||||
dummypad.SetOrientation( aRefPad->GetOrientation() );
|
||||
|
||||
if( !checkClearancePadToPad( pad, &dummypad ) )
|
||||
if( !checkClearancePadToPad( pad, &dummypad, &allowed, &actual ) )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_HOLE_NEAR_PAD );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( "(minimum %s; actual %s)" ),
|
||||
MessageTextFromValue( userUnits(), allowed, true ),
|
||||
MessageTextFromValue( userUnits(), actual, true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetItems( aRefPad, pad );
|
||||
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, aRefPad->GetPosition() );
|
||||
|
@ -1420,9 +1444,15 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_li
|
|||
continue;
|
||||
}
|
||||
|
||||
if( !checkClearancePadToPad( aRefPad, pad ) )
|
||||
if( !checkClearancePadToPad( aRefPad, pad, &allowed, &actual ) )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_PAD_NEAR_PAD1 );
|
||||
|
||||
msg.Printf( drcItem->GetErrorText() + _( "(minimum %s; actual %s)" ),
|
||||
MessageTextFromValue( userUnits(), allowed, true ),
|
||||
MessageTextFromValue( userUnits(), actual, true ) );
|
||||
|
||||
drcItem->SetErrorMessage( msg );
|
||||
drcItem->SetItems( aRefPad, pad );
|
||||
|
||||
MARKER_PCB* marker = new MARKER_PCB( drcItem, aRefPad->GetPosition() );
|
||||
|
|
|
@ -301,9 +301,11 @@ private:
|
|||
/**
|
||||
* @param aRefPad The reference pad to check
|
||||
* @param aPad Another pad to check against
|
||||
* @param aAllowed [out] is the allowed distance (only guaranteed to be set for violations)
|
||||
* @param aActual [out] it the actual difference (only guaranteed to be set for violations)
|
||||
* @return bool - true if clearance between aRefPad and aPad is >= dist_min, else false
|
||||
*/
|
||||
bool checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad );
|
||||
bool checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, int* aAllowed, int* aActual );
|
||||
|
||||
|
||||
/**
|
||||
|
@ -316,11 +318,13 @@ private:
|
|||
* @param aPad Is the pad involved in the check
|
||||
* @param aSegmentWidth width of the segment to test
|
||||
* @param aMinDist Is the minimum clearance needed
|
||||
* @param aActualDist [out] Is the actual clearance (only guarantted to be set on violations)
|
||||
*
|
||||
* @return true distance >= dist_min,
|
||||
* false if distance < dist_min
|
||||
*/
|
||||
bool checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMinDist );
|
||||
bool checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMinDist,
|
||||
int* aActualDist );
|
||||
|
||||
|
||||
/**
|
||||
|
@ -329,13 +333,14 @@ private:
|
|||
* The segment is expected starting at 0,0, and on the X axis
|
||||
* (used to test DRC between a segment and a round pad, via or round end of a track
|
||||
* @param aCentre The coordinate of the circle's center
|
||||
* @param aRadius A "keep out" radius centered over the circle
|
||||
* @param aAllowed A "keep out" radius centered over the circle
|
||||
* @param aLength The length of the segment (i.e. coordinate of end, because it is on
|
||||
* the X axis)
|
||||
* @param aActual [out] is the actual distance (only guaranteed to be set on violations)
|
||||
* @return bool - true if distance >= radius, else
|
||||
* false when distance < aRadius
|
||||
* false when distance < aAllowed
|
||||
*/
|
||||
static bool checkMarginToCircle( wxPoint aCentre, int aRadius, int aLength );
|
||||
static bool checkMarginToCircle( wxPoint aCentre, int aAllowed, int aLength, int* aActual );
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -46,17 +46,24 @@
|
|||
* i.e if for each edge of the first polygon distance from each edge of the other polygon
|
||||
* is >= aDist
|
||||
*/
|
||||
bool poly2polyDRC( wxPoint* aTref, int aTrefCount, wxPoint* aTtest, int aTtestCount, int aDist )
|
||||
bool poly2polyDRC( wxPoint* aTref, int aTrefCount, wxPoint* aTtest, int aTtestCount,
|
||||
int aAllowedDist, int* actualDist )
|
||||
{
|
||||
/* Test if one polygon is contained in the other and thus the polygon overlap.
|
||||
* This case is not covered by the following check if one polygone is
|
||||
* completely contained in the other (because edges don't intersect)!
|
||||
*/
|
||||
if( TestPointInsidePolygon( aTref, aTrefCount, aTtest[0] ) )
|
||||
{
|
||||
*actualDist = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( TestPointInsidePolygon( aTtest, aTtestCount, aTref[0] ) )
|
||||
{
|
||||
*actualDist = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
for( int ii = 0, jj = aTrefCount - 1; ii < aTrefCount; jj = ii, ii++ )
|
||||
{
|
||||
|
@ -70,8 +77,17 @@ bool poly2polyDRC( wxPoint* aTref, int aTrefCount, wxPoint* aTtest, int aTtestCo
|
|||
aTtest[kk].x, aTtest[kk].y, aTtest[ll].x, aTtest[ll].y,
|
||||
nullptr, nullptr, &d );
|
||||
|
||||
if( intersect || ( d < aDist ) )
|
||||
if( intersect )
|
||||
{
|
||||
*actualDist = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( d < aAllowedDist )
|
||||
{
|
||||
*actualDist = KiROUND( d );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,25 +98,36 @@ bool poly2polyDRC( wxPoint* aTref, int aTrefCount, wxPoint* aTtest, int aTtestCo
|
|||
/*
|
||||
* compare a trapezoid (can be rectangle) and a segment and return true if distance > aDist
|
||||
*/
|
||||
bool poly2segmentDRC( wxPoint* aTref, int aTrefCount, wxPoint aSegStart, wxPoint aSegEnd, int aDist )
|
||||
bool poly2segmentDRC( wxPoint* aTref, int aTrefCount, wxPoint aSegStart, wxPoint aSegEnd,
|
||||
int aDist, int* aActual )
|
||||
{
|
||||
/* Test if the segment is contained in the polygon.
|
||||
* This case is not covered by the following check if the segment is
|
||||
* completely contained in the polygon (because edges don't intersect)!
|
||||
*/
|
||||
if( TestPointInsidePolygon( aTref, aTrefCount, aSegStart ) )
|
||||
{
|
||||
*aActual = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
for( int ii = 0, jj = aTrefCount-1; ii < aTrefCount; jj = ii, ii++ )
|
||||
{ // for all edges in polygon
|
||||
double d;
|
||||
int intersect = TestForIntersectionOfStraightLineSegments(
|
||||
aTref[ii].x, aTref[ii].y, aTref[jj].x, aTref[jj].y,
|
||||
aSegStart.x, aSegStart.y, aSegEnd.x, aSegEnd.y,
|
||||
NULL, NULL, &d );
|
||||
|
||||
if( intersect || ( d < aDist) )
|
||||
if( TestForIntersectionOfStraightLineSegments( aTref[ii].x, aTref[ii].y, aTref[jj].x,
|
||||
aTref[jj].y, aSegStart.x, aSegStart.y,
|
||||
aSegEnd.x, aSegEnd.y, NULL, NULL, &d ) )
|
||||
{
|
||||
*aActual = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( d < aDist )
|
||||
{
|
||||
*aActual = KiROUND( d );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -128,6 +155,7 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
int net_code_ref = aRefSeg->GetNetCode();
|
||||
int ref_seg_clearance = netclass->GetClearance();
|
||||
int ref_seg_width = aRefSeg->GetWidth();
|
||||
int actual;
|
||||
|
||||
|
||||
/******************************************/
|
||||
|
@ -311,7 +339,7 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
|
||||
m_padToTestPos = dummypad.GetPosition() - origin;
|
||||
|
||||
if( !checkClearanceSegmToPad( &dummypad, ref_seg_width, ref_seg_clearance ) )
|
||||
if( !checkClearanceSegmToPad( &dummypad, ref_seg_width, ref_seg_clearance, &actual ) )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_NEAR_THROUGH_HOLE );
|
||||
drcItem->SetItems( aRefSeg, pad );
|
||||
|
@ -337,7 +365,7 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
m_padToTestPos = shape_pos - origin;
|
||||
int segToPadClearance = std::max( ref_seg_clearance, pad->GetClearance() );
|
||||
|
||||
if( !checkClearanceSegmToPad( pad, ref_seg_width, segToPadClearance ) )
|
||||
if( !checkClearanceSegmToPad( pad, ref_seg_width, segToPadClearance, &actual ) )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_NEAR_PAD );
|
||||
drcItem->SetItems( aRefSeg, pad );
|
||||
|
@ -414,7 +442,7 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
RotatePoint( &delta, angle );
|
||||
RotatePoint( &segStartPoint, angle );
|
||||
|
||||
if( !checkMarginToCircle( segStartPoint, w_dist, delta.x ) )
|
||||
if( !checkMarginToCircle( segStartPoint, w_dist, delta.x, &actual ) )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_VIA_NEAR_TRACK );
|
||||
drcItem->SetItems( aRefSeg, track );
|
||||
|
@ -443,7 +471,7 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
|
||||
if( track->Type() == PCB_VIA_T )
|
||||
{
|
||||
if( checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) )
|
||||
if( checkMarginToCircle( segStartPoint, w_dist, m_segmLength, &actual ) )
|
||||
continue;
|
||||
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_NEAR_VIA );
|
||||
|
@ -488,7 +516,7 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
return;
|
||||
}
|
||||
|
||||
if( !checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) )
|
||||
if( !checkMarginToCircle( segStartPoint, w_dist, m_segmLength, &actual ) )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_ENDS );
|
||||
drcItem->SetItems( aRefSeg, track );
|
||||
|
@ -519,7 +547,7 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
return;
|
||||
}
|
||||
|
||||
if( !checkMarginToCircle( segEndPoint, w_dist, m_segmLength ) )
|
||||
if( !checkMarginToCircle( segEndPoint, w_dist, m_segmLength, &actual ) )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_ENDS );
|
||||
drcItem->SetItems( aRefSeg, track );
|
||||
|
@ -572,7 +600,7 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
}
|
||||
|
||||
// At this point the drc error is due to an end near a reference segm end
|
||||
if( !checkMarginToCircle( segStartPoint, w_dist, m_segmLength ) )
|
||||
if( !checkMarginToCircle( segStartPoint, w_dist, m_segmLength, &actual ) )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_ENDS );
|
||||
drcItem->SetItems( aRefSeg, track );
|
||||
|
@ -583,7 +611,7 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
if( !m_reportAllTrackErrors )
|
||||
return;
|
||||
}
|
||||
if( !checkMarginToCircle( segEndPoint, w_dist, m_segmLength ) )
|
||||
if( !checkMarginToCircle( segEndPoint, w_dist, m_segmLength, &actual ) )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_ENDS );
|
||||
drcItem->SetItems( aRefSeg, track );
|
||||
|
@ -664,7 +692,7 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
RotatePoint( &relStartPos, angle );
|
||||
RotatePoint( &relEndPos, angle );
|
||||
|
||||
if( !checkMarginToCircle( relStartPos, w_dist, delta.x ) )
|
||||
if( !checkMarginToCircle( relStartPos, w_dist, delta.x, &actual ) )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_ENDS );
|
||||
drcItem->SetItems( aRefSeg, track );
|
||||
|
@ -676,7 +704,7 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
return;
|
||||
}
|
||||
|
||||
if( !checkMarginToCircle( relEndPos, w_dist, delta.x ) )
|
||||
if( !checkMarginToCircle( relEndPos, w_dist, delta.x, &actual ) )
|
||||
{
|
||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_ENDS );
|
||||
drcItem->SetItems( aRefSeg, track );
|
||||
|
@ -781,13 +809,16 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
|||
}
|
||||
|
||||
|
||||
bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
||||
bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, int* aAllowed, int* aActual )
|
||||
{
|
||||
int dist;
|
||||
int dist;
|
||||
double pad_angle;
|
||||
|
||||
// Get the clearance between the 2 pads. this is the min distance between aRefPad and aPad
|
||||
int dist_min = aRefPad->GetClearance( aPad );
|
||||
int dist_min = aRefPad->GetClearance( aPad );
|
||||
int dist_extra = 0;
|
||||
|
||||
*aAllowed = dist_min;
|
||||
|
||||
// relativePadPos is the aPad shape position relative to the aRefPad shape position
|
||||
wxPoint relativePadPos = aPad->ShapePos() - aRefPad->ShapePos();
|
||||
|
@ -876,7 +907,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
|||
m_segmEnd.x = m_segmEnd.y = 0;
|
||||
|
||||
m_padToTestPos = relativePadPos;
|
||||
diag = checkClearanceSegmToPad( aPad, aRefPad->GetSize().x, dist_min );
|
||||
diag = checkClearanceSegmToPad( aPad, aRefPad->GetSize().x, dist_min, aActual );
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_TRAPEZOID:
|
||||
|
@ -891,7 +922,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
|||
if( aRefPad->GetShape() == PAD_SHAPE_ROUNDRECT )
|
||||
{
|
||||
int padRadius = aRefPad->GetRoundRectCornerRadius();
|
||||
dist_min += padRadius;
|
||||
dist_extra = padRadius;
|
||||
GetRoundRectCornerCenters( polyref, padRadius, wxPoint( 0, 0 ), aRefPad->GetSize(),
|
||||
aRefPad->GetOrientation() );
|
||||
}
|
||||
|
@ -939,7 +970,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
|||
if( aPad->GetShape() == PAD_SHAPE_ROUNDRECT )
|
||||
{
|
||||
int padRadius = aPad->GetRoundRectCornerRadius();
|
||||
dist_min += padRadius;
|
||||
dist_extra = padRadius;
|
||||
GetRoundRectCornerCenters( polycompare, padRadius, relativePadPos, aPad->GetSize(),
|
||||
aPad->GetOrientation() );
|
||||
}
|
||||
|
@ -986,17 +1017,23 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
|||
{
|
||||
const SHAPE_LINE_CHAIN& refpoly = polysetref.COutline( 0 );
|
||||
// And now test polygons:
|
||||
if( !poly2polyDRC( (wxPoint*) &refpoly.CPoint( 0 ), refpoly.PointCount(),
|
||||
polycompare, 4, dist_min ) ) // Therefore error
|
||||
if( !poly2polyDRC((wxPoint*) &refpoly.CPoint( 0 ), refpoly.PointCount(),
|
||||
polycompare, 4, dist_min + dist_extra, aActual ) )
|
||||
{
|
||||
*aActual = std::max( 0, *aActual - dist_extra );
|
||||
diag = false;
|
||||
}
|
||||
}
|
||||
else if( polysetref.OutlineCount() == 0 && polysetcompare.OutlineCount())
|
||||
{
|
||||
const SHAPE_LINE_CHAIN& cmppoly = polysetcompare.COutline( 0 );
|
||||
// And now test polygons:
|
||||
if( !poly2polyDRC( (wxPoint*) &cmppoly.CPoint( 0 ), cmppoly.PointCount(),
|
||||
polyref, 4, dist_min ) ) // Therefore error
|
||||
if( !poly2polyDRC((wxPoint*) &cmppoly.CPoint( 0 ), cmppoly.PointCount(),
|
||||
polyref, 4, dist_min + dist_extra, aActual ) )
|
||||
{
|
||||
*aActual = std::max( 0, *aActual - dist_extra );
|
||||
diag = false;
|
||||
}
|
||||
}
|
||||
else if( polysetref.OutlineCount() && polysetcompare.OutlineCount() )
|
||||
{
|
||||
|
@ -1004,15 +1041,21 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
|||
const SHAPE_LINE_CHAIN& cmppoly = polysetcompare.COutline( 0 );
|
||||
|
||||
// And now test polygons:
|
||||
if( !poly2polyDRC( (wxPoint*) &refpoly.CPoint( 0 ), refpoly.PointCount(),
|
||||
(wxPoint*) &cmppoly.CPoint( 0 ), cmppoly.PointCount(),
|
||||
dist_min ) ) // Therefore error
|
||||
if( !poly2polyDRC((wxPoint*) &refpoly.CPoint( 0 ), refpoly.PointCount(),
|
||||
(wxPoint*) &cmppoly.CPoint( 0 ), cmppoly.PointCount(),
|
||||
dist_min + dist_extra, aActual ) )
|
||||
{
|
||||
*aActual = std::max( 0, *aActual - dist_extra );
|
||||
diag = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !poly2polyDRC( polyref, 4, polycompare, 4, dist_min ) ) // Therefore error
|
||||
if( !poly2polyDRC( polyref, 4, polycompare, 4, dist_min + dist_extra, aActual ) )
|
||||
{
|
||||
*aActual = std::max( 0, *aActual - dist_extra );
|
||||
diag = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1060,7 +1103,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
|||
m_padToTestPos = relativePadPos - segstart;
|
||||
|
||||
// Use segment to pad check to test the second pad:
|
||||
diag = checkClearanceSegmToPad( aPad, segm_width, dist_min );
|
||||
diag = checkClearanceSegmToPad( aPad, segm_width, dist_min, aActual );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1078,7 +1121,8 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad )
|
|||
* and its orientation is m_segmAngle (m_segmAngle must be already initialized)
|
||||
* and have aSegmentWidth.
|
||||
*/
|
||||
bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMinDist )
|
||||
bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMinDist,
|
||||
int* aActualDist )
|
||||
{
|
||||
// Note:
|
||||
// we are using a horizontal segment for test, because we know here
|
||||
|
@ -1119,7 +1163,15 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
|
|||
* calculate pad coordinates in the X,Y axis with X axis = segment to test
|
||||
*/
|
||||
RotatePoint( &m_padToTestPos, m_segmAngle );
|
||||
return checkMarginToCircle( m_padToTestPos, distToLine + padHalfsize.x, m_segmLength );
|
||||
|
||||
if( !checkMarginToCircle( m_padToTestPos, aMinDist + segmHalfWidth + padHalfsize.x,
|
||||
m_segmLength, aActualDist ) )
|
||||
{
|
||||
*aActualDist = std::max( 0, *aActualDist - segmHalfWidth - padHalfsize.x );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* calculate the bounding box of the pad, including the clearance and the segment width
|
||||
|
@ -1196,6 +1248,7 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
|
|||
// If the segment legth is zero, only check the endpoints, skip the rectangle
|
||||
if( m_segmLength && !checkLine( startPoint, endPoint ) )
|
||||
{
|
||||
// JEY TODO: set aActual
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1207,8 +1260,10 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
|
|||
// to the segment:
|
||||
RotatePoint( &cstart, m_segmAngle );
|
||||
|
||||
if( !checkMarginToCircle( cstart, radius + distToLine, m_segmLength ) )
|
||||
if( !checkMarginToCircle( cstart, aMinDist + radius + segmHalfWidth, m_segmLength,
|
||||
aActualDist) )
|
||||
{
|
||||
*aActualDist = std::max( 0, *aActualDist - radius - segmHalfWidth );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1216,8 +1271,10 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
|
|||
RotatePoint( &cend, m_padToTestPos, orient );
|
||||
RotatePoint( &cend, m_segmAngle );
|
||||
|
||||
if( !checkMarginToCircle( cend, radius + distToLine, m_segmLength ) )
|
||||
if( !checkMarginToCircle( cend, aMinDist + radius + segmHalfWidth, m_segmLength,
|
||||
aActualDist ) )
|
||||
{
|
||||
*aActualDist = std::max( 0, *aActualDist - radius - segmHalfWidth );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1243,7 +1300,10 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
|
|||
m_ycliphi = m_padToTestPos.y + padHalfsize.y;
|
||||
|
||||
if( !checkLine( startPoint, endPoint ) )
|
||||
{
|
||||
// JEY TODO: set aActual
|
||||
return false;
|
||||
}
|
||||
|
||||
// Testing the second rectangle dimx , dimy + distToLine
|
||||
m_xcliplo = m_padToTestPos.x - padHalfsize.x;
|
||||
|
@ -1252,7 +1312,10 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
|
|||
m_ycliphi = m_padToTestPos.y + padHalfsize.y + distToLine;
|
||||
|
||||
if( !checkLine( startPoint, endPoint ) )
|
||||
{
|
||||
// JEY TODO: set aActual
|
||||
return false;
|
||||
}
|
||||
|
||||
// testing the 4 circles which are the clearance area of each corner:
|
||||
|
||||
|
@ -1262,8 +1325,12 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
|
|||
RotatePoint( &startPoint, m_padToTestPos, orient );
|
||||
RotatePoint( &startPoint, m_segmAngle );
|
||||
|
||||
if( !checkMarginToCircle( startPoint, distToLine, m_segmLength ) )
|
||||
if( !checkMarginToCircle( startPoint, aMinDist + segmHalfWidth, m_segmLength,
|
||||
aActualDist ) )
|
||||
{
|
||||
*aActualDist = std::max( 0, *aActualDist - segmHalfWidth );
|
||||
return false;
|
||||
}
|
||||
|
||||
// testing the right top corner of the rectangle
|
||||
startPoint.x = m_padToTestPos.x + padHalfsize.x;
|
||||
|
@ -1271,8 +1338,12 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
|
|||
RotatePoint( &startPoint, m_padToTestPos, orient );
|
||||
RotatePoint( &startPoint, m_segmAngle );
|
||||
|
||||
if( !checkMarginToCircle( startPoint, distToLine, m_segmLength ) )
|
||||
if( !checkMarginToCircle( startPoint, aMinDist + segmHalfWidth, m_segmLength,
|
||||
aActualDist ) )
|
||||
{
|
||||
*aActualDist = std::max( 0, *aActualDist - segmHalfWidth );
|
||||
return false;
|
||||
}
|
||||
|
||||
// testing the left bottom corner of the rectangle
|
||||
startPoint.x = m_padToTestPos.x - padHalfsize.x;
|
||||
|
@ -1280,8 +1351,12 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
|
|||
RotatePoint( &startPoint, m_padToTestPos, orient );
|
||||
RotatePoint( &startPoint, m_segmAngle );
|
||||
|
||||
if( !checkMarginToCircle( startPoint, distToLine, m_segmLength ) )
|
||||
if( !checkMarginToCircle( startPoint, aMinDist + segmHalfWidth, m_segmLength,
|
||||
aActualDist ) )
|
||||
{
|
||||
*aActualDist = std::max( 0, *aActualDist - segmHalfWidth );
|
||||
return false;
|
||||
}
|
||||
|
||||
// testing the right bottom corner of the rectangle
|
||||
startPoint.x = m_padToTestPos.x + padHalfsize.x;
|
||||
|
@ -1289,8 +1364,12 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
|
|||
RotatePoint( &startPoint, m_padToTestPos, orient );
|
||||
RotatePoint( &startPoint, m_segmAngle );
|
||||
|
||||
if( !checkMarginToCircle( startPoint, distToLine, m_segmLength ) )
|
||||
if( !checkMarginToCircle( startPoint, aMinDist + segmHalfWidth, m_segmLength,
|
||||
aActualDist ) )
|
||||
{
|
||||
*aActualDist = std::max( 0, *aActualDist - segmHalfWidth );
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
@ -1306,10 +1385,13 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
|
|||
RotatePoint( &poly[ii], m_segmAngle );
|
||||
}
|
||||
|
||||
if( !poly2segmentDRC( poly, 4, wxPoint( 0, 0 ),
|
||||
wxPoint(m_segmLength,0), distToLine ) )
|
||||
if( !poly2segmentDRC( poly, 4, wxPoint( 0, 0 ), wxPoint( m_segmLength, 0 ),
|
||||
aMinDist + segmHalfWidth, aActualDist ) )
|
||||
{
|
||||
*aActualDist = std::max( 0, *aActualDist - segmHalfWidth );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_CUSTOM:
|
||||
|
@ -1320,8 +1402,7 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
|
|||
// relatives to the segment being tested
|
||||
// Note, the pad position relative to the segment origin
|
||||
// is m_padToTestPos
|
||||
aPad->CustomShapeAsPolygonToBoardPosition( &polyset,
|
||||
m_padToTestPos, orient );
|
||||
aPad->CustomShapeAsPolygonToBoardPosition( &polyset, m_padToTestPos, orient );
|
||||
|
||||
// Rotate all coordinates by m_segmAngle, because the segment orient
|
||||
// is m_segmAngle
|
||||
|
@ -1329,17 +1410,18 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
|
|||
// only the lenght and orientation+ of the segment
|
||||
// therefore all coordinates of the pad to test must be rotated by
|
||||
// m_segmAngle (they are already relative to the segment origin)
|
||||
aPad->CustomShapeAsPolygonToBoardPosition( &polyset,
|
||||
wxPoint( 0, 0 ), m_segmAngle );
|
||||
aPad->CustomShapeAsPolygonToBoardPosition( &polyset, wxPoint( 0, 0 ), m_segmAngle );
|
||||
|
||||
const SHAPE_LINE_CHAIN& refpoly = polyset.COutline( 0 );
|
||||
|
||||
if( !poly2segmentDRC( (wxPoint*) &refpoly.CPoint( 0 ),
|
||||
refpoly.PointCount(),
|
||||
if( !poly2segmentDRC( (wxPoint*) &refpoly.CPoint( 0 ), refpoly.PointCount(),
|
||||
wxPoint( 0, 0 ), wxPoint(m_segmLength,0),
|
||||
distToLine ) )
|
||||
aMinDist + segmHalfWidth, aActualDist ) )
|
||||
{
|
||||
*aActualDist = std::max( 0, *aActualDist - segmHalfWidth );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PAD_SHAPE_CHAMFERED_RECT:
|
||||
|
@ -1370,12 +1452,14 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
|
|||
|
||||
const SHAPE_LINE_CHAIN& refpoly = polyset.COutline( 0 );
|
||||
|
||||
if( !poly2segmentDRC( (wxPoint*) &refpoly.CPoint( 0 ),
|
||||
refpoly.PointCount(),
|
||||
if( !poly2segmentDRC( (wxPoint*) &refpoly.CPoint( 0 ), refpoly.PointCount(),
|
||||
wxPoint( 0, 0 ), wxPoint(m_segmLength,0),
|
||||
distToLine ) )
|
||||
aMinDist + segmHalfWidth, aActualDist ) )
|
||||
{
|
||||
*aActualDist = std::max( 0, *aActualDist - segmHalfWidth );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1387,25 +1471,34 @@ bool DRC::checkClearanceSegmToPad( const D_PAD* aPad, int aSegmentWidth, int aMi
|
|||
* Helper function checkMarginToCircle
|
||||
* Check the distance between a circle (round pad, via or round end of track)
|
||||
* and a segment. the segment is expected starting at 0,0, and on the X axis
|
||||
* return true if distance >= aRadius
|
||||
* return true if distance >= aAllowed
|
||||
*/
|
||||
bool DRC::checkMarginToCircle( wxPoint aCentre, int aRadius, int aLength )
|
||||
bool DRC::checkMarginToCircle( wxPoint aCentre, int aAllowed, int aLength, int* aActual )
|
||||
{
|
||||
if( abs( aCentre.y ) >= aRadius ) // trivial case
|
||||
if( abs( aCentre.y ) >= aAllowed ) // trivial case
|
||||
return true;
|
||||
|
||||
// Here, distance between aCentre and X axis is < aRadius
|
||||
if( (aCentre.x > -aRadius ) && ( aCentre.x < (aLength + aRadius) ) )
|
||||
// Here, distance between aCentre and X axis is < aAllowed
|
||||
if( ( aCentre.x > -aAllowed ) && ( aCentre.x < ( aLength + aAllowed ) ) )
|
||||
{
|
||||
if( (aCentre.x >= 0) && (aCentre.x <= aLength) )
|
||||
return false; // aCentre is between the starting point and the ending point of the segm
|
||||
if( ( aCentre.x >= 0 ) && ( aCentre.x <= aLength ) )
|
||||
{
|
||||
// aCentre is between the starting point and the ending point of the segm
|
||||
*aActual = abs( aCentre.y );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( aCentre.x > aLength ) // aCentre is after the ending point
|
||||
aCentre.x -= aLength; // move aCentre to the starting point of the segment
|
||||
|
||||
if( EuclideanNorm( aCentre ) < aRadius )
|
||||
// distance between aCentre and the starting point or the ending point is < aRadius
|
||||
int distToOrigin = KiROUND( EuclideanNorm( aCentre ) );
|
||||
|
||||
if( distToOrigin < aAllowed )
|
||||
{
|
||||
// distance between aCentre and the starting point or the ending point is < aAllowed
|
||||
*aActual = distToOrigin;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -32,9 +32,12 @@
|
|||
#include <class_board.h>
|
||||
|
||||
|
||||
wxString DRC_ITEM::GetErrorText() const
|
||||
wxString DRC_ITEM::GetErrorText( int aCode ) const
|
||||
{
|
||||
switch( m_errorCode )
|
||||
if( aCode < 0 )
|
||||
aCode = m_errorCode;
|
||||
|
||||
switch( aCode )
|
||||
{
|
||||
case DRCE_UNCONNECTED_ITEMS:
|
||||
return wxString( _( "Unconnected items" ) );
|
||||
|
@ -179,7 +182,7 @@ wxString DRC_ITEM::ShowHtml( PCB_BASE_FRAME* aFrame ) const
|
|||
{
|
||||
BOARD_ITEM* mainItem = nullptr;
|
||||
BOARD_ITEM* auxItem = nullptr;
|
||||
wxString msg = m_errorMessage.IsEmpty() ? GetErrorText() : m_errorMessage;
|
||||
wxString msg = m_errorMessage.IsEmpty() ? GetErrorText( m_errorCode ) : m_errorMessage;
|
||||
wxString mainText;
|
||||
wxString auxText;
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
* Function GetErrorText
|
||||
* returns the string form of a drc error code.
|
||||
*/
|
||||
wxString GetErrorText() const override;
|
||||
wxString GetErrorText( int aErrorCode = -1 ) const override;
|
||||
|
||||
/**
|
||||
* Function ShowHtml
|
||||
|
|
Loading…
Reference in New Issue