From 9ebe983eaa3767bd3fe3e2f3c81a9178e352681f Mon Sep 17 00:00:00 2001 From: Miguel Angel Ajo <miguelangel@nbee.es> Date: Mon, 19 Mar 2012 12:21:29 +0100 Subject: [PATCH] * cleanups: board.i board_item.i separated from pcbnew.i * dlist.i empty list fixed (Segfault) * units.i: FromMM FromMils ToMM ToMils * added a little example (listPcb.py) that shows most items in a board --- pcbnew/scripting/TODO.txt | 4 + pcbnew/scripting/board.i | 80 +++++++++++++++++ pcbnew/scripting/board_item.i | 86 +++++++++++++++++++ pcbnew/scripting/examples/listPcb.py | 62 ++++++++++++++ pcbnew/scripting/pcbnew.i | 95 +-------------------- pcbnew/scripting/pcbnew_scripting_helpers.h | 1 + pcbnew/scripting/units.i | 58 +++++++++++++ scripting/dlist.i | 42 +++++++++ scripting/kicad.i | 50 +++++------ 9 files changed, 357 insertions(+), 121 deletions(-) create mode 100644 pcbnew/scripting/TODO.txt create mode 100644 pcbnew/scripting/board.i create mode 100644 pcbnew/scripting/board_item.i create mode 100644 pcbnew/scripting/examples/listPcb.py create mode 100644 pcbnew/scripting/units.i create mode 100644 scripting/dlist.i diff --git a/pcbnew/scripting/TODO.txt b/pcbnew/scripting/TODO.txt new file mode 100644 index 0000000000..525d130cd6 --- /dev/null +++ b/pcbnew/scripting/TODO.txt @@ -0,0 +1,4 @@ + +iterator for NETCLASSES (NETCLASS) see class_netclass.h + + diff --git a/pcbnew/scripting/board.i b/pcbnew/scripting/board.i new file mode 100644 index 0000000000..3d20f10d2f --- /dev/null +++ b/pcbnew/scripting/board.i @@ -0,0 +1,80 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 NBEE Embedded Systems, Miguel Angel Ajo <miguelangel@nbee.es> + * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * + * 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 2 + * 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-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file board.i + * @brief Specific BOARD extensions and templates + */ + + +%extend BOARD +{ + %pythoncode + { + def GetModules(self): return self.m_Modules + def GetDrawings(self): return self.m_Drawings + def GetTracks(self): return self.m_Track + def GetSegZones(self): return self.m_Zone + def GetFullRatsnest(self): return self.m_FullRatsnest + def GetLocalRatsnest(self): return self.m_LocalRatsnest + def GetNetClasses(self): return self.m_NetClasses + def GetCurrentNetClassName(self): return self.m_CurrentNetClassName + def GetViasDimensionsList(self): return self.m_ViasDimensionsList + def GetTrackWidthList(self): return self.m_TrackWidthList + + def Save(self,filename): + return pcbnew.SaveBoard(filename,self) + } + +} + +// this is to help python with the * accessor of DLIST templates + +%rename(Get) operator BOARD_ITEM*; +%rename(Get) operator TRACK*; +%rename(Get) operator D_PAD*; +%rename(Get) operator MODULE*; +%rename(Get) operator SEGZONE*; + +// we must translate C++ templates to scripting languages + +%template(BOARD_ITEM_List) DLIST<BOARD_ITEM>; +%template(MODULE_List) DLIST<MODULE>; +%template(SEGZONE_List) DLIST<SEGZONE>; +%template(TRACK_List) DLIST<TRACK>; +%template(PAD_List) DLIST<D_PAD>; + +// std::vector templates + +%template(VIA_DIMENSION_Vector) std::vector<VIA_DIMENSION>; +%template (RASTNET_Vector) std::vector<RATSNEST_ITEM>; + +%extend DRAWSEGMENT +{ + %pythoncode + { + def GetShapeStr(self): + return self.ShowShape(self.GetShape()) + } +} \ No newline at end of file diff --git a/pcbnew/scripting/board_item.i b/pcbnew/scripting/board_item.i new file mode 100644 index 0000000000..37e3ed1f83 --- /dev/null +++ b/pcbnew/scripting/board_item.i @@ -0,0 +1,86 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 Miguel Angel Ajo <miguelangel@nbee.es> + * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * + * 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 2 + * 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-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file board_item.i + * @brief board_item helpers, mainly for casting down to all child classes + */ + + +/* Cast downs from EDA_ITEM/BOARD_ITEM to childs */ + +%inline +{ + BOARD_ITEM* Cast_to_BOARD_ITEM(EDA_ITEM* base) { return dynamic_cast<BOARD_ITEM*>(base); } +} + +%extend BOARD_ITEM +{ + TEXTE_PCB* Cast_to_TEXTE_PCB() { return dynamic_cast<TEXTE_PCB*>(self); } + DIMENSION* Cast_to_DIMENSION() { return dynamic_cast<DIMENSION*>(self); } + MODULE* Cast_to_MODULE() { return dynamic_cast<MODULE*>(self); } + TEXTE_MODULE* Cast_to_TEXTE_MODULE(){ return dynamic_cast<TEXTE_MODULE*>(self); } + DRAWSEGMENT* Cast_to_DRAWSEGMENT() { return dynamic_cast<DRAWSEGMENT*>(self); } + MARKER_PCB* Cast_to_MARKER_PCB() { return dynamic_cast<MARKER_PCB*>(self); } + BOARD* Cast_to_BOARD() { return dynamic_cast<BOARD*>(self); } + EDGE_MODULE* Cast_to_EDGE_MODULE() { return dynamic_cast<EDGE_MODULE*>(self); } + D_PAD* Cast_to_D_PAD() { return dynamic_cast<D_PAD*>(self); } + TRACK* Cast_to_TRACK() { return dynamic_cast<TRACK*>(self); } + SEGZONE* Cast_to_SEGZONE() { return dynamic_cast<SEGZONE*>(self); } + SEGVIA* Cast_to_SEGVIA() { return dynamic_cast<SEGVIA*>(self); } + + + + %pythoncode + { + def Cast(self): + + ct = self.GetClass() + + if ct=="PTEXT": + return self.Cast_to_TEXTE_PCB() + elif ct=="BOARD": + return self.Cast_to_BOARD() + elif ct=="DIMENSION": + return self.Cast_to_DIMENSION() + elif ct=="DRAWSEGMENT": + return self.Cast_to_DRAWSEGMENT() + elif ct=="MGRAPHIC": + return self.Cast_to_EDGE_MODULE() + elif ct=="MODULE": + return self.Cast_to_MODULE() + elif ct=="PAD": + return self.Cast_to_D_PAD() + elif ct=="MTEXT": + return self.Cast_to_TEXTE_MODULE() + elif ct=="ZONE": + return self.Cast_to_SEGZONE() + elif ct=="VIA": + return self.Cast_to_SEGVIA() + elif ct=="TRACK": + return self.Cast_to_TRACK() + else: + return None + } +} diff --git a/pcbnew/scripting/examples/listPcb.py b/pcbnew/scripting/examples/listPcb.py new file mode 100644 index 0000000000..879622dba4 --- /dev/null +++ b/pcbnew/scripting/examples/listPcb.py @@ -0,0 +1,62 @@ +import sys +from pcbnew import * + +filename=sys.argv[1] + +pcb = LoadBoard(filename) + +#ToUnits = ToMM +#FromUnits = FromMM +ToUnits=ToMils +FromUnits=FromMils + +print "LISTING VIAS:" + +for item in pcb.GetTracks(): + if type(item) is SEGVIA: + + pos = item.GetPosition() + drill = item.GetDrillValue() + width = item.GetWidth() + print " * Via: %s - %f/%f "%(ToUnits(pos),ToUnits(drill),ToUnits(width)) + + elif type(item) is TRACK: + + start = item.GetStart() + end = item.GetEnd() + width = item.GetWidth() + + print " * Track: %s to %s, width %f" % (ToUnits(start),ToUnits(end),ToUnits(width)) + + else: + print "Unknown type %s" % type(item) + +print "" +print "LISTING DRAWINGS:" + +for item in pcb.GetDrawings(): + if type(item) is TEXTE_PCB: + print "* Text: '%s' at %s"%(item.GetText(),item.GetPosition()) + elif type(item) is DRAWSEGMENT: + print "* Drawing: %s"%item.GetShapeStr() # dir(item) + else: + print type(item) + +print "" +print "LIST MODULES:" + +for module in pcb.GetModules(): + print "* Module: %s at %s"%(module.GetReference(),ToUnits(module.GetPosition())) + +print "" +print "LIST ZONES:" + +for zone in pcb.GetSegZones(): + print zone + + +print "" +print "RATSNEST:",len(pcb.GetFullRatsnest()) + +print dir(pcb.GetNetClasses()) + \ No newline at end of file diff --git a/pcbnew/scripting/pcbnew.i b/pcbnew/scripting/pcbnew.i index c74d00fdc6..4d858f7581 100644 --- a/pcbnew/scripting/pcbnew.i +++ b/pcbnew/scripting/pcbnew.i @@ -85,76 +85,7 @@ %include <class_netinfo.h> %include <layers_id_colors_and_visibility.h> - -/* the IO_ERROR exception handler, not working yet... */ -%exception -{ - try { - $function - } - catch (IO_ERROR e) { - PyErr_SetString(PyExc_IOError,"IO error"); - return NULL; - } -} - -/* Cast downs from EDA_ITEM/BOARD_ITEM to childs */ - - -%inline -{ - BOARD_ITEM* Cast_to_BOARD_ITEM(EDA_ITEM* base) { return dynamic_cast<BOARD_ITEM*>(base); } -} - -%extend BOARD_ITEM -{ - TEXTE_PCB* Cast_to_TEXTE_PCB() { return dynamic_cast<TEXTE_PCB*>(self); } - DIMENSION* Cast_to_DIMENSION() { return dynamic_cast<DIMENSION*>(self); } - MODULE* Cast_to_MODULE() { return dynamic_cast<MODULE*>(self); } - TEXTE_MODULE* Cast_to_TEXTE_MODULE(){ return dynamic_cast<TEXTE_MODULE*>(self); } - DRAWSEGMENT* Cast_to_DRAWSEGMENT() { return dynamic_cast<DRAWSEGMENT*>(self); } - MARKER_PCB* Cast_to_MARKER_PCB() { return dynamic_cast<MARKER_PCB*>(self); } - BOARD* Cast_to_BOARD() { return dynamic_cast<BOARD*>(self); } - EDGE_MODULE* Cast_to_EDGE_MODULE() { return dynamic_cast<EDGE_MODULE*>(self); } - D_PAD* Cast_to_D_PAD() { return dynamic_cast<D_PAD*>(self); } - TRACK* Cast_to_TRACK() { return dynamic_cast<TRACK*>(self); } - SEGZONE* Cast_to_SEGZONE() { return dynamic_cast<SEGZONE*>(self); } - SEGVIA* Cast_to_SEGVIA() { return dynamic_cast<SEGVIA*>(self); } - - - - %pythoncode - { - def Cast(self): - ct = self.GetClass() - if ct=="PTEXT": - return self.Cast_to_TEXTE_PCB() - elif ct=="BOARD": - return self.Cast_to_BOARD() - elif ct=="DIMENSION": - return self.Cast_to_DIMENSION() - elif ct=="DRAWSEGMENT": - return self.Cast_to_DRAWSEGMENT() - elif ct=="MGRAPHIC": - return self.Cast_to_EDGE_MODULE() - elif ct=="MODULE": - return self.Cast_to_MODULE() - elif ct=="PAD": - return self.Cast_to_D_PAD() - elif ct=="MTEXT": - return self.Cast_to_TEXTE_MODULE() - elif ct=="ZONE": - return self.Cast_to_SEGZONE() - elif ct=="VIA": - return self.Cast_to_SEGVIA() - elif ct=="TRACK": - return self.Cast_to_TRACK() - else: - return None - } -} - - +%include "board_item.i" %include <pcbnew_scripting_helpers.h> @@ -163,27 +94,7 @@ %include <kicad_plugin.h> #endif -/* this is to help python with the * accessor of DLIST templates */ - -%rename(Get) operator BOARD_ITEM*; -%rename(Get) operator TRACK*; -%rename(Get) operator D_PAD*; -%rename(Get) operator MODULE*; - - -BOARD *GetBoard(); - -// we must translate C++ templates to scripting languages - -%template(BOARD_ITEM_List) DLIST<BOARD_ITEM>; -%template(MODULE_List) DLIST<MODULE>; -%template(TRACK_List) DLIST<TRACK>; -%template(PAD_List) DLIST<D_PAD>; - - - -%template(MARKER_Vector) std::vector<MARKER_PCB*>; -%template(ZONE_CONTAINER_Vector) std::vector<ZONE_CONTAINER*>; -%template(VIA_DIMENSION_Vector) std::vector<VIA_DIMENSION>; +%include "board.i" +%include "units.i" diff --git a/pcbnew/scripting/pcbnew_scripting_helpers.h b/pcbnew/scripting/pcbnew_scripting_helpers.h index 4750f56f46..eca5f62aba 100644 --- a/pcbnew/scripting/pcbnew_scripting_helpers.h +++ b/pcbnew/scripting/pcbnew_scripting_helpers.h @@ -8,6 +8,7 @@ #ifndef SWIG void ScriptingSetPcbEditFrame(PCB_EDIT_FRAME *aPCBEdaFrame); +BOARD *GetBoard(); #endif BOARD* LoadBoard(wxString aFileName); diff --git a/pcbnew/scripting/units.i b/pcbnew/scripting/units.i new file mode 100644 index 0000000000..87b784f5d9 --- /dev/null +++ b/pcbnew/scripting/units.i @@ -0,0 +1,58 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2012 NBEE Embedded Systems, Miguel Angel Ajo <miguelangel@nbee.es> + * Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors. + * + * 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 2 + * 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-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file units.i + * @brief unit conversion code + */ + +// Unit conversion, must be conditionally adapter to the new +// nanometer mode that will be soon included in pcbnew + +%pythoncode +{ + def ToMM(iu): + if type(iu) is int: + return iu * 0.00254 + elif type(iu) is wxPoint: + return tuple(map(ToMM,iu)) + + def FromMM(mm): + if type(iu) is int: + return iu / 0.00254 + elif type(iu) is wxPoint: + return tuple(map(FromMM,iu)) + + def ToMils(iu): + if type(iu) is int: + return iu / 10.0 + elif type(iu) is wxPoint: + return tuple(map(ToMils,iu)) + + def FromMils(mils): + if type(iu) is int: + return mils*10.0 + elif type(iu) is wxPoint: + return tuple(map(FromMils,iu)) +} \ No newline at end of file diff --git a/scripting/dlist.i b/scripting/dlist.i new file mode 100644 index 0000000000..c05c6a237f --- /dev/null +++ b/scripting/dlist.i @@ -0,0 +1,42 @@ +/* DLIST python iteration code, to allow standard iteration over DLIST */ + +%extend DLIST +{ + %pythoncode + { + class DLISTIter: + def __init__(self,aList): + self.last = aList + + def next(self): + + item = self.last + try: + item = item.Get() + except: + pass + + if item is None: + raise StopIteration + else: + ret = None + + # first item in list has "Get" as a DLIST + try: + ret = self.last.Get() + except: + ret = self.last #next items just not.. + + self.last = self.last.Next() + + # when the iterated object can be casted down in inheritance, just do it.. + if 'Cast' in dir(ret): + ret = ret.Cast() + + return ret + + def __iter__(self): + return self.DLISTIter(self) + + } +} diff --git a/scripting/kicad.i b/scripting/kicad.i index b2c9809c69..becaa24027 100644 --- a/scripting/kicad.i +++ b/scripting/kicad.i @@ -60,47 +60,39 @@ using namespace std; #include <class_title_block.h> #include <class_colors_design_settings.h> + #include <class_marker_base.h> %} /* all the wx wrappers for wxString, wxPoint, wxRect, wxChar .. */ %include <wx.i> +/* exception handling */ + +/* the IO_ERROR exception handler, not working yet... */ +%exception +{ + try { + $function + } + catch (IO_ERROR e) { + PyErr_SetString(PyExc_IOError,"IO error"); + return NULL; + } +} + + + %include <dlist.h> %include <base_struct.h> %include <common.h> %include <class_title_block.h> %include <class_colors_design_settings.h> +%include <class_marker_base.h> -%extend DLIST -{ - %pythoncode - { - class DLISTIter: - def __init__(self,aList): - self.last = aList - - def next(self): - if self.last is None: - raise StopIteration - else: - ret = None - - # first item in list has "Get" as a DLIST - try: - ret = self.last.Get() - except: - ret = self.last #next items just not.. - - self.last = self.last.Next() - return ret - - def __iter__(self): - return self.DLISTIter(self) - - } -} +%include "dlist.i" + +/* std template mappings */ %template(intVector) std::vector<int>; -