KiCad PCB EDA Suite
pns_log_viewer.cpp File Reference
#include <wx/clipbrd.h>
#include <pcb_painter.h>
#include <pcb_test_frame.h>
#include <qa_utils/utility_registry.h>
#include <pgm_base.h>
#include <profile.h>
#include <view/view_overlay.h>
#include "pns_log.h"
#include "router/pns_diff_pair.h"
#include "pns_log_viewer_frame_base.h"
#include "qa/drc_proto/drc_proto.h"

Go to the source code of this file.

Classes

class  PNS_LOG_VIEWER_FRAME
 
class  WX_SHAPE_TREE_ITEM_DATA
 

Macros

#define ID_LIST_COPY   10001
 
#define ID_LIST_SHOW_ALL   10002
 
#define ID_LIST_SHOW_NONE   10003
 

Functions

static const COLOR4D assignColor (int aStyle)
 
static BOARDloadBoard (const std::string &filename)
 
static void expandAllChildren (wxTreeListCtrl *tree, const wxTreeListItem &item)
 
static bool commonParallelProjection (SEG p, SEG n, SEG &pClip, SEG &nClip)
 
int replay_main_func (int argc, char *argv[])
 
template<typename T1 , typename T2 >
std::map< T1, T2 >::iterator findClosestKey (std::map< T1, T2 > &data, T1 key)
 
void extractDiffPair (BOARD *aBoard, int net_p, int net_n)
 
static int matchDpSuffix (const wxString &aNetName, wxString &aComplementNet, wxString &aBaseDpName)
 
static int dpCoupledNet (BOARD *aBoard, int aNet)
 
void extractAllDiffPairs (BOARD *aBoard)
 
bool segmentCrossesHullBoundary (const SHAPE_LINE_CHAIN &hull, const SEG &seg)
 
bool walkaround2 (SHAPE_LINE_CHAIN &aLine, SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN &aPre, SHAPE_LINE_CHAIN &aWalk, SHAPE_LINE_CHAIN &aPost, bool aCw)
 
int test2_main_func (int argc, char *argv[])
 

Variables

static bool registered2
 
static std::shared_ptr< KIGFX::VIEW_OVERLAYoverlay
 
static bool registered4
 

Macro Definition Documentation

◆ ID_LIST_COPY

#define ID_LIST_COPY   10001

Definition at line 45 of file pns_log_viewer.cpp.

◆ ID_LIST_SHOW_ALL

#define ID_LIST_SHOW_ALL   10002

Definition at line 46 of file pns_log_viewer.cpp.

◆ ID_LIST_SHOW_NONE

#define ID_LIST_SHOW_NONE   10003

Definition at line 47 of file pns_log_viewer.cpp.

Function Documentation

◆ assignColor()

static const COLOR4D assignColor ( int  aStyle)
static

Definition at line 137 of file pns_log_viewer.cpp.

138 {
139  COLOR4D color;
140 
141  switch( aStyle )
142  {
143  case 0:
144  color = COLOR4D( 0, 1, 0, 1 );
145  break;
146 
147  case 1:
148  color = COLOR4D( 1, 0, 0, 1 );
149  break;
150 
151  case 2:
152  color = COLOR4D( 1, 1, 0, 1 );
153  break;
154 
155  case 3:
156  color = COLOR4D( 0, 0, 1, 1 );
157  break;
158 
159  case 4:
160  color = COLOR4D( 1, 1, 1, 1 );
161  break;
162 
163  case 5:
164  color = COLOR4D( 1, 1, 0, 1 );
165  break;
166 
167  case 6:
168  color = COLOR4D( 0, 1, 1, 1 );
169  break;
170 
171  case 32:
172  color = COLOR4D( 0, 0, 1, 1 );
173  break;
174 
175  default:
176  color = COLOR4D( 0.4, 0.4, 0.4, 1 );
177  break;
178  }
179 
180  return color;
181 }
int color
Definition: DXF_plotter.cpp:60
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:98

References color.

Referenced by PNS_LOG_VIEWER_FRAME::drawLoggedItems().

◆ commonParallelProjection()

bool commonParallelProjection ( SEG  p,
SEG  n,
SEG pClip,
SEG nClip 
)
static

Definition at line 618 of file pns_log_viewer.cpp.

