From 3e6d5622e855c7f45570a10de9729190673b80fc Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Fri, 11 Sep 2020 12:55:51 +0200 Subject: [PATCH] Improvement on Python interface of Occurrence, Point & CellViewer. * Bug: In Isobar::PyOccurrence, use "compare by value" instead of "compare by pointer" for the Python comparison function. So we really can compare identical Occurrences. * New: In Isobar::PyPoint, export the "manhattanDistance()" function. * New: In Isobal::PyCellViewer, add the following funtions to the exported interface: - "select()" - "unselect()" - "unselectAll()" - "reframe()" - "setShowSelection()" So now we can easily highlight components from Python (to ease debug). * New: In Hurricane::CellViewer, create a proxy for the CellWidget "reframe()" function. --- hurricane/src/isobar/PyOccurrence.cpp | 23 ++- hurricane/src/isobar/PyPoint.cpp | 76 +++++---- .../isobar/hurricane/isobar/PyOccurrence.h | 6 +- hurricane/src/viewer/CellViewer.cpp | 4 + hurricane/src/viewer/PyCellViewer.cpp | 151 ++++++++++++++---- .../src/viewer/hurricane/viewer/CellViewer.h | 30 ++-- .../viewer/hurricane/viewer/PyCellViewer.h | 7 +- 7 files changed, 199 insertions(+), 98 deletions(-) diff --git a/hurricane/src/isobar/PyOccurrence.cpp b/hurricane/src/isobar/PyOccurrence.cpp index 787ecece..8879b601 100644 --- a/hurricane/src/isobar/PyOccurrence.cpp +++ b/hurricane/src/isobar/PyOccurrence.cpp @@ -243,8 +243,27 @@ extern "C" { - DirectDeleteMethod(PyOccurrence_DeAlloc,PyOccurrence) - PyTypeObjectLinkPyTypeNewInit(Occurrence) + DirectDeleteMethod (PyOccurrence_DeAlloc,PyOccurrence) + DirectReprMethod (PyOccurrence_Repr ,PyOccurrence, Occurrence) + DirectStrMethod (PyOccurrence_Str ,PyOccurrence, Occurrence) + DirectCmpByValueMethod(PyOccurrence_Cmp ,IsPyOccurrence, PyOccurrence) + DirectHashMethod (PyOccurrence_Hash ,Occurrence) + + extern void PyOccurrence_LinkPyType () + { + cdebug_log(20,0) << "PyOccurrence_LinkType()" << endl; + + PyTypeOccurrence.tp_dealloc = (destructor) PyOccurrence_DeAlloc; + PyTypeOccurrence.tp_compare = (cmpfunc) PyOccurrence_Cmp; + PyTypeOccurrence.tp_repr = (reprfunc) PyOccurrence_Repr; + PyTypeOccurrence.tp_str = (reprfunc) PyOccurrence_Str; + PyTypeOccurrence.tp_hash = (hashfunc) PyOccurrence_Hash; + PyTypeOccurrence.tp_new = (newfunc) PyOccurrence_NEW; + PyTypeOccurrence.tp_init = (initproc) PyOccurrence_Init; + PyTypeOccurrence.tp_methods = PyOccurrence_Methods; + } + +//PyTypeObjectLinkPyTypeNewInit(Occurrence) //PyTypeObjectLinkPyType(Occurrence) diff --git a/hurricane/src/isobar/PyPoint.cpp b/hurricane/src/isobar/PyPoint.cpp index 4a0c809d..6c88df9a 100644 --- a/hurricane/src/isobar/PyPoint.cpp +++ b/hurricane/src/isobar/PyPoint.cpp @@ -27,21 +27,18 @@ extern "C" { #define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Point,point,function) -// x=================================================================x +// +=================================================================+ // | "PyPoint" Python Module Code Part | -// x=================================================================x +// +=================================================================+ #if defined(__PYTHON_MODULE__) - // x-------------------------------------------------------------x + // +-------------------------------------------------------------+ // | "PyPoint" Attribute Methods | - // x-------------------------------------------------------------x + // +-------------------------------------------------------------+ - // --------------------------------------------------------------- - // Attribute Method : "PyPoint_NEW ()" - static PyObject* PyPoint_NEW ( PyObject* module, PyObject *args ) { cdebug_log(20,0) << "PyPoint_NEW()" << endl; @@ -86,36 +83,48 @@ extern "C" { } - // --------------------------------------------------------------- - // Attribute Method : "PyPoint_Translate ()" - - static PyObject* PyPoint_Translate ( PyPoint *self, PyObject* args ) + static PyObject* PyPoint_translate ( PyPoint *self, PyObject* args ) { - cdebug_log(20,0) << "PyPoint_Translate()" << endl; - + cdebug_log(20,0) << "PyPoint_translate()" << endl; HTRY - - METHOD_HEAD ( "Box.Translate()" ) - - PyObject* arg0; - PyObject* arg1; - if ( ! ParseTwoArg ( "Box.Translate", args, INTS2_ARG, &arg0, &arg1 ) ) return ( NULL ); - - point->translate ( PyAny_AsLong(arg0), PyAny_AsLong(arg1) ); - + METHOD_HEAD( "Point.translate()" ) + PyObject* arg0; + PyObject* arg1; + if (not ParseTwoArg( "Point.translate", args, INTS2_ARG, &arg0, &arg1 )) return NULL; + point->translate( PyAny_AsLong(arg0), PyAny_AsLong(arg1) ); HCATCH - Py_RETURN_NONE; } + static PyObject* PyPoint_manhattanDistance ( PyPoint *self, PyObject* args ) + { + cdebug_log(20,0) << "PyPoint_manhattanDistance()" << endl; + DbU::Unit distance = 0; + HTRY + METHOD_HEAD ( "Point.manahattanDistance()" ) + PyObject* pyPoint = NULL; + if (not PyArg_ParseTuple(args,"O:Point.manhattanDistance()", &pyPoint)) { + PyErr_SetString ( ConstructorError, "Point.manhattanDistance(): Takes exactly one argument." ); + return NULL; + } + if (not IsPyPoint(pyPoint)) { + PyErr_SetString ( ConstructorError, "Point.manhattanDistance(): Argument is not a Point." ); + return NULL; + } + distance = point->manhattanDistance( *(PYPOINT_O(pyPoint)) ); + HCATCH + return PyDbU_FromLong(distance); + } + + // Standart Accessors (Attributes). DirectGetLongAttribute(PyPoint_getX,getX,PyPoint,Point) DirectGetLongAttribute(PyPoint_getY,getY,PyPoint,Point) - DirectSetLongAttribute(PyPoint_SetX,setX,PyPoint,Point) - DirectSetLongAttribute(PyPoint_SetY,setY,PyPoint,Point) + DirectSetLongAttribute(PyPoint_setX,setX,PyPoint,Point) + DirectSetLongAttribute(PyPoint_setY,setY,PyPoint,Point) // Standart destroy (Attribute). @@ -128,14 +137,15 @@ extern "C" { // PyPoint Attribute Method table. PyMethodDef PyPoint_Methods[] = - { { "getX" , (PyCFunction)PyPoint_getX , METH_NOARGS , "Return the Point X value." } - , { "getY" , (PyCFunction)PyPoint_getY , METH_NOARGS , "Return the Point Y value." } - , { "setX" , (PyCFunction)PyPoint_SetX , METH_VARARGS, "Modify the Point X value." } - , { "setY" , (PyCFunction)PyPoint_SetY , METH_VARARGS, "Modify the Point Y value." } - , { "translate", (PyCFunction)PyPoint_Translate, METH_VARARGS, "Translate the point of dx and dy." } - , { "destroy" , (PyCFunction)PyPoint_destroy , METH_NOARGS - , "Destroy associated hurricane object The python object remains." } - , {NULL, NULL, 0, NULL} /* sentinel */ + { { "getX" , (PyCFunction)PyPoint_getX , METH_NOARGS , "Return the Point X value." } + , { "getY" , (PyCFunction)PyPoint_getY , METH_NOARGS , "Return the Point Y value." } + , { "setX" , (PyCFunction)PyPoint_setX , METH_VARARGS, "Modify the Point X value." } + , { "setY" , (PyCFunction)PyPoint_setY , METH_VARARGS, "Modify the Point Y value." } + , { "translate" , (PyCFunction)PyPoint_translate , METH_VARARGS, "Translate the point of dx and dy." } + , { "manhattanDistance" , (PyCFunction)PyPoint_manhattanDistance, METH_VARARGS, "Compute the Manhattan distance between the two points." } + , { "destroy" , (PyCFunction)PyPoint_destroy , METH_NOARGS + , "Destroy associated hurricane object The python object remains." } + , {NULL, NULL, 0, NULL} /* sentinel */ }; diff --git a/hurricane/src/isobar/hurricane/isobar/PyOccurrence.h b/hurricane/src/isobar/hurricane/isobar/PyOccurrence.h index 8a814a2c..c93e5845 100644 --- a/hurricane/src/isobar/hurricane/isobar/PyOccurrence.h +++ b/hurricane/src/isobar/hurricane/isobar/PyOccurrence.h @@ -14,9 +14,7 @@ // +-----------------------------------------------------------------+ -#ifndef PY_OCCURRENCE_H -#define PY_OCCURRENCE_H - +#pragma once #include "hurricane/isobar/PyHurricane.h" #include "hurricane/Occurrence.h" @@ -51,5 +49,3 @@ namespace Isobar { } // extern "C". } // Isobar namespace. - -#endif // PY_OCCURRENCE_H diff --git a/hurricane/src/viewer/CellViewer.cpp b/hurricane/src/viewer/CellViewer.cpp index 2ebdf8a5..309a9ee3 100644 --- a/hurricane/src/viewer/CellViewer.cpp +++ b/hurricane/src/viewer/CellViewer.cpp @@ -838,6 +838,10 @@ namespace Hurricane { { if ( _cellWidget ) _cellWidget->unselectAll(); } + void CellViewer::reframe ( const Box& area, bool historyEnable ) + { if ( _cellWidget ) _cellWidget->reframe( area, historyEnable ); } + + void CellViewer::printDisplay () { if ( !_cellWidget ) return; diff --git a/hurricane/src/viewer/PyCellViewer.cpp b/hurricane/src/viewer/PyCellViewer.cpp index f5821f06..fa6171a6 100644 --- a/hurricane/src/viewer/PyCellViewer.cpp +++ b/hurricane/src/viewer/PyCellViewer.cpp @@ -14,7 +14,9 @@ // +-----------------------------------------------------------------+ +#include "hurricane/isobar/PyBox.h" #include "hurricane/isobar/PyCell.h" +#include "hurricane/isobar/PyOccurrence.h" #include "hurricane/viewer/PyCellViewer.h" #include "hurricane/viewer/CellWidget.h" @@ -233,15 +235,85 @@ extern "C" { } + static PyObject* PyCellViewer_select ( PyCellViewer* self, PyObject* args ) + { + cdebug_log(20,0) << "PyCellViewer_select()" << endl; + HTRY + METHOD_HEAD("CellViewer.select()") + PyObject* pyOccurrence = NULL; + if (not PyArg_ParseTuple(args,"O:CellViewer.select()", &pyOccurrence)) { + PyErr_SetString ( ConstructorError, "CellViewer.select(): Takes exactly one argument." ); + return NULL; + } + if (not IsPyOccurrence(pyOccurrence)) { + PyErr_SetString ( ConstructorError, "CellViewer.select(): Argument is not an Occurrence." ); + return NULL; + } + cw->select( *(PYOCCURRENCE_O(pyOccurrence)) ); + HCATCH + Py_RETURN_NONE; + } + + + static PyObject* PyCellViewer_unselect ( PyCellViewer* self, PyObject* args ) + { + cdebug_log(20,0) << "PyCellViewer_unselect()" << endl; + HTRY + METHOD_HEAD("CellViewer.unselect()") + PyObject* pyOccurrence = NULL; + if (not PyArg_ParseTuple(args,"O:CellViewer.unselect()", &pyOccurrence)) { + PyErr_SetString ( ConstructorError, "CellViewer.unselect(): Takes exactly one argument." ); + return NULL; + } + if (not IsPyOccurrence(pyOccurrence)) { + PyErr_SetString ( ConstructorError, "CellViewer.unselect(): Argument is not an Occurrence." ); + return NULL; + } + cw->unselect( *(PYOCCURRENCE_O(pyOccurrence)) ); + HCATCH + Py_RETURN_NONE; + } + + + static PyObject* PyCellViewer_unselectAll ( PyCellViewer* self ) + { + cdebug_log(20,0) << "PyCellViewer_unselectAll()" << endl; + HTRY + METHOD_HEAD("CellViewer.unselectAll()") + cw->unselectAll(); + HCATCH + Py_RETURN_NONE; + } + + + static PyObject* PyCellViewer_reframe ( PyCellViewer* self, PyObject* args ) + { + cdebug_log(20,0) << "PyCellViewer_reframe ()" << endl; + HTRY + METHOD_HEAD("CellViewer.reframe()") + PyObject* pyBox = NULL; + PyObject* historyEnable = NULL; + if (not PyArg_ParseTuple(args,"OO:CellViewer.reframe()", &pyBox, &historyEnable)) { + PyErr_SetString ( ConstructorError, "CellViewer.reframe(): Takes exactly two argument." ); + return NULL; + } + if (not IsPyBox(pyBox)) { + PyErr_SetString ( ConstructorError, "CellViewer.reframe(): First argument is not a Box." ); + return NULL; + } + cw->reframe ( *(PYBOX_O(pyBox)), (PyObject_IsTrue(historyEnable) != 0) ); + HCATCH + Py_RETURN_NONE; + } + + static PyObject* PyCellViewer_fit ( PyCellViewer* self ) { cdebug_log(20,0) << "PyCellViewer_fit()" << endl; - HTRY - METHOD_HEAD("CellViewer.fit()") - cw->getCellWidget()->fitToContents(); + METHOD_HEAD("CellViewer.fit()") + cw->getCellWidget()->fitToContents(); HCATCH - Py_RETURN_NONE; } @@ -276,42 +348,53 @@ extern "C" { } - DirectSetBoolAttribute(PyCellViewer_setShowSelection,setShowSelection,PyCellViewer,CellViewer) + DirectSetBoolAttribute(PyCellViewer_setShowSelection ,setShowSelection ,PyCellViewer,CellViewer) + DirectSetBoolAttribute(PyCellViewer_setCumulativeSelection,setCumulativeSelection,PyCellViewer,CellViewer) // --------------------------------------------------------------- // PyCellViewer Attribute Method table. PyMethodDef PyCellViewer_Methods[] = - { { "hasMenu" , (PyCFunction)PyCellViewer_hasMenu , METH_VARARGS - , "Return true if the menu at \"path\" exists." } - , { "hasMenuAction" , (PyCFunction)PyCellViewer_hasMenuAction , METH_VARARGS - , "Return true if the menu action at \"path\" exists." } - , { "addMenu" , (PyCFunction)PyCellViewer_addMenu , METH_VARARGS - , "Create a new menu at \"path\" and returns true if success." } - , { "addToMenu" , (PyCFunction)PyCellViewer_addToMenu , METH_VARARGS - , "Creates a new action at \"path\" and returns true if success." } - , { "getCell" , (PyCFunction)PyCellViewer_getCell , METH_NOARGS - , "Return the currently edited Cell." } - , { "setCell" , (PyCFunction)PyCellViewer_setCell , METH_VARARGS - , "Load a Cell into the viewer." } - , { "setApplicationName" , (PyCFunction)PyCellViewer_setApplicationName , METH_VARARGS - , "Sets the application (binary) name." } - , { "setAnonNetSelectable", (PyCFunction)PyCellViewer_setAnonNetSelectable, METH_VARARGS - , "Allow/disallow anonymous nets to be selectables." } - , { "setLayerVisible" , (PyCFunction)PyCellViewer_setLayerVisible , METH_VARARGS - , "Sets the visibility state of the layer ." } - , { "setShowSelection" , (PyCFunction)PyCellViewer_setShowSelection , METH_VARARGS - , "Display/hide the selection." } - , { "fit" , (PyCFunction)PyCellViewer_fit , METH_NOARGS - , "Triggers a full redraw of the visible area." } - , { "refresh" , (PyCFunction)PyCellViewer_refresh , METH_NOARGS - , "Fit the contents to the viewer's visible area." } - , { "removeHistory" , (PyCFunction)PyCellViewer_removeHistory , METH_VARARGS - , "Remove a Cell from the viewer's history." } - , { "destroy" , (PyCFunction)PyCellViewer_destroy , METH_NOARGS - , "Destroy the associated hurricane object. The python object remains." } - , {NULL, NULL, 0, NULL} /* sentinel */ + { { "hasMenu" , (PyCFunction)PyCellViewer_hasMenu , METH_VARARGS + , "Return true if the menu at \"path\" exists." } + , { "hasMenuAction" , (PyCFunction)PyCellViewer_hasMenuAction , METH_VARARGS + , "Return true if the menu action at \"path\" exists." } + , { "addMenu" , (PyCFunction)PyCellViewer_addMenu , METH_VARARGS + , "Create a new menu at \"path\" and returns true if success." } + , { "addToMenu" , (PyCFunction)PyCellViewer_addToMenu , METH_VARARGS + , "Creates a new action at \"path\" and returns true if success." } + , { "getCell" , (PyCFunction)PyCellViewer_getCell , METH_NOARGS + , "Return the currently edited Cell." } + , { "setCell" , (PyCFunction)PyCellViewer_setCell , METH_VARARGS + , "Load a Cell into the viewer." } + , { "setApplicationName" , (PyCFunction)PyCellViewer_setApplicationName , METH_VARARGS + , "Sets the application (binary) name." } + , { "setAnonNetSelectable" , (PyCFunction)PyCellViewer_setAnonNetSelectable , METH_VARARGS + , "Allow/disallow anonymous nets to be selectables." } + , { "setLayerVisible" , (PyCFunction)PyCellViewer_setLayerVisible , METH_VARARGS + , "Sets the visibility state of the layer ." } + , { "setShowSelection" , (PyCFunction)PyCellViewer_setShowSelection , METH_VARARGS + , "Display/hide the selection." } + , { "setCumulativeSelection", (PyCFunction)PyCellViewer_setCumulativeSelection, METH_VARARGS + , "Make the selection cumulative." } + , { "select" , (PyCFunction)PyCellViewer_select , METH_VARARGS + , "Add an occurrence to the selected set." } + , { "unselect" , (PyCFunction)PyCellViewer_unselect , METH_VARARGS + , "Add an occurrence to the selected set." } + , { "unselectAll" , (PyCFunction)PyCellViewer_unselectAll , METH_NOARGS + , "Clear the selected set." } + , { "reframe" , (PyCFunction)PyCellViewer_reframe , METH_VARARGS + , "Zoom toward the given area." } + , { "fit" , (PyCFunction)PyCellViewer_fit , METH_NOARGS + , "Triggers a full redraw of the visible area." } + , { "refresh" , (PyCFunction)PyCellViewer_refresh , METH_NOARGS + , "Fit the contents to the viewer's visible area ." } + , { "removeHistory" , (PyCFunction)PyCellViewer_removeHistory , METH_VARARGS + , "Remove a Cell from the viewer's history." } + , { "destroy" , (PyCFunction)PyCellViewer_destroy , METH_NOARGS + , "Destroy the associated hurricane object. The python object remains." } + , {NULL, NULL, 0, NULL} /* sentinel */ }; diff --git a/hurricane/src/viewer/hurricane/viewer/CellViewer.h b/hurricane/src/viewer/hurricane/viewer/CellViewer.h index 2a65a28a..fbf5864b 100644 --- a/hurricane/src/viewer/hurricane/viewer/CellViewer.h +++ b/hurricane/src/viewer/hurricane/viewer/CellViewer.h @@ -14,14 +14,11 @@ // +-----------------------------------------------------------------+ -#ifndef HURRICANE_CELL_VIEWER_H -#define HURRICANE_CELL_VIEWER_H - +#pragma once #include #include #include #include - #include #include class QEvent; @@ -29,17 +26,16 @@ class QKeyEvent; class QAction; class QMenu; class QPrinter; - -#include "hurricane/Commons.h" -#include "hurricane/Observer.h" -#include "hurricane/Name.h" -#include "hurricane/Occurrence.h" -#include "hurricane/viewer/MoveCommand.h" -#include "hurricane/viewer/ZoomCommand.h" -#include "hurricane/viewer/RulerCommand.h" -#include "hurricane/viewer/SelectCommand.h" -#include "hurricane/viewer/HierarchyCommand.h" -#include "hurricane/viewer/CellWidget.h" +#include "hurricane/Commons.h" +#include "hurricane/Observer.h" +#include "hurricane/Name.h" +#include "hurricane/Occurrence.h" +#include "hurricane/viewer/MoveCommand.h" +#include "hurricane/viewer/ZoomCommand.h" +#include "hurricane/viewer/RulerCommand.h" +#include "hurricane/viewer/SelectCommand.h" +#include "hurricane/viewer/HierarchyCommand.h" +#include "hurricane/viewer/CellWidget.h" namespace Hurricane { @@ -133,6 +129,7 @@ namespace Hurricane { void unselect ( Occurrence& ); void unselectAll (); inline void setLayerVisible ( const Name& layer, bool visible ); + void reframe ( const Box& , bool historyEnable=true ); void runScript ( QString scriptPath ); virtual CellViewer* vcreate () const; virtual std::string _getString () const; @@ -227,6 +224,3 @@ namespace Hurricane { GETSTRING_POINTER_SUPPORT(Hurricane::CellViewer) IOSTREAM_POINTER_SUPPORT(Hurricane::CellViewer) - - -#endif diff --git a/hurricane/src/viewer/hurricane/viewer/PyCellViewer.h b/hurricane/src/viewer/hurricane/viewer/PyCellViewer.h index 730466b4..0e8038d0 100644 --- a/hurricane/src/viewer/hurricane/viewer/PyCellViewer.h +++ b/hurricane/src/viewer/hurricane/viewer/PyCellViewer.h @@ -14,9 +14,7 @@ // +-----------------------------------------------------------------+ -#ifndef PY_HURRICANE_CELL_VIEWER_H -#define PY_HURRICANE_CELL_VIEWER_H - +#pragma once #include "hurricane/isobar/PyHurricane.h" #include "hurricane/viewer/CellViewer.h" @@ -56,6 +54,3 @@ extern "C" { } // End of Isobar namespace. - - -#endif // PY_HURRICANE_CELL_VIEWER_H