MODULE::CoverageRatio(): replace wxRegion (not working for us on Windows) by polygons to calculate areas.
At least on Windows, using wxRegion generates crashes. Fixes: lp:1740646 https://bugs.launchpad.net/kicad/+bug/1740646
This commit is contained in:
parent
03e9f0c94a
commit
11d1188fdf
|
@ -626,6 +626,8 @@ const VECTOR2I SHAPE_LINE_CHAIN::PointAlong( int aPathLength ) const
|
||||||
|
|
||||||
double SHAPE_LINE_CHAIN::Area() const
|
double SHAPE_LINE_CHAIN::Area() const
|
||||||
{
|
{
|
||||||
|
// see https://www.mathopenref.com/coordpolygonarea2.html
|
||||||
|
|
||||||
if( !m_closed )
|
if( !m_closed )
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
|
||||||
|
|
|
@ -1240,35 +1240,60 @@ wxString MODULE::GetReferencePrefix() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double CalcArea( wxRegion aRegion )
|
// Calculate the area of aPolySet, after fracturation, because
|
||||||
|
// polygons with no hole are expected.
|
||||||
|
static double polygonArea( SHAPE_POLY_SET& aPolySet )
|
||||||
{
|
{
|
||||||
double area = 0.0;
|
double area = 0.0;
|
||||||
for( wxRegionIterator iterator( aRegion ); iterator.HaveRects(); iterator++ )
|
for( int ii = 0; ii < aPolySet.OutlineCount(); ii++ )
|
||||||
{
|
{
|
||||||
wxRect aRect = iterator.GetRect();
|
SHAPE_LINE_CHAIN& outline = aPolySet.Outline( ii );
|
||||||
area += static_cast<double>( aRect.GetWidth() ) * aRect.GetHeight();
|
// Ensure the curr outline is closed, to calculate area
|
||||||
}
|
outline.SetClosed( true );
|
||||||
|
|
||||||
|
area += outline.Area();
|
||||||
|
}
|
||||||
|
|
||||||
return area;
|
return area;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// a helper function to add a rectangular polygon aRect to aPolySet
|
||||||
|
static void addRect( SHAPE_POLY_SET& aPolySet, wxRect aRect )
|
||||||
|
{
|
||||||
|
aPolySet.NewOutline();
|
||||||
|
|
||||||
|
aPolySet.Append( aRect.GetX(), aRect.GetY() );
|
||||||
|
aPolySet.Append( aRect.GetX()+aRect.width, aRect.GetY() );
|
||||||
|
aPolySet.Append( aRect.GetX()+aRect.width, aRect.GetY()+aRect.height );
|
||||||
|
aPolySet.Append( aRect.GetX(), aRect.GetY()+aRect.height );
|
||||||
|
}
|
||||||
|
|
||||||
double MODULE::CoverageRatio() const
|
double MODULE::CoverageRatio() const
|
||||||
{
|
{
|
||||||
double moduleArea = GetFootprintRect().GetArea();
|
double moduleArea = GetFootprintRect().GetArea();
|
||||||
wxRegion uncoveredRegion( GetFootprintRect() );
|
SHAPE_POLY_SET coveredRegion;
|
||||||
|
addRect(coveredRegion, GetFootprintRect() );
|
||||||
|
|
||||||
|
// build hole list if full area
|
||||||
|
SHAPE_POLY_SET holes;
|
||||||
for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
|
for( D_PAD* pad = m_Pads; pad; pad = pad->Next() )
|
||||||
uncoveredRegion.Subtract( pad->GetBoundingBox() );
|
addRect( holes, pad->GetBoundingBox() );
|
||||||
|
|
||||||
for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
|
for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
|
||||||
uncoveredRegion.Subtract( item->GetBoundingBox() );
|
addRect( holes, item->GetBoundingBox() );
|
||||||
|
|
||||||
uncoveredRegion.Subtract( m_Reference->GetBoundingBox() );
|
addRect( holes, m_Reference->GetBoundingBox() );
|
||||||
uncoveredRegion.Subtract( m_Value->GetBoundingBox() );
|
addRect( holes, m_Value->GetBoundingBox() );
|
||||||
|
|
||||||
double coveredArea = moduleArea - CalcArea( uncoveredRegion );
|
SHAPE_POLY_SET uncoveredRegion;
|
||||||
|
uncoveredRegion.BooleanSubtract( coveredRegion, holes, SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||||
|
uncoveredRegion.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||||
|
uncoveredRegion.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||||
|
|
||||||
|
double uncoveredRegionArea = polygonArea( uncoveredRegion );
|
||||||
|
double coveredArea = moduleArea - uncoveredRegionArea;
|
||||||
double ratio = ( coveredArea / moduleArea );
|
double ratio = ( coveredArea / moduleArea );
|
||||||
|
|
||||||
return std::min( ratio, 1.0 );
|
return std::min( ratio, 1.0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue