DRAW_PANEL_GAL: added DebugOverlay() method, creating a temporary overlay for drawing debug graphics

This commit is contained in:
Tomasz Wlostowski 2020-10-06 11:22:07 +02:00
parent 5127d6c772
commit bd27d38d9a
11 changed files with 815 additions and 609 deletions

View File

@ -587,3 +587,25 @@ void EDA_DRAW_PANEL_GAL::onSetCursor( wxSetCursorEvent& event )
{
event.SetCursor( m_currentCursor );
}
std::shared_ptr<KIGFX::VIEW_OVERLAY> EDA_DRAW_PANEL_GAL::DebugOverlay()
{
if( !m_debugOverlay )
{
m_debugOverlay.reset( new KIGFX::VIEW_OVERLAY() );
m_view->Add( m_debugOverlay.get() );
}
return m_debugOverlay;
}
void EDA_DRAW_PANEL_GAL::ClearDebugOverlay()
{
if( m_debugOverlay )
{
m_view->Remove( m_debugOverlay.get() );
m_debugOverlay = nullptr;
}
}

View File

@ -49,6 +49,7 @@ class WX_VIEW_CONTROLS;
class VIEW_CONTROLS;
class PAINTER;
class GAL_DISPLAY_OPTIONS;
class VIEW_OVERLAY;
}
@ -219,6 +220,18 @@ public:
*/
void DoRePaint();
/**
* Creates an overlay for rendering debug graphics.
*/
std::shared_ptr<KIGFX::VIEW_OVERLAY> DebugOverlay();
/**
* Clears the contents of the debug overlay and removes it from the VIEW.
*/
void ClearDebugOverlay();
protected:
virtual void onPaint( wxPaintEvent& WXUNUSED( aEvent ) );
@ -275,6 +288,9 @@ protected:
/// Flag to indicate whether the panel should take focus at certain times (when moused over,
/// and on various mouse/key events)
bool m_stealsFocus;
/// Optional overlay for drawing transient debug objects
std::shared_ptr<KIGFX::VIEW_OVERLAY> m_debugOverlay;
};
#endif

View File

@ -150,6 +150,18 @@ public:
m_seg.B += aVector;
}
const std::string Format() const
{
std::stringstream ss;
ss << "2 0 ";
ss << m_seg.A.x << " " << m_seg.A.y << " ";
ss << m_seg.B.x << " " << m_seg.B.y << " ";
return ss.str();
}
private:
SEG m_seg;
int m_width;

View File

@ -60,6 +60,7 @@ add_subdirectory( drc_proto )
add_subdirectory( common_tools )
add_subdirectory( pcbnew_tools )
# add_subdirectory( pcb_test_window )
#add_subdirectory( libeval_compiler )
add_subdirectory( pns )
# add_subdirectory( gal/gal_pixel_alignment )

View File