619 {
620  SEG n_proj_p( p.LineProject( n.A ), p.LineProject( n.B ) );
621 
622  int64_t t_a = 0;
623  int64_t t_b = p.TCoef( p.B );
624 
625  int64_t tproj_a = p.TCoef( n_proj_p.A );
626  int64_t tproj_b = p.TCoef( n_proj_p.B );
627 
628  if( t_b < t_a )
629  std::swap( t_b, t_a );
630 
631  if( tproj_b < tproj_a )
632  std::swap( tproj_b, tproj_a );
633 
634  if( t_b <= tproj_a )
635  return false;
636 
637  if( t_a >= tproj_b )
638  return false;
639 
640  int64_t t[4] = { 0, p.TCoef( p.B ), p.TCoef( n_proj_p.A ), p.TCoef( n_proj_p.B ) };
641  std::vector<int64_t> tv( t, t + 4 );
642  std::sort( tv.begin(), tv.end() ); // fixme: awful and disgusting way of finding 2 midpoints
643 
644  int64_t pLenSq = p.SquaredLength();
645 
646  VECTOR2I dp = p.B - p.A;
647  pClip.A.x = p.A.x + rescale( (int64_t)dp.x, tv[1], pLenSq );
648  pClip.A.y = p.A.y + rescale( (int64_t)dp.y, tv[1], pLenSq );
649 
650  pClip.B.x = p.A.x + rescale( (int64_t)dp.x, tv[2], pLenSq );
651  pClip.B.y = p.A.y + rescale( (int64_t)dp.y, tv[2], pLenSq );
652 
653  nClip.A = n.LineProject( pClip.A );
654  nClip.B = n.LineProject( pClip.B );
655 
656  return true;
657 }
ecoord SquaredLength() const
Definition: seg.h:360
VECTOR2I LineProject(const VECTOR2I &aP) const
Compute the perpendicular projection point of aP on a line passing through ends of the segment.
Definition: seg.h:404
ecoord TCoef(const VECTOR2I &aP) const
Definition: seg.h:431
Definition: seg.h:41
VECTOR2I A
Definition: seg.h:49
T rescale(T aNumerator, T aValue, T aDenominator)
Function rescale()
Definition: util.h:95
VECTOR2I B
Definition: seg.h:50

References SEG::A, SEG::B, SEG::LineProject(), rescale(), SEG::SquaredLength(), SEG::TCoef(), VECTOR2< T >::x, and VECTOR2< T >::y.

◆ dpCoupledNet()

static int dpCoupledNet ( BOARD aBoard,
int  aNet 
)
static

Definition at line 1040 of file pns_log_viewer.cpp.

1041 {
1042  wxString refName = aBoard->FindNet( aNet )->GetNetname();
1043  wxString dummy, coupledNetName;
1044 
1045  if( matchDpSuffix( refName, coupledNetName, dummy ) )
1046  {
1047  NETINFO_ITEM* net = aBoard->FindNet( coupledNetName );
1048 
1049  if( !net )
1050  return -1;
1051 
1052  return net->GetNetCode();
1053  }
1054 
1055  return -1;
1056 }
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition: board.cpp:1289
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
Definition: sch_symbol.cpp:69
static int matchDpSuffix(const wxString &aNetName, wxString &aComplementNet, wxString &aBaseDpName)
const wxString & GetNetname() const
Definition: netinfo.h:119
Handle the data for a net.
Definition: netinfo.h:64
int GetNetCode() const
Definition: netinfo.h:113

References dummy(), BOARD::FindNet(), NETINFO_ITEM::GetNetCode(), NETINFO_ITEM::GetNetname(), and matchDpSuffix().

Referenced by extractAllDiffPairs().

◆ expandAllChildren()

static void expandAllChildren ( wxTreeListCtrl *  tree,
const wxTreeListItem &  item 
)
static

Definition at line 564 of file pns_log_viewer.cpp.

565 {
566  tree->Freeze();
567  // expand this item first, this might result in its children being added on
568  // the fly
569  if ( item != tree->GetRootItem() )
570  tree->Expand(item);
571  //else: expanding hidden root item is unsupported and unnecessary
572 
573  // then (recursively) expand all the children
574  for ( auto idCurr = tree->GetFirstChild(item);
575  idCurr.IsOk();
576  idCurr = tree->GetNextSibling(item) )
577  {
578  expandAllChildren(tree, idCurr);
579  }
580  tree->Thaw();
581 }
static void expandAllChildren(wxTreeListCtrl *tree, const wxTreeListItem &item)

◆ extractAllDiffPairs()

void extractAllDiffPairs ( BOARD aBoard)

Definition at line 1059 of file pns_log_viewer.cpp.

