KiCad PCB EDA Suite
pns_log_viewer.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2020-2021 KiCad Developers.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 
25 // WARNING - this Tom's crappy PNS hack tool code. Please don't complain about its quality
26 // (unless you want to improve it).
27 
28 #include <wx/clipbrd.h>
29 
31 #include <pgm_base.h>
32 
33 #include <profile.h>
34 #include <trace_helpers.h>
35 
36 #include <view/view_overlay.h>
37 
38 #include "pns_log.h"
39 #include "router/pns_diff_pair.h"
40 #include "router/pns_utils.h"
41 
42 #include "pns_log_viewer_frame.h"
43 
44 #include "qa/drc_proto/drc_proto.h"
45 
46 #include "label_manager.h"
47 #define TOM_EXTRA_DEBUG
48 
49 
50 LABEL_MANAGER::LABEL_MANAGER( KIGFX::GAL* aGal ) : m_gal( aGal )
51 {
52 
53 };
54 
55 
57 {
58 }
59 
60 
61 void LABEL_MANAGER::Add( VECTOR2I target, std::string msg, COLOR4D color )
62 {
63  LABEL lbl;
64 
65  lbl.m_target = target;
66  lbl.m_msg = msg;
67  lbl.m_color = color;
69 
70  VECTOR2I textDims = m_gal->GetTextLineSize( msg );
71 
72  lbl.m_bbox.SetOrigin( lbl.m_target - textDims - VECTOR2I( m_textSize, m_textSize ) );
73  lbl.m_bbox.SetSize( textDims );
74  m_labels.push_back( lbl );
75 }
76 
77 
79 {
80  for( int i = 0; i < aL.PointCount(); i++ )
81  {
82  char msg[1024];
83  snprintf( msg, sizeof( msg ), "%d", i );
84  Add( aL.CPoint( i ), msg, color );
85  }
86 }
87 
89 {
90  recalculate();
91 
92  for( auto& lbl : m_labels )
93  {
94  aOvl->SetIsFill( false );
95  aOvl->SetIsStroke( true );
96  aOvl->SetLineWidth( 10000 );
97  aOvl->SetStrokeColor( lbl.m_color.Brighten( 0.7 ) );
98  aOvl->Rectangle( lbl.m_bbox.GetOrigin(), lbl.m_bbox.GetEnd() );
99  aOvl->BitmapText( lbl.m_msg, lbl.m_bbox.Centre(), 0.0 );
100  VECTOR2I nearest = nearestBoxCorner( lbl.m_bbox, lbl.m_target );
101  aOvl->Line( lbl.m_target, nearest );
102  }
103 }
104 
105 
107 {
108  VECTOR2I ptest[4] = { b.GetPosition(), b.GetPosition() + VECTOR2I( b.GetWidth(), 0 ),
109  b.GetPosition() + VECTOR2I( b.GetWidth(), b.GetHeight() ),
110  b.GetPosition() + VECTOR2I( 0, b.GetHeight() ) };
111 
112  int bestDist = INT_MAX;
113  VECTOR2I rv;
114 
115  for( int i = 0; i < 4; i++ )
116  {
117  int dist = ( ptest[i] - p ).EuclideanNorm();
118 
119  if( dist < bestDist )
120  {
121  bestDist = dist;
122  rv = ptest[i];
123  }
124  }
125 
126  return rv;
127 }
128 
129 
131 {
132  VECTOR2I rv( 0, 0 );
133 
134  b1.Normalize();
135  b2.Normalize();
136 
137  if( !b1.Intersects( b2 ) )
138  return rv;
139 
140  int bestDist = INT_MAX;
141 
142  VECTOR2I p[4] = { b2.GetPosition(), b2.GetPosition() + VECTOR2I( b2.GetWidth(), 0 ),
143  b2.GetPosition() + VECTOR2I( b2.GetWidth(), b2.GetHeight() ),
144  b2.GetPosition() + VECTOR2I( 0, b2.GetHeight() ) };
145 
146  for( int i = 0; i < 4; i++ )
147  {
148  if( b1.Contains( p[i] ) )
149  {
150  // printf("CONT %d\n", i );
151  VECTOR2I dp[4] = { VECTOR2I( b1.GetEnd().x - p[i].x + 1, 0 ),
152  VECTOR2I( b1.GetPosition().x - p[i].x - 1, 0 ),
153  VECTOR2I( 0, b1.GetEnd().y - p[i].y + 1 ),
154  VECTOR2I( 0, b1.GetPosition().y - p[i].y - 1 ) };
155 
156  for( int j = 0; j < 4; j++ )
157  {
158  BOX2I btest( b2 );
159  btest.Move( dp[j] );
160 
161  if( !b1.Intersects( btest ) )
162  {
163  int dist = dp[j].EuclideanNorm();
164 
165  if( dist < bestDist )
166  {
167  bestDist = dist;
168  rv = dp[j];
169  }
170  }
171  }
172  }
173  }
174 
175  return rv;
176 }
177 
178 
180 {
181  int iterLimit = 5;
182 
183  while( iterLimit > 0 )
184  {
185  printf( "Iter %d\n", iterLimit );
186  bool collisionsFound = false;
187 
188  for( int i = 0; i < m_labels.size(); i++ )
189  {
190  for( int j = 0; j < m_labels.size(); j++ )
191  {
192  if( i == j )
193  continue;
194 
195  auto bb_i = m_labels[i].m_bbox;
196  auto bb_j = m_labels[j].m_bbox;
197 
198  bb_i.Inflate( 100000 );
199  bb_j.Inflate( 100000 );
200  VECTOR2I mtv = boxMtv( bb_i, bb_j );
201 
202  if( mtv.x || mtv.y )
203  {
204  m_labels[i].m_bbox.Move( -mtv );
205  collisionsFound = true;
206  }
207  }
208  }
209 
210  if( !collisionsFound )
211  break;
212 
213  iterLimit--;
214  }
215 }
216 
217 
218 class WX_SHAPE_TREE_ITEM_DATA : public wxClientData
219 {
220 public:
222 
224 };
225 
226 
228 {
229  m_labelMgr.reset( new LABEL_MANAGER( aGal ) );
230 }
231 
232 
234  bool aShowVertexNumbers )
235 {
236  Polyline( aL );
237 
238  if( aShowVertexNumbers)
239  m_labelMgr->Add( aL, GetStrokeColor() );
240 }
241 
242 
243 void PNS_LOG_VIEWER_OVERLAY::AnnotatedPoint( const VECTOR2I p, int size, std::string name, bool aShowVertexNumbers )
244 {
245  Line( p + VECTOR2D( size, size ), p - VECTOR2D( size, size ) );
246  Line( p + VECTOR2D( -size, size ), p - VECTOR2D( -size, size ) );
247 
248  //if( aShowVertexNumbers)
249  // m_labelMgr->Add( aL, GetStrokeColor() );
250 }
251 
252 
254 {
255  double radius = arc.GetRadius();
256  double start_angle = DEG2RAD( arc.GetStartAngle() );
257  double angle = DEG2RAD( arc.GetCentralAngle() );
258 
260  KIGFX::VIEW_OVERLAY::Arc( arc.GetCenter(), radius, start_angle, start_angle + angle );
261 
263  COLOR4D lightStrokeCol = prevStrokeCol.WithAlpha(0.5);
264  KIGFX::VIEW_OVERLAY::SetStrokeColor( lightStrokeCol );
265 
267  KIGFX::VIEW_OVERLAY::Arc( arc.GetCenter(), radius, start_angle, start_angle + angle );
268 
269  KIGFX::VIEW_OVERLAY::SetStrokeColor( prevStrokeCol );
270 }
271 
273 {
274  m_labelMgr->Redraw( this );
275 }
276 
277 
279 {
280  LoadSettings();
282 
283  m_viewSizer->Add( m_galPanel.get(), 1, wxEXPAND, 5 );
284 
285  Layout();
286 
287  Show( true );
288  Maximize();
289  Raise();
290 
291  auto settings = static_cast<KIGFX::PCB_RENDER_SETTINGS*>(
292  m_galPanel->GetView()->GetPainter()->GetSettings() );
293 
294  settings->SetZoneDisplayMode( ZONE_DISPLAY_MODE::SHOW_FILLED );
295 
296  m_listPopupMenu = new wxMenu( wxEmptyString );
297  m_listPopupMenu->Append( ID_LIST_COPY, wxT( "Copy selected geometry" ), wxEmptyString,
298  wxITEM_NORMAL );
299  m_listPopupMenu->Append( ID_LIST_SHOW_ALL, wxT( "Show all" ), wxEmptyString, wxITEM_NORMAL );
300  m_listPopupMenu->Append( ID_LIST_SHOW_NONE, wxT( "Show none" ), wxEmptyString, wxITEM_NORMAL );
301 
302  m_itemList->Connect( m_itemList->GetId(), wxEVT_TREELIST_ITEM_CONTEXT_MENU,
303  wxMouseEventHandler( PNS_LOG_VIEWER_FRAME::onListRightClick ), nullptr,
304  this );
305  //m_itemList->Connect(m_itemList->GetId(),wxEVT_LISTBOX,wxCommandEventHandler(PNS_LOG_VIEWER_FRAME::onListSelect),nullptr,this);
306  m_itemList->Connect( m_itemList->GetId(), wxEVT_TREELIST_SELECTION_CHANGED,
307  wxCommandEventHandler( PNS_LOG_VIEWER_FRAME::onListSelect ),
308  nullptr, this );
309  m_itemList->Connect( m_itemList->GetId(), wxEVT_TREELIST_ITEM_CHECKED,
310  wxCommandEventHandler( PNS_LOG_VIEWER_FRAME::onListChecked ),
311  nullptr, this );
312 
313  m_itemList->AppendColumn( "Type" );
314  m_itemList->AppendColumn( "Value" );
315  m_itemList->AppendColumn( "File" );
316  m_itemList->AppendColumn( "Method" );
317  m_itemList->AppendColumn( "Line" );
318 
319  m_overlay.reset( new PNS_LOG_VIEWER_OVERLAY ( m_galPanel->GetGAL() ) );
320  m_galPanel->GetView()->Add( m_overlay.get() );
321 }
322 
323 
325 {
326  m_overlay = nullptr;
327 }
328 
329 
331 {
332 
333 }
334 
335 
337 {
338  PNS_TEST_DEBUG_DECORATOR* dbgd = m_env->GetDebugDecorator();
339  int count = dbgd->GetStageCount();
340 
341  int iter = m_rewindIter;
342 
343  if( count <= 0 )
344  return nullptr;
345 
346  if( iter < 0 )
347  iter = 0;
348 
349  if( iter >= count )
350  iter = count - 1;
351 
352  return dbgd->GetStage( iter );
353 }
354 
355 
357 {
358  if( !m_env )
359  return;
360 
362 
363  if( !st )
364  return;
365 
366  m_overlay.reset( new PNS_LOG_VIEWER_OVERLAY ( m_galPanel->GetGAL() ) );
367  m_galPanel->GetView()->Add( m_overlay.get() );
368 
369  auto drawShapes = [&]( PNS_TEST_DEBUG_DECORATOR::DEBUG_ENT* ent ) -> bool
370  {
371  bool isEnabled = ent->IsVisible();
372  bool isSelected = false;
373 
374  if( !isEnabled )
375  return true;
376 
377  for( auto& sh : ent->m_shapes )
378  {
379  COLOR4D color = ent->m_color;
380  int lineWidth = ent->m_width;
381 
382  m_overlay->SetIsStroke( true );
383  m_overlay->SetIsFill( false );
384 
385  if( isSelected )
386  {
387  color.Brighten( 0.5 );
388  }
389 
390  m_overlay->SetStrokeColor( color );
391  m_overlay->SetLineWidth( ent->m_width );
392 
393  switch( sh->Type() )
394  {
395  case SH_CIRCLE:
396  {
397  auto cir = static_cast<SHAPE_CIRCLE*>( sh );
398  m_overlay->Circle( cir->GetCenter(), cir->GetRadius() );
399 
400  break;
401  }
402  case SH_RECT:
403  {
404  auto rect = static_cast<SHAPE_RECT*>( sh );
405  m_overlay->Rectangle( rect->GetPosition(), rect->GetPosition() + rect->GetSize() );
406 
407  break;
408  }
409  case SH_LINE_CHAIN:
410  {
411  auto lc = static_cast<SHAPE_LINE_CHAIN*>( sh );
412  m_overlay->AnnotatedPolyline( *lc, ent->m_name, ent->m_hasLabels && isSelected );
413 
414  break;
415 
416  }
417  default:
418  break;
419  }
420  }
421 
422  return true;
423  };
424 
426 
427  m_overlay->DrawAnnotations();
428 
429  m_galPanel->GetView()->MarkDirty();
430  m_galPanel->GetParent()->Refresh();
431 }
432 
433 
434 static BOARD* loadBoard( const std::string& filename )
435 {
436  PLUGIN::RELEASER pi( new PCB_PLUGIN );
437  BOARD* brd = nullptr;
438 
439  try
440  {
441  brd = pi->Load( wxString( filename.c_str() ), nullptr, nullptr );
442  }
443  catch( const IO_ERROR& )
444  {
445  return nullptr;
446  }
447 
448  return brd;
449 }
450 
451 
453 {
454  m_logFile.reset( aLog );
455 
456  SetBoard( m_logFile->GetBoard() );
457 
458  m_env.reset( new PNS_TEST_ENVIRONMENT );
459 
460  m_env->SetMode( PNS::PNS_MODE_ROUTE_SINGLE );
461  m_env->ReplayLog( m_logFile.get() );
462 
463  auto dbgd = m_env->GetDebugDecorator();
464  int n_stages = dbgd->GetStageCount();
465  m_rewindSlider->SetMax( n_stages - 1 );
466  m_rewindSlider->SetValue( n_stages - 1 );
467  m_rewindIter = n_stages - 1;
468 
469  auto extents = m_board->GetBoundingBox();
470 
471 
472  BOX2D bbd;
473  bbd.SetOrigin( extents.GetOrigin() );
474  bbd.SetWidth( extents.GetWidth() );
475  bbd.SetHeight( extents.GetHeight() );
476  bbd.Inflate( std::min( bbd.GetWidth(), bbd.GetHeight() ) / 5 );
477 
478  m_galPanel->GetView()->SetViewport( bbd );
479 
482 }
483 
484 
485 
486 void PNS_LOG_VIEWER_FRAME::SetBoard2( std::shared_ptr<BOARD> aBoard )
487 {
488  SetBoard( aBoard );
489 
490  auto extents = m_board->GetBoundingBox();
491 
492  BOX2D bbd;
493  bbd.SetOrigin( extents.GetOrigin() );
494  bbd.SetWidth( extents.GetWidth() );
495  bbd.SetHeight( extents.GetHeight() );
496  bbd.Inflate( std::min( bbd.GetWidth(), bbd.GetHeight() ) / 5 );
497 
498  m_galPanel->GetView()->SetViewport( bbd );
499 }
500 
501 void PNS_LOG_VIEWER_FRAME::onReload( wxCommandEvent& event )
502 {
503  event.Skip();
504 }
505 
506 void PNS_LOG_VIEWER_FRAME::onExit( wxCommandEvent& event )
507 {
508  event.Skip();
509 }
510 
511 
512 void PNS_LOG_VIEWER_FRAME::onListChecked( wxCommandEvent& event )
513 {
514  syncModel();
516 }
517 
518 
519 void PNS_LOG_VIEWER_FRAME::onRewindScroll( wxScrollEvent& event )
520 {
521  m_rewindIter = event.GetPosition();
524  char str[128];
525  sprintf( str, "%d", m_rewindIter );
526  m_rewindPos->SetValue( str );
527  event.Skip();
528 }
529 
530 
531 void PNS_LOG_VIEWER_FRAME::onBtnRewindLeft( wxCommandEvent& event )
532 {
533  if( m_rewindIter > 0 )
534  {
535  m_rewindIter--;
538  char str[128];
539  sprintf( str, "%d", m_rewindIter );
540  m_rewindPos->SetValue( str );
541  }
542 }
543 
544 
545 void PNS_LOG_VIEWER_FRAME::onBtnRewindRight( wxCommandEvent& event )
546 {
547  auto dbgd = m_env->GetDebugDecorator();
548  int count = dbgd->GetStageCount();
549 
550  if( m_rewindIter < count )
551  {
552  m_rewindIter++;
555  char str[128];
556  sprintf( str, "%d", m_rewindIter );
557  m_rewindPos->SetValue( str );
558  }
559 }
560 
561 
562 void PNS_LOG_VIEWER_FRAME::onRewindCountText( wxCommandEvent& event )
563 {
564  if( !m_env )
565  return;
566 
567  int val = wxAtoi( m_rewindPos->GetValue() );
568 
569  auto dbgd = m_env->GetDebugDecorator();
570  int count = dbgd->GetStageCount();
571 
572  if( val < 0 )
573  val = 0;
574 
575  if( val >= count )
576  val = count - 1;
577 
578  m_rewindIter = val;
579  m_rewindSlider->SetValue( m_rewindIter );
582 
583  event.Skip();
584 }
585 
586 
588 {
589  for( wxTreeListItem item = m_itemList->GetFirstItem(); item.IsOk();
590  item = m_itemList->GetNextItem( item ) )
591  {
592  WX_SHAPE_TREE_ITEM_DATA* idata =
593  static_cast<WX_SHAPE_TREE_ITEM_DATA*>( m_itemList->GetItemData( item ) );
594 
595  if( idata )
596  {
597  bool checked = m_itemList->GetCheckedState( item ) == wxCHK_CHECKED;
598  bool selected = m_itemList->IsSelected( item );
599  idata->m_item->m_visible = checked || selected;
600  idata->m_item->m_selected = selected;
601  }
602  }
603 }
604 
605 
606 void PNS_LOG_VIEWER_FRAME::onListRightClick( wxMouseEvent& event )
607 {
608  auto sel = m_itemList->GetPopupMenuSelectionFromUser( *m_listPopupMenu );
609 
610  switch( sel )
611  {
612  case ID_LIST_SHOW_NONE:
613  m_itemList->CheckItemRecursively( m_itemList->GetRootItem(), wxCHK_UNCHECKED );
614  syncModel();
616  break;
617  case ID_LIST_SHOW_ALL:
618  m_itemList->CheckItemRecursively( m_itemList->GetRootItem(), wxCHK_CHECKED );
619  syncModel();
621  break;
622  case ID_LIST_COPY:
623  {
624  wxString s;
625 
627 
628  if( !st )
629  return;
630 
631  auto formatShapes = [&]( PNS_TEST_DEBUG_DECORATOR::DEBUG_ENT* ent ) -> bool
632  {
633  if( ent->m_selected )
634  {
635  for( auto sh : ent->m_shapes )
636  {
637  s += "// " + ent->m_name + "\n " + sh->Format() + "; \n";
638  }
639  }
640 
641  return true;
642  };
643 
644  st->m_entries->IterateTree( formatShapes );
645 
646  if( wxTheClipboard->Open() )
647  {
648  // This data objects are held by the clipboard,
649  // so do not delete them in the app.
650  wxTheClipboard->SetData( new wxTextDataObject( s ) );
651  wxTheClipboard->Flush(); // Allow data to be available after closing KiCad
652  wxTheClipboard->Close();
653  }
654 
655  return;
656  }
657  }
658 }
659 
660 
661 void PNS_LOG_VIEWER_FRAME::onListSelect( wxCommandEvent& event )
662 {
663  syncModel();
665 }
666 
667 
668 void PNS_LOG_VIEWER_FRAME::buildListTree( wxTreeListItem item,
669  PNS_TEST_DEBUG_DECORATOR::DEBUG_ENT* ent, int depth )
670 {
671 #ifdef EXTRA_VERBOSE
672  for( int i = 0; i < depth * 2; i++ )
673  printf( " " );
674 
675  if( ent->m_msg.length() )
676  printf( "MSG: %s\n", ent->m_msg.c_str() );
677  else
678  printf( "SHAPES: %s [%d]\n", ent->m_name.c_str(), ent->m_children.size() );
679 #endif
680 
681  wxTreeListItem ritem;
682 
683  printf("depth %d\n", depth );
684 
685  if( ent->m_msg.length() )
686  {
687  ritem = m_itemList->AppendItem( item, "Child" );
688  m_itemList->SetItemText( ritem, 0, "Message" );
689  m_itemList->SetItemText( ritem, 1, ent->m_msg );
690  }
691  else
692  {
693  ritem = m_itemList->AppendItem( item, "Child" );
694  m_itemList->SetItemText( ritem, 0, "Shapes" );
695  m_itemList->SetItemText( ritem, 1, ent->m_name );
696  }
697 
698  m_itemList->SetItemText( ritem, 2, wxFileNameFromPath( ent->m_srcLoc.fileName ) );
699  m_itemList->SetItemText( ritem, 3, ent->m_srcLoc.funcName );
700  m_itemList->SetItemText( ritem, 4, wxString::Format("%d", ent->m_srcLoc.line ) );
701 
702  m_itemList->SetItemData( ritem, new WX_SHAPE_TREE_ITEM_DATA( ent ) );
703 
704  if( !ent->m_children.size() )
705  return;
706 
707  for( auto child : ent->m_children )
708  {
709  buildListTree( ritem, child, depth + 1 );
710  }
711 }
712 
713 
714 static void expandAllChildren( wxTreeListCtrl* tree )
715 {
716  wxTreeListItem child = tree->GetFirstItem ();
717 
718  while( child.IsOk() )
719  {
720  tree->Expand ( child );
721  child = tree->GetNextItem( child );
722  }
723 }
724 
725 
727 {
728  if( !m_env )
729  return;
730 
731  auto dbgd = m_env->GetDebugDecorator();
732  int count = dbgd->GetStageCount();
733 
734  wxArrayString dumpStrings;
735 
736  if( count <= 0 )
737  return;
738 
739  if( iter < 0 )
740  iter = 0;
741 
742  if( iter >= count )
743  iter = count - 1;
744 
745  auto st = dbgd->GetStage( iter );
746  auto rootItem = m_itemList->GetRootItem();
747 
748  m_itemList->DeleteAllItems();
749  buildListTree( rootItem, st->m_entries );
750  m_itemList->CheckItemRecursively( rootItem, wxCHK_UNCHECKED );
751 
753 
754  m_itemList->Refresh();
755 }
756 
757 
758 int replay_main_func( int argc, char* argv[] )
759 {
760  auto frame = new PNS_LOG_VIEWER_FRAME( nullptr );
761 
762  // drcCreateTestsProviderClearance();
763  // drcCreateTestsProviderEdgeClearance();
764 
765  if( argc >= 2 && std::string( argv[1] ) == "-h" )
766  {
767  printf( "PNS Log (Re)player. Allows to step through the log written by the ROUTER_TOOL "
768  "in debug KiCad builds. " );
769  printf( "Requires a board file with UUIDs and a matching log file. Both are written to "
770  "/tmp when you press '0' during routing." );
771  return 0;
772  }
773 
774  if( argc < 3 )
775  {
776  printf( "Expected parameters: log_file.log board_file.dump\n" );
777  return 0;
778  }
779 
780  PNS_LOG_FILE* logFile = new PNS_LOG_FILE;
781  logFile->Load( argv[1], argv[2] );
782 
783  frame->SetLogFile( logFile );
784  //SetTopFrame( frame ); // wxApp gets a face.
785 
786  return 0;
787 }
788 
789 
791  "replay",
792  "PNS Log Player",
794 } );
795 
796 
797 
798 int render_perftest_main_func( int argc, char* argv[] )
799 {
800  auto frame = new PNS_LOG_VIEWER_FRAME( nullptr );
801 
802  // drcCreateTestsProviderClearance();
803  // drcCreateTestsProviderEdgeClearance();
804 
805  if( argc >= 2 && std::string( argv[1] ) == "-h" )
806  {
807  printf( "PCB render performance test. Just renders a board without UI update overhead.\n" );
808  return 0;
809  }
810 
811  if( argc < 2 )
812  {
813  printf( "Expected parameters: board_file\n" );
814  return 0;
815  }
816 
817  PROF_TIMER cnt("load-board");
818  std::shared_ptr<BOARD> brd ( loadBoard( argv[1] ) );
819  cnt.Stop();
820 
821  KI_TRACE( traceGalProfile, "%s\n", cnt.to_string() );
822 
823  frame->SetBoard2( brd );
824 
825  return 0;
826 }
827 
828 
830  "render_perftest",
831  "Renderer performance test",
833 } );
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:146
bool Load(const std::string &logName, const std::string boardName)
Definition: pns_log.cpp:52
void Move(const Vec &aMoveVector)
Move the rectangle by the aMoveVector.
Definition: box2.h:104
std::shared_ptr< PNS_LOG_FILE > m_logFile
void BitmapText(const wxString &aText, const VECTOR2D &aPosition, double aRotationAngle)
STAGE * GetStage(int index)
Definition: pns_log.h:243
Class PNS_LOG_VIEWER_FRAME_BASE.
const Vec GetEnd() const
Definition: box2.h:178
void buildListTree(wxTreeListItem item, PNS_TEST_DEBUG_DECORATOR::DEBUG_ENT *ent, int depth=0)
void SetBoard2(std::shared_ptr< BOARD > aBoard)
virtual void onBtnRewindRight(wxCommandEvent &event) override
double GetRadius() const
Definition: shape_arc.cpp:452
#define ID_LIST_COPY
const COLOR4D & GetStrokeColor() const
Definition: view_overlay.h:103
int color
Definition: DXF_plotter.cpp:57
COLOR4D WithAlpha(double aAlpha) const
Return a color with the same color, but the given alpha.
Definition: color4d.h:321
A PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
Definition: pcb_plugin.h:141
PNS_TEST_DEBUG_DECORATOR::DEBUG_ENT * m_item
void SetSize(const Vec &size)
Definition: box2.h:195
const wxChar *const traceGalProfile
Flag to enable debug output of GAL performance profiling.
double GetStartAngle() const
Definition: shape_arc.cpp:404
void Add(VECTOR2I target, std::string msg, COLOR4D color)
void createView(wxWindow *aParent, PCB_DRAW_PANEL_GAL::GAL_TYPE aGalType=PCB_DRAW_PANEL_GAL::GAL_TYPE_OPENGL)
VECTOR2< int > VECTOR2I
Definition: vector2d.h:622
int PointCount() const
Return the number of points (vertices) in this line chain.
VECTOR2D GetTextLineSize(const UTF8 &aText) const
Compute the X and Y size of a given text.
void SetIsStroke(bool aIsStrokeEnabled)
void Redraw(KIGFX::VIEW_OVERLAY *aOvl)
static bool registered3
int GetStageCount() const
Definition: pns_log.h:241
Releases a PLUGIN in the context of a potential thrown exception through its destructor.
Definition: io_mgr.h:555
void Polyline(const SHAPE_LINE_CHAIN &aPolyLine)
bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:217
VECTOR2I nearestBoxCorner(BOX2I b, VECTOR2I p)
void Line(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
virtual void onExit(wxCommandEvent &event) override
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
PNS_TEST_DEBUG_DECORATOR::STAGE * getCurrentStage()
#define ID_LIST_SHOW_ALL
void Arc(const VECTOR2D &aCenterPoint, double aRadius, double aStartAngle, double aEndAngle)
#define ID_LIST_SHOW_NONE
VECTOR2< double > VECTOR2D
Definition: vector2d.h:621
LABEL_MANAGER(KIGFX::GAL *aGal)
virtual void onRewindCountText(wxCommandEvent &event) override
static bool Register(const KI_TEST::UTILITY_PROGRAM &aProgInfo)
Register a utility program factory function against an ID string.
void updateDumpPanel(int iter)
coord_type GetWidth() const
Definition: box2.h:180
BOX2< Vec > & Normalize()
Ensure that the height ant width are positive.
Definition: box2.h:112
bool Contains(const Vec &aPoint) const
Definition: box2.h:134
virtual void onBtnRewindLeft(wxCommandEvent &event) override
virtual void createUserTools() override
static bool registered2
PNS_LOG_VIEWER_OVERLAY(KIGFX::GAL *aGal)
wxLogTrace helper definitions.
void Arc(const SHAPE_ARC &arc)
std::string to_string()
Definition: profile.h:153
int drawShapes(int argc, char *argv[])
Definition: playground.cpp:230
void SetStrokeColor(const COLOR4D &aColor)
PNS_LOG_VIEWER_FRAME(wxFrame *frame)
VECTOR2I boxMtv(BOX2I b1, BOX2I b2)
static void expandAllChildren(wxTreeListCtrl *tree)
virtual void onReload(wxCommandEvent &event) override
A small class to help profiling.
Definition: profile.h:46
circle
Definition: shape.h:46
void SetGlyphSize(const VECTOR2D &aSize)
Set the font glyph size.
void Stop()
Save the time when this function was called, and set the counter stane to stop.
Definition: profile.h:86
void SetIsFill(bool aIsFillEnabled)
std::unique_ptr< LABEL_MANAGER > m_labelMgr
std::vector< DEBUG_ENT * > m_children
Definition: pns_log.h:174
const Vec & GetPosition() const
Definition: box2.h:177
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
int render_perftest_main_func(int argc, char *argv[])
void IterateTree(std::function< bool(DEBUG_ENT *)> visitor, int depth=0)
Definition: pns_log.cpp:440
std::shared_ptr< PCB_DRAW_PANEL_GAL > m_galPanel
std::shared_ptr< BOARD > m_board
PNS::DEBUG_DECORATOR::SRC_LOCATION_INFO m_srcLoc
Definition: pns_log.h:181
void SetHeight(coord_type val)
Definition: box2.h:206
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:281
int GetWidth() const
Definition: shape_arc.h:156
std::shared_ptr< PNS_LOG_VIEWER_OVERLAY > m_overlay
see class PGM_BASE
const char * name
Definition: DXF_plotter.cpp:56
void SetLineWidth(double aLineWidth)
double DEG2RAD(double deg)
Definition: trigo.h:229
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:191
void AnnotatedPoint(const VECTOR2I p, int size, std::string name="", bool aShowVertexNumbers=false)
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
KIGFX::GAL * m_gal
Definition: label_manager.h:33
virtual void onListRightClick(wxMouseEvent &event)
std::shared_ptr< PNS_TEST_ENVIRONMENT > m_env
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
virtual void SetBoard(std::shared_ptr< BOARD > b)
void SetOrigin(const Vec &pos)
Definition: box2.h:193
double GetCentralAngle() const
Definition: shape_arc.cpp:439
#define KI_TRACE(...)
line chain (polyline)
Definition: shape.h:45
coord_type GetHeight() const
Definition: box2.h:181
virtual void onListSelect(wxCommandEvent &event)
void drawLoggedItems(int iter)
virtual void onRewindScroll(wxScrollEvent &event) override
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:293
axis-aligned rectangle
Definition: shape.h:43
int replay_main_func(int argc, char *argv[])
void AnnotatedPolyline(const SHAPE_LINE_CHAIN &aL, std::string name, bool aShowVertexNumbers=false)
static BOARD * loadBoard(const std::string &filename)
virtual void onListChecked(wxCommandEvent &event)
std::vector< LABEL > m_labels
Definition: label_manager.h:35
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75
VECTOR2I GetCenter() const
Definition: shape_arc.cpp:424
WX_SHAPE_TREE_ITEM_DATA(PNS_TEST_DEBUG_DECORATOR::DEBUG_ENT *item)
void SetLogFile(PNS_LOG_FILE *aLog)
void SetWidth(coord_type val)
Definition: box2.h:205
void Rectangle(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Abstract interface for drawing on a 2D-surface.
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:103