mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-15 02:33:15 +02:00
ADDED: report copper area for current selection.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/20439
This commit is contained in:
parent
d16a5bf87d
commit
07eda5d57e
@ -1749,6 +1749,11 @@ void PCB_TRACK::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_I
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SHAPE_POLY_SET copper;
|
||||||
|
TransformShapeToPolySet( copper, GetLayer(), 0, ARC_LOW_DEF, ERROR_INSIDE );
|
||||||
|
aList.emplace_back( _( "Copper Area" ),
|
||||||
|
aFrame->MessageTextFromValue( copper.Area(), true, EDA_DATA_TYPE::AREA ) );
|
||||||
|
|
||||||
wxString source;
|
wxString source;
|
||||||
int clearance = GetOwnClearance( GetLayer(), &source );
|
int clearance = GetOwnClearance( GetLayer(), &source );
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pcb_control.h"
|
#include "pcb_control.h"
|
||||||
|
#include "convert_basic_shapes_to_polygon.h"
|
||||||
|
|
||||||
#include <kiplatform/ui.h>
|
#include <kiplatform/ui.h>
|
||||||
#include <tools/edit_tool.h>
|
#include <tools/edit_tool.h>
|
||||||
@ -1873,7 +1874,7 @@ int PCB_CONTROL::UpdateMessagePanel( const TOOL_EVENT& aEvent )
|
|||||||
PCB_LAYER_ID layer = overlap.CuStack().front();
|
PCB_LAYER_ID layer = overlap.CuStack().front();
|
||||||
|
|
||||||
constraint = drcEngine->EvalRules( CLEARANCE_CONSTRAINT, a, b, layer );
|
constraint = drcEngine->EvalRules( CLEARANCE_CONSTRAINT, a, b, layer );
|
||||||
msgItems.emplace_back( _( "Resolved clearance" ),
|
msgItems.emplace_back( _( "Resolved Clearance" ),
|
||||||
m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
|
m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
|
||||||
|
|
||||||
std::shared_ptr<SHAPE> a_shape( a_conn->GetEffectiveShape( layer ) );
|
std::shared_ptr<SHAPE> a_shape( a_conn->GetEffectiveShape( layer ) );
|
||||||
@ -1883,8 +1884,8 @@ int PCB_CONTROL::UpdateMessagePanel( const TOOL_EVENT& aEvent )
|
|||||||
|
|
||||||
if( actual_clearance > -1 && actual_clearance < std::numeric_limits<int>::max() )
|
if( actual_clearance > -1 && actual_clearance < std::numeric_limits<int>::max() )
|
||||||
{
|
{
|
||||||
msgItems.emplace_back( _( "Actual clearance" ),
|
msgItems.emplace_back( _( "Actual Clearance" ),
|
||||||
m_frame->MessageTextFromValue( actual_clearance ) );
|
m_frame->MessageTextFromValue( actual_clearance ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1926,13 +1927,13 @@ int PCB_CONTROL::UpdateMessagePanel( const TOOL_EVENT& aEvent )
|
|||||||
if( actual < std::numeric_limits<int>::max() )
|
if( actual < std::numeric_limits<int>::max() )
|
||||||
{
|
{
|
||||||
constraint = drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, a, b, layer );
|
constraint = drcEngine->EvalRules( HOLE_CLEARANCE_CONSTRAINT, a, b, layer );
|
||||||
msgItems.emplace_back( _( "Resolved hole clearance" ),
|
msgItems.emplace_back( _( "Resolved Hole Clearance" ),
|
||||||
m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
|
m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
|
||||||
|
|
||||||
if( actual > -1 && actual < std::numeric_limits<int>::max() )
|
if( actual > -1 && actual < std::numeric_limits<int>::max() )
|
||||||
{
|
{
|
||||||
msgItems.emplace_back( _( "Actual hole clearance" ),
|
msgItems.emplace_back( _( "Actual Hole Clearance" ),
|
||||||
m_frame->MessageTextFromValue( actual ) );
|
m_frame->MessageTextFromValue( actual ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1964,12 +1965,12 @@ int PCB_CONTROL::UpdateMessagePanel( const TOOL_EVENT& aEvent )
|
|||||||
|
|
||||||
if( edgeLayer == Edge_Cuts )
|
if( edgeLayer == Edge_Cuts )
|
||||||
{
|
{
|
||||||
msgItems.emplace_back( _( "Resolved edge clearance" ),
|
msgItems.emplace_back( _( "Resolved Edge Clearance" ),
|
||||||
m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
|
m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
msgItems.emplace_back( _( "Resolved margin clearance" ),
|
msgItems.emplace_back( _( "Resolved Margin Clearance" ),
|
||||||
m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
|
m_frame->MessageTextFromValue( constraint.m_Value.Min() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1993,8 +1994,7 @@ int PCB_CONTROL::UpdateMessagePanel( const TOOL_EVENT& aEvent )
|
|||||||
if( BOARD_CONNECTED_ITEM* bci = dynamic_cast<BOARD_CONNECTED_ITEM*>( item ) )
|
if( BOARD_CONNECTED_ITEM* bci = dynamic_cast<BOARD_CONNECTED_ITEM*>( item ) )
|
||||||
{
|
{
|
||||||
netNames.insert( UnescapeString( bci->GetNetname() ) );
|
netNames.insert( UnescapeString( bci->GetNetname() ) );
|
||||||
netClasses.insert( UnescapeString(
|
netClasses.insert( UnescapeString( bci->GetEffectiveNetClass()->GetHumanReadableName() ) );
|
||||||
bci->GetEffectiveNetClass()->GetHumanReadableName() ) );
|
|
||||||
|
|
||||||
if( netNames.size() > 1 && netClasses.size() > 1 )
|
if( netNames.size() > 1 && netClasses.size() > 1 )
|
||||||
break;
|
break;
|
||||||
@ -2020,16 +2020,21 @@ int PCB_CONTROL::UpdateMessagePanel( const TOOL_EVENT& aEvent )
|
|||||||
accumulateTrackLength =
|
accumulateTrackLength =
|
||||||
[&]( EDA_ITEM* aItem )
|
[&]( EDA_ITEM* aItem )
|
||||||
{
|
{
|
||||||
if( PCB_TRACK* track = dynamic_cast<PCB_TRACK*>( aItem ) )
|
if( aItem->Type() == PCB_TRACE_T || aItem->Type() == PCB_ARC_T )
|
||||||
{
|
{
|
||||||
selectedLength += track->GetLength();
|
selectedLength += static_cast<PCB_TRACK*>( aItem )->GetLength();
|
||||||
}
|
}
|
||||||
else if( PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem ) )
|
else if( aItem->Type() == PCB_VIA_T )
|
||||||
{
|
{
|
||||||
const SHAPE_T shapeType = shape->GetShape();
|
// zero 2D length
|
||||||
|
}
|
||||||
|
else if( aItem->Type() == PCB_SHAPE_T )
|
||||||
|
{
|
||||||
|
PCB_SHAPE* shape = static_cast<PCB_SHAPE*>( aItem );
|
||||||
|
|
||||||
if( shapeType == SHAPE_T::SEGMENT || shapeType == SHAPE_T::ARC
|
if( shape->GetShape() == SHAPE_T::SEGMENT
|
||||||
|| shapeType == SHAPE_T::BEZIER )
|
|| shape->GetShape() == SHAPE_T::ARC
|
||||||
|
|| shape->GetShape() == SHAPE_T::BEZIER )
|
||||||
{
|
{
|
||||||
selectedLength += shape->GetLength();
|
selectedLength += shape->GetLength();
|
||||||
}
|
}
|
||||||
@ -2038,6 +2043,7 @@ int PCB_CONTROL::UpdateMessagePanel( const TOOL_EVENT& aEvent )
|
|||||||
lengthValid = false;
|
lengthValid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Use dynamic_cast to include PCB_GENERATORs.
|
||||||
else if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( aItem ) )
|
else if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( aItem ) )
|
||||||
{
|
{
|
||||||
group->RunOnChildren( accumulateTrackLength );
|
group->RunOnChildren( accumulateTrackLength );
|
||||||
@ -2049,7 +2055,10 @@ int PCB_CONTROL::UpdateMessagePanel( const TOOL_EVENT& aEvent )
|
|||||||
};
|
};
|
||||||
|
|
||||||
for( EDA_ITEM* item : selection )
|
for( EDA_ITEM* item : selection )
|
||||||
accumulateTrackLength( item );
|
{
|
||||||
|
if( lengthValid )
|
||||||
|
accumulateTrackLength( item );
|
||||||
|
}
|
||||||
|
|
||||||
if( lengthValid )
|
if( lengthValid )
|
||||||
{
|
{
|
||||||
@ -2057,6 +2066,72 @@ int PCB_CONTROL::UpdateMessagePanel( const TOOL_EVENT& aEvent )
|
|||||||
m_frame->MessageTextFromValue( selectedLength ) );
|
m_frame->MessageTextFromValue( selectedLength ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( selection.GetSize() >= 2 && selection.GetSize() < 100 )
|
||||||
|
{
|
||||||
|
LSET enabledCopper = LSET::AllCuMask( m_frame->GetBoard()->GetCopperLayerCount() );
|
||||||
|
bool areaValid = true;
|
||||||
|
|
||||||
|
std::map<PCB_LAYER_ID, SHAPE_POLY_SET> copperPolys;
|
||||||
|
SHAPE_POLY_SET holes;
|
||||||
|
|
||||||
|
std::function<void( EDA_ITEM* )> accumulateArea;
|
||||||
|
|
||||||
|
accumulateArea =
|
||||||
|
[&]( EDA_ITEM* aItem )
|
||||||
|
{
|
||||||
|
if( aItem->Type() == PCB_FOOTPRINT_T )
|
||||||
|
{
|
||||||
|
areaValid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( aItem ) )
|
||||||
|
{
|
||||||
|
boardItem->RunOnChildren( accumulateArea );
|
||||||
|
|
||||||
|
for( PCB_LAYER_ID layer : LSET( boardItem->GetLayerSet() & enabledCopper ) )
|
||||||
|
{
|
||||||
|
boardItem->TransformShapeToPolySet( copperPolys[layer], layer, 0,
|
||||||
|
ARC_LOW_DEF, ERROR_INSIDE );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( aItem->Type() == PCB_PAD_T && static_cast<PAD*>( aItem )->HasHole() )
|
||||||
|
{
|
||||||
|
static_cast<PAD*>( aItem )->TransformHoleToPolygon( holes, 0, ARC_LOW_DEF,
|
||||||
|
ERROR_OUTSIDE );
|
||||||
|
}
|
||||||
|
else if( aItem->Type() == PCB_VIA_T )
|
||||||
|
{
|
||||||
|
PCB_VIA* via = static_cast<PCB_VIA*>( aItem );
|
||||||
|
VECTOR2I center = via->GetPosition();
|
||||||
|
int R = via->GetDrillValue() / 2;
|
||||||
|
|
||||||
|
TransformCircleToPolygon( holes, center, R, ARC_LOW_DEF, ERROR_OUTSIDE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for( EDA_ITEM* item : selection )
|
||||||
|
{
|
||||||
|
if( areaValid )
|
||||||
|
accumulateArea( item );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( areaValid )
|
||||||
|
{
|
||||||
|
double area = 0.0;
|
||||||
|
|
||||||
|
for( auto& [layer, copperPoly] : copperPolys )
|
||||||
|
{
|
||||||
|
copperPoly.BooleanSubtract( holes );
|
||||||
|
area += copperPoly.Area();
|
||||||
|
}
|
||||||
|
|
||||||
|
msgItems.emplace_back( _( "Selected 2D Copper Area" ),
|
||||||
|
m_frame->MessageTextFromValue( area, true, EDA_DATA_TYPE::AREA ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1504,20 +1504,8 @@ double ZONE::CalculateFilledArea()
|
|||||||
{
|
{
|
||||||
m_area = 0.0;
|
m_area = 0.0;
|
||||||
|
|
||||||
// Iterate over each outline polygon in the zone and then iterate over
|
for( const auto& [layer, poly] : m_FilledPolysList )
|
||||||
// each hole it has to compute the total area.
|
m_area += poly->Area();
|
||||||
for( std::pair<const PCB_LAYER_ID, std::shared_ptr<SHAPE_POLY_SET>>& pair : m_FilledPolysList )
|
|
||||||
{
|
|
||||||
std::shared_ptr<SHAPE_POLY_SET>& poly = pair.second;
|
|
||||||
|
|
||||||
for( int i = 0; i < poly->OutlineCount(); i++ )
|
|
||||||
{
|
|
||||||
m_area += poly->Outline( i ).Area();
|
|
||||||
|
|
||||||
for( int j = 0; j < poly->HoleCount( i ); j++ )
|
|
||||||
m_area -= poly->Hole( i, j ).Area();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_area;
|
return m_area;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user