1060 {
1061  std::map<int, int> diffPairs;
1062 
1063  // FIXMe: GetNetInfo copies f***ing pointers...
1064  const auto& netinfo = aBoard->GetNetInfo();
1065 
1066  int n_nets = netinfo.GetNetCount();
1067 
1068  for (int net = 0 ; net < n_nets; net++ )
1069  {
1070  int coupled = dpCoupledNet(aBoard, net );
1071 
1072  if( coupled > 0 && diffPairs.find( coupled ) == diffPairs.end() )
1073  {
1074  diffPairs[net] = coupled;
1075  }
1076  }
1077 
1078  for( auto p : diffPairs )
1079  {
1080  printf("Extract DP: %s/%s\n", (const char*) aBoard->FindNet( p.first )->GetNetname(),
1081  (const char*) aBoard->FindNet( p.second )->GetNetname() );
1082 
1083  extractDiffPair ( aBoard, p.first, p.second );
1084  }
1085 }
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition: board.cpp:1289
const NETINFO_LIST & GetNetInfo() const
Definition: board.h:754
void extractDiffPair(BOARD *aBoard, int net_p, int net_n)
const wxString & GetNetname() const
Definition: netinfo.h:119
static int dpCoupledNet(BOARD *aBoard, int aNet)
unsigned GetNetCount() const
Definition: netinfo.h:339

References dpCoupledNet(), extractDiffPair(), BOARD::FindNet(), NETINFO_LIST::GetNetCount(), BOARD::GetNetInfo(), and NETINFO_ITEM::GetNetname().

◆ extractDiffPair()

void extractDiffPair ( BOARD aBoard,
int  net_p,
int  net_n 
)

Definition at line 931 of file pns_log_viewer.cpp.

932 {
933  std::set<TRACK*> pendingItems, complementItems;
934 
935  struct DP_COUPLED_SEGMENTS
936  {
937  TRACK* itemP, *itemN;
938  };
939 
940  for( auto trk: aBoard->Tracks() )
941  {
942  if( trk->Type() == PCB_TRACE_T || trk->Type() == PCB_ARC_T )
943  {
944  if( trk->GetNetCode() == net_p )
945  pendingItems.insert( trk );
946  else if( trk->GetNetCode() == net_n )
947  complementItems.insert( trk );
948  }
949  }
950 
951  while( pendingItems.size() )
952  {
953  auto li = *pendingItems.begin();
954  pendingItems.erase( li );
955  auto sp = dyn_cast<TRACK*>(li);
956 
957  if(!sp)
958  continue;
959 
960  for ( auto ci : complementItems )
961  {
962  auto sn = dyn_cast<TRACK*> ( ci );
963 
964  if( ( sn->GetLayerSet() & sp->GetLayerSet() ).none() )
965  continue;
966 
967  SEG ssp ( sp->GetStart(), sp->GetEnd() );
968  SEG ssn ( sn->GetStart(), sn->GetEnd() );
969 
970  if( ssp.ApproxParallel(ssn) )
971  {
972  SEG ca, cb;
973  bool coupled = commonParallelProjection( ssp, ssn, ca, cb );
974 
975  }
976  }
977  }
978 
979 }
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:97
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:95
Definition: seg.h:41
static bool commonParallelProjection(SEG p, SEG n, SEG &pClip, SEG &nClip)
TRACKS & Tracks()
Definition: board.h:302
Definition: track.h:83

References PNS::commonParallelProjection(), PCB_ARC_T, PCB_TRACE_T, and BOARD::Tracks().

Referenced by extractAllDiffPairs().

◆ findClosestKey()

template<typename T1 , typename T2 >
std::map<T1, T2>::iterator findClosestKey ( std::map< T1, T2 > &  data,
T1  key 
)

Definition at line 907 of file pns_log_viewer.cpp.

908 {
909  if (data.size() == 0) {
910  return data.end();
911  }
912 
913  auto lower = data.lower_bound(key);
914 
915  if (lower == data.end()) // If none found, return the last one.
916  return std::prev(lower);
917 
918  if (lower == data.begin())
919  return lower;
920 
921  // Check which one is closest.
922  auto previous = std::prev(lower);
923  if ((key - previous->first) < (lower->first - key))
924  return previous;
925 
926  return lower;
927 }

◆ loadBoard()

static BOARD* loadBoard ( const std::string &  filename)
static

Definition at line 289 of file pns_log_viewer.cpp.

