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.
This commit is contained in:
parent
0b5ce309eb
commit
3e6d5622e8
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 <name>." }
|
||||
, { "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 <name>." }
|
||||
, { "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 */
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -14,14 +14,11 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef HURRICANE_CELL_VIEWER_H
|
||||
#define HURRICANE_CELL_VIEWER_H
|
||||
|
||||
#pragma once
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <boost/any.hpp>
|
||||
|
||||
#include <QIcon>
|
||||
#include <QMainWindow>
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue