Fix a few issues with zone islands

This commit is contained in:
Jon Evans 2020-06-29 12:16:37 -04:00
parent 9cbcf3fe56
commit 44f3cdb31e
7 changed files with 64 additions and 27 deletions

View File

@ -230,9 +230,25 @@ void StripTrailingZeros( wxString& aStringValue, unsigned aTrailingZeroAllowed )
* otherwise the actual value is rounded when read from dialog and converted
* in internal units, and therefore modified.
*/
wxString StringFromValue( EDA_UNITS aUnits, double aValue, bool aAddUnitSymbol, bool aUseMils )
wxString StringFromValue( EDA_UNITS aUnits, double aValue, bool aAddUnitSymbol, bool aUseMils,
EDA_DATA_TYPE aType )
{
double value_to_print = To_User_Unit( aUnits, aValue, aUseMils );
double value_to_print = aValue;
switch( aType )
{
case EDA_DATA_TYPE::VOLUME:
value_to_print = To_User_Unit( aUnits, value_to_print, aUseMils );
KI_FALLTHROUGH;
case EDA_DATA_TYPE::AREA:
value_to_print = To_User_Unit( aUnits, value_to_print, aUseMils );
KI_FALLTHROUGH;
case EDA_DATA_TYPE::DISTANCE:
value_to_print = To_User_Unit( aUnits, value_to_print, aUseMils );
}
#if defined( EESCHEMA )
wxString stringValue = wxString::Format( wxT( "%.3f" ), value_to_print );
@ -327,9 +343,9 @@ double From_User_Unit( EDA_UNITS aUnits, double aValue, bool aUseMils )
}
double DoubleValueFromString( EDA_UNITS aUnits, const wxString& aTextValue, bool aUseMils )
double DoubleValueFromString( EDA_UNITS aUnits, const wxString& aTextValue, bool aUseMils,
EDA_DATA_TYPE aType )
{
double value;
double dtmp = 0;
// Acquire the 'right' decimal point separator
@ -395,9 +411,21 @@ double DoubleValueFromString( EDA_UNITS aUnits, const wxString& aTextValue, bool
}
}
value = From_User_Unit( aUnits, dtmp, aUseMils );
switch( aType )
{
case EDA_DATA_TYPE::VOLUME:
dtmp = From_User_Unit( aUnits, dtmp, aUseMils );
KI_FALLTHROUGH;
return value;
case EDA_DATA_TYPE::AREA:
dtmp = From_User_Unit( aUnits, dtmp, aUseMils );
KI_FALLTHROUGH;
case EDA_DATA_TYPE::DISTANCE:
dtmp = From_User_Unit( aUnits, dtmp, aUseMils );
}
return dtmp;
}
@ -440,9 +468,10 @@ void FetchUnitsFromString( const wxString& aTextValue, EDA_UNITS& aUnits, bool&
}
long long int ValueFromString( EDA_UNITS aUnits, const wxString& aTextValue, bool aUseMils )
long long int ValueFromString( EDA_UNITS aUnits, const wxString& aTextValue, bool aUseMils,
EDA_DATA_TYPE aType )
{
double value = DoubleValueFromString( aUnits, aTextValue, aUseMils );
double value = DoubleValueFromString( aUnits, aTextValue, aUseMils, aType );
return KiROUND<double, long long int>( value );
}

View File

