diff --git a/pcbnew/router/pns_logger.h b/pcbnew/router/pns_logger.h index 04145d282f..e654b5e964 100644 --- a/pcbnew/router/pns_logger.h +++ b/pcbnew/router/pns_logger.h @@ -46,7 +46,8 @@ public: EVT_START_DRAG, EVT_FIX, EVT_MOVE, - EVT_ABORT + EVT_ABORT, + EVT_TOGGLE_VIA }; struct EVENT_ENTRY { diff --git a/qa/pns/CMakeLists.txt b/qa/pns/CMakeLists.txt index 8083cd50df..762383193c 100644 --- a/qa/pns/CMakeLists.txt +++ b/qa/pns/CMakeLists.txt @@ -51,15 +51,19 @@ add_executable( test_pns ../../pcbnew/drc/drc_test_provider_diff_pair_coupling.cpp ../../pcbnew/drc/drc_engine.cpp ../../pcbnew/drc/drc_item.cpp - pns_log.cpp - pns_log_viewer.cpp + pns_log_file.cpp + pns_log_player.cpp + pns_test_debug_decorator.cpp + pns_log_viewer_frame.cpp pns_log_viewer_frame_base.cpp + label_manager.cpp ../qa_utils/pcb_test_frame.cpp ../qa_utils/test_app_main.cpp ../qa_utils/utility_program.cpp ../qa_utils/mocks.cpp ../../common/base_units.cpp playground.cpp + main.cpp ) # Pcbnew tests, so pretend to be pcbnew (for units, etc) diff --git a/qa/pns/label_manager.cpp b/qa/pns/label_manager.cpp new file mode 100644 index 0000000000..eae0c9431f --- /dev/null +++ b/qa/pns/label_manager.cpp @@ -0,0 +1,177 @@ +#include +#include +#include + +#include "label_manager.h" + +using KIGFX::GAL; +using KIGFX::COLOR4D; +using KIGFX::VIEW_OVERLAY; + +LABEL_MANAGER::LABEL_MANAGER( GAL* aGal ) : m_gal( aGal ) +{ +}; + + +LABEL_MANAGER::~LABEL_MANAGER() +{ +} + + +void LABEL_MANAGER::Add( VECTOR2I target, wxString msg, COLOR4D color ) +{ + LABEL lbl; + + lbl.m_target = target; + lbl.m_msg = msg; + lbl.m_color = color; + m_gal->SetGlyphSize( VECTOR2D( m_textSize, m_textSize ) ); + + KIFONT::FONT* strokeFont = KIFONT::FONT::GetFont( wxEmptyString ); + UTF8 text( msg ); + VECTOR2I textDims = strokeFont->StringBoundaryLimits( text, VECTOR2D( m_textSize, m_textSize ), + m_textSize/8, false, false ); + + lbl.m_bbox.SetOrigin( lbl.m_target - textDims - VECTOR2I( m_textSize, m_textSize ) ); + lbl.m_bbox.SetSize( textDims ); + m_labels.push_back( lbl ); +} + + +void LABEL_MANAGER::Add( const SHAPE_LINE_CHAIN& aL, COLOR4D color ) +{ + for( int i = 0; i < aL.PointCount(); i++ ) + { + char msg[1024]; + snprintf( msg, sizeof( msg ), "%d", i ); + Add( aL.CPoint( i ), msg, color ); + } +} + +void LABEL_MANAGER::Redraw( VIEW_OVERLAY* aOvl ) +{ + recalculate(); + + for( auto& lbl : m_labels ) + { + aOvl->SetIsFill( false ); + aOvl->SetIsStroke( true ); + aOvl->SetLineWidth( 10000 ); + aOvl->SetStrokeColor( lbl.m_color.Brighten( 0.7 ) ); + aOvl->Rectangle( lbl.m_bbox.GetOrigin(), lbl.m_bbox.GetEnd() ); + aOvl->BitmapText( lbl.m_msg, lbl.m_bbox.Centre(), ANGLE_HORIZONTAL ); + VECTOR2I nearest = nearestBoxCorner( lbl.m_bbox, lbl.m_target ); + aOvl->Line( lbl.m_target, nearest ); + } +} + + +VECTOR2I LABEL_MANAGER::nearestBoxCorner( BOX2I b, VECTOR2I p ) +{ + VECTOR2I ptest[4] = { b.GetPosition(), b.GetPosition() + VECTOR2I( b.GetWidth(), 0 ), + b.GetPosition() + VECTOR2I( b.GetWidth(), b.GetHeight() ), + b.GetPosition() + VECTOR2I( 0, b.GetHeight() ) }; + + int bestDist = INT_MAX; + VECTOR2I rv; + + for( int i = 0; i < 4; i++ ) + { + int dist = ( ptest[i] - p ).EuclideanNorm(); + + if( dist < bestDist ) + { + bestDist = dist; + rv = ptest[i]; + } + } + + return rv; +} + + +VECTOR2I LABEL_MANAGER::boxMtv( BOX2I b1, BOX2I b2 ) +{ + VECTOR2I rv( 0, 0 ); + + b1.Normalize(); + b2.Normalize(); + + if( !b1.Intersects( b2 ) ) + return rv; + + int bestDist = INT_MAX; + + VECTOR2I p[4] = { b2.GetPosition(), b2.GetPosition() + VECTOR2I( b2.GetWidth(), 0 ), + b2.GetPosition() + VECTOR2I( b2.GetWidth(), b2.GetHeight() ), + b2.GetPosition() + VECTOR2I( 0, b2.GetHeight() ) }; + + for( int i = 0; i < 4; i++ ) + { + if( b1.Contains( p[i] ) ) + { + // printf("CONT %d\n", i ); + VECTOR2I dp[4] = { VECTOR2I( b1.GetEnd().x - p[i].x + 1, 0 ), + VECTOR2I( b1.GetPosition().x - p[i].x - 1, 0 ), + VECTOR2I( 0, b1.GetEnd().y - p[i].y + 1 ), + VECTOR2I( 0, b1.GetPosition().y - p[i].y - 1 ) }; + + for( int j = 0; j < 4; j++ ) + { + BOX2I btest( b2 ); + btest.Move( dp[j] ); + + if( !b1.Intersects( btest ) ) + { + int dist = dp[j].EuclideanNorm(); + + if( dist < bestDist ) + { + bestDist = dist; + rv = dp[j]; + } + } + } + } + } + + return rv; +} + + +void LABEL_MANAGER::recalculate() +{ + int iterLimit = 5; + + while( iterLimit > 0 ) + { + bool collisionsFound = false; + + for( int i = 0; i < m_labels.size(); i++ ) + { + for( int j = 0; j < m_labels.size(); j++ ) + { + if( i == j ) + continue; + + auto bb_i = m_labels[i].m_bbox; + auto bb_j = m_labels[j].m_bbox; + + bb_i.Inflate( 100000 ); + bb_j.Inflate( 100000 ); + VECTOR2I mtv = boxMtv( bb_i, bb_j ); + + if( mtv.x || mtv.y ) + { + m_labels[i].m_bbox.Move( -mtv ); + collisionsFound = true; + } + } + } + + if( !collisionsFound ) + break; + + iterLimit--; + } +} diff --git a/qa/pns/label_manager.h b/qa/pns/label_manager.h index 1ebf5caa1d..0756035b13 100644 --- a/qa/pns/label_manager.h +++ b/qa/pns/label_manager.h @@ -1,37 +1,40 @@ #ifndef __LABEL_MANAGER_H #define __LABEL_MANAGER_H +#include + #include #include #include #include +#include +#include class LABEL_MANAGER { public: struct LABEL { - COLOR4D m_color; - std::string m_msg; - VECTOR2I m_target; - BOX2I m_bbox; + KIGFX::COLOR4D m_color; + wxString m_msg; + VECTOR2I m_target; + BOX2I m_bbox; }; LABEL_MANAGER( KIGFX::GAL* aGal ); - ~LABEL_MANAGER( ); + ~LABEL_MANAGER(); - void Add( VECTOR2I target, std::string msg, COLOR4D color ); - void Add( const SHAPE_LINE_CHAIN& aL, COLOR4D color ); + void Add( VECTOR2I target, wxString msg, KIGFX::COLOR4D color ); + void Add( const SHAPE_LINE_CHAIN& aL, KIGFX::COLOR4D color ); void Redraw( KIGFX::VIEW_OVERLAY* aOvl ); private: - VECTOR2I nearestBoxCorner( BOX2I b, VECTOR2I p ); VECTOR2I boxMtv( BOX2I b1, BOX2I b2 ); - void recalculate(); + void recalculate(); - KIGFX::GAL* m_gal; - int m_textSize = 100000; + KIGFX::GAL* m_gal; + int m_textSize = 100000; std::vector