@ -25,7 +25,7 @@ find_package(Boost COMPONENTS unit_test_framework REQUIRED)
find_package( wxWidgets 3.0.0 COMPONENTS gl aui adv html core net base xml stc REQUIRED )
add_definitions(-DBOOST_TEST_DYN_LINK -DPCBNEW -DDRC_PROTO)
add_definitions(-DBOOST_TEST_DYN_LINK -DPCBNEW -DDRC_PROTO -DTEST_APP_NO_MAIN)
if( BUILD_GITHUB_PLUGIN )
set( GITHUB_PLUGIN_LIBRARIES github_plugin )
@ -35,6 +35,7 @@ endif()
add_executable( drc_proto
drc_proto_test.cpp
drc_proto.cpp
../../pcbnew/drc/drc_rule.cpp
../../pcbnew/drc/drc_rule_condition.cpp
../../pcbnew/drc/drc_rule_parser.cpp
@ -53,13 +54,16 @@ add_executable( drc_proto
../../pcbnew/drc/drc_test_provider_misc.cpp
../../pcbnew/drc/drc_test_provider_silk_to_mask.cpp
../../pcbnew/drc/drc_test_provider_silk_to_silk.cpp
../../pcbnew/drc/drc_test_provider_matched_length.cpp
../../pcbnew/drc/drc_test_provider_diff_pair_coupling.cpp
../../pcbnew/drc/drc_engine.cpp
../../pcbnew/drc/drc_item.cpp
../qa_utils/mocks.cpp
../pcbnew_utils/board_file_utils.cpp
../qa_utils/test_app_main.cpp
../qa_utils/utility_program.cpp
../qa_utils/stdstream_line_reader.cpp
../../common/base_units.cpp
../../3d-viewer/3d_viewer/3d_viewer_settings.cpp
)
add_dependencies( drc_proto pnsrouter pcbcommon ${PCBNEW_IO_LIBRARIES} ${GITHUB_PLUGIN_LIBRARIES} )
@ -87,31 +91,25 @@ include_directories(
)
target_link_libraries( drc_proto
pnsrouter
common
qa_pcbnew_utils
3d-viewer
connectivity
pcbcommon
bitmaps
pnsrouter
common
pcbcommon
bitmaps
pnsrouter
common
pcbcommon
bitmaps
pnsrouter
common
pcbcommon
bitmaps
gal
common
pcbcommon
gal
qa_utils
dxflib_qcad
tinyspline_lib
nanosvg
idf3
unit_test_utils
${PCBNEW_IO_LIBRARIES}
${GITHUB_PLUGIN_LIBRARIES}
common
pcbcommon
${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY}
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
${wxWidgets_LIBRARIES}
${GITHUB_PLUGIN_LIBRARIES}
${GDI_PLUS_LIBRARIES}
${PYTHON_LIBRARIES}
${Boost_LIBRARIES} # must follow GITHUB
${PCBNEW_EXTRA_LIBS} # -lrt must follow Boost
)

View File

@ -27,233 +27,39 @@
#include <profile.h>
#include <wx/cmdline.h>
#include <property_mgr.h>
#include <pcbnew_utils/board_file_utils.h>
#include <pcbnew/drc/drc_engine.h>
#include <pcbnew/class_board.h>
#include <pcbnew/drc/drc_rule_parser.h>
#include <reporter.h>
#include <widgets/progress_reporter.h>
#include <pgm_base.h>
#include <project.h>
#include <settings/settings_manager.h>
#include <wildcards_and_files_ext.h>
#include "drc_proto.h"
class CONSOLE_LOG
int main( int argc, char** argv )
{
public:
enum COLOR {
RED = 0,
GREEN,
DEFAULT
};
wxInitialize( argc, argv );
CONSOLE_LOG() {};
Pgm().InitPgm();
void PrintProgress( const wxString& aMessage )
{
if( m_lastLineIsProgressBar )
eraseLastLine();
printf("%s", (const char *) aMessage.c_str() );
fflush(stdout);
m_lastLineIsProgressBar = true;
}
void Print( const wxString& aMessage )
{
if( m_lastLineIsProgressBar )
eraseLastLine();
printf("%s", (const char *) aMessage.c_str() );
fflush(stdout);
m_lastLineIsProgressBar = false;
}
void SetColor( COLOR color )
{
std::map<COLOR, wxString> colorMap =
{
{ RED, "\033[0;31m" },
{ GREEN, "\033[0;32m" },
{ DEFAULT, "\033[0;37m" }
};
printf( "%s", (const char*) colorMap[ color ].c_str() );
fflush(stdout);
}
private:
void eraseLastLine()
{
printf("\r\033[K");
fflush(stdout);
}
bool m_lastLineIsProgressBar = false;
std::mutex m_lock;
};
class CONSOLE_PROGRESS_REPORTER : public PROGRESS_REPORTER
{
public:
CONSOLE_PROGRESS_REPORTER( CONSOLE_LOG* log ) :
PROGRESS_REPORTER( 0 ),
m_log( log ) {};
~CONSOLE_PROGRESS_REPORTER() {};
virtual void SetCurrentProgress( double aProgress ) override
{
PROGRESS_REPORTER::SetCurrentProgress( aProgress );
updateUI();
}
private:
virtual bool updateUI() override
{
m_log->SetColor( CONSOLE_LOG::GREEN );
m_log->PrintProgress( wxString::Format( " | %s : %.02f%%", m_rptMessage, (double) m_progress / (double) m_maxProgress * 100.0 ) );
return true;
}
CONSOLE_LOG* m_log;
};
class CONSOLE_MSG_REPORTER : public REPORTER
{
public:
CONSOLE_MSG_REPORTER( CONSOLE_LOG *log ) :
m_log(log)
{};
~CONSOLE_MSG_REPORTER() {};
virtual REPORTER& Report( const wxString& aText, SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) override
{
switch( aSeverity )
{
case RPT_SEVERITY_ERROR:
m_log->SetColor( CONSOLE_LOG::RED );
m_log->Print("ERROR | ");
break;
default:
m_log->SetColor( CONSOLE_LOG::DEFAULT );
m_log->Print(" | ");
}
m_log->SetColor( CONSOLE_LOG::DEFAULT );
m_log->Print( aText + "\n" );
return *this;
}
virtual bool HasMessage() const override
{
return true;
}
private:
CONSOLE_LOG* m_log;
};
class DRC_REPORT
{
public:
struct ENTRY
{
std::shared_ptr<DRC_ITEM> m_item;
MARKER_PCB* m_marker;
};
typedef std::vector<ENTRY> ENTRIES;
DRC_REPORT() {};
~DRC_REPORT();
void AddItem( std::shared_ptr<DRC_ITEM> aItem, MARKER_PCB *aMarker = nullptr )
{
ENTRY ent;
ent.m_item = aItem;
ent.m_marker = aMarker;
m_entries.push_back(ent);
}
const ENTRIES& GetReportEntries() const { return m_entries; };
private:
ENTRIES m_entries;
};
struct PROJECT_CONTEXT {
PROJECT* project;
std::shared_ptr<BOARD> board;
};
SETTINGS_MANAGER g_settingsManager( true );
PROJECT_CONTEXT loadKicadProject( wxString filename )
{
PROJECT_CONTEXT rv;
wxFileName pro( filename );
wxFileName brdName ( filename );
pro.SetExt( ProjectFileExtension );
brdName.SetExt( KiCadPcbFileExtension );
g_settingsManager.LoadProject( pro.GetFullPath() );
rv.project = &g_settingsManager.Prj();
rv.board.reset( KI_TEST::ReadBoardFromFileOrStream( (const char *) brdName.GetFullPath().c_str() ).release() );
rv.board->SetProject( rv.project );
return rv;
}
int main( int argc, char *argv[] )
{
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
propMgr.Rebuild();
if( argc < 2 )
{
printf("usage: %s board_file.kicad_pcb [drc-rules-file]\n", argv[0] );
printf("usage: %s <project-file/board-file> [drc-rules-file]\n", argv[0] );
Pgm().Destroy();
wxUninitialize();
return -1;
}
PROJECT_CONTEXT project = loadKicadProject( argv[1] );
PROJECT_CONTEXT project = loadKicadProject( argv[1], argv[2] ? wxString( argv[2] ) : OPT<wxString>() );
// This causes some glib warnings on GTK3 (http://trac.wxwidgets.org/ticket/18274)
// but without it, Valgrind notices a lot of leaks from WX
runDRCProto( project );
DRC_ENGINE drcEngine( project.board.get(), &project.board->GetDesignSettings() );
Pgm().Destroy();
CONSOLE_LOG consoleLog;
drcEngine.SetLogReporter( new CONSOLE_MSG_REPORTER ( &consoleLog ) );
drcEngine.SetProgressReporter( new CONSOLE_PROGRESS_REPORTER ( &consoleLog ) );
drcEngine.SetViolationHandler(
[&]( const std::shared_ptr<DRC_ITEM>& aItem, wxPoint aPos )
{
// fixme
} );
wxString rulesFilepath;
if( argc > 2 )
rulesFilepath = wxString( argv[2] );
else
rulesFilepath = project.project->AbsolutePath( "drc-rules" );
drcEngine.InitEngine( rulesFilepath );
drcEngine.RunTests();
wxUninitialize();
return 0;
}
}

