← Back to team overview

kicad-developers team mailing list archive

[PATCH] expose BOARD_COMMIT to python

 

Back in November I was in a thread about board_commit:
https://lists.launchpad.net/kicad-developers/msg32063.html

The topic had come up in another patch:
https://lists.launchpad.net/kicad-developers/msg32134.html


See attached path file. added needed code to SWIG to enable using
BOARD_COMMIT


As a basic test, I ran the attached commit.py [1] on the attached
commit.kicad_pcb. It just moves some modules and adds some vias. undo seems
to work fine and (perhaps more important) the canvas updates correctly
(there are some bugs in fresh that I haven't figured out)

I have also updated some of my other scripts to use it and almost all seems
well.

*The thing that doesn't work...*

If I run a script as an external plugin, undoing, brings me back to an
empty canvas. I don't know how to debug that. Some guidance could be
helpful. I don't think this is a problem in the python interface, but
rather some multi-threading thing in BOARD_COMMIT itself.

Here's a demo of the problem:
https://youtu.be/YR-9dx_lkUo

place_by_sch described in the video is here:
https://github.com/mmccoo/kicad_mmccoo/blob/master/place_by_sch/place_by_sch.py

The board_commit stuff isn't in that version[2]


Miles


[1] I have a feeling the py file will be filtered, so here it is
toplayer = layertable['F.Cu']
bottomlayer = layertable['B.Cu']

for mod in board.GetModules():
    print("mod {}".format(mod.GetReference()))
    newvia = pcbnew.VIA(board)
    board.Add(newvia)
    newvia.SetNet(gnd)
    nc = gnd.GetNetClass()
    newvia.SetWidth(nc.GetViaDiameter())
    newvia.SetPosition(mod.GetPosition())
    newvia.SetLayerPair(toplayer, bottomlayer)
    newvia.SetViaType(pcbnew.VIA_THROUGH)
    bc.Added(newvia)

    bc.Modify(mod)
    mod.SetPosition(pcbnew.wxPoint(mod.GetPosition().x +
pcbnew.Millimeter2iu(10),
                                   mod.GetPosition().y +
pcbnew.Millimeter2iu(10)))




bc.Push("moved stuff")


[2]
diff --git a/place_by_sch/place_by_sch.py b/place_by_sch/place_by_sch.py
index 22bc21c..5f70354 100644
--- a/place_by_sch/place_by_sch.py
+++ b/place_by_sch/place_by_sch.py
@@ -7,7 +7,9 @@ import re

 def PlaceBySch():
     board = pcbnew.GetBoard()
-
+    print("getting board commit")
+    bc = pcbnew.NewBoardCommit()
+
     board_path = board.GetFileName()
     sch_path = board_path.replace(".kicad_pcb", ".sch")

@@ -114,9 +116,10 @@ def PlaceBySch():
         # oldvalue * 25.4 / 10e4
         newx = locs[ref][0] * 25.4 * 1000.0
         newy = locs[ref][1] * 25.4 * 1000.0
+        bc.Modify(mod)
         mod.SetPosition(pcbnew.wxPoint(int(newx), int(newy)))
         mod.SetOrientation(locs[ref][2]*10)
         print("placing {} at {},{}".format(ref, newx, newy))

-
-    pcbnew.Refresh();
+    bc.Push("place_by_sch")
+    #pcbnew.Refresh();




for my personal reference: this is my sixth patch
From 86c1f376c4bcfaa489a383535f1bceacea83fd6e Mon Sep 17 00:00:00 2001
From: Miles McCoo <mail@xxxxxxxxxx>
Date: Sat, 24 Feb 2018 10:39:44 +0100
Subject: [PATCH] Exposing BOARD_COMMIT to python
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="------------2.7.4"

This is a multi-part message in MIME format.
--------------2.7.4
Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit


This change just adds the necessary includes to the swig .i file to expose BOARD_COMMIT.
In addition to the class API, also need a global function to create a new BOARD_COMMIT object.
---
 pcbnew/CMakeLists.txt                    |  1 +
 pcbnew/swig/board.i                      |  1 +
 pcbnew/swig/board_commit.i               | 39 ++++++++++++++++++++++++++++++++
 pcbnew/swig/pcbnew_scripting_helpers.cpp | 14 ++++++++++++
 pcbnew/swig/pcbnew_scripting_helpers.h   | 10 +++++++-
 5 files changed, 64 insertions(+), 1 deletion(-)
 create mode 100644 pcbnew/swig/board_commit.i


--------------2.7.4
Content-Type: text/x-patch; name="0001-Exposing-BOARD_COMMIT-to-python.patch"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="0001-Exposing-BOARD_COMMIT-to-python.patch"

diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt
index 520dc11..fff5b2c 100644
--- a/pcbnew/CMakeLists.txt
+++ b/pcbnew/CMakeLists.txt
@@ -440,6 +440,7 @@ if( KICAD_SCRIPTING )   # Generate pcbnew.py and pcbnew_wrap.cxx using swig
         DEPENDS exporters/gendrill_Excellon_writer.h
         DEPENDS swig/pcbnew.i
         DEPENDS swig/board.i
+        DEPENDS swig/board_commit.i
         DEPENDS swig/board_connected_item.i
         DEPENDS swig/board_design_settings.i
         DEPENDS swig/board_item.i
diff --git a/pcbnew/swig/board.i b/pcbnew/swig/board.i
index cc337bb..61663d6 100644
--- a/pcbnew/swig/board.i
+++ b/pcbnew/swig/board.i
@@ -44,6 +44,7 @@ HANDLE_EXCEPTIONS(BOARD::TracksInNetBetweenPoints)
 
 //%import dlist.h       // comes in from kicad.i which wraps & includes board.i
 
+%include board_commit.i
 %include board_item.i
 %include board_item_container.i
 %include board_connected_item.i
diff --git a/pcbnew/swig/board_commit.i b/pcbnew/swig/board_commit.i
new file mode 100644
index 0000000..59ed42d
--- /dev/null
+++ b/pcbnew/swig/board_commit.i
@@ -0,0 +1,39 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2018 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
+ */
+
+// it's important to have commit.h before board_commit.h. Otherwise
+// BOARD_COMMIT pointers won't have COMMIT methods available.
+// swig does not automatically recurse includes
+// from http://www.swig.org/Doc1.3/Preprocessor.html
+//    By default, the #include is ignored unless you run SWIG with the
+//    -includeall option. The reason for ignoring traditional includes
+//    is that you often don't want SWIG to try and wrap everything included
+//    in standard header system headers and auxiliary files.
+%include commit.h
+%include board_commit.h
+
+
+%{
+#include <commit.h>
+#include <board_commit.h>
+%}
diff --git a/pcbnew/swig/pcbnew_scripting_helpers.cpp b/pcbnew/swig/pcbnew_scripting_helpers.cpp
index 3dbedc3..af49f88 100644
--- a/pcbnew/swig/pcbnew_scripting_helpers.cpp
+++ b/pcbnew/swig/pcbnew_scripting_helpers.cpp
@@ -40,6 +40,7 @@
 #include <macros.h>
 #include <stdlib.h>
 #include <pcb_draw_panel_gal.h>
+#include <board_commit.h>
 
 static PCB_EDIT_FRAME* s_PcbEditFrame = NULL;
 
@@ -57,6 +58,10 @@ void ScriptingSetPcbEditFrame( PCB_EDIT_FRAME* aPcbEditFrame )
     s_PcbEditFrame = aPcbEditFrame;
 }
 
