coriolis/hurricane/src/isobar/PyPolygon.cpp

271 lines
8.5 KiB
C++

// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2018-2018, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | I s o b a r - Hurricane / Python Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./PyPolygon.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/isobar/PyPoint.h"
#include "hurricane/isobar/PyPointCollection.h"
#include "hurricane/isobar/PyNet.h"
#include "hurricane/isobar/PyLayer.h"
#include "hurricane/isobar/PyBox.h"
#include "hurricane/isobar/PyPolygon.h"
namespace Isobar {
using namespace Hurricane;
template< typename CppType >
bool ListToVector ( PyObject* list, PyTypeObject* itemType, std::vector<CppType>& v )
{
if (not PyList_Check(list)) return false;
int length = PyList_Size( list );
for ( int i=0 ; i<length ; ++i ) {
PyObject* item = PyList_GetItem( list, i );
if ((item)->ob_type != itemType) {
string message = "Polygon: Item at position " + getString(i) + "has wrong type.";
PyErr_SetString( ConstructorError, message.c_str() );
return false;
}
v.push_back( *PYPOINT_O(item) );
}
return true;
}
PyObject* VectorToList ( const std::vector<Point>& v )
{
PyObject* pyList = PyList_New( v.size() );
for ( size_t i=0 ; i<v.size() ; ++i ) {
PyPoint* pyPoint = PyObject_NEW( PyPoint, &PyTypePoint );
if (pyPoint == NULL) { return NULL; }
HTRY
pyPoint->_object = new Point ( v[i] );
HCATCH
PyList_SetItem( pyList, i, (PyObject*)pyPoint );
}
return pyList;
}
extern "C" {
#undef ACCESS_OBJECT
#undef ACCESS_CLASS
#define ACCESS_OBJECT _baseObject._baseObject._object
#define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject._baseObject)
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Polygon,polygon,function)
// +=================================================================+
// | "PyPolygon" Python Module Code Part |
// +=================================================================+
#if defined(__PYTHON_MODULE__)
// Standard Accessors (Attributes).
DirectGetLongAttribute(PyPolygon_getX, getX, PyPolygon, Polygon)
DirectGetLongAttribute(PyPolygon_getY, getY, PyPolygon, Polygon)
// Standard Destroy (Attribute).
DBoDestroyAttribute(PyPolygon_destroy, PyPolygon)
static PyObject* PyPolygon_create ( PyObject*, PyObject *args )
{
cdebug_log(20,0) << "PyPolygon_create()" << endl;
PyObject* arg0 = NULL;
PyObject* arg1 = NULL;
PyObject* arg2 = NULL;
Polygon* polygon = NULL;
HTRY
if (not PyArg_ParseTuple(args, "OOO:Polygon.create" ,&arg0 ,&arg1 ,&arg2 )) {
PyErr_SetString( ConstructorError, "Invalid number of parameters for Polygon constructor." );
return NULL;
}
if (not IsPyNet(arg0)) {
PyErr_SetString( ConstructorError, "First parameter of Polygon constructor must be a Net." );
return NULL;
}
if (not IsPyDerivedLayer(arg1)) {
PyErr_SetString( ConstructorError, "Second parameter of Polygon constructor must be a Layer." );
return NULL;
}
vector<Point> points;
if (not ListToVector<Point>(arg2,&PyTypePoint,points)) return NULL;
polygon = Polygon::create( PYNET_O(arg0), PYDERIVEDLAYER_O(arg1), points );
HCATCH
return PyPolygon_Link(polygon);
}
static PyObject* PyPolygon_getBoundingBox ( PyPolygon *self )
{
cdebug_log(20,0) << "PyPolygon_getBoundingBox()" << endl;
METHOD_HEAD( "Polygon.BoundingBox()" )
PyBox* pyBox = PyObject_NEW( PyBox, &PyTypeBox );
if (pyBox == NULL) { return NULL; }
HTRY
pyBox->_object = new Box ( polygon->getBoundingBox() );
HCATCH
return (PyObject*)pyBox;
}
static PyObject* PyPolygon_getSubPolygons ( PyPolygon *self )
{
cdebug_log(20,0) << "PyPolygon_getSubPolygons()" << endl;
PyObject* pySubPolygons = NULL;
METHOD_HEAD( "Polygon.SubPolygons()" )
HTRY
vector< vector<Point> > subpolygons;
polygon->getSubPolygons( subpolygons );
pySubPolygons = PyList_New( subpolygons.size() );
for ( size_t i=0 ; i<subpolygons.size() ; ++i ) {
PyList_SetItem( pySubPolygons, i, VectorToList( subpolygons[i] ) );
}
HCATCH
return pySubPolygons;
}
static PyObject* PyPolygon_setPoints ( PyPolygon *self, PyObject* args )
{
cdebug_log(20,0) << "Polygon.setPoints()" << endl;
HTRY
METHOD_HEAD( "Polygon.setPoints()" )
PyObject* arg0 = NULL;
if (not PyArg_ParseTuple( args, "O:Polygon.setPoints", &arg0 )) {
PyErr_SetString( ConstructorError, "Invalid number of parameters for Polygon.setPoints()." );
return NULL;
}
vector<Point> points;
if (not ListToVector<Point>(arg0,&PyTypePoint,points)) return NULL;
polygon->setPoints( points );
HCATCH
Py_RETURN_NONE;
}
static PyObject* PyPolygon_translate ( PyPolygon *self, PyObject* args )
{
cdebug_log(20,0) << "PyPolygon_translate ()" << endl;
HTRY
METHOD_HEAD ( "Polygon.translate()" )
PyObject* arg0 = NULL;
PyObject* arg1 = NULL;
__cs.init ("Polygon.translate");
if (PyArg_ParseTuple(args,"O&O&:Polygon.translate", Converter, &arg0, Converter, &arg1)) {
if (__cs.getObjectIds() == INTS2_ARG) polygon->translate( PyAny_AsLong(arg0), PyAny_AsLong(arg1) );
else {
PyErr_SetString ( ConstructorError, "Polygon.translate(): Invalid type for parameter(s)." );
return NULL;
}
} else {
PyErr_SetString ( ConstructorError, "Polygon.translate(): Invalid number of parameters." );
return NULL;
}
HCATCH
Py_RETURN_NONE;
}
static PyObject* PyPolygon_getMContour ( PyPolygon *self )
{
cdebug_log(20,0) << "PyPolygon_getMContour()" << endl;
METHOD_HEAD( "Polygon.getMContour()" )
PyPointCollection* pyPointCollection = NULL;
HTRY
Points* points = new Points( polygon->getMContour() );
pyPointCollection = PyObject_NEW(PyPointCollection, &PyTypePointCollection);
if (pyPointCollection == NULL) return NULL;
pyPointCollection->_object = points;
HCATCH
return (PyObject*)pyPointCollection;
}
// ---------------------------------------------------------------
// PyPolygon Attribute Method table.
PyMethodDef PyPolygon_Methods[] =
{ { "create" , (PyCFunction)PyPolygon_create , METH_VARARGS|METH_STATIC
, "Create a new Polygon." }
, { "getX" , (PyCFunction)PyPolygon_getX , METH_NOARGS , "Return the Polygon X value." }
, { "getY" , (PyCFunction)PyPolygon_getY , METH_NOARGS , "Return the Polygon Y value." }
, { "getBoundingBox", (PyCFunction)PyPolygon_getBoundingBox, METH_NOARGS , "Return the Polygon Bounding Box." }
, { "getMContour" , (PyCFunction)PyPolygon_getMContour , METH_NOARGS , "Return the points of the manhattanized contour." }
, { "getSubPolygons", (PyCFunction)PyPolygon_getSubPolygons, METH_NOARGS , "Return the list of sub-polygons (GDSII compliants)." }
, { "setPoints" , (PyCFunction)PyPolygon_setPoints , METH_VARARGS, "Sets the Polygon Bounding Box." }
, { "translate" , (PyCFunction)PyPolygon_translate , METH_VARARGS, "Translates the Polygon of dx and dy." }
, { "destroy" , (PyCFunction)PyPolygon_destroy , METH_NOARGS
, "Destroy associated hurricane object, the python object remains." }
, {NULL, NULL, 0, NULL} /* sentinel */
};
DBoDeleteMethod(Polygon)
PyTypeObjectLinkPyType(Polygon)
#else // Python Module Code Part.
// +=================================================================+
// | "PyPolygon" Shared Library Code Part |
// +=================================================================+
// Link/Creation Method.
DBoLinkCreateMethod(Polygon)
PyTypeInheritedObjectDefinitions(Polygon,Component)
#endif // Shared Library Code Part.
} // extern "C".
} // Isobar namespace.