View File

@ -1,358 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2020 CERN
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-3.0.html
* or you may search the http://www.gnu.org website for the version 3 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef DRC_RTREE_H_
#define DRC_RTREE_H_
#include <eda_rect.h>
#include <class_board_item.h>
#include <set>
#include <vector>
#include <geometry/rtree.h>
#include <vector2d.h>
/**
* DRC_RTREE -
* Implements an R-tree for fast spatial and layer indexing of connectable items.
* Non-owning.
*/
class DRC_RTREE
{
private:
using drc_rtree = RTree<BOARD_ITEM*, int, 2, double>;
public:
DRC_RTREE()
{
for( int layer : LSET::AllLayersMask().Seq() )
m_tree[layer] = new drc_rtree();
m_count = 0;
}
~DRC_RTREE()
{
for( auto tree : m_tree )
delete tree;
}
/**
* Function Insert()
* Inserts an item into the tree. Item's bounding box is taken via its GetBoundingBox() method.
*/
void insert( BOARD_ITEM* aItem )
{
if( ZONE_CONTAINER* zone = dyn_cast<ZONE_CONTAINER*>( aItem ) )
{
for( int layer : zone->GetLayerSet().Seq() )
{
const SHAPE_POLY_SET& polyset = zone->GetFilledPolysList( PCB_LAYER_ID( layer ) );
for( int ii = 0; ii < polyset.TriangulatedPolyCount(); ++ii )
{
const auto poly = polyset.TriangulatedPolygon( ii );
for( int jj = 0; jj < poly->GetTriangleCount(); ++jj )
{
VECTOR2I a;
VECTOR2I b;
VECTOR2I c;
poly->GetTriangle( jj, a, b, c );
const int mmin2[2] = { std::min( a.x, std::min( b.x, c.x ) ),
std::min( a.y, std::min( b.y, c.y ) ) };
const int mmax2[2] = { std::max( a.x, std::max( b.x, c.x ) ),
std::max( a.y, std::max( b.y, c.y ) ) };
m_tree[layer]->Insert( mmin2, mmax2, aItem );
}
}
}
}
else
{
const EDA_RECT& bbox = aItem->GetBoundingBox();
const int mmin[2] = { bbox.GetX(), bbox.GetY() };
const int mmax[2] = { bbox.GetRight(), bbox.GetBottom() };
for( int layer : aItem->GetLayerSet().Seq() )
{
m_tree[layer]->Insert( mmin, mmax, aItem );
}
}
m_count++;
}
/**
* Function Remove()
* Removes an item from the tree. Removal is done by comparing pointers, attempting
* to remove a copy of the item will fail.
*/
bool remove( BOARD_ITEM* aItem )
{
// First, attempt to remove the item using its given BBox
const EDA_RECT& bbox = aItem->GetBoundingBox();
const int mmin[2] = { bbox.GetX(), bbox.GetY() };
const int mmax[2] = { bbox.GetRight(), bbox.GetBottom() };
bool removed = false;
for( auto layer : aItem->GetLayerSet().Seq() )
{
if( ZONE_CONTAINER* zone = dyn_cast<ZONE_CONTAINER*>( aItem ) )
{
// Continue removing the zone elements from the tree until they cannot be found
while( !m_tree[int( layer )]->Remove( mmin, mmax, aItem ) )
;
const int mmin2[2] = { INT_MIN, INT_MIN };
const int mmax2[2] = { INT_MAX, INT_MAX };
// If we are not successful ( true == not found ), then we expand
// the search to the full tree
while( !m_tree[int( layer )]->Remove( mmin2, mmax2, aItem ) )
;
// Loop to the next layer
continue;
}
// The non-zone search expects only a single element in the tree with the same
// pointer aItem
if( m_tree[int( layer )]->Remove( mmin, mmax, aItem ) )
{
// N.B. We must search the whole tree for the pointer to remove
// because the item may have been moved before we have the chance to
// delete it from the tree
const int mmin2[2] = { INT_MIN, INT_MIN };
const int mmax2[2] = { INT_MAX, INT_MAX };
if( m_tree[int( layer )]->Remove( mmin2, mmax2, aItem ) )
continue;
}
removed = true;
}
m_count -= int( removed );
return removed;
}
/**
* Function RemoveAll()
* Removes all items from the RTree
*/
void clear()
{
for( auto tree : m_tree )
tree->RemoveAll();
m_count = 0;
}
/**
* Determine if a given item exists in the tree. Note that this does not search the full tree
* so if the item has been moved, this will return false when it should be true.
*
* @param aItem Item that may potentially exist in the tree
* @param aRobust If true, search the whole tree, not just the bounding box
* @return true if the item definitely exists, false if it does not exist within bbox
*/
bool contains( BOARD_ITEM* aItem, bool aRobust = false )
{
const EDA_RECT& bbox = aItem->GetBoundingBox();
const int mmin[2] = { bbox.GetX(), bbox.GetY() };
const int mmax[2] = { bbox.GetRight(), bbox.GetBottom() };
bool found = false;
auto search = [&found, &aItem]( const BOARD_ITEM* aSearchItem ) {
if( aSearchItem == aItem )
{
found = true;
return false;
}
return true;
};
for( int layer : aItem->GetLayerSet().Seq() )
{
m_tree[layer]->Search( mmin, mmax, search );
if( found )
break;
}
if( !found && aRobust )
{
for( int layer : LSET::AllCuMask().Seq() )
{
// N.B. We must search the whole tree for the pointer to remove
// because the item may have been moved. We do not expand the item
// layer search as this should not change.
const int mmin2[2] = { INT_MIN, INT_MIN };
const int mmax2[2] = { INT_MAX, INT_MAX };
m_tree[layer]->Search( mmin2, mmax2, search );
if( found )
break;
}
}
return found;
}
std::vector<std::pair<int, BOARD_ITEM*>> GetNearest( const wxPoint &aPoint,
PCB_LAYER_ID aLayer,
int aLimit )
{
const int point[2] = { aPoint.x, aPoint.y };
auto result = m_tree[int( aLayer )]->NearestNeighbors( point,
[aLimit]( std::size_t a_count, int a_maxDist ) -> bool
{
return a_count >= aLimit;
},
[]( BOARD_ITEM* aElement) -> bool
{
// Don't remove any elements from the list
return false;
},
[aLayer]( const int* a_point, BOARD_ITEM* a_data ) -> int
{
switch( a_data->Type() )
{
case PCB_TRACE_T:
{
TRACK* track = static_cast<TRACK*>( a_data );
SEG seg( track->GetStart(), track->GetEnd() );
return seg.Distance( VECTOR2I( a_point[0], a_point[1] ) ) -
( track->GetWidth() + 1 ) / 2;
}
case PCB_VIA_T:
{
VIA* via = static_cast<VIA*>( a_data );
return ( VECTOR2I( via->GetPosition() ) -
VECTOR2I( a_point[0], a_point[1] ) ).EuclideanNorm() -
( via->GetWidth() + 1 ) / 2;
}
default:
{
VECTOR2I point( a_point[0], a_point[1] );
int dist = 0;
auto shape = a_data->GetEffectiveShape( aLayer );
// Here we use a hack to get the distance by colliding with a large area
// However, we can't use just MAX_INT because we will overflow the collision calculations
shape->Collide( point, std::numeric_limits<int>::max() / 2, &dist);
return dist;
}
}
return 0;
});
return result;
}
/**
* Returns the number of items in the tree
* @return number of elements in the tree;
*/
size_t size()
{
return m_count;
}
bool empty()
{
return m_count == 0;
}
using iterator = typename drc_rtree::Iterator;
/**
* The DRC_LAYER struct provides a layer-specific auto-range iterator to the RTree. Using
* this struct, one can write lines like:
*
* for( auto item : rtree.OnLayer( In1_Cu ) )
*
* and iterate over only the RTree items that are on In1
*/
struct DRC_LAYER
{
DRC_LAYER( drc_rtree* aTree ) : layer_tree( aTree )
{
m_rect = { { INT_MIN, INT_MIN }, { INT_MAX, INT_MAX } };
};
DRC_LAYER( drc_rtree* aTree, const EDA_RECT aRect ) : layer_tree( aTree )
{
m_rect = { { aRect.GetX(), aRect.GetY() },
{ aRect.GetRight(), aRect.GetBottom() } };
};
drc_rtree::Rect m_rect;
drc_rtree* layer_tree;
iterator begin()
{
return layer_tree->begin( m_rect );
}
iterator end()
{
return layer_tree->end( m_rect );
}
};
DRC_LAYER OnLayer( PCB_LAYER_ID aLayer )
{
return DRC_LAYER( m_tree[int( aLayer )] );
}
DRC_LAYER Overlapping( PCB_LAYER_ID aLayer, const wxPoint& aPoint, int aAccuracy = 0 )
{
EDA_RECT rect( aPoint, wxSize( 0, 0 ) );
rect.Inflate( aAccuracy );
return DRC_LAYER( m_tree[int( aLayer )], rect );
}
DRC_LAYER Overlapping( PCB_LAYER_ID aLayer, const EDA_RECT& aRect )
{
return DRC_LAYER( m_tree[int( aLayer )], aRect );
}
private:
drc_rtree* m_tree[MAX_CU_LAYERS];
size_t m_count;
};
#endif /* DRC_RTREE_H_ */

