ADDED: Display calculated clearance in status bar

In addition to showing resolved clearance, we also show the calculated
clearance in the same method as is used for DRC.  This will allow users
to better examine their system while working.

Fixes https://gitlab.com/kicad/code/kicad/issues/7934
This commit is contained in:
Seth Hillbrand 2022-07-21 15:01:50 -07:00
parent 9b74372f9d
commit 16e3d40552
9 changed files with 78 additions and 18 deletions

View File

@ -104,7 +104,7 @@ public:
virtual size_t GetIndexableSubshapeCount() const { return 0; }
virtual void GetIndexableSubshapes( std::vector<SHAPE*>& aSubshapes ) { }
virtual void GetIndexableSubshapes( std::vector<const SHAPE*>& aSubshapes ) const { }
protected:
///< type of our shape
@ -143,6 +143,13 @@ public:
return nullptr;
};
/**
* Return the actual minimum distance between two shapes
*
* @retval distance in IU
*/
int GetClearance( const SHAPE* aOther ) const;
/**
* Return true if the shape is a null shape.
*

View File

@ -82,10 +82,10 @@ public:
// Don't make clients deal with nested SHAPE_COMPOUNDs
if( aShape->HasIndexableSubshapes() )
{
std::vector<SHAPE*> subshapes;
std::vector<const SHAPE*> subshapes;
aShape->GetIndexableSubshapes( subshapes );
for( SHAPE* subshape : subshapes )
for( const SHAPE* subshape : subshapes )
m_shapes.push_back( subshape->Clone() );
delete aShape;
@ -127,9 +127,11 @@ public:
return m_shapes.size();
}
virtual void GetIndexableSubshapes( std::vector<SHAPE*>& aSubshapes ) override
virtual void GetIndexableSubshapes( std::vector<const SHAPE*>& aSubshapes ) const override
{
aSubshapes = m_shapes;
aSubshapes.clear();
aSubshapes.reserve( m_shapes.size() );
std::copy( m_shapes.begin(), m_shapes.end(), std::back_inserter( aSubshapes ) );
}
bool ConvertToSimplePolygon( SHAPE_SIMPLE* aOut ) const;

View File

@ -517,7 +517,7 @@ public:
virtual size_t GetIndexableSubshapeCount() const override;
virtual void GetIndexableSubshapes( std::vector<SHAPE*>& aSubshapes ) override;
virtual void GetIndexableSubshapes( std::vector<const SHAPE*>& aSubshapes ) const override;
/**
* Convert a global vertex index ---i.e., a number that globally identifies a vertex in a

View File

@ -24,6 +24,12 @@
#include <geometry/shape.h>
#include <geometry/shape_arc.h>
#include <geometry/shape_line_chain.h>
#include <geometry/shape_circle.h>
#include <geometry/shape_rect.h>
#include <geometry/shape_segment.h>
#include <geometry/shape_compound.h>
bool SHAPE::Parse( std::stringstream& aStream )
{
@ -37,3 +43,36 @@ const std::string SHAPE::Format() const
assert( false );
return std::string( "" );
}
int SHAPE::GetClearance( const SHAPE* aOther ) const
{
int actual_clearance = std::numeric_limits<int>::max();
std::vector<const SHAPE*> a_shapes;
std::vector<const SHAPE*> b_shapes;
GetIndexableSubshapes( a_shapes );
aOther->GetIndexableSubshapes( b_shapes );
if( GetIndexableSubshapeCount() == 0 )
a_shapes.push_back( this );
if( aOther->GetIndexableSubshapeCount() == 0 )
b_shapes.push_back( aOther );
// Clearance gets the distance to the centerline. We add in the additional size
// after to get the true clearance
for( const SHAPE* a : a_shapes )
{
for( const SHAPE* b : b_shapes )
{
int temp_dist = 0;
a->Collide( b, std::numeric_limits<int>::max() / 2, &temp_dist );
if( temp_dist < actual_clearance )
actual_clearance = temp_dist;
}
}
return actual_clearance;
}

View File

@ -2526,7 +2526,7 @@ size_t SHAPE_POLY_SET::GetIndexableSubshapeCount() const
}
void SHAPE_POLY_SET::GetIndexableSubshapes( std::vector<SHAPE*>& aSubshapes )
void SHAPE_POLY_SET::GetIndexableSubshapes( std::vector<const SHAPE*>& aSubshapes ) const
{
aSubshapes.reserve( GetIndexableSubshapeCount() );

View File

@ -51,7 +51,7 @@ public:
struct ITEM_WITH_SHAPE
{
ITEM_WITH_SHAPE( BOARD_ITEM *aParent, SHAPE* aShape,
ITEM_WITH_SHAPE( BOARD_ITEM *aParent, const SHAPE* aShape,
std::shared_ptr<SHAPE> aParentShape = nullptr ) :
parent ( aParent ),
shape ( aShape ),
@ -59,7 +59,7 @@ public:
{};
BOARD_ITEM* parent;
SHAPE* shape;
const SHAPE* shape;
std::shared_ptr<SHAPE> parentShape;
};
@ -108,7 +108,7 @@ public:
if( aItem->Type() == PCB_FP_TEXT_T && !static_cast<FP_TEXT*>( aItem )->IsVisible() )
return;
std::vector<SHAPE*> subshapes;
std::vector<const SHAPE*> subshapes;
std::shared_ptr<SHAPE> shape = aItem->GetEffectiveShape( aRefLayer );
subshapes.clear();
@ -128,9 +128,9 @@ public:
}
}
for( SHAPE* subshape : subshapes )
for( const SHAPE* subshape : subshapes )
{
if( dynamic_cast<SHAPE_NULL*>( subshape ) )
if( dynamic_cast<const SHAPE_NULL*>( subshape ) )
continue;
BOX2I bbox = subshape->BBox();
@ -336,9 +336,9 @@ public:
auto polyVisitor =
[&]( ITEM_WITH_SHAPE* aItem ) -> bool
{
SHAPE* shape = aItem->shape;
wxASSERT( dynamic_cast<SHAPE_POLY_SET::TRIANGULATED_POLYGON::TRI*>( shape ) );
auto tri = static_cast<SHAPE_POLY_SET::TRIANGULATED_POLYGON::TRI*>( shape );
const SHAPE* shape = aItem->shape;
wxASSERT( dynamic_cast<const SHAPE_POLY_SET::TRIANGULATED_POLYGON::TRI*>( shape ) );
auto tri = static_cast<const SHAPE_POLY_SET::TRIANGULATED_POLYGON::TRI*>( shape );
const SHAPE_LINE_CHAIN& outline = poly->Outline( 0 );

View File

@ -937,7 +937,7 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE_BASE::syncPad( PAD* aPad )
if( shape->HasIndexableSubshapes() && shape->GetIndexableSubshapeCount() == 1 )
{
std::vector<SHAPE*> subshapes;
std::vector<const SHAPE*> subshapes;
shape->GetIndexableSubshapes( subshapes );
solid->SetShape( subshapes[0]->Clone() );

View File

@ -450,10 +450,10 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
if( m_shape->HasIndexableSubshapes() )
{
std::vector<SHAPE*> subshapes;
std::vector<const SHAPE*> subshapes;
m_shape->GetIndexableSubshapes( subshapes );
for( SHAPE* shape : subshapes )
for( const SHAPE* shape : subshapes )
drawShape( shape, gal );
}
else

View File

@ -1276,8 +1276,20 @@ int PCB_CONTROL::UpdateMessagePanel( const TOOL_EVENT& aEvent )
constraint = drcEngine->EvalRules( CLEARANCE_CONSTRAINT, a, b,
overlap.CuStack().front() );
std::shared_ptr<SHAPE> a_shape( a_conn->GetEffectiveShape( overlap.CuStack().front() ) );
std::shared_ptr<SHAPE> b_shape( b_conn->GetEffectiveShape( overlap.CuStack().front() ) );
int actual_clearance = a_shape->GetClearance( b_shape.get() );
msgItems.emplace_back( MSG_PANEL_ITEM( _( "Resolved clearance" ),
clearanceString( constraint ) ) );
if( actual_clearance > -1 && actual_clearance < std::numeric_limits<int>::max() )
{
msgItems.emplace_back(
MSG_PANEL_ITEM( _( "Actual clearance" ),
StringFromValue( units, actual_clearance, true ) ) );
}
}
}