@ -187,6 +187,8 @@ bool UNIT_BINDER::Validate( double aMin, double aMax, EDA_UNITS aUnits, bool aUs
return true;
}
// TODO: Validate() does not currently support m_dataType being anything other than DISTANCE
if( GetValue() < From_User_Unit( aUnits, aMin, aUseMils ) )
{
m_errorMessage = wxString::Format( _( "%s must be at least %s." ),
@ -219,13 +221,13 @@ bool UNIT_BINDER::Validate( double aMin, double aMax, EDA_UNITS aUnits, bool aUs
void UNIT_BINDER::SetValue( int aValue )
{
SetValue( StringFromValue( m_units, aValue, false, m_useMils ) );
SetValue( StringFromValue( m_units, aValue, false, m_useMils, m_dataType ) );
}
void UNIT_BINDER::SetDoubleValue( double aValue )
{
SetValue( StringFromValue( m_units, aValue, false, m_useMils ) );
SetValue( StringFromValue( m_units, aValue, false, m_useMils, m_dataType ) );
}
@ -287,7 +289,7 @@ long long int UNIT_BINDER::GetValue()
else
return 0;
return ValueFromString( m_units, value, m_useMils );
return ValueFromString( m_units, value, m_useMils, m_dataType );
}
@ -309,7 +311,7 @@ double UNIT_BINDER::GetDoubleValue()
else
return 0.0;
return DoubleValueFromString( m_units, value, m_useMils );
return DoubleValueFromString( m_units, value, m_useMils, m_dataType );
}

View File

@ -150,7 +150,7 @@ wxString MessageTextFromValue( EDA_UNITS aUnits, long long int aValue, bool aUse
* @return A wxString object containing value and optionally the symbol unit (like 2.000 mm)
*/
wxString StringFromValue( EDA_UNITS aUnit, double aValue, bool aAddUnitSymbol = false,
bool aUseMils = false );
bool aUseMils = false, EDA_DATA_TYPE aType = EDA_DATA_TYPE::DISTANCE );
/**
* Return in internal units the value "val" given in a real unit
@ -167,8 +167,8 @@ double From_User_Unit( EDA_UNITS aUnit, double aValue, bool aUseMils = false );
* @param aUseMils Indicates mils should be used for imperial units (inches).
* @return A double representing that value in internal units
*/
double DoubleValueFromString( EDA_UNITS aUnits, const wxString& aTextValue,
bool aUseMils = false );
double DoubleValueFromString( EDA_UNITS aUnits, const wxString& aTextValue, bool aUseMils = false,
EDA_DATA_TYPE aType = EDA_DATA_TYPE::DISTANCE );
/**
* Function ValueFromString
@ -179,8 +179,8 @@ double DoubleValueFromString( EDA_UNITS aUnits, const wxString& aTextValue,
* @param aUseMils Indicates mils should be used for imperial units (inches).
* @return The string from Value, according to units (inch, mm ...) for display,
*/
long long int ValueFromString( EDA_UNITS aUnits, const wxString& aTextValue,
bool aUseMils = false );
long long int ValueFromString( EDA_UNITS aUnits, const wxString& aTextValue, bool aUseMils = false,
EDA_DATA_TYPE aType = EDA_DATA_TYPE::DISTANCE );
/**
* Function FetchUnitsFromString

View File

@ -1905,7 +1905,7 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
{
m_out->Print( 0, " (island_removal_mode %d) (island_area_min %s)",
static_cast<int>( aZone->GetIslandRemovalMode() ),
FormatInternalUnits( aZone->GetMinIslandArea() ).c_str() );
FormatInternalUnits( aZone->GetMinIslandArea() / IU_PER_MM ).c_str() );
}
if( aZone->GetFillMode() == ZONE_FILL_MODE::HATCH_PATTERN )

View File

@ -3981,9 +3981,12 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent )
break;
case T_island_area_min:
zone->SetMinIslandArea( parseBoardUnits( T_island_area_min ) );
{
int area = parseBoardUnits( T_island_area_min );
zone->SetMinIslandArea( area * IU_PER_MM );
NeedRIGHT();
break;
}
default:
Expecting( "mode, arc_segments, thermal_gap, thermal_bridge_width, "

View File

@ -500,7 +500,7 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
// aggregateArea will be simplified and fractured
// (Long calculation time)
for( int i = 0; i < aggregateArea.OutlineCount(); i++ )
for( int i = aggregateArea.OutlineCount() - 1; i >= 0; i-- )
{
if( zone->IsIsland( layer, i ) )
{
@ -539,7 +539,7 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
SHAPE_POLY_SET candidateArea = candidate->GetFilledPolysList( layer );
for( int i = 0; i < candidateArea.OutlineCount(); i++ )
for( int i = candidateArea.OutlineCount() - 1; i >= 0; i-- )
{
if( candidate->IsIsland( layer, i ) )
{

View File

@ -230,17 +230,20 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE_CONTAINER*>& aZones, bool aCheck
// Remove solid areas outside the board cutouts and the insulated islands
// only zones with net code > 0 can have insulated islands by definition
if( zone.m_zone->GetNetCode() > 0 && mode != ISLAND_REMOVAL_MODE::NEVER )
if( zone.m_zone->GetNetCode() > 0 )
{
// Area threshold is stored 1-D in internal units
if( mode == ISLAND_REMOVAL_MODE::AREA )
minArea *= minArea;
// solid areas outside the board cutouts are also removed, because they are usually
// insulated islands
for( auto idx : zone.m_islands )
{
if( mode == ISLAND_REMOVAL_MODE::ALWAYS || poly.Outline( idx ).Area() < minArea
double metricMin = minArea * ( MM_PER_IU * MM_PER_IU );
double metricArea = poly.Outline( idx ).Area() * ( MM_PER_IU * MM_PER_IU );
std::cout << ( metricArea < metricMin ) << std::endl;
if( mode == ISLAND_REMOVAL_MODE::ALWAYS
|| ( mode == ISLAND_REMOVAL_MODE::AREA
&& poly.Outline( idx ).Area() < minArea )
|| !m_boardOutline.Contains( poly.Polygon( idx ).front().CPoint( 0 ) ) )
poly.DeletePolygon( idx );
else