Polygon internal normalization. Sub-polygons for GDSII driver.
* Change: In Hurricane::Polygon, store the points so they are always ordered in the counter-clockwise (trigonometric) direction. This simplicificate internal computations. * New: In Hurricane::Polygon, added getSubPolygons() methods, that split horizontally the polygon in sub-polygons of about 1000 vertexes. This is mainly to be used by the GDSII driver to abide to the XY 4000 points limitation. * New: In Hurricane::Isobar, export support for Point collections so the various contour Polygon methods can be created in the Python interface. * New: In CRL::GdsDriver, split the Polygons into set of sub-polygons of less than 1000 vertexes. Use the getSubPolygons() method. * Change: In stratus1.dpgen_RF2, makes more explicit error messages about placement by displaying the faulty vs. expected coordinates.
This commit is contained in:
parent
ea16b5a556
commit
4f089ffdea
|
@ -30,6 +30,8 @@ using namespace std;
|
|||
#include "hurricane/Horizontal.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "hurricane/Diagonal.h"
|
||||
#include "hurricane/Rectilinear.h"
|
||||
#include "hurricane/Polygon.h"
|
||||
#include "hurricane/Pad.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/Cell.h"
|
||||
|
@ -338,6 +340,7 @@ namespace {
|
|||
GdsStream& operator<< ( const BasicLayer* );
|
||||
GdsStream& operator<< ( const Box& );
|
||||
GdsStream& operator<< ( const Points );
|
||||
GdsStream& operator<< ( const vector<Point>& points );
|
||||
GdsStream& operator<< ( const Cell* );
|
||||
GdsStream& operator<< ( const Transformation& );
|
||||
private:
|
||||
|
@ -513,6 +516,20 @@ namespace {
|
|||
}
|
||||
|
||||
|
||||
GdsStream& GdsStream::operator<< ( const vector<Point>& points )
|
||||
{
|
||||
GdsRecord record ( GdsRecord::XY );
|
||||
for ( Point p : points ) {
|
||||
record.push( (int32_t)DbU::toGrid(p.getX()) );
|
||||
record.push( (int32_t)DbU::toGrid(p.getY()) );
|
||||
}
|
||||
record.push( (int32_t)DbU::toGrid(points[0].getX()) );
|
||||
record.push( (int32_t)DbU::toGrid(points[0].getY()) );
|
||||
_ostream << record;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
GdsStream& GdsStream::operator<< ( const Cell* cell )
|
||||
{
|
||||
time_t t = time( 0 );
|
||||
|
@ -546,6 +563,20 @@ namespace {
|
|||
|
||||
for ( Net* net : cell->getNets() ) {
|
||||
for ( Component* component : net->getComponents() ) {
|
||||
Polygon* polygon = dynamic_cast<Polygon*>(component);
|
||||
if (polygon) {
|
||||
vector< vector<Point> > subpolygons;
|
||||
polygon->getSubPolygons( subpolygons );
|
||||
|
||||
for ( const vector<Point>& subpolygon : subpolygons ) {
|
||||
for ( const BasicLayer* layer : component->getLayer()->getBasicLayers() ) {
|
||||
(*this) << BOUNDARY;
|
||||
(*this) << layer;
|
||||
(*this) << subpolygon;
|
||||
(*this) << ENDEL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Diagonal* diagonal = dynamic_cast<Diagonal*>(component);
|
||||
if (diagonal) {
|
||||
for ( const BasicLayer* layer : component->getLayer()->getBasicLayers() ) {
|
||||
|
@ -567,6 +598,7 @@ namespace {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(*this) << ENDSTR;
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@
|
|||
hurricane/Technology.h
|
||||
hurricane/Timer.h
|
||||
hurricane/Transformation.h
|
||||
hurricane/Polygon.h
|
||||
hurricane/Polygon.h hurricane/Polygons.h
|
||||
hurricane/DbU.h
|
||||
hurricane/UpdateSession.h
|
||||
hurricane/VectorCollection.h
|
||||
|
|
|
@ -85,7 +85,7 @@ namespace Hurricane {
|
|||
DbU::Unit m = y % DbU::getPolygonStep();
|
||||
|
||||
if (m) {
|
||||
if (isClockwise() xor not isXIncrease()) y += DbU::getPolygonStep() - m;
|
||||
if (not isXIncrease()) y += DbU::getPolygonStep() - m;
|
||||
else y += -m;
|
||||
}
|
||||
_steps.push_back( y );
|
||||
|
@ -111,7 +111,7 @@ namespace Hurricane {
|
|||
DbU::Unit m = x % DbU::getPolygonStep();
|
||||
|
||||
if (m) {
|
||||
if (isClockwise() xor isYIncrease()) x += DbU::getPolygonStep() - m;
|
||||
if (isYIncrease()) x += DbU::getPolygonStep() - m;
|
||||
else x += -m;
|
||||
}
|
||||
_steps.push_back( x );
|
||||
|
@ -132,7 +132,6 @@ namespace Hurricane {
|
|||
|
||||
Point point;
|
||||
|
||||
|
||||
if (_flags & YSteps) {
|
||||
DbU::Unit delta = DbU::getPolygonStep();
|
||||
if (not (_flags & Polygon::YIncrease)) delta = -delta;
|
||||
|
@ -219,7 +218,28 @@ namespace Hurricane {
|
|||
sign = nextSign;
|
||||
}
|
||||
|
||||
Polygon* triangle = new Polygon ( net, layer, points );
|
||||
size_t istart = 0;
|
||||
for ( size_t i=0 ; i<points.size() ; ++i ) {
|
||||
if ( (points[i].getX() > points[istart].getX())
|
||||
or ( (points[i].getX() == points[istart].getX())
|
||||
and (points[i].getY() > points[istart].getY()) ) )
|
||||
istart = i;
|
||||
}
|
||||
|
||||
vector<Point> normalized ( points.size(), Point() );
|
||||
if ( (istart != 0) or (sign > 0.0) ) {
|
||||
if (sign < 0.0) {
|
||||
for ( size_t i=0 ; i<points.size() ; ++i )
|
||||
normalized[ (points.size()-i) % points.size() ] = points[ (istart+i) % points.size() ];
|
||||
} else {
|
||||
for ( size_t i=0 ; i<points.size() ; ++i )
|
||||
normalized[ i ] = points[ (istart+i) % points.size() ];
|
||||
}
|
||||
|
||||
} else
|
||||
normalized = points;
|
||||
|
||||
Polygon* triangle = new Polygon ( net, layer, normalized );
|
||||
triangle->_postCreate();
|
||||
triangle->manhattanize();
|
||||
return triangle;
|
||||
|
@ -368,20 +388,218 @@ namespace Hurricane {
|
|||
for ( Edge* edge : _edges ) delete edge;
|
||||
_edges.clear();
|
||||
|
||||
bool clockwise = (getSign(_points,0) <= 0);
|
||||
|
||||
for ( size_t i=0 ; i<_points.size() ; ++i ) {
|
||||
const Point& origin = _points[ i % _points.size()];
|
||||
const Point& extremity = _points[ (i+1) % _points.size()];
|
||||
bool dxPositive = (extremity.getX() > origin.getX());
|
||||
uint32_t flags = (clockwise xor dxPositive) ? 0 : Above;
|
||||
flags |= (clockwise) ? Clockwise : 0;
|
||||
uint32_t flags = (dxPositive) ? 0 : Above;
|
||||
|
||||
_edges.push_back( new Edge ( origin, extremity, flags ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Polygon::getSubPolygons ( vector< vector<Point> >& subpolygons ) const
|
||||
{
|
||||
static const size_t subPolygonSize = 1000;
|
||||
|
||||
// cerr << "Polygon::getSubPolygons(): " << this << endl;
|
||||
|
||||
vector<Point> upSide;
|
||||
vector<Point> downSide;
|
||||
Point first;
|
||||
|
||||
bool firstToDown = false;
|
||||
bool inUpSide = true;
|
||||
for ( Point p : getMContour() ) {
|
||||
// cerr << "| " << p << endl;
|
||||
|
||||
if (upSide.size() == 1) {
|
||||
if (upSide[0].getX() == p.getX()) {
|
||||
if (not firstToDown) { firstToDown = true; first = upSide[0]; }
|
||||
upSide.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
if (inUpSide and not upSide.empty()) {
|
||||
if (upSide.back().getX() < p.getX()) {
|
||||
inUpSide = false;
|
||||
// cerr << "Switch to down side." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (inUpSide) {
|
||||
size_t length = upSide.size();
|
||||
if ( (length > 1)
|
||||
and ( ( (upSide[length-2].getX() == upSide[length-1].getX()) and (upSide.back().getX() == p.getX()) )
|
||||
or ( (upSide[length-2].getY() == upSide[length-1].getY()) and (upSide.back().getY() == p.getY()) ) ) ) {
|
||||
upSide.pop_back();
|
||||
}
|
||||
upSide.push_back( p );
|
||||
} else {
|
||||
size_t length = downSide.size();
|
||||
if ( (length > 1)
|
||||
and ( ( (downSide[length-2].getX() == downSide[length-1].getX()) and (downSide.back().getX() == p.getX()) )
|
||||
or ( (downSide[length-2].getY() == downSide[length-1].getY()) and (downSide.back().getY() == p.getY()) ) ) ) {
|
||||
downSide.pop_back();
|
||||
}
|
||||
|
||||
if (downSide.empty()) {
|
||||
downSide.push_back( upSide.back() );
|
||||
upSide.pop_back();
|
||||
}
|
||||
downSide.push_back( p );
|
||||
}
|
||||
}
|
||||
|
||||
std::reverse( upSide.begin(), upSide.end() );
|
||||
|
||||
// cerr << "firstToDown:" << firstToDown << endl;
|
||||
if (firstToDown and (first.getX() > downSide.back().getX())) downSide.push_back( first );
|
||||
while ( downSide.size() > 1 ) {
|
||||
size_t length = downSide.size()-1;
|
||||
if (downSide[length-1].getX() != downSide[length].getX()) break;
|
||||
downSide.pop_back();
|
||||
}
|
||||
|
||||
// cerr << "Up side" << endl;
|
||||
// for ( size_t i=0 ; i<upSide.size() ; ++i )
|
||||
// cerr << "[ " << setw(3) << i << "] " << upSide[i] << endl;
|
||||
|
||||
// cerr << "Down side" << endl;
|
||||
// for ( size_t i=0 ; i<downSide.size() ; ++i )
|
||||
// cerr << "[ " << setw(3) << i << "] " << downSide[i] << endl;
|
||||
|
||||
vector<Point>* polygon = NULL;
|
||||
size_t startUp = 0;
|
||||
size_t startDown = 0;
|
||||
size_t stopUp = 1;
|
||||
size_t stopDown = 1;
|
||||
|
||||
while ( true ) {
|
||||
size_t leftCutUp = 0;
|
||||
size_t leftCutDown = 0;
|
||||
size_t rightCutUp = 0;
|
||||
size_t rightCutDown = 0;
|
||||
size_t downIncrease = 0;
|
||||
size_t upDecrease = 0;
|
||||
|
||||
if (stopUp - startUp + stopDown - startDown > subPolygonSize) {
|
||||
// carve out a new sub-polygon->
|
||||
// cerr << "New sub polygon:" << endl;
|
||||
// cerr << " stopUp:" << setw(3) << stopUp << " startUp:" << setw(3) << startUp << endl;
|
||||
// cerr << " stopDown:" << setw(3) << stopDown << " startDown:" << setw(3) << startDown << endl;
|
||||
|
||||
subpolygons.push_back( vector<Point>() );
|
||||
polygon = &subpolygons.back();
|
||||
|
||||
if (upSide[startUp].getX() > downSide[startDown].getX()) {
|
||||
polygon->push_back( Point( downSide[startDown].getX(), upSide[startUp].getY() ) );
|
||||
// cerr << " + " << polygon->back() << endl;
|
||||
leftCutUp = 1;
|
||||
} else {
|
||||
if (upSide[startUp].getX() < downSide[startDown].getX()) {
|
||||
polygon->push_back( Point( upSide[startUp].getX(), downSide[startDown].getY() ) );
|
||||
// cerr << " + " << polygon->back() << endl;
|
||||
leftCutDown = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (upSide[stopUp].getX() > downSide[stopDown].getX()) rightCutUp = 1;
|
||||
else if (upSide[stopUp].getX() < downSide[stopDown].getX()) rightCutDown = 1;
|
||||
|
||||
if (not leftCutDown and (downSide[startDown+1].getY() > downSide[startDown].getY())) downIncrease = 1;
|
||||
|
||||
for ( size_t i=startDown+downIncrease ; i<=stopDown-rightCutDown ; ++i ) {
|
||||
polygon->push_back( downSide[i] );
|
||||
// cerr << " > " << polygon->back() << endl;
|
||||
}
|
||||
|
||||
if (rightCutUp) {
|
||||
polygon->push_back( Point( downSide[stopDown].getX(), upSide[stopUp].getY() ) );
|
||||
// cerr << " + " << polygon->back() << endl;
|
||||
} else {
|
||||
if (rightCutDown) {
|
||||
polygon->push_back( Point( upSide[stopUp].getX(), downSide[stopDown].getY() ) );
|
||||
// cerr << " + " << polygon->back() << endl;
|
||||
// cerr << " Adjust down (cut)" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (not leftCutUp and (upSide[startUp+1].getY() < upSide[startUp].getY())) upDecrease = 1;
|
||||
|
||||
for ( size_t i=rightCutUp ; i<=stopUp-startUp-upDecrease ; ++i ) {
|
||||
polygon->push_back( upSide[stopUp-i] );
|
||||
// cerr << " < " << polygon->back() << endl;
|
||||
}
|
||||
|
||||
startUp = stopUp;
|
||||
startDown = stopDown;
|
||||
|
||||
// cerr << "Done sub polygon." << endl;
|
||||
}
|
||||
|
||||
if (upSide[stopUp].getX() == downSide[stopDown].getX()) {
|
||||
stopUp += 2;
|
||||
stopDown += 2;
|
||||
} else {
|
||||
if (upSide[stopUp].getX() < downSide[stopDown].getX()) stopUp += 2;
|
||||
else stopDown += 2;
|
||||
}
|
||||
stopUp = std::min( stopUp , upSide.size()-1 );
|
||||
stopDown = std::min( stopDown, downSide.size()-1 );
|
||||
|
||||
// cerr << " stopUp:" << stopUp << " stopDown:" << stopDown << endl;
|
||||
|
||||
if ( (stopUp+5 > upSide.size()) and (stopDown+5 > downSide.size()) ) {
|
||||
stopUp = upSide.size() - 1;
|
||||
stopDown = downSide.size() - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
subpolygons.push_back( vector<Point>() );
|
||||
polygon = &subpolygons.back();
|
||||
|
||||
// cerr << "Last (right) sub polygon:" << endl;
|
||||
// cerr << " stopUp:" << setw(3) << stopUp << " startUp:" << setw(3) << startUp << endl;
|
||||
// cerr << " stopDown:" << setw(3) << stopDown << " startDown:" << setw(3) << startDown << endl;
|
||||
|
||||
size_t downIncrease = 0;
|
||||
size_t upDecrease = 0;
|
||||
size_t leftCutUp = 0;
|
||||
size_t leftCutDown = 0;
|
||||
|
||||
if (upSide[startUp].getX() > downSide[startDown].getX()) {
|
||||
polygon->push_back( Point( downSide[startDown].getX(), upSide[startUp].getY() ) );
|
||||
// cerr << " + " << polygon->back() << endl;
|
||||
leftCutUp = 1;
|
||||
} else {
|
||||
if (upSide[startUp].getX() < downSide[startDown].getX()) {
|
||||
polygon->push_back( Point( upSide[startUp].getX(), downSide[startDown].getY() ) );
|
||||
// cerr << " + " << polygon->back() << endl;
|
||||
leftCutDown = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (not leftCutDown and (downSide[startDown+1].getY() > downSide[startDown].getY())) downIncrease = 1;
|
||||
|
||||
for ( size_t i=startDown+downIncrease ; i<=stopDown ; ++i ) {
|
||||
polygon->push_back( downSide[i] );
|
||||
// cerr << " > " << polygon->back() << endl;
|
||||
}
|
||||
|
||||
if (not leftCutUp and (upSide[startUp+1].getY() < upSide[startUp].getY())) upDecrease = 1;
|
||||
|
||||
for ( size_t i=0 ; i<=stopUp-startUp-upDecrease ; ++i ) {
|
||||
polygon->push_back( upSide[stopUp-i] );
|
||||
// cerr << " < " << polygon->back() << endl;
|
||||
}
|
||||
|
||||
// cerr << endl;
|
||||
}
|
||||
|
||||
|
||||
void Polygon::_toJson ( JsonWriter* writer ) const
|
||||
{
|
||||
Super::_toJson( writer );
|
||||
|
|
|
@ -56,6 +56,9 @@ namespace Hurricane {
|
|||
if (not layer)
|
||||
throw Error( "Rectilinear::create(): Can't create, NULL layer" );
|
||||
|
||||
if (points.size() > 1000)
|
||||
throw Error( "Rectilinear::create(): Rectlinear polygons must not exceed 1000 vertexes." );
|
||||
|
||||
for ( size_t i=0 ; i<points.size() ; ++i ) {
|
||||
size_t j = (i+1) % points.size();
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@ namespace Hurricane {
|
|||
static const uint32_t YIncrease = (1<<4);
|
||||
static const uint32_t Horizontal = (1<<5);
|
||||
static const uint32_t Vertical = (1<<6);
|
||||
static const uint32_t Clockwise = (1<<7);
|
||||
|
||||
public:
|
||||
class Edge {
|
||||
|
@ -61,7 +60,6 @@ namespace Hurricane {
|
|||
inline size_t getSize () const;
|
||||
Point getPoint ( size_t i ) const;
|
||||
inline bool isPositiveSlope () const;
|
||||
inline bool isClockwise () const;
|
||||
inline bool isYIncrease () const;
|
||||
inline bool isXIncrease () const;
|
||||
inline bool isHV () const;
|
||||
|
@ -118,6 +116,7 @@ namespace Hurricane {
|
|||
virtual Point getPoint ( size_t ) const;
|
||||
virtual Box getBoundingBox () const;
|
||||
virtual Box getBoundingBox ( const BasicLayer* ) const;
|
||||
void getSubPolygons ( vector< vector<Point> >& ) const;
|
||||
virtual const Layer* getLayer () const;
|
||||
void setLayer ( const Layer* layer );
|
||||
virtual void translate ( const DbU::Unit& dx, const DbU::Unit& dy );
|
||||
|
@ -144,7 +143,6 @@ namespace Hurricane {
|
|||
inline const vector<Polygon::Edge*>& Polygon::getEdges () const { return _edges; }
|
||||
inline const vector<Point>& Polygon::getPoints () const { return _points; }
|
||||
|
||||
inline bool Polygon::Edge::isClockwise () const { return (_flags & Polygon::Clockwise); }
|
||||
inline bool Polygon::Edge::isYIncrease () const { return (_flags & Polygon::YIncrease); }
|
||||
inline bool Polygon::Edge::isXIncrease () const { return (_flags & Polygon::XIncrease); }
|
||||
inline bool Polygon::Edge::isPositiveSlope () const { return not ( (_flags & Polygon::XIncrease) xor (_flags & Polygon::YIncrease) ); }
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
PyPlug.cpp
|
||||
PyPlugCollection.cpp
|
||||
PyPoint.cpp
|
||||
PyPointCollection.cpp
|
||||
PyReference.cpp
|
||||
PyReferenceCollection.cpp
|
||||
PyRoutingPad.cpp
|
||||
|
@ -129,6 +130,7 @@
|
|||
hurricane/isobar/PyPlug.h
|
||||
hurricane/isobar/PyPlugCollection.h
|
||||
hurricane/isobar/PyPoint.h
|
||||
hurricane/isobar/PyPointCollection.h
|
||||
hurricane/isobar/PyReference.h
|
||||
hurricane/isobar/PyReferenceCollection.h
|
||||
hurricane/isobar/PyRoutingPad.h
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "hurricane/isobar/PyVertical.h"
|
||||
#include "hurricane/isobar/PyContact.h"
|
||||
#include "hurricane/isobar/PyPin.h"
|
||||
#include "hurricane/isobar/PyPointCollection.h"
|
||||
#include "hurricane/isobar/PyComponentCollection.h"
|
||||
|
||||
|
||||
|
@ -196,6 +197,26 @@ extern "C" {
|
|||
}
|
||||
|
||||
|
||||
static PyObject* PyComponent_getContour ( PyComponent *self )
|
||||
{
|
||||
cdebug_log(20,0) << "PyComponent_getContour()" << endl;
|
||||
METHOD_HEAD( "Component.getContour()" )
|
||||
|
||||
PyPointCollection* pyPointCollection = NULL;
|
||||
|
||||
HTRY
|
||||
Points* points = new Points( component->getContour() );
|
||||
|
||||
pyPointCollection = PyObject_NEW(PyPointCollection, &PyTypePointCollection);
|
||||
if (pyPointCollection == NULL) return NULL;
|
||||
|
||||
pyPointCollection->_object = points;
|
||||
HCATCH
|
||||
|
||||
return (PyObject*)pyPointCollection;
|
||||
}
|
||||
|
||||
|
||||
PyMethodDef PyComponent_Methods[] =
|
||||
{ { "getBodyHook" , (PyCFunction)PyComponent_getBodyHook , METH_NOARGS , "Return the component body hook (is a master Hook)." }
|
||||
, { "getX" , (PyCFunction)PyComponent_getX , METH_NOARGS , "Return the Component X value." }
|
||||
|
@ -205,6 +226,7 @@ extern "C" {
|
|||
, { "getNet" , (PyCFunction)PyComponent_getNet , METH_NOARGS , "Returns the net owning the component." }
|
||||
, { "getLayer" , (PyCFunction)PyComponent_getLayer , METH_NOARGS , "Return the component layer." }
|
||||
, { "getBoundingBox" , (PyCFunction)PyComponent_getBoundingBox , METH_VARARGS, "Return the component boundingBox (optionally on a BasicLayer)." }
|
||||
, { "getContour" , (PyCFunction)PyComponent_getContour , METH_NOARGS , "Return the points of the polygonic contour." }
|
||||
, { "getConnexComponents" , (PyCFunction)PyComponent_getConnexComponents, METH_NOARGS , "All the components connecteds to this one through hyper hooks." }
|
||||
, { "getSlaveComponents" , (PyCFunction)PyComponent_getSlaveComponents , METH_NOARGS , "All the components anchored directly or indirectly on this one." }
|
||||
, { "destroy" , (PyCFunction)PyComponent_destroy , METH_NOARGS
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "hurricane/isobar/PyUpdateSession.h"
|
||||
#include "hurricane/isobar/PyDbU.h"
|
||||
#include "hurricane/isobar/PyPoint.h"
|
||||
#include "hurricane/isobar/PyPointCollection.h"
|
||||
#include "hurricane/isobar/PyInterval.h"
|
||||
#include "hurricane/isobar/PyBox.h"
|
||||
#include "hurricane/isobar/PyTransformation.h"
|
||||
|
@ -517,6 +518,7 @@ extern "C" {
|
|||
PyUpdateSession_LinkPyType ();
|
||||
PyDbU_LinkPyType ();
|
||||
PyPoint_LinkPyType ();
|
||||
PyPointCollection_LinkPyType ();
|
||||
PyInterval_LinkPyType ();
|
||||
PyBox_LinkPyType ();
|
||||
PyTransformation_LinkPyType ();
|
||||
|
@ -584,6 +586,7 @@ extern "C" {
|
|||
PYTYPE_READY ( UpdateSession )
|
||||
PYTYPE_READY ( DbU )
|
||||
PYTYPE_READY ( Point )
|
||||
PYTYPE_READY ( PointCollection )
|
||||
PYTYPE_READY ( Interval )
|
||||
PYTYPE_READY ( Box )
|
||||
PYTYPE_READY ( Transformation )
|
||||
|
@ -709,6 +712,7 @@ extern "C" {
|
|||
__cs.addType ( "plug" , &PyTypePlug , "<Plug>" , false, "comp" );
|
||||
__cs.addType ( "plugCol" , &PyTypePlugCollection , "<PlugCollection>" , false );
|
||||
__cs.addType ( "point" , &PyTypePoint , "<Point>" , false );
|
||||
__cs.addType ( "points" , &PyTypePointCollection , "<Points>" , false );
|
||||
__cs.addType ( "rp" , &PyTypeRoutingPad , "<RoutingPad>" , false, "comp" );
|
||||
__cs.addType ( "segment" , &PyTypeSegment , "<Segment>" , false, "comp" );
|
||||
__cs.addType ( "pad " , &PyTypePad , "<Pad>" , false, "comp" );
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
// -*- 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 : "./PyPointCollection.cpp" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include "hurricane/isobar/PyPointCollection.h"
|
||||
#include "hurricane/isobar/PyPoint.h"
|
||||
|
||||
namespace Isobar {
|
||||
|
||||
using namespace Hurricane;
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
||||
// +=================================================================+
|
||||
// | "PyPointCollection" Python Module Code Part |
|
||||
// +=================================================================+
|
||||
|
||||
#if defined(__PYTHON_MODULE__)
|
||||
|
||||
|
||||
DirectDeleteMethod(PyPointCollection_DeAlloc, PyPointCollection)
|
||||
|
||||
|
||||
static PyObject* PyPointLocatorNext ( PyPointCollectionLocator* pyLocator )
|
||||
{
|
||||
Locator<Point>* locator = pyLocator->_object;
|
||||
|
||||
HTRY
|
||||
if (locator->isValid()) {
|
||||
Point point = locator->getElement();
|
||||
PyPoint* pyPoint = PyObject_NEW(PyPoint, &PyTypePoint);
|
||||
if (pyPoint == NULL) return NULL;
|
||||
pyPoint->_object = new Point(point);
|
||||
|
||||
locator->progress();
|
||||
return (PyObject*)pyPoint;
|
||||
}
|
||||
HCATCH
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
CollectionMethods(Point)
|
||||
|
||||
|
||||
#else // Python Module Code Part.
|
||||
|
||||
|
||||
// +=================================================================+
|
||||
// | "PyPointCollection" Shared Library Code Part |
|
||||
// +=================================================================+
|
||||
|
||||
|
||||
PyTypeCollectionObjectDefinitions(PointCollection)
|
||||
PyTypeCollectionObjectDefinitions(PointCollectionLocator)
|
||||
|
||||
|
||||
#endif // Shared Library Code Part.
|
||||
|
||||
|
||||
} // extern "C".
|
||||
|
||||
} // Isobar namespace.
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
|
||||
#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"
|
||||
|
@ -169,6 +170,26 @@ extern "C" {
|
|||
}
|
||||
|
||||
|
||||
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.
|
||||
|
||||
|
@ -178,6 +199,7 @@ extern "C" {
|
|||
, { "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." }
|
||||
, { "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
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
// -*- 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++ Header : "./hurricane/isobar/PyPointCollection.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef PY_POINT_COLLECTION_H
|
||||
#define PY_POINT_COLLECTION_H
|
||||
|
||||
#include "hurricane/isobar/PyHurricane.h"
|
||||
#include "hurricane/Point.h"
|
||||
#include "hurricane/Points.h"
|
||||
|
||||
|
||||
namespace Isobar {
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Python Object : "PyPointCollection".
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
Hurricane::Points* _object;
|
||||
} PyPointCollection;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
Hurricane::Locator<Hurricane::Point>* _object;
|
||||
PyPointCollection* _collection;
|
||||
} PyPointCollectionLocator;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Functions & Types exported to "PyHurricane.ccp".
|
||||
|
||||
extern PyTypeObject PyTypePointCollection;
|
||||
extern PyTypeObject PyTypePointCollectionLocator;
|
||||
|
||||
extern void PyPointCollection_LinkPyType();
|
||||
extern void PyPointCollectionLocator_LinkPyType();
|
||||
|
||||
} // extern "C".
|
||||
|
||||
} // Isobar namespace.
|
||||
|
||||
#endif // PY_POINT_COLLECTION_H
|
|
@ -127,7 +127,7 @@ namespace Hurricane {
|
|||
_flags = flags;
|
||||
|
||||
//int scale = 80 * Cfg::getParamEnumerate("viewer.printer.mode")->asInt();
|
||||
int scale = (Graphics::isHighDpi()) ? 1 : 2;
|
||||
int scale = (Graphics::isHighDpi()) ? 4 : 2;
|
||||
_drawingWidth = _cellWidget->width () * scale;
|
||||
_drawingHeight = _cellWidget->height() * scale;
|
||||
|
||||
|
|
|
@ -685,6 +685,17 @@ namespace Hurricane {
|
|||
for ( Point point : component->getMContour() )
|
||||
contour << _cellWidget->dbuToScreenPoint( point );
|
||||
_cellWidget->drawScreenPolygon( contour );
|
||||
|
||||
// const Polygon* polygon = dynamic_cast<const Polygon*>( component );
|
||||
// if (polygon) {
|
||||
// vector< vector<Point> > subpolygons;
|
||||
// polygon->getSubPolygons( subpolygons );
|
||||
// for ( const vector<Point>& sp : subpolygons ) {
|
||||
// contour.clear();
|
||||
// for ( Point point : sp ) contour << _cellWidget->dbuToScreenPoint( point );
|
||||
// _cellWidget->drawScreenPolygon( contour );
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -940,7 +940,7 @@ class top_rf2 ( Model ) :
|
|||
global adrange
|
||||
|
||||
#HCELL = 50
|
||||
HCELL = DbU.toLambda( self.In[0]._hur_masterCell.getAbutmentBox().getHeight() )
|
||||
HCELL = self.In[0]._hur_masterCell.getAbutmentBox().getHeight()
|
||||
|
||||
# placement des lignes de bit en dessous des buffers
|
||||
bottom = 0
|
||||
|
|
|
@ -66,8 +66,10 @@ def Place ( ins, sym, ref, plac = FIXED, cell = None ) :
|
|||
raise Exception ( err )
|
||||
|
||||
if ref._y % MYSLICE :
|
||||
err = "\n[Stratus ERROR] Place : " + ins._name + " : coordinate y is not a mutiple of SLICE.\n"
|
||||
raise Exception ( err )
|
||||
message = '\n[ERROR] Stratus.Model.Place(): For instance "' \
|
||||
+ ins._name + '", coordinate Y ' + DbU.getValueString(ref._y) + ' (' + str(ref._y) + ')' \
|
||||
+ " is not a mutiple of slice " + DbU.getValueString(MYSLICE) + '.'
|
||||
raise Exception( message )
|
||||
|
||||
# Error message : if ref is not a reference
|
||||
if str ( ref.__class__ ) != "st_ref.XY" :
|
||||
|
@ -127,12 +129,16 @@ def PlaceRight ( ins, symetry, offsetX = 0, offsetY = 0, plac = FIXED ) :
|
|||
cell = CELLS[-1]
|
||||
|
||||
if offsetX % MYPITCH :
|
||||
err = "\n[Stratus ERROR] PlaceRight : " + ins._name + " : offsetX is not a mutiple of PITCH.\n"
|
||||
raise Exception ( err )
|
||||
message = '\n[ERROR] Stratus.Model.PlaceRight(): For instance "' \
|
||||
+ ins._name + '", offsetX ' + DbU.getValueString(offsetX) \
|
||||
+ " is not a mutiple of pitch " + DbU.getValueString(MYPITCH) + '.'
|
||||
raise Exception( message )
|
||||
|
||||
if offsetY % MYSLICE :
|
||||
err = "\n[Stratus ERROR] PlaceRight : " + ins._name + " : offsetY is not a mutiple of SLICE.\n"
|
||||
raise Exception ( err )
|
||||
message = '\n[ERROR] Stratus.Model.PlaceRight(): For instance "' \
|
||||
+ ins._name + '", offsetY ' + DbU.getValueString(offsetX) \
|
||||
+ " is not a mutiple of slice " + DbU.getValueString(MYSLICE) + '.'
|
||||
raise Exception( message )
|
||||
|
||||
if ( plac != PLACED ) and ( plac != FIXED ) :
|
||||
err = "\n[Stratus ERROR] PlaceRight : " + ins._name + " : wrong argument for placement type.\n"
|
||||
|
|
|
@ -47,6 +47,9 @@
|
|||
# x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
from Hurricane import DbU
|
||||
|
||||
|
||||
NOSYM = 1000
|
||||
SYM_X = 1001
|
||||
SYM_Y = 1002
|
||||
|
@ -66,5 +69,5 @@ SOUTH = 1022
|
|||
EAST = 1023
|
||||
WEST = 1024
|
||||
|
||||
MYPITCH = 5
|
||||
MYSLICE = 50
|
||||
MYPITCH = DbU.fromLambda( 5.0 )
|
||||
MYSLICE = DbU.fromLambda( 50.0 )
|
||||
|
|
Loading…
Reference in New Issue