Add zone area to message panel

ADDED: Area of zone fill is displayed in the message panel

Fixes https://gitlab.com/kicad/code/kicad/issues/2412
This commit is contained in:
Ian McInerney 2020-02-05 09:43:52 +00:00
parent 7d64527eeb
commit 6b8d81e95d
7 changed files with 123 additions and 14 deletions

View File

@ -124,25 +124,40 @@ double To_User_Unit( EDA_UNITS aUnit, double aValue, bool aUseMils )
*/
// A lower-precision (for readability) version of StringFromValue()
wxString MessageTextFromValue( EDA_UNITS aUnits, int aValue, bool aUseMils )
wxString MessageTextFromValue( EDA_UNITS aUnits, int aValue, bool aUseMils, EDA_DATA_TYPE aType )
{
return MessageTextFromValue( aUnits, double( aValue ), aUseMils );
}
// A lower-precision (for readability) version of StringFromValue()
wxString MessageTextFromValue( EDA_UNITS aUnits, long long int aValue, bool aUseMils )
wxString MessageTextFromValue( EDA_UNITS aUnits, long long int aValue,
bool aUseMils, EDA_DATA_TYPE aType )
{
return MessageTextFromValue( aUnits, double( aValue ), aUseMils );
}
// A lower-precision (for readability) version of StringFromValue()
wxString MessageTextFromValue( EDA_UNITS aUnits, double aValue, bool aUseMils )
wxString MessageTextFromValue( EDA_UNITS aUnits, double aValue, bool aUseMils, EDA_DATA_TYPE aType )
{
wxString text;
const wxChar* format;
double value = To_User_Unit( aUnits, aValue, aUseMils );
double value = aValue;
switch( aType )
{
case EDA_DATA_TYPE::VOLUME:
value = To_User_Unit( aUnits, value, aUseMils );
// Fall through to continue computation
case EDA_DATA_TYPE::AREA:
value = To_User_Unit( aUnits, value, aUseMils );
// Fall through to continue computation
case EDA_DATA_TYPE::DISTANCE:
value = To_User_Unit( aUnits, value, aUseMils );
}
if( aUnits == EDA_UNITS::INCHES )
{
@ -175,7 +190,7 @@ wxString MessageTextFromValue( EDA_UNITS aUnits, double aValue, bool aUseMils )
text.Printf( format, value );
text += " ";
text += GetAbbreviatedUnitsLabel( aUnits, aUseMils );
text += GetAbbreviatedUnitsLabel( aUnits, aUseMils, aType );
return text;
}
@ -449,18 +464,46 @@ wxString AngleToStringDegrees( double aAngle )
}
wxString GetAbbreviatedUnitsLabel( EDA_UNITS aUnit, bool aUseMils )
wxString GetAbbreviatedUnitsLabel( EDA_UNITS aUnit, bool aUseMils, EDA_DATA_TYPE aType )
{
switch( aUnit )
{
case EDA_UNITS::INCHES:
if( aUseMils )
return _( "mils" );
{
switch( aType )
{
case EDA_DATA_TYPE::DISTANCE:
return _( "mils" );
case EDA_DATA_TYPE::AREA:
return _( "sq. mils" );
case EDA_DATA_TYPE::VOLUME:
return _( "cu. mils" );
}
}
else
return _( "in" );
{
switch( aType )
{
case EDA_DATA_TYPE::DISTANCE:
return _( "in" );
case EDA_DATA_TYPE::AREA:
return _( "sq. in" );
case EDA_DATA_TYPE::VOLUME:
return _( "cu. in" );
}
}
case EDA_UNITS::MILLIMETRES:
return _( "mm" );
switch( aType )
{
case EDA_DATA_TYPE::DISTANCE:
return _( "mm" );
case EDA_DATA_TYPE::AREA:
return _( "sq. mm" );
case EDA_DATA_TYPE::VOLUME:
return _( "cu. mm" );
}
case EDA_UNITS::PERCENT:
return _( "%" );

View File

@ -107,13 +107,17 @@ wxString AngleToStringDegrees( double aAngle );
* message text.
* @param aValue The double value to convert.
* @param aUseMils Convert inch values to mils if true.
* @param aType Type of the unit being used (e.g. distance, area, etc.)
* @return The converted string for display in user interface elements.
*/
wxString MessageTextFromValue( EDA_UNITS aUnits, double aValue, bool aUseMils = false );
wxString MessageTextFromValue( EDA_UNITS aUnits, double aValue, bool aUseMils = false,
EDA_DATA_TYPE aType = EDA_DATA_TYPE::DISTANCE );
wxString MessageTextFromValue( EDA_UNITS aUnits, int aValue, bool aUseMils = false );
wxString MessageTextFromValue( EDA_UNITS aUnits, int aValue, bool aUseMils = false,
EDA_DATA_TYPE aType = EDA_DATA_TYPE::DISTANCE );
wxString MessageTextFromValue( EDA_UNITS aUnits, long long int aValue, bool aUseMils = false );
wxString MessageTextFromValue( EDA_UNITS aUnits, long long int aValue, bool aUseMils = false,
EDA_DATA_TYPE aType = EDA_DATA_TYPE::DISTANCE );
/**
* Function StringFromValue
@ -177,9 +181,12 @@ void FetchUnitsFromString( const wxString& aTextValue, EDA_UNITS& aUnits, bool&
* Get the units string for a given units type.
*
* @param aUnits - The units requested.
* @param aUseMils - Use mils for the unit
* @param aType - The data type of the unit (e.g. distance, area, etc.)
* @return The human readable units string.
*/
wxString GetAbbreviatedUnitsLabel( EDA_UNITS aUnit, bool aUseMils = false );
wxString GetAbbreviatedUnitsLabel( EDA_UNITS aUnit, bool aUseMils = false,
EDA_DATA_TYPE aType = EDA_DATA_TYPE::DISTANCE );
/**
* Function FormatInternalUnits

View File

@ -69,6 +69,16 @@ typedef uint32_t timestamp_t;
#define TEXT_ANGLE_HORIZ 0
#define TEXT_ANGLE_VERT 900
/**
* The type of unit.
*/
enum class EDA_DATA_TYPE
{
DISTANCE = 0,
AREA = 1,
VOLUME = 2
};
enum class EDA_UNITS
{
INCHES = 0,

View File

@ -44,7 +44,8 @@
ZONE_CONTAINER::ZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent, bool aInModule )
: BOARD_CONNECTED_ITEM( aParent, aInModule ? PCB_MODULE_ZONE_AREA_T : PCB_ZONE_AREA_T )
: BOARD_CONNECTED_ITEM( aParent, aInModule ? PCB_MODULE_ZONE_AREA_T : PCB_ZONE_AREA_T ),
m_area( 0.0 )
{
m_CornerSelection = nullptr; // no corner is selected
m_IsFilled = false; // fill status : true when the zone is filled
@ -753,6 +754,9 @@ void ZONE_CONTAINER::GetMsgPanelInfo( EDA_UNITS aUnits, std::vector<MSG_PANEL_IT
aList.emplace_back( MSG_PANEL_ITEM( _( "Fill Mode" ), msg, BROWN ) );
msg = MessageTextFromValue( aUnits, m_area, false, EDA_DATA_TYPE::AREA );
aList.emplace_back( MSG_PANEL_ITEM( _( "Filled Area" ), msg, BLUE ) );
// Useful for statistics :
msg.Printf( wxT( "%d" ), (int) m_HatchLines.size() );
aList.emplace_back( MSG_PANEL_ITEM( _( "Hatch Lines" ), msg, BLUE ) );
@ -1259,6 +1263,27 @@ bool ZONE_CONTAINER::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly,
return true;
};
double ZONE_CONTAINER::CalculateFilledArea()
{
m_area = 0.0;
// Iterate over each outline polygon in the zone and then iterate over
// each hole it has to compute the total area.
for( int i = 0; i < m_FilledPolysList.OutlineCount(); i++ )
{
m_area += m_FilledPolysList.Outline( i ).Area();
for( int j = 0; m_FilledPolysList.HoleCount( i ); j++ )
{
m_area -= m_FilledPolysList.Hole( i, j ).Area();
}
}
return m_area;
}
/* Function TransformOutlinesShapeWithClearanceToPolygon
* Convert the zone filled areas polygons to polygons
* inflated (optional) by max( aClearanceValue, the zone clearance)

View File

@ -167,6 +167,24 @@ public:
}
int GetThermalReliefCopperBridge( D_PAD* aPad = NULL ) const;
/**
* Compute the area currently occupied by the zone fill.
*
* @return the currently filled area
*/
double CalculateFilledArea();
/**
* Get the area currently occupied by the zone fill.
* This area is cached from the most recent call to CalculateFilledArea().
*
* @return the filled area
*/
double GetFilledArea()
{
return m_area;
}
bool IsFilled() const { return m_IsFilled; }
void SetIsFilled( bool isFilled ) { m_IsFilled = isFilled; }
@ -814,6 +832,8 @@ protected:
std::vector<int> m_insulatedIslands;
bool m_hv45; // constrain edges to horizontal, vertical or 45º
double m_area; // The filled zone area
};

View File

@ -3889,7 +3889,10 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent )
}
if( !pts.IsEmpty() )
{
zone->SetFilledPolysList( pts );
zone->CalculateFilledArea();
}
// Ensure keepout and non copper zones do not have a net
// (which have no sense for these zones)

View File

@ -241,6 +241,7 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE_CONTAINER*>& aZones, bool aCheck
}
zone.m_zone->SetFilledPolysList( poly );
zone.m_zone->CalculateFilledArea();
if( aCheck && zone.m_zone->GetHashValue() != poly.GetHash() )
outOfDate = true;