290 {
291  PLUGIN::RELEASER pi( new PCB_IO );
292  BOARD* brd = nullptr;
293 
294  try
295  {
296  brd = pi->Load( wxString( filename.c_str() ), NULL, NULL );
297  }
298  catch( const IO_ERROR& ioe )
299  {
300  wxString msg = wxString::Format( _( "Error loading board.\n%s" ),
301  ioe.Problem() );
302 
303  printf( "Board Loading Error: '%s'\n", (const char*) msg.mb_str() );
304  return nullptr;
305  }
306 
307  return brd;
308 }
A PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
virtual const wxString Problem() const
what was the problem?
Definition: exceptions.cpp:45
Releases a PLUGIN in the context of a potential thrown exception through its destructor.
Definition: io_mgr.h:550
#define NULL
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
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
#define _(s)
Definition: 3d_actions.cpp:33
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:75

References _, Format(), NULL, and IO_ERROR::Problem().

◆ matchDpSuffix()

static int matchDpSuffix ( const wxString &  aNetName,
wxString &  aComplementNet,
wxString &  aBaseDpName 
)
static

Definition at line 981 of file pns_log_viewer.cpp.

983 {
984  int rv = 0;
985 
986  if( aNetName.EndsWith( "+" ) )
987  {
988  aComplementNet = "-";
989  rv = 1;
990  }
991  else if( aNetName.EndsWith( "P" ) )
992  {
993  aComplementNet = "N";
994  rv = 1;
995  }
996  else if( aNetName.EndsWith( "-" ) )
997  {
998  aComplementNet = "+";
999  rv = -1;
1000  }
1001  else if( aNetName.EndsWith( "N" ) )
1002  {
1003  aComplementNet = "P";
1004  rv = -1;
1005  }
1006  // Match P followed by 2 digits
1007  else if( aNetName.Right( 2 ).IsNumber() && aNetName.Right( 3 ).Left( 1 ) == "P" )
1008  {
1009  aComplementNet = "N" + aNetName.Right( 2 );
1010  rv = 1;
1011  }
1012  // Match P followed by 1 digit
1013  else if( aNetName.Right( 1 ).IsNumber() && aNetName.Right( 2 ).Left( 1 ) == "P" )
1014  {
1015  aComplementNet = "N" + aNetName.Right( 1 );
1016  rv = 1;
1017  }
1018  // Match N followed by 2 digits
1019  else if( aNetName.Right( 2 ).IsNumber() && aNetName.Right( 3 ).Left( 1 ) == "N" )
1020  {
1021  aComplementNet = "P" + aNetName.Right( 2 );
1022  rv = -1;
1023  }
1024  // Match N followed by 1 digit
1025  else if( aNetName.Right( 1 ).IsNumber() && aNetName.Right( 2 ).Left( 1 ) == "N" )
1026  {
1027  aComplementNet = "P" + aNetName.Right( 1 );
1028  rv = -1;
1029  }
1030  if( rv != 0 )
1031  {
1032  aBaseDpName = aNetName.Left( aNetName.Length() - aComplementNet.Length() );
1033  aComplementNet = aBaseDpName + aComplementNet;
1034  }
1035 
1036  return rv;
1037 }

Referenced by dpCoupledNet().

◆ replay_main_func()

int replay_main_func ( int  argc,
char *  argv[] 
)

Definition at line 864 of file pns_log_viewer.cpp.

865 {
866  auto frame = new PNS_LOG_VIEWER_FRAME(nullptr);
867 
868  // drcCreateTestsProviderClearance();
869 // drcCreateTestsProviderEdgeClearance();
870 
871 
872  if( argc >= 2 && std::string(argv[1]) == "-h")
873  {
874  printf("PNS Log (Re)player. Allows to step through the log written by the ROUTER_TOOL in debug Kicad builds. ");
875  printf("Requires a board file with UUIDs and a matching log file. Both are written to /tmp when you press '0' during routing.");
876  return 0;
877  }
878 
879  if(argc < 3)
880  {
881  printf("Expected parameters: log_file.log board_file.dump\n");
882  return 0;
883  }
884 
885  PNS_LOG_FILE* logFile = new PNS_LOG_FILE;
886  logFile->Load( argv[1], argv[2] );
887 
888  frame->SetLogFile( logFile );
889  //SetTopFrame( frame ); // wxApp gets a face.
890 
891  return 0;
892 }
bool Load(const std::string &logName, const std::string boardName)
Definition: pns_log.cpp:45

References PNS_LOG_FILE::Load().

◆ segmentCrossesHullBoundary()

bool segmentCrossesHullBoundary ( const SHAPE_LINE_CHAIN hull,
const SEG seg 
)

Definition at line 1121 of file pns_log_viewer.cpp.

1122 {
1123  for( int j = 0; j < hull.SegmentCount(); j++ )
1124  {
1125  auto sr = hull.CSegment(j);
1126  }
1127 
1128 
1129 }
int SegmentCount() const
Function SegmentCount()
const SEG CSegment(int aIndex) const
Function CSegment()