View File

@ -24,6 +24,17 @@
#include "eeschema_test_utils.h"
#include <cstdlib>
#include <memory>
#include <eeschema/sch_io_mgr.h>
#include <eeschema/sch_screen.h>
#include <eeschema/schematic.h>
#include <eeschema/connection_graph.h>
#ifndef QA_EESCHEMA_DATA_LOCATION
#define QA_EESCHEMA_DATA_LOCATION "???"
#endif
wxFileName KI_TEST::GetEeschemaTestDataDir()
{
@ -47,3 +58,37 @@ wxFileName KI_TEST::GetEeschemaTestDataDir()
return wxFileName{ fn };
}
std::unique_ptr<SCHEMATIC> ReadSchematicFromFile( const std::string& aFilename )
{
auto pi = SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD );
std::unique_ptr<SCHEMATIC> schematic( new SCHEMATIC ( nullptr ) );
schematic->Reset();
schematic->SetRoot( pi->Load( aFilename, schematic.get() ) );
schematic->CurrentSheet().push_back( &schematic->Root() );
SCH_SCREENS screens( schematic->Root() );
for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
screen->UpdateLocalLibSymbolLinks();
SCH_SHEET_LIST sheets = schematic->GetSheets();
// Restore all of the loaded symbol instances from the root sheet screen.
sheets.UpdateSymbolInstances( schematic->RootScreen()->GetSymbolInstances() );
sheets.AnnotatePowerSymbols();
// NOTE: This is required for multi-unit symbols to be correct
// Normally called from SCH_EDIT_FRAME::FixupJunctions() but could be refactored
for( SCH_SHEET_PATH& sheet : sheets )
sheet.UpdateAllScreenReferences();
// NOTE: SchematicCleanUp is not called; QA schematics must already be clean or else
// SchematicCleanUp must be freed from its UI dependencies.
schematic->ConnectionGraph()->Recalculate( sheets, true );
return schematic;
}