+PCB_EDIT_FRAME* GetPcbEditFrame()
+{
+  return s_PcbEditFrame;
+}
 
 BOARD* LoadBoard( wxString& aFileName )
 {
@@ -135,3 +140,12 @@ void UpdateUserInterface()
     if( s_PcbEditFrame )
         s_PcbEditFrame->UpdateUserInterface();
 }
+
+
+BOARD_COMMIT*
+NewBoardCommit()
+{
+    if( s_PcbEditFrame ) {
+        return new BOARD_COMMIT( s_PcbEditFrame );
+    }
+}
diff --git a/pcbnew/swig/pcbnew_scripting_helpers.h b/pcbnew/swig/pcbnew_scripting_helpers.h
index e0a0ae9..fc30748 100644
--- a/pcbnew/swig/pcbnew_scripting_helpers.h
+++ b/pcbnew/swig/pcbnew_scripting_helpers.h
@@ -28,15 +28,18 @@
 #include <pcb_edit_frame.h>
 #include <io_mgr.h>
 
+class BOARD_COMMIT;
+
 /* we could be including all these methods as static in a class, but
  * we want plain pcbnew.<method_name> access from python
  */
 
 #ifndef SWIG
 void    ScriptingSetPcbEditFrame( PCB_EDIT_FRAME* aPCBEdaFrame );
-
 #endif
 
+PCB_EDIT_FRAME* GetPcbEditFrame();
+
 // For Python scripts: return the current board.
 BOARD*  GetBoard();
 
@@ -69,4 +72,9 @@ void    WindowZoom( int xl, int yl, int width, int height );
  */
 void UpdateUserInterface();
 
+/**
+ * Create and return a new BOARD_COMMIT
+ */
+BOARD_COMMIT* NewBoardCommit();
+
 #endif      // __PCBNEW_SCRIPTING_HELPERS_H

--------------2.7.4--




import pcbnew

layertable = {}
numlayers = pcbnew.PCB_LAYER_ID_COUNT
for i in range(numlayers):
    layertable[pcbnew.GetBoard().GetLayerName(i)] = i



bc = pcbnew.NewBoardCommit()


board = pcbnew.GetBoard()


gnd = board.GetNetsByName()['GND']
        
toplayer = layertable['F.Cu']
bottomlayer = layertable['B.Cu']
  
for mod in board.GetModules():
    print("mod {}".format(mod.GetReference()))
    newvia = pcbnew.VIA(board)
    board.Add(newvia)
    newvia.SetNet(gnd)
    nc = gnd.GetNetClass()
    newvia.SetWidth(nc.GetViaDiameter())
    newvia.SetPosition(mod.GetPosition())
    newvia.SetLayerPair(toplayer, bottomlayer)
    newvia.SetViaType(pcbnew.VIA_THROUGH)
    bc.Added(newvia)
    
    bc.Modify(mod)
    mod.SetPosition(pcbnew.wxPoint(mod.GetPosition().x + pcbnew.Millimeter2iu(10),
                                   mod.GetPosition().y + pcbnew.Millimeter2iu(10)))
    
    


bc.Push("moved stuff")


Attachment: commit.kicad_pcb
Description: Binary data


Follow ups