References SHAPE_LINE_CHAIN::CSegment(), and SHAPE_LINE_CHAIN::SegmentCount().

◆ test2_main_func()

int test2_main_func ( int  argc,
char *  argv[] 
)

Definition at line 1361 of file pns_log_viewer.cpp.

1362 {
1363  auto frame = new PNS_LOG_VIEWER_FRAME(nullptr);
1364  Pgm().App().SetTopWindow( frame ); // wxApp gets a face.
1365  frame->Show();
1366 
1367  overlay = frame->GetPanel()->DebugOverlay();
1368 
1369 
1370  overlay->SetIsFill(false);
1371  overlay->SetLineWidth(10000);
1372 
1373  // auto hull = SHAPE_LINE_CHAIN( { VECTOR2I( 155977520, 128439216), VECTOR2I( 155639216, 128777520), VECTOR2I( 155160784, 128777520), VECTOR2I( 154822480, 128439216), VECTOR2I( 154822480, 97960784), VECTOR2I( 155160784, 97622480), VECTOR2I( 155639216, 97622480), VECTOR2I( 155977520, 97960784)}, true );
1374  //auto path = SHAPE_LINE_CHAIN( { VECTOR2I( 148981200, 102320000), VECTOR2I( 154822480, 102320000), VECTOR2I( 154822480, 98777520), VECTOR2I( 60977520, 98777520), VECTOR2I( 60977520, 127622480), VECTOR2I( 155639216, 127622480), VECTOR2I( 155977520, 127960784), VECTOR2I( 155977520, 128439216), VECTOR2I( 155639216, 128777520), VECTOR2I( 60160784, 128777520), VECTOR2I( 59822480, 128439216), VECTOR2I( 59822480, 97960784), VECTOR2I( 60160784, 97622480), VECTOR2I( 155639216, 97622480), VECTOR2I( 155977520, 97960784), VECTOR2I( 155977520, 102320000), VECTOR2I( 160208000, 102320000), VECTOR2I( 160462000, 102574000)}, false );
1375 
1376  //auto path = SHAPE_LINE_CHAIN( { VECTOR2I( 112456000, 102726400), VECTOR2I( 112456000, 98560800), VECTOR2I( 112456000, 98827020)}, false );
1377  //auto hull = SHAPE_LINE_CHAIN( { VECTOR2I( 155659720, 97572980), VECTOR2I( 156027020, 97940280), VECTOR2I( 156027020, 98459720), VECTOR2I( 155659720, 98827020), VECTOR2I( 60140280, 98827020), VECTOR2I( 59772980, 98459720), VECTOR2I( 59772980, 97940280), VECTOR2I( 60140280, 97572980)}, true );
1378 
1379  //auto path = SHAPE_LINE_CHAIN( { VECTOR2I( 119364800, 100288000), VECTOR2I( 119364800, 97697200), VECTOR2I( 119364800, 97572980)}, false );
1380  //auto hull = SHAPE_LINE_CHAIN( { VECTOR2I( 155659720, 97572980), VECTOR2I( 156027020, 97940280), VECTOR2I( 156027020, 98459720), VECTOR2I( 155659720, 98827020), VECTOR2I( 60140280, 98827020), VECTOR2I( 59772980, 98459720), VECTOR2I( 59772980, 97940280), VECTOR2I( 60140280, 97572980)}, true );
1381 
1382  //auto path = SHAPE_LINE_CHAIN( { VECTOR2I( 119263200, 101253200), VECTOR2I( 119263200, 98827020), VECTOR2I( 61027020, 98827020), VECTOR2I( 61027020, 127572980), VECTOR2I( 154772980, 127572980), VECTOR2I( 154772980, 97940280), VECTOR2I( 155140280, 97572980), VECTOR2I( 155659720, 97572980), VECTOR2I( 156027020, 97940280), VECTOR2I( 156027020, 128459720), VECTOR2I( 155659720, 128827020), VECTOR2I( 60140280, 128827020), VECTOR2I( 59772980, 128459720), VECTOR2I( 59772980, 97940280), VECTOR2I( 60140280, 97572980), VECTOR2I( 119641420, 97572980), VECTOR2I( 121650800, 95563600)}, false );
1383  //auto hull = SHAPE_LINE_CHAIN( { VECTOR2I( 155659720, 97572980), VECTOR2I( 156027020, 97940280), VECTOR2I( 156027020, 98459720), VECTOR2I( 155659720, 98827020), VECTOR2I( 60140280, 98827020), VECTOR2I( 59772980, 98459720), VECTOR2I( 59772980, 97940280), VECTOR2I( 60140280, 97572980)}, true );
1384 
1385 // auto hull = SHAPE_LINE_CHAIN( { VECTOR2I( 96722489, 117694794), VECTOR2I( 97594794, 116822489), VECTOR2I( 99205206, 116822489), VECTOR2I( 100077511, 117694794), VECTOR2I( 100077511, 119305206), VECTOR2I( 99205206, 120177511), VECTOR2I( 97594794, 120177511), VECTOR2I( 96722489, 119305206)}, true );
1386  // auto path = SHAPE_LINE_CHAIN( { VECTOR2I( 103400000, 118500000), VECTOR2I( 93400000, 118500000)}, false );
1387 
1388  auto hull = SHAPE_LINE_CHAIN( { VECTOR2I( 66280505, 107710033), VECTOR2I( 65914967, 107344495), VECTOR2I( 65914967, 106827549), VECTOR2I( 66280505, 106462011), VECTOR2I( 74810033, 106462009), VECTOR2I( 75175571, 106827547), VECTOR2I( 75175571, 107344493), VECTOR2I( 74810033, 107710031)}, true );
1389  auto path = SHAPE_LINE_CHAIN( { /*VECTOR2I( 143928480, 109445996), VECTOR2I( 111066480, 109445996), VECTOR2I( 106254391, 104633907), VECTOR2I( 105909001, 104633907), VECTOR2I( 105775094, 104500000),*/ VECTOR2I( 76250000, 104500000), VECTOR2I( 74287991, 106462009), VECTOR2I( 66280505, 106462011), VECTOR2I( 66012989, 106462011)}, false );
1390 
1391 
1392  BOX2D bb ( path.BBox().GetPosition(), path.BBox().GetSize() );
1393 
1394  frame->GetPanel()->GetView()->SetViewport(bb);
1395 
1396  PNS::LINE l;
1397  SHAPE_LINE_CHAIN path_pre, path_walk, path_post;
1398  l.SetShape( path );
1399 
1400  auto status = l.Walkaround( hull, path_walk, false );
1401  printf("Stat: %d\n", status );
1402 
1403  //printf("status: %d\n", walkaround2( path, hull, path_pre, path_walk,
1404  // path_post, false ) );
1405 
1406  overlay->SetLineWidth(200000.0);
1407  overlay->SetStrokeColor( BLUE );
1408  //overlay->Polyline( path_pre );
1409  overlay->Polyline( path_walk );
1410  //overlay->Polyline( path_post );
1411 
1412  overlay->SetStrokeColor( WHITE );
1413  overlay->SetLineWidth( 100000.0 );
1414  overlay->Polyline( path );
1415 
1416  overlay->SetStrokeColor( RED );
1417  overlay->Polyline( hull );
1418 
1419 
1420  return 0;
1421 }
bool Walkaround(SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN &aPre, SHAPE_LINE_CHAIN &aWalk, SHAPE_LINE_CHAIN &aPost, bool aCw) const
Calculate a line tightly wrapping a convex hull of an obstacle object (aObstacle).
Represents a track on a PCB, connecting two non-trivial joints (that is, vias, pads,...
Definition: pns_line.h:60
VECTOR2< int > VECTOR2I
Definition: vector2d.h:623
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:106
void SetShape(const SHAPE_LINE_CHAIN &aLine)
Return the shape of the line.
Definition: pns_line.h:126
Definition: color4d.h:59
Definition: color4d.h:48
Definition: color4d.h:56
SHAPE_LINE_CHAIN.
static std::shared_ptr< KIGFX::VIEW_OVERLAY > overlay

References BLUE, overlay, path, Pgm(), RED, PNS::LINE::SetShape(), PNS::LINE::Walkaround(), and WHITE.

◆ walkaround2()

bool walkaround2 ( SHAPE_LINE_CHAIN aLine,
SHAPE_LINE_CHAIN  aObstacle,
SHAPE_LINE_CHAIN aPre,
SHAPE_LINE_CHAIN aWalk,
SHAPE_LINE_CHAIN aPost,
bool  aCw 
)

Definition at line 1131 of file pns_log_viewer.cpp.

1133 {
1134  const SHAPE_LINE_CHAIN& line( aLine );
1135 
1136  if( line.SegmentCount() < 1 )
1137  return false;
1138 
1139  const auto pFirst = line.CPoint(0);
1140  const auto pLast = line.CPoint(-1);
1141 
1142  bool inFirst = aObstacle.PointInside( pFirst ) && !aObstacle.PointOnEdge( pFirst );
1143  bool inLast = aObstacle.PointInside( pLast ) && !aObstacle.PointOnEdge( pLast );
1144 
1145  if( inFirst || inLast )
1146  {
1147  return false;
1148  }
1149 
1150  enum VERTEX_TYPE { INSIDE = 0, OUTSIDE, ON_EDGE };
1151 
1152  struct VERTEX
1153  {
1154  VERTEX_TYPE type;
1155  bool isHull;
1156  VECTOR2I pos;
1157  std::vector<VERTEX*> neighbours;
1158  int indexp, indexh;
1159  bool visited = false;
1160  };
1161 
1163 
1164  line.Intersect( aObstacle, ips );
1165 
1166  SHAPE_LINE_CHAIN pnew(aLine), hnew(aObstacle);
1167 
1168  std::vector<VERTEX> vts;
1169 
1170  auto findVertex = [&]( VECTOR2I pos) -> VERTEX*
1171  {
1172  for(auto& v : vts)
1173  if(v.pos == pos )
1174  return &v;
1175 
1176  return nullptr;
1177  };
1178 
1179  for( auto ip : ips )
1180  {
1181  bool isNewP, isNewH;
1182 
1183  if( pnew.Find( ip.p ) < 0 )
1184  {
1185  pnew.Split(ip.p);
1186  //overlay->SetStrokeColor( YELLOW );
1187  //overlay->Circle( ip.p, 200000 );
1188  }
1189 
1190  if( hnew.Find( ip.p ) < 0 )
1191  {
1192  hnew.Split(ip.p);
1193  //overlay->SetStrokeColor( CYAN );
1194  //overlay->Circle( ip.p, 250000 );
1195  }
1196  }
1197 
1198  if ( !aCw )
1199  hnew = hnew.Reverse();
1200 
1201  for( int i = 0; i < pnew.PointCount(); i++ )
1202  {
1203  auto p = pnew.CPoint(i);
1204  VERTEX v;
1205  v.indexp = i;
1206  v.isHull = false;
1207  v.pos = p;
1208  v.type = hnew.PointInside( p ) && !hnew.PointOnEdge( p ) ? INSIDE : hnew.PointOnEdge( p ) ? ON_EDGE : OUTSIDE;
1209  vts.push_back(v);
1210  overlay->SetStrokeColor( WHITE );
1211  overlay->SetFillColor( WHITE );
1212  overlay->SetGlyphSize( VECTOR2D( 200000, 200000 ));
1213  overlay->BitmapText( wxString::Format("%d", i), v.pos, 0 );
1214  }
1215 
1216  for( int i = 0; i < pnew.PointCount() - 1; i++ )
1217  {
1218  vts[i].neighbours.push_back(&vts[i+1]);
1219  }
1220 
1221  for( int i = 0; i < hnew.PointCount(); i++ )
1222  {
1223  auto hp = hnew.CPoint(i);
1224  bool found = false;
1225  auto vn = findVertex( hp );
1226 
1227  if( vn )
1228  {
1229  vn->isHull = true;
1230  vn->indexh = i;
1231  } else {
1232  VERTEX v;
1233  v.pos = hp;
1234  v.type = ON_EDGE;
1235  v.indexh = i;
1236  v.isHull = true;
1237  vts.push_back( v );
1238  }
1239 
1240  overlay->SetStrokeColor( WHITE );
1241  overlay->SetFillColor( WHITE );
1242  overlay->SetGlyphSize( VECTOR2D( 200000, 200000 ));
1243  // overlay->BitmapText( wxString::Format("%d", i), hp, 0 );
1244  }
1245 
1246 
1247  for( int i = 0; i < hnew.PointCount(); i++ )
1248  {
1249  auto vc = findVertex( hnew.CPoint(i ) );
1250  auto vnext = findVertex( hnew.CPoint(i+1) );
1251 
1252 
1253 
1254  if(vc && vnext)
1255  vc->neighbours.push_back(vnext);
1256  }
1257 
1258  for( auto& v : vts )
1259  {
1260  printf(" ip %d ih %d t %d ishull %d\n", v.indexp, v.indexh, v.type, v.isHull?1:0);
1261  }
1262 
1263 
1264  VERTEX* v = &vts[0];
1265 
1266  SHAPE_LINE_CHAIN out;
1267 
1268  int n = 0;
1269  while (v->indexp != pnew.PointCount() )
1270  {
1271  printf("SCAN ip %d ih %d t %d ishull %d\n", v->indexp, v->indexh, v->type, v->isHull?1:0);
1272 
1273  out.Append( v->pos );
1274  if(v->visited)
1275  break;
1276 
1277  overlay->SetStrokeColor( v->isHull ? RED : WHITE );
1278  overlay->SetFillColor( v->isHull ? RED : WHITE );
1279  overlay->SetGlyphSize( VECTOR2D( 200000, 200000 ));
1280  //overlay->BitmapText( wxString::Format("%d", v->isHull ? v->indexh : v->indexp), v->pos, 0 );
1281 
1282 
1283  v->visited = true;
1284 
1285  if ( (n++) == 2000 ) // sanity check
1286  break;
1287 
1288  for( auto vn : v->neighbours )
1289  {
1290  printf(" ---> next ip %d ih %d t %d ishull %d\n",vn->indexp, vn->indexh, vn->type, vn->isHull?1:0);
1291  }
1292 
1293 
1294  if (v->type == OUTSIDE)
1295  {
1296  out.Append(v->pos);
1297  for( auto vn : v->neighbours )
1298  if( (vn->indexp > v->indexp) && vn->type != INSIDE )
1299  {
1300  v = vn;
1301  break;
1302  }
1303  }
1304  else if (v->type == ON_EDGE)
1305  {
1306  VERTEX* v_next = nullptr;
1307  int best_dist = INT_MAX;
1308 
1309  for( auto vn: v->neighbours)
1310  {
1311  if( vn->type == ON_EDGE && (vn->indexp == (v->indexp + 1) ) )
1312  {
1313  v_next = vn;
1314  break;
1315  }
1316  }
1317 
1318  if( !v_next )
1319  {
1320  for( auto vn: v->neighbours)
1321  {
1322  if( vn->type == OUTSIDE )
1323  {
1324  v_next = vn;
1325  break;
1326  }
1327  }
1328  }
1329 
1330  if( !v_next )
1331  {
1332  for( auto vn: v->neighbours)
1333  {
1334  if ( v->type == ON_EDGE )
1335  {
1336  if( vn->indexh == ( (v->indexh + 1) % hnew.PointCount() ) )
1337  {
1338  v_next = vn;
1339  //printf("E2\n");
1340 
1341 
1342  break;
1343  }
1344  }
1345  }
1346  }
1347 
1348  v = v_next;
1349 
1350 
1351  }
1352  }
1353 
1354  out.Append( v->pos );
1355 
1356  aWalk = out;
1357 
1358  return true;
1359 }
std::vector< INTERSECTION > INTERSECTIONS
bool PointOnEdge(const VECTOR2I &aP, int aAccuracy=0) const
Check if point aP lies on an edge or vertex of the line chain.
static std::pair< bool, SHAPE_POLY_SET::VERTEX_INDEX > findVertex(SHAPE_POLY_SET &aPolySet, const EDIT_POINT &aPoint)
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
VECTOR2< double > VECTOR2D
Definition: vector2d.h:622
bool PointInside(const VECTOR2I &aPt, int aAccuracy=0, bool aUseBBoxCache=false) const
Check if point aP lies inside a polygon (any type) defined by the line chain.
Text appears outside the dimension line (default)
Definition: color4d.h:59
Definition: color4d.h:48
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
SHAPE_LINE_CHAIN.
static std::shared_ptr< KIGFX::VIEW_OVERLAY > overlay

References SHAPE_LINE_CHAIN::Append(), SHAPE_LINE_CHAIN::CPoint(), SHAPE_LINE_CHAIN::Find(), findVertex(), Format(), SHAPE_LINE_CHAIN::Intersect(), OUTSIDE, overlay, SHAPE_LINE_CHAIN::PointCount(), SHAPE_LINE_CHAIN_BASE::PointInside(), SHAPE_LINE_CHAIN_BASE::PointOnEdge(), RED, SHAPE_LINE_CHAIN::Reverse(), SHAPE_LINE_CHAIN::SegmentCount(), SHAPE_LINE_CHAIN::Split(), and WHITE.

Variable Documentation

◆ overlay

◆ registered2

bool registered2
static
Initial value:
"replay",
"PNS Log Player",
} )
static bool Register(const KI_TEST::UTILITY_PROGRAM &aProgInfo)
Register a utility program factory function against an ID string.
int replay_main_func(int argc, char *argv[])

Definition at line 894 of file pns_log_viewer.cpp.

◆ registered4

bool registered4
static
Initial value:
"test2",
"Test2",
} )
static bool Register(const KI_TEST::UTILITY_PROGRAM &aProgInfo)
Register a utility program factory function against an ID string.
int test2_main_func(int argc, char *argv[])

Definition at line 1432 of file pns_log_viewer.cpp.