View File

@ -83,7 +83,7 @@ static struct PGM_MOCK_EESCHEMA_FRAME : public PGM_BASE
// Destroy everything in PGM_BASE, especially wxSingleInstanceCheckerImpl
// earlier than wxApp and earlier than static destruction would.
PGM_BASE::Destroy();
//PGM_BASE::Destroy();
}
void MacOpenFile( const wxString& aFileName ) override

View File

@ -19,10 +19,13 @@ bool testEvalExpr( const std::string expr, LIBEVAL::VALUE expectedResult, bool e
PCB_EXPR_UCODE ucode;
bool ok = true;
ucode.SetItems( itemA, itemB );
PCB_EXPR_CONTEXT context, preflightContext;
bool error = !compiler.Compile( expr, &ucode );
context.SetItems( itemA, itemB );
bool error = !compiler.Compile( expr, &ucode, &preflightContext );
if( error )
{
if ( expectError )
@ -40,23 +43,13 @@ bool testEvalExpr( const std::string expr, LIBEVAL::VALUE expectedResult, bool e
if( ok )
{
result = *ucode.Run();
ok = (result == expectedResult);
result = *ucode.Run( &context );
ok = (result.EqualTo( &expectedResult) );
}
return ok;
}
bool EvaluatePCBExpression( const std::string& aExpr, int& aResult )
{
PCB_EXPR_COMPILER compiler;
PCB_EXPR_UCODE ucode;
if( !compiler.Compile( aExpr, &ucode ) )
return false;
auto result = ucode.Run();
return true;
}
int main( int argc, char *argv[] )
{
@ -66,6 +59,8 @@ int main( int argc, char *argv[] )
using VAL = LIBEVAL::VALUE;
/* testEvalExpr( "10mm + 20 mm", VAL(30e6) );
testEvalExpr( "3*(7+8)", VAL(3*(7+8)) );
testEvalExpr( "3*7+8", VAL(3*7+8) );
@ -97,6 +92,10 @@ int main( int argc, char *argv[] )
trackA.SetWidth( Mils2iu( 10 ));
trackB.SetWidth( Mils2iu( 20 ));
testEvalExpr( "A.fromTo('U1', 'U3') && A.NetClass == 'DDR3_A' ", VAL(0),false, &trackA, &trackB );
return 0;
// testEvalExpr( "A.onlayer('F.Cu') || A.onlayer('B.Cu')", VAL( 1.0 ), false, &trackA, &trackB );
testEvalExpr( "A.type == 'Pad' && B.type == 'Pad' && (A.existsOnLayer('F.Cu'))", VAL( 0.0 ), false, &trackA, &trackB );
return 0;

View File

@ -41,6 +41,10 @@
#include <dialog_find.h>
#include <dialog_filter_selection.h>
FP_LIB_TABLE GFootprintTable;
#if 0
static struct IFACE : public KIFACE_I
{
@ -133,9 +137,9 @@ KIFACE_I& Kiface()
{
return kiface;
}
#endif
FP_LIB_TABLE GFootprintTable;
// FP_LIB_TABLE GFootprintTable;
DIALOG_FIND::DIALOG_FIND( PCB_BASE_FRAME* aParent ) : DIALOG_FIND_BASE( aParent )
{
@ -254,3 +258,664 @@ void ROUTER_TOOL::NeighboringSegmentFilter( const VECTOR2I&, GENERAL_COLLECTOR&
{
}
static const int viewer3dSchemaVersion = 0;
#include "3d_viewer/3d_viewer_settings.h"
EDA_3D_VIEWER_SETTINGS::EDA_3D_VIEWER_SETTINGS()
: APP_SETTINGS_BASE( "3d_viewer", viewer3dSchemaVersion ),
m_Render(),
m_Camera()
{
}
bool EDA_3D_VIEWER_SETTINGS::MigrateFromLegacy( wxConfigBase* aCfg )
{
return false;
}
#include "3d_viewer/eda_3d_viewer.h"
#include <3d_viewer/3d_viewer_settings.h>
#include <3d-viewer/3d_viewer_id.h>
/**
* Flag to enable 3D viewer main frame window debug tracing.
*
* Use "KI_TRACE_EDA_3D_VIEWER" to enable.
*
* @ingroup trace_env_vars
*/
const wxChar * EDA_3D_VIEWER::m_logTrace = wxT( "KI_TRACE_EDA_3D_VIEWER" );
BEGIN_EVENT_TABLE( EDA_3D_VIEWER, EDA_BASE_FRAME )
EVT_ACTIVATE( EDA_3D_VIEWER::OnActivate )
EVT_SET_FOCUS( EDA_3D_VIEWER::OnSetFocus )
EVT_TOOL_RANGE( ID_START_COMMAND_3D, ID_MENU_COMMAND_END,
EDA_3D_VIEWER::Process_Special_Functions )
EVT_TOOL( ID_TOOL_SET_VISIBLE_ITEMS, EDA_3D_VIEWER::Install3DViewOptionDialog )
EVT_MENU( wxID_CLOSE, EDA_3D_VIEWER::Exit3DFrame )
EVT_MENU( ID_RENDER_CURRENT_VIEW, EDA_3D_VIEWER::OnRenderEngineSelection )
EVT_MENU( ID_DISABLE_RAY_TRACING, EDA_3D_VIEWER::OnDisableRayTracing )
EVT_CLOSE( EDA_3D_VIEWER::OnCloseWindow )
END_EVENT_TABLE()
EDA_3D_VIEWER::EDA_3D_VIEWER( KIWAY *aKiway, PCB_BASE_FRAME *aParent, const wxString &aTitle,
long style ) :
KIWAY_PLAYER( aKiway, aParent, FRAME_PCB_DISPLAY3D, aTitle, wxDefaultPosition,
wxDefaultSize, style, QUALIFIED_VIEWER3D_FRAMENAME( aParent ) ),
m_mainToolBar( nullptr ),
m_canvas( nullptr ),
m_currentCamera( m_trackBallCamera ),
m_trackBallCamera( RANGE_SCALE_3D )
{
}
EDA_3D_VIEWER::~EDA_3D_VIEWER()
{
}
void EDA_3D_VIEWER::setupUIConditions()
{
}
void EDA_3D_VIEWER::ReloadRequest()
{
}
void EDA_3D_VIEWER::NewDisplay( bool aForceImmediateRedraw )
{
}
void EDA_3D_VIEWER::Exit3DFrame( wxCommandEvent &event )
{
}
void EDA_3D_VIEWER::OnCloseWindow( wxCloseEvent &event )
{
}
void EDA_3D_VIEWER::Process_Special_Functions( wxCommandEvent &event )
{
}
void EDA_3D_VIEWER::OnRenderEngineSelection( wxCommandEvent &event )
{
}
void EDA_3D_VIEWER::OnDisableRayTracing( wxCommandEvent& aEvent )
{
}
void EDA_3D_VIEWER::OnActivate( wxActivateEvent &event )
{
}
void EDA_3D_VIEWER::OnSetFocus(wxFocusEvent &event)
{
}
void EDA_3D_VIEWER::LoadSettings( APP_SETTINGS_BASE *aCfg )
{
}
void EDA_3D_VIEWER::SaveSettings( APP_SETTINGS_BASE *aCfg )
{
}
void EDA_3D_VIEWER::SynchroniseColoursWithBoard()
{
}
void EDA_3D_VIEWER::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
{
}
void EDA_3D_VIEWER::takeScreenshot( wxCommandEvent& event )
{
}
void EDA_3D_VIEWER::RenderEngineChanged()
{
}
bool EDA_3D_VIEWER::Set3DColorFromUser( SFVEC4F &aColor, const wxString& aTitle,
CUSTOM_COLORS_LIST* aPredefinedColors,
bool aAllowOpacityControl,
KIGFX::COLOR4D aDefaultColor )
{
return true;
}
bool EDA_3D_VIEWER::Set3DSilkScreenColorFromUser()
{
return false;
}
bool EDA_3D_VIEWER::Set3DSolderMaskColorFromUser()
{
return false;
}
void EDA_3D_VIEWER::Redraw(){};
bool EDA_3D_VIEWER::Set3DCopperColorFromUser(){ return false; }
bool EDA_3D_VIEWER::Set3DBoardBodyColorFromUser() { return false; }
bool EDA_3D_VIEWER::Set3DSolderPasteColorFromUser() { return false; }
void EDA_3D_VIEWER::loadCommonSettings() { }
void EDA_3D_VIEWER::Install3DViewOptionDialog( wxCommandEvent& event ) { };
#include <tools/selection_tool.h>
/**
* Private implementation of firewalled private data
*/
class SELECTION_TOOL::PRIV
{
public:
DIALOG_FILTER_SELECTION::OPTIONS m_filterOpts;
};
SELECTION_TOOL::SELECTION_TOOL() :
PCB_TOOL_BASE( "pcbnew.InteractiveSelection" ),
m_frame( NULL ),
m_additive( false ),
m_subtractive( false ),
m_exclusive_or( false ),
m_multiple( false ),
m_skip_heuristics( false ),
m_locked( true ),
m_enteredGroup( NULL ),
m_priv( nullptr )
{
}
SELECTION_TOOL::~SELECTION_TOOL()
{
}
bool SELECTION_TOOL::Init()
{
return true;
}
void SELECTION_TOOL::Reset( RESET_REASON aReason )
{
}
int SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
{
return 0;
}
void SELECTION_TOOL::EnterGroup()
{
}
void SELECTION_TOOL::ExitGroup( bool aSelectGroup )
{
}
PCBNEW_SELECTION& SELECTION_TOOL::GetSelection()
{
return m_selection;
}
PCBNEW_SELECTION& SELECTION_TOOL::RequestSelection( CLIENT_SELECTION_FILTER aClientFilter,
std::vector<BOARD_ITEM*>* aFiltered,
bool aConfirmLockedItems )
{
return m_selection;
}
const GENERAL_COLLECTORS_GUIDE SELECTION_TOOL::getCollectorsGuide() const
{
}
bool SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag,
bool* aSelectionCancelledFlag,
CLIENT_SELECTION_FILTER aClientFilter )
{
return false;
}
bool SELECTION_TOOL::selectCursor( bool aForceSelect, CLIENT_SELECTION_FILTER aClientFilter )
{
return false;
}
bool SELECTION_TOOL::selectMultiple()
{
return false;
}
SELECTION_LOCK_FLAGS SELECTION_TOOL::CheckLock()
{
return SELECTION_UNLOCKED;
}
int SELECTION_TOOL::CursorSelection( const TOOL_EVENT& aEvent )
{
return 0;
}
int SELECTION_TOOL::ClearSelection( const TOOL_EVENT& aEvent )
{
return 0;
}
int SELECTION_TOOL::SelectItems( const TOOL_EVENT& aEvent )
{
return 0;
}
int SELECTION_TOOL::SelectItem( const TOOL_EVENT& aEvent )
{
return 0;
}
int SELECTION_TOOL::SelectAll( const TOOL_EVENT& aEvent )
{
return 0;
}
void SELECTION_TOOL::AddItemToSel( BOARD_ITEM* aItem, bool aQuietMode )
{
}
int SELECTION_TOOL::UnselectItems( const TOOL_EVENT& aEvent )
{
return 0;
}
int SELECTION_TOOL::UnselectItem( const TOOL_EVENT& aEvent )
{
return 0;
}
void SELECTION_TOOL::RemoveItemFromSel( BOARD_ITEM* aItem, bool aQuietMode )
{
}
void SELECTION_TOOL::BrightenItem( BOARD_ITEM* aItem )
{
}
void SELECTION_TOOL::UnbrightenItem( BOARD_ITEM* aItem )
{
}
int SELECTION_TOOL::expandConnection( const TOOL_EVENT& aEvent )
{
return 0;
}
void SELECTION_TOOL::selectConnectedTracks( BOARD_CONNECTED_ITEM& aStartItem,
STOP_CONDITION aStopCondition )
{
}
void SELECTION_TOOL::selectAllItemsOnNet( int aNetCode, bool aSelect )
{
}
int SELECTION_TOOL::selectNet( const TOOL_EVENT& aEvent )
{
return 0;
}
void SELECTION_TOOL::selectAllItemsOnSheet( wxString& aSheetPath )
{
}
void SELECTION_TOOL::zoomFitSelection()
{
}
int SELECTION_TOOL::selectSheetContents( const TOOL_EVENT& aEvent )
{
return 0;
}
int SELECTION_TOOL::selectSameSheet( const TOOL_EVENT& aEvent )
{
return 0;
}
void SELECTION_TOOL::findCallback( BOARD_ITEM* aItem )
{
}
int SELECTION_TOOL::find( const TOOL_EVENT& aEvent )
{
return 0;
}
/**
* Function itemIsIncludedByFilter()
*
* Determine if an item is included by the filter specified
*
* @return true if aItem should be selected by this filter (i..e not filtered out)
*/
static bool itemIsIncludedByFilter( const BOARD_ITEM& aItem, const BOARD& aBoard,
const DIALOG_FILTER_SELECTION::OPTIONS& aFilterOptions )
{
return false;
}
int SELECTION_TOOL::filterSelection( const TOOL_EVENT& aEvent )
{
return 0;
}
void SELECTION_TOOL::filterCollectedItems( GENERAL_COLLECTOR& aCollector )
{
}
bool SELECTION_TOOL::itemPassesFilter( BOARD_ITEM* aItem )
{
return true;
}
void SELECTION_TOOL::ClearSelection( bool aQuietMode )
{
}
void SELECTION_TOOL::RebuildSelection()
{
}
int SELECTION_TOOL::SelectionMenu( const TOOL_EVENT& aEvent )
{
return 0;
}
bool SELECTION_TOOL::doSelectionMenu( GENERAL_COLLECTOR* aCollector, const wxString& aTitle )
{
return false;
}
BOARD_ITEM* SELECTION_TOOL::pickSmallestComponent( GENERAL_COLLECTOR* aCollector )
{
return nullptr;
}
bool SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibilityOnly ) const
{
return false;
}
void SELECTION_TOOL::select( BOARD_ITEM* aItem )
{
}
void SELECTION_TOOL::unselect( BOARD_ITEM* aItem )
{
}
void SELECTION_TOOL::highlight( BOARD_ITEM* aItem, int aMode, PCBNEW_SELECTION* aGroup )
{
}
void SELECTION_TOOL::highlightInternal( BOARD_ITEM* aItem, int aMode, PCBNEW_SELECTION* aGroup, bool isChild )
{
}
void SELECTION_TOOL::unhighlight( BOARD_ITEM* aItem, int aMode, PCBNEW_SELECTION* aGroup )
{
}
void SELECTION_TOOL::unhighlightInternal( BOARD_ITEM* aItem, int aMode, PCBNEW_SELECTION* aGroup, bool isChild )
{
}
bool SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const
{
return false;
}
void SELECTION_TOOL::GuessSelectionCandidates( GENERAL_COLLECTOR& aCollector,
const VECTOR2I& aWhere ) const
{
}
void SELECTION_TOOL::FilterCollectorForGroups( GENERAL_COLLECTOR& aCollector ) const
{
}
int SELECTION_TOOL::updateSelection( const TOOL_EVENT& aEvent )
{
return 0;
}
int SELECTION_TOOL::UpdateMenu( const TOOL_EVENT& aEvent )
{
return 0;
}
void SELECTION_TOOL::setTransitions()
{}
void PCB_TOOL_BASE::doInteractiveItemPlacement( const std::string& aTool,
INTERACTIVE_PLACER_BASE* aPlacer,
const wxString& aCommitMessage, int aOptions )
{
}
bool PCB_TOOL_BASE::Init()
{
return true;
}
void PCB_TOOL_BASE::Reset( RESET_REASON aReason )
{
}
void PCB_TOOL_BASE::setTransitions()
{
}
const PCB_DISPLAY_OPTIONS& PCB_TOOL_BASE::displayOptions() const
{
}
PCB_DRAW_PANEL_GAL* PCB_TOOL_BASE::canvas() const
{
return nullptr;
}
const PCBNEW_SELECTION& PCB_TOOL_BASE::selection() const
{
}
PCBNEW_SELECTION& PCB_TOOL_BASE::selection()
{
}
EDA_ITEM* PCBNEW_SELECTION::GetTopLeftItem( bool onlyModules ) const
{
return nullptr;
}
const KIGFX::VIEW_GROUP::ITEMS PCBNEW_SELECTION::updateDrawList() const
{
std::vector<VIEW_ITEM*> items;
return items;
}
const LSET PCBNEW_SELECTION::GetSelectionLayers()
{
return LSET();
}