From 0902b21f230cf54c3a738252f217ef6015e4dc9a Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Fri, 4 May 2018 17:06:41 +0200 Subject: [PATCH] Added support for huge approximated polygons (for photonics). * New: Hurricane::Triange as been renamed into Hurricane::Polygon. Add support for convex polygons. Polygon are approximateds by excess by a manhattan rectilinear polygon (with potentially thousands of vertexes). To reduce the memory footprint, compaction techniques reducing by at least a factor 4 has been implemented. We could go further by only storing the non-repetitive part of the edge (defined by the integral fraction dY/dY). We will see, if the program slows too much. The manhattan approximate is always computed but displayed only if the polygon grid step is greated than 4 pixels. The level of approximation of the polygons can be controlled through the "DbU::_polygonStep" parameter. * Change: In CRL/coriolisInit.py and CRL/helpers/Technology.py, regroup all DbU related parameters into "technoConfig" (i.e. suppress "viewerConfig"). Update all the relevant technology.conf configuration files. Change the loader behavior so that "technoConfig" is read first and is now responsible for creating the Technology of the DataBase. * New: In Hurricane::CellWidget, added support for displaying mahanttanized polygons. * Change: In documenation/scripts/expample/polygons.py, perform (I hope) a comprehensive test of the polygons (check all slopes, clockwise and conter-clockwise). * New: In Hurricane::DbU, added template to manage vector<> of DbU. Support for the "polygonStep" parameter. --- crlcore/etc/180/scn6m_deep_09/technology.conf | 11 +- crlcore/etc/45/freepdk_45/technology.conf | 11 +- crlcore/etc/common/technology.conf | 2 +- crlcore/etc/symbolic/cmos/technology.conf | 11 +- crlcore/etc/symbolic/ispd05/technology.conf | 11 +- crlcore/python/coriolisInit.py | 5 +- crlcore/python/helpers/Alliance.py | 2 - crlcore/python/helpers/Technology.py | 120 ++-- documentation/examples/scripts/polygons.py | 64 ++- hurricane/doc/hurricane/Polygon.dox | 53 ++ hurricane/doc/hurricane/doxyfile | 2 + hurricane/src/hurricane/CMakeLists.txt | 4 +- hurricane/src/hurricane/DataBase.cpp | 9 +- hurricane/src/hurricane/DbU.cpp | 5 +- hurricane/src/hurricane/Polygon.cpp | 518 ++++++++++++++++++ hurricane/src/hurricane/Technology.cpp | 5 +- hurricane/src/hurricane/Triangle.cpp | 227 -------- hurricane/src/hurricane/hurricane/DbU.h | 33 +- hurricane/src/hurricane/hurricane/Polygon.h | 200 +++++++ .../hurricane/{Triangles.h => Polygons.h} | 0 hurricane/src/hurricane/hurricane/Triangle.h | 90 --- hurricane/src/isobar/CMakeLists.txt | 4 +- hurricane/src/isobar/PyDbU.cpp | 65 ++- hurricane/src/isobar/PyHurricane.cpp | 14 +- hurricane/src/isobar/PyLayer.cpp | 13 + hurricane/src/isobar/PyPolygon.cpp | 209 +++++++ hurricane/src/isobar/PyTriangle.cpp | 206 ------- .../src/isobar/hurricane/isobar/PyLayer.h | 1 + .../isobar/{PyTriangle.h => PyPolygon.h} | 28 +- hurricane/src/viewer/CellWidget.cpp | 30 +- .../src/viewer/hurricane/viewer/CellWidget.h | 1 + 31 files changed, 1296 insertions(+), 658 deletions(-) create mode 100644 hurricane/doc/hurricane/Polygon.dox create mode 100644 hurricane/src/hurricane/Polygon.cpp delete mode 100644 hurricane/src/hurricane/Triangle.cpp create mode 100644 hurricane/src/hurricane/hurricane/Polygon.h rename hurricane/src/hurricane/hurricane/{Triangles.h => Polygons.h} (100%) delete mode 100644 hurricane/src/hurricane/hurricane/Triangle.h create mode 100644 hurricane/src/isobar/PyPolygon.cpp delete mode 100644 hurricane/src/isobar/PyTriangle.cpp rename hurricane/src/isobar/hurricane/isobar/{PyTriangle.h => PyPolygon.h} (63%) diff --git a/crlcore/etc/180/scn6m_deep_09/technology.conf b/crlcore/etc/180/scn6m_deep_09/technology.conf index 09d25fd1..d20d2617 100644 --- a/crlcore/etc/180/scn6m_deep_09/technology.conf +++ b/crlcore/etc/180/scn6m_deep_09/technology.conf @@ -22,10 +22,13 @@ execfile( helpers.sysConfDir+'/common/technology.conf' ) # # We set the foundry grid to .005um and set the gridsPerLambda to 18. -technoConfig = { 'name' : 'scn6m_deep' - , 'gridValue' : 0.005 - , 'gridUnit' : DbU.UnitPowerMicro - , 'gridsPerLambda': 18 +technoConfig = { 'name' : 'scn6m_deep' + , 'precision' : 2 + , 'gridValue' : 0.005 + , 'gridUnit' : DbU.UnitPowerMicro + , 'gridsPerLambda' : 18 + , 'symbolicGridStep': 1.0 + , 'polygonStep' : 9.0 } diff --git a/crlcore/etc/45/freepdk_45/technology.conf b/crlcore/etc/45/freepdk_45/technology.conf index 6c31b144..c234485a 100644 --- a/crlcore/etc/45/freepdk_45/technology.conf +++ b/crlcore/etc/45/freepdk_45/technology.conf @@ -16,10 +16,13 @@ execfile( helpers.sysConfDir+'/common/technology.conf' ) helpers.micronsMode() -technoConfig = { 'name' : 'freepdk_45' - , 'gridValue' : 0.0025 - , 'gridUnit' : DbU.UnitPowerMicro - , 'gridsPerLambda': 18 +technoConfig = { 'name' : 'freepdk_45' + , 'precision' : 2 + , 'gridValue' : 0.0025 + , 'gridUnit' : DbU.UnitPowerMicro + , 'gridsPerLambda' : 18 + , 'symbolicGridStep' : 1.0 + , 'polygonStep' : 1.0 } diff --git a/crlcore/etc/common/technology.conf b/crlcore/etc/common/technology.conf index 7ff49277..3d258542 100644 --- a/crlcore/etc/common/technology.conf +++ b/crlcore/etc/common/technology.conf @@ -10,7 +10,7 @@ from helpers.Technology import TypeContact from helpers.Technology import TypeVia -viewerConfig = { 'precision':2, 'gridstep':1.0 } +#viewerConfig = { 'precision':2, 'gridstep':1.0 } # The informations here are extracted from the Alliance ".rds" file, # and must be coherent with it. diff --git a/crlcore/etc/symbolic/cmos/technology.conf b/crlcore/etc/symbolic/cmos/technology.conf index 5b7c733c..4efca1f0 100644 --- a/crlcore/etc/symbolic/cmos/technology.conf +++ b/crlcore/etc/symbolic/cmos/technology.conf @@ -15,10 +15,13 @@ from Hurricane import DbU execfile( helpers.sysConfDir+'/common/technology.conf' ) -technoConfig = { 'name' : 'hcmos9gp' - , 'gridValue' : 0.005 - , 'gridUnit' : DbU.UnitPowerMicro - , 'gridsPerLambda': 24 +technoConfig = { 'name' : 'hcmos9gp' + , 'precision' : 2 + , 'gridValue' : 0.005 + , 'gridUnit' : DbU.UnitPowerMicro + , 'gridsPerLambda' : 24 + , 'symbolicGridStep' : 1.0 + , 'polygonStep' : 24.0 } diff --git a/crlcore/etc/symbolic/ispd05/technology.conf b/crlcore/etc/symbolic/ispd05/technology.conf index fb23f999..c7b1be63 100644 --- a/crlcore/etc/symbolic/ispd05/technology.conf +++ b/crlcore/etc/symbolic/ispd05/technology.conf @@ -12,10 +12,13 @@ from Hurricane import DbU execfile( helpers.sysConfDir+'/common/technology.conf' ) -technoConfig = { 'name' : 'hcmos9gp' - , 'gridValue' : 0.005 - , 'gridUnit' : DbU.UnitPowerMicro - , 'gridsPerLambda': 24 +technoConfig = { 'name' : 'ISPD05/symbolic' + , 'precision' : 2 + , 'gridValue' : 0.005 + , 'gridUnit' : DbU.UnitPowerMicro + , 'gridsPerLambda' : 24 + , 'symbolicGridStep' : 1.0 + , 'polygonStep' : 24.0 } diff --git a/crlcore/python/coriolisInit.py b/crlcore/python/coriolisInit.py index 613a6df5..299308b2 100644 --- a/crlcore/python/coriolisInit.py +++ b/crlcore/python/coriolisInit.py @@ -79,7 +79,6 @@ def coriolisConfigure(): , ('allianceConfig' , Alliance.loadAllianceConfig , SystemMandatory|AllianceHelper) , ('routingGaugesTable' , Alliance.loadRoutingGaugesTable, SystemMandatory|KiteHelper) , ('cellGaugesTable' , Alliance.loadCellGaugesTable , SystemMandatory|KiteHelper) - , ('viewerConfig' , Technology.loadViewerConfig , SystemMandatory|TechnologyHelper) , ('realLayersTable' , Technology.loadRealLayers , SystemMandatory|TechnologyHelper) , ('compositeLayersTable' , Technology.loadCompositeLayers , SystemMandatory|TechnologyHelper) , ('symbolicLayersTable' , Technology.tagSymbolicLayers , SystemMandatory|TechnologyHelper) @@ -97,8 +96,8 @@ def coriolisConfigure(): Cfg.Configuration.pushDefaultPriority ( Cfg.Parameter.Priority.ConfigurationFile ) - confFiles = [ (helpers.technoDir+'/alliance.conf' , SystemFile|AllianceHelper) - , (helpers.technoDir+'/technology.conf', SystemFile|TechnologyHelper) + confFiles = [ (helpers.technoDir+'/technology.conf', SystemFile|TechnologyHelper) + , (helpers.technoDir+'/alliance.conf' , SystemFile|AllianceHelper) , (helpers.technoDir+'/patterns.conf' , SystemFile|PatternsHelper) , (helpers.technoDir+'/display.conf' , SystemFile|DisplayHelper) , (helpers.technoDir+'/misc.conf' , SystemFile|ConfigurationHelper) diff --git a/crlcore/python/helpers/Alliance.py b/crlcore/python/helpers/Alliance.py index 3942b019..196b2cac 100644 --- a/crlcore/python/helpers/Alliance.py +++ b/crlcore/python/helpers/Alliance.py @@ -219,8 +219,6 @@ def loadAllianceConfig ( table, fromFile ): af = AllianceFramework.get() db = DataBase.getDB() technology = db.getTechnology() - if not technology: - technology = Hurricane.Technology.create(db,'Alliance') _loadAllianceConfig( af, table ) env = af.getEnvironment() diff --git a/crlcore/python/helpers/Technology.py b/crlcore/python/helpers/Technology.py index 8dcd436d..ced149b1 100644 --- a/crlcore/python/helpers/Technology.py +++ b/crlcore/python/helpers/Technology.py @@ -7,6 +7,7 @@ import traceback import Hurricane from Hurricane import DbU from Hurricane import DataBase +from Hurricane import Technology from Hurricane import Layer from Hurricane import BasicLayer from Hurricane import DiffusionLayer @@ -298,16 +299,6 @@ def tagSymbolicLayers ( symbolicLayersTable, confFile ): return -def loadViewerConfig ( viewerConfig, confFile ): - global technologyFile - technologyFile = confFile - try: - if viewerConfig.has_key('precision'): DbU.setPrecision(viewerConfig['precision']) - except Exception, e: - ErrorMessage.wrapPrint(e,'In %s:.') - return - - def loadGdsLayers ( realLayersTable, confFile ): technologyFile = confFile technology = DataBase.getDB().getTechnology() @@ -345,47 +336,86 @@ def loadGdsLayers ( realLayersTable, confFile ): return -def loadTechnoConfig ( technoConfig, confFile ): +def loadTechnoConfig ( technoConfig, confFile ): technologyFile = confFile technology = DataBase.getDB().getTechnology() + if not technology: + name = 'Unknown' + if technoConfig.has_key('name'): name = technoConfig['name'] + technology = Technology.create( DataBase.getDB(), name ) gridValue = 1 gridUnit = DbU.UnitPowerMicro - for key in [ 'gridUnit', 'gridValue', 'gridsPerLambda' ]: - try: - if key == 'gridUnit': - if technoConfig.has_key(key): - gridUnit = technoConfig[key] - if gridUnit != DbU.UnitPowerPico and \ - gridUnit != DbU.UnitPowerNano and \ - gridUnit != DbU.UnitPowerMicro and \ - gridUnit != DbU.UnitPowerMilli and \ - gridUnit != DbU.UnitPowerUnity and \ - gridUnit != DbU.UnitPowerKilo: - raise ErrorMessage(1,'In , invalid DbU unit power for gridUnit, reseting to Micro.') - else: - raise ErrorMessage(1,' has no defined, assuming Micro.') + for key in [ 'precision' + , 'gridUnit' + , 'gridValue' + , 'gridsPerLambda' + , 'symbolicGridStep' + , 'polygonStep' ]: + try: + if key == 'precision': + if technoConfig.has_key('precision'): + precision = technoConfig['precision'] + if not isinstance(gridUnit,int): + raise ErrorMessage(1,['In , must be of type int (and not: %s).' + % helpers.stype(precision) + ]) + DbU.setPrecision(precision) + else: + raise ErrorMessage(1,' has no defined.') - elif key == 'gridValue': - if technoConfig.has_key('gridValue'): - gridValue = technoConfig['gridValue'] - if not isinstance(gridUnit,float) and not isinstance(gridUnit,int): - raise ErrorMessage(1,['In , must be of type float (and not: %s).' - % helpers.stype(gridValue) - ]) - DbU.setPhysicalsPerGrid(gridValue,gridUnit) - else: - raise ErrorMessage(1,' has no defined.') + elif key == 'gridUnit': + if technoConfig.has_key(key): + gridUnit = technoConfig[key] + if gridUnit != DbU.UnitPowerPico and \ + gridUnit != DbU.UnitPowerNano and \ + gridUnit != DbU.UnitPowerMicro and \ + gridUnit != DbU.UnitPowerMilli and \ + gridUnit != DbU.UnitPowerUnity and \ + gridUnit != DbU.UnitPowerKilo: + raise ErrorMessage(1,'In , invalid DbU unit power for gridUnit, reseting to Micro.') + else: + raise ErrorMessage(1,' has no defined, assuming Micro.') + + elif key == 'gridValue': + if technoConfig.has_key('gridValue'): + gridValue = technoConfig['gridValue'] + if not isinstance(gridUnit,float) and not isinstance(gridUnit,int): + raise ErrorMessage(1,['In , must be of type float (and not: %s).' + % helpers.stype(gridValue) + ]) + DbU.setPhysicalsPerGrid(gridValue,gridUnit) + else: + raise ErrorMessage(1,' has no defined.') - elif key == 'gridsPerLambda': - if technoConfig.has_key('gridsPerLambda'): - gridsPerLambda = technoConfig['gridsPerLambda'] - if not isinstance(gridsPerLambda,int): - raise ErrorMessage(1,['In , must be of type int (and not: %s).' - % helpers.stype(gridsPerLambda) - ]) - DbU.setGridsPerLambda(gridsPerLambda) + elif key == 'gridsPerLambda': + if technoConfig.has_key('gridsPerLambda'): + gridsPerLambda = technoConfig['gridsPerLambda'] + if not isinstance(gridsPerLambda,int): + raise ErrorMessage(1,['In , must be of type int (and not: %s).' + % helpers.stype(gridsPerLambda) + ]) + DbU.setGridsPerLambda(gridsPerLambda) + + elif key == 'polygonStep': + if technoConfig.has_key('polygonStep'): + polygonStep = technoConfig['polygonStep'] + if not isinstance(polygonStep,float): + raise ErrorMessage(1,['In , must be of type float (and not: %s).' + % helpers.stype(polygonStep) + ]) + DbU.setPolygonStep( DbU.fromGrid(polygonStep) ) + + elif key == 'symbolicGridStep': + if technoConfig.has_key('symbolicGridStep'): + gridStep = technoConfig['symbolicGridStep'] + if not isinstance(gridStep,float): + raise ErrorMessage(1,['In , must be of type float (and not: %s).' + % helpers.stype(gridStep) + ]) + DbU.setSymbolicSnapGridStep( DbU.fromLambda(gridStep) ) - except Exception, e: - ErrorMessage.wrapPrint(e) + except Exception, e: + ErrorMessage.wrapPrint(e) + return diff --git a/documentation/examples/scripts/polygons.py b/documentation/examples/scripts/polygons.py index 49ead425..2b5cbb44 100644 --- a/documentation/examples/scripts/polygons.py +++ b/documentation/examples/scripts/polygons.py @@ -15,12 +15,14 @@ def doBreak ( level, message ): def buildPolygons ( editor ): + #DbU.setPolygonStep( toDbU(0.1) ) + UpdateSession.open() cell = AllianceFramework.get().createCell( 'polygons' ) cell.setTerminal( True ) - cell.setAbutmentBox( Box( toDbU(0.0), toDbU(0.0), toDbU(15.0), toDbU(50.0) ) ) + cell.setAbutmentBox( Box( toDbU(-5.0), toDbU(-5.0), toDbU(65.0), toDbU(75.0) ) ) if editor: UpdateSession.close() @@ -30,6 +32,8 @@ def buildPolygons ( editor ): technology = DataBase.getDB().getTechnology() metal1 = technology.getLayer( "METAL1" ) + metal2 = technology.getLayer( "METAL2" ) + metal4 = technology.getLayer( "METAL4" ) poly = technology.getLayer( "POLY" ) ptrans = technology.getLayer( "PTRANS" ) ntrans = technology.getLayer( "NTRANS" ) @@ -44,14 +48,64 @@ def buildPolygons ( editor ): net = Net.create( cell, 'my_net' ) net.setExternal( True ) - t = Triangle.create( net, metal1, Point( toDbU( 0.0), toDbU( 0.0) ) - , Point( toDbU( 100.0), toDbU( 0.0) ) - , Point( toDbU( 50.0), toDbU( 50.0) ) ) + #points = [ Point( toDbU( 0.0), toDbU( 0.0) ) + # , Point( toDbU( 10.0), toDbU( 0.0) ) + # , Point( toDbU( 7.0), toDbU( 8.0) ) + # , Point( toDbU( 3.0), toDbU( 8.0) ) ] + #p = Polygon.create( net, metal4, points ) + + # Counter-clockwise, slope > 1. + points = [ Point( toDbU( 3.0), toDbU( 0.0) ) + , Point( toDbU( 13.0), toDbU( 0.0) ) + , Point( toDbU( 16.0), toDbU( 10.0) ) + , Point( toDbU( 16.0), toDbU( 20.0) ) + , Point( toDbU( 13.0), toDbU( 30.0) ) + , Point( toDbU( 3.0), toDbU( 30.0) ) + , Point( toDbU( 0.0), toDbU( 20.0) ) + , Point( toDbU( 0.0), toDbU( 10.0) ) ] + p = Polygon.create( net, metal2, points ) + #p.translate( toDbU(40.0), toDbU(0.0) ) + + # clockwise, slope > 1. + points = [ Point( toDbU( 0.0), toDbU( 10.0) ) + , Point( toDbU( 0.0), toDbU( 20.0) ) + , Point( toDbU( 3.0), toDbU( 30.0) ) + , Point( toDbU( 13.0), toDbU( 30.0) ) + , Point( toDbU( 16.0), toDbU( 20.0) ) + , Point( toDbU( 16.0), toDbU( 10.0) ) + , Point( toDbU( 13.0), toDbU( 0.0) ) + , Point( toDbU( 3.0), toDbU( 0.0) ) ] + p = Polygon.create( net, metal2, points ) + p.translate( toDbU(0.0), toDbU(40.0) ) + + # Counter-clockwise, slope < 1. + points = [ Point( toDbU( 10.0), toDbU( 0.0) ) + , Point( toDbU( 20.0), toDbU( 0.0) ) + , Point( toDbU( 30.0), toDbU( 3.0) ) + , Point( toDbU( 30.0), toDbU( 13.0) ) + , Point( toDbU( 20.0), toDbU( 16.0) ) + , Point( toDbU( 10.0), toDbU( 16.0) ) + , Point( toDbU( 0.0), toDbU( 13.0) ) + , Point( toDbU( 0.0), toDbU( 3.0) ) ] + p = Polygon.create( net, metal2, points ) + p.translate( toDbU(30.0), toDbU(0.0) ) + + # clockwise. + points = [ Point( toDbU( 0.0), toDbU( 3.0) ) + , Point( toDbU( 0.0), toDbU( 13.0) ) + , Point( toDbU( 10.0), toDbU( 16.0) ) + , Point( toDbU( 20.0), toDbU( 16.0) ) + , Point( toDbU( 30.0), toDbU( 13.0) ) + , Point( toDbU( 30.0), toDbU( 3.0) ) + , Point( toDbU( 20.0), toDbU( 0.0) ) + , Point( toDbU( 10.0), toDbU( 0.0) ) ] + p = Polygon.create( net, metal2, points ) + p.translate( toDbU(30.0), toDbU(40.0) ) UpdateSession.close() #AllianceFramework.get().saveCell( cell, Catalog.State.Views ) - # No saving as we don't have + # No saving as we don't have a GDSII driver (yet). return diff --git a/hurricane/doc/hurricane/Polygon.dox b/hurricane/doc/hurricane/Polygon.dox new file mode 100644 index 00000000..58c692e1 --- /dev/null +++ b/hurricane/doc/hurricane/Polygon.dox @@ -0,0 +1,53 @@ + + // -*- C++ -*- + + + namespace Hurricane { + + /*! \class Polygon + * \brief Polygon description (\b API) + * + * \section secPadIntro Introduction + * + * Polygon should be used to create huge convex and manhattanized polygons. + * Manhattanization is done so the real geometric shape is completly included + * in it. The memory representation has been optimized for very large shape + * (compare to the foundry grid) and is inefficient for small ones. + * + * The minimal step length for the manhattanisation is set up with + * DbU::setPolygonStep(). + */ + + + + /*! \typedef Polygon::Super + * Useful for calling upon methods of the base class without + * knowing it. + */ + + + /*! \function Polygon* Polygon::create( Net* net, const Layer* layer, const std::vector& points ); + * Create a polygon of \c layer in \c net. \c points define the vertexes. + */ + + + //! \name Polygon Collection + // \{ + + /*! \typedef Polygons + * Generic collection representing a set of polygons. + */ + + /*! \typedef PolygonLocator + * Generic locator for traversing a collection of polygons. + */ + + /*! \typedef PolygonFilter + * Generic filter allowing to select a subset of polygons matching + * some criteria. + */ + + // \} + + + } diff --git a/hurricane/doc/hurricane/doxyfile b/hurricane/doc/hurricane/doxyfile index 5e7f4ee3..5054775c 100644 --- a/hurricane/doc/hurricane/doxyfile +++ b/hurricane/doc/hurricane/doxyfile @@ -703,6 +703,8 @@ INPUT = Generalities.dox \ ../../src/hurricane/hurricane/Pads.h \ ../../src/hurricane/hurricane/Pad.h \ Pad.dox \ + ../../src/hurricane/hurricane/Polygon.h \ + Polygon.dox \ ../../src/hurricane/hurricane/Rubbers.h \ ../../src/hurricane/hurricane/Rubber.h \ RoutingPad.dox \ diff --git a/hurricane/src/hurricane/CMakeLists.txt b/hurricane/src/hurricane/CMakeLists.txt index 9cefd8d6..b9c62711 100644 --- a/hurricane/src/hurricane/CMakeLists.txt +++ b/hurricane/src/hurricane/CMakeLists.txt @@ -92,7 +92,7 @@ hurricane/Technology.h hurricane/Timer.h hurricane/Transformation.h - hurricane/Triangle.h + hurricane/Polygon.h hurricane/DbU.h hurricane/UpdateSession.h hurricane/VectorCollection.h @@ -161,7 +161,7 @@ Horizontal.cpp Pad.cpp RoutingPad.cpp - Triangle.cpp + Polygon.cpp NetExternalComponents.cpp NetRoutingProperty.cpp Reference.cpp diff --git a/hurricane/src/hurricane/DataBase.cpp b/hurricane/src/hurricane/DataBase.cpp index 38188af0..60005397 100644 --- a/hurricane/src/hurricane/DataBase.cpp +++ b/hurricane/src/hurricane/DataBase.cpp @@ -167,10 +167,11 @@ Record* DataBase::_getRecord() const { Record* record = Inherit::_getRecord(); if (record) { - record->add(getSlot("_technology" , _technology )); - record->add(getSlot("_rootLibrary" , _rootLibrary )); - record->add(getSlot("DbU::precision" , DbU::getPrecision())); - record->add(getSlot("DbU::resolution", DbU::db(1) )); + record->add(getSlot("_technology" , _technology )); + record->add(getSlot("_rootLibrary" , _rootLibrary )); + record->add(getSlot("DbU::precision" , DbU::getPrecision())); + record->add(getSlot("DbU::resolution" , DbU::db(1) )); + record->add( DbU::getValueSlot("DbU::polygonStep", &DbU::_polygonStep )); //record->add(getSlot("GridStep", getValueString(getGridStep()))); } return record; diff --git a/hurricane/src/hurricane/DbU.cpp b/hurricane/src/hurricane/DbU.cpp index b9e89b28..29e91517 100644 --- a/hurricane/src/hurricane/DbU.cpp +++ b/hurricane/src/hurricane/DbU.cpp @@ -54,6 +54,7 @@ namespace Hurricane { DbU::UnitPower DbU::_stringModeUnitPower = DbU::Nano; DbU::Unit DbU::_symbolicSnapGridStep = DbU::fromLambda( 1.0); DbU::Unit DbU::_realSnapGridStep = DbU::fromGrid (10.0); + DbU::Unit DbU::_polygonStep = DbU::fromGrid ( 1.0); const DbU::Unit DbU::Min = std::numeric_limits::min(); const DbU::Unit DbU::Max = std::numeric_limits::max(); @@ -159,7 +160,7 @@ namespace Hurricane { _resolution = 1; while ( precision-- ) _resolution /= 10; - if (not (flags & NoTechnoUpdate)) + if (not (flags & NoTechnoUpdate) and DataBase::getDB()->getTechnology()) DataBase::getDB()->getTechnology()->_onDbuChange ( scale ); setSymbolicSnapGridStep ( DbU::lambda( 1.0) ); @@ -210,7 +211,7 @@ namespace Hurricane { _gridsPerLambda = gridsPerLambda; - if (not (flags & NoTechnoUpdate)) + if (not (flags & NoTechnoUpdate) and DataBase::getDB()->getTechnology()) DataBase::getDB()->getTechnology()->_onDbuChange ( scale ); setSymbolicSnapGridStep ( DbU::lambda(1) ); diff --git a/hurricane/src/hurricane/Polygon.cpp b/hurricane/src/hurricane/Polygon.cpp new file mode 100644 index 00000000..65bc9e6d --- /dev/null +++ b/hurricane/src/hurricane/Polygon.cpp @@ -0,0 +1,518 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2000-2018, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./Polygon.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" +#include "hurricane/Polygon.h" +#include "hurricane/Net.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/Layer.h" +#include "hurricane/Error.h" + + +namespace Hurricane { + + +// ------------------------------------------------------------------- +// Class : "Polygon::Edge". + + Polygon::Edge::Edge ( Point origin, Point extremity, uint32_t flags ) + : _flags (flags) + , _xyOrigin(0) + , _steps () + { + if (origin.getX() == extremity.getX()) { + _flags |= Polygon::Vertical; + _xyOrigin = origin.getX(); + _steps.push_back( origin.getY() ); + return; + } + if (origin.getY() == extremity.getY()) { + _flags |= Polygon::Horizontal; + _xyOrigin = origin.getX(); + _steps.push_back( origin.getY() ); + return; + } + + float slope = Polygon::getSlope( origin, extremity ); + if (extremity.getX() > origin.getX()) _flags |= Polygon::XIncrease; + if (extremity.getY() > origin.getY()) _flags |= Polygon::YIncrease; + + if ( (slope > 1.0) or (slope < -1.0) ) { + _flags |= Polygon::XSteps; + _xyOrigin = origin.getX(); + + DbU::Unit b = origin.getY() +- slope*origin.getX(); + DbU::Unit delta = DbU::getPolygonStep(); + if (not (_flags & Polygon::XIncrease)) delta = -delta; + + _steps.push_back( origin.getY() ); + + DbU::Unit x = origin.getX() + delta; + while ( true ) { + if ( (delta > 0) and (x > extremity.getX()) ) break; + if ( (delta < 0) and (x < extremity.getX()) ) break; + + DbU::Unit y = slope*x + b; + DbU::Unit m = y % DbU::getPolygonStep(); + + if (m) { + if (isClockwise() xor not isXIncrease()) y += DbU::getPolygonStep() - m; + else y += -m; + } + _steps.push_back( y ); + + x += delta; + } + } else { + _flags |= Polygon::YSteps; + _xyOrigin = origin.getY(); + + float islope = 1/slope; + DbU::Unit delta = DbU::getPolygonStep(); + if (not (_flags & Polygon::YIncrease)) delta = -delta; + + _steps.push_back( origin.getX() ); + + DbU::Unit y = origin.getY() + delta; + while ( true ) { + if ( (delta > 0) and (y > extremity.getY()) ) break; + if ( (delta < 0) and (y < extremity.getY()) ) break; + + DbU::Unit x = islope*(y - origin.getY()) + origin.getX(); + DbU::Unit m = x % DbU::getPolygonStep(); + + if (m) { + if (isClockwise() xor isYIncrease()) x += DbU::getPolygonStep() - m; + else x += -m; + } + _steps.push_back( x ); + + y += delta; + } + } + } + + + Point Polygon::Edge::getPoint ( size_t i ) const + { + if (i >= getSize()) return Point( 0, 0 ); + if (isHV()) return Point( _xyOrigin, _steps[0] ); + + size_t offset = (_flags & Polygon::Above) ? 0 : 1; + if (not (_flags & Polygon::YIncrease)) offset = 1 - offset; + + Point point; + + + if (_flags & YSteps) { + DbU::Unit delta = DbU::getPolygonStep(); + if (not (_flags & Polygon::YIncrease)) delta = -delta; + + point.setX( _steps[ (i+offset)/2 ] ); + point.setY( _xyOrigin + delta*((i+1-offset)/2) ); + } else { + DbU::Unit delta = DbU::getPolygonStep(); + if (not (_flags & Polygon::XIncrease)) delta = -delta; + + point.setX( _xyOrigin + delta*((i+offset)/2) ); + point.setY( _steps[ (i+1-offset)/2 ] ); + } + + return point; + } + + + void Polygon::Edge::translate ( DbU::Unit dx, DbU::Unit dy ) + { + if (isXSteps()) { + _xyOrigin += dx; + for ( DbU::Unit& y : _steps ) y += dy; + } else if (isYSteps()) { + _xyOrigin += dy; + for ( DbU::Unit& x : _steps ) x += dx; + } else if (isHV()) { + _xyOrigin += dx; + _steps[0] += dy; + } + } + + + string Polygon::Edge::_getTypeName () const + { return _TName( "Polygon::Edge" ); }; + + + string Polygon::Edge::_getString() const + { + string s = "add( getSlot("_flags" , _flags ) ); + record->add( DbU::getValueSlot("_xyOrigin", &_xyOrigin) ); + record->add( getSlot("_steps" , &_steps ) ); + return record; + } + + +// ------------------------------------------------------------------- +// Class : "Polygon". + + Polygon::Polygon ( Net* net, const Layer* layer, const vector& points ) + : Super (net) + , _layer (layer) + , _points(points) + , _edges () + { } + + + Polygon* Polygon::create ( Net* net, const Layer* layer, const vector& points ) + { + if (not layer) + throw Error("Can't create " + _TName("Polygon") + " : null layer"); + + if (points.size() < 3) + throw Error("Can't create " + _TName("Polygon") + " : less than three points"); + + float sign = 0.0; + for ( size_t i=0 ; i_postCreate(); + triangle->manhattanize(); + return triangle; + } + + + Polygon::~Polygon () + { + for ( Edge* edge : _edges ) delete edge; + } + + + const Layer* Polygon::getLayer () const + { return _layer; }; + + + DbU::Unit Polygon::getX () const + { + DbU::Unit center = 0; + for ( Point p : _points ) center += p.getX(); + return center/_points.size(); + } + + + DbU::Unit Polygon::getY () const + { + DbU::Unit center = 0; + for ( Point p : _points ) center += p.getY(); + return center/_points.size(); + } + + + Box Polygon::getBoundingBox() const + { + DbU::Unit xmin = DbU::Max; + DbU::Unit ymin = DbU::Max; + DbU::Unit xmax = DbU::Min; + DbU::Unit ymax = DbU::Min; + + for ( Point p : _points ) { + xmin = std::min( xmin, p.getX() ); + ymin = std::min( ymin, p.getY() ); + xmax = std::max( xmax, p.getX() ); + ymax = std::max( ymax, p.getY() ); + } + + return Box( xmin, ymin, xmax, ymax ); + } + + + Box Polygon::getBoundingBox ( const BasicLayer* basicLayer ) const + { + if (not _layer->contains(basicLayer)) return Box(); + return getBoundingBox(); + } + + + void Polygon::translate ( const DbU::Unit& dx, const DbU::Unit& dy ) + { + if ((dx != 0) or (dy != 0)) { + invalidate( true ); + for ( Point& p : _points ) p .translate( dx, dy ); + for ( Edge* e : _edges ) e->translate( dx, dy ); + } + } + + + void Polygon::setLayer ( const Layer* layer ) + { + if (not layer) throw Error("Can't set layer : null layer"); + + if (layer != _layer) { + invalidate(false); + _layer = layer; + } + } + + + void Polygon::setPoints ( const vector& points ) + { + invalidate( true ); + + vector emptyVector; + _points.swap( emptyVector ); + _points.reserve( points.size() ); + _points = points; + + if (isManhattanized()) { + for ( Edge* edge : _edges ) delete edge; + _edges.clear(); + + manhattanize(); + } + } + + + float Polygon::getSign ( const vector& points, size_t i ) + { + size_t i1 = (i+1) % points.size(); + size_t i2 = (i+2) % points.size(); + + float dx1 = (float)(points[i1].getX() - points[i ].getX()); + float dy1 = (float)(points[i1].getY() - points[i ].getY()); + float dx2 = (float)(points[i2].getX() - points[i1].getX()); + float dy2 = (float)(points[i2].getY() - points[i1].getY()); + return dx1*dy2 - dx2*dy1; + } + + + float Polygon::getSlope ( const Point& origin, const Point& extremity ) + { + float dx1 = (float)(extremity.getX() - origin.getX()); + float dy1 = (float)(extremity.getY() - origin.getY()); + return dy1 / dx1; + } + + + float Polygon::getSlope ( size_t i ) const + { + return getSlope( _points[ i % _points.size() ], _points[ (i+1) % _points.size() ] ); + } + + + void Polygon::manhattanize () + { + 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; + + _edges.push_back( new Edge ( origin, extremity, flags ) ); + } + } + + + void Polygon::_toJson ( JsonWriter* writer ) const + { + Super::_toJson( writer ); + + jsonWrite( writer, "_layer", _layer->getName() ); + for ( size_t i=0 ; i<_points.size() ; ++i ) { + string label = "_points[" + getString(i) + "]"; + jsonWrite( writer, label, &_points[i] ); + } + } + + + string Polygon::_getTypeName () const + { return _TName( "Polygon" ); }; + + + string Polygon::_getString() const + { + string s = Super::_getString(); + s.insert( s.length() - 1, " " + getString(_layer->getName())); + s.insert( s.length() - 1, " points:" + getString(_points.size())); + return s; + } + + + Record* Polygon::_getRecord() const + { + Record* record = Inherit::_getRecord(); + if (record) { + record->add( getSlot("_layer" , _layer ) ); + record->add( getSlot("_points", &_points) ); + record->add( getSlot("_edges" , &_edges ) ); + } + return record; + } + + + Initializer jsonPolygonInit ( 0 ); + + + void JsonPolygon::initialize () + { JsonTypes::registerType( new JsonPolygon (JsonWriter::RegisterMode) ); } + + + JsonPolygon::JsonPolygon ( unsigned long flags ) + : JsonComponent(flags) + { + add( "_layer" , typeid(string) ); + // THIS IS BUGGY ! + add( "_point[0]", typeid(Point) ); + add( "_point[1]", typeid(Point) ); + add( "_point[2]", typeid(Point) ); + } + + + string JsonPolygon::getTypeName () const + { return "Polygon"; } + + + JsonPolygon* JsonPolygon::clone ( unsigned long flags ) const + { return new JsonPolygon ( flags ); } + + + void JsonPolygon::toData ( JsonStack& stack ) + { + check( stack, "JsonPolygon::toData" ); + unsigned int jsonId = presetId( stack ); + + vector points; + points.push_back( get(stack,".Point") ); + points.push_back( get(stack,".Point") ); + points.push_back( get(stack,".Point") ); + + Polygon* triangle = Polygon::create + ( get(stack,".Net") + , DataBase::getDB()->getTechnology()->getLayer( get(stack,"_layer") ) + , points + ); + + JsonNet* jnet = jget( stack ); + if (jnet) { + jnet->addHookLink( triangle->getBodyHook(), jsonId, get(stack,"_bodyHook" ) ); + } else { + cerr << Error( "JsonPolygon::toData(): Missing (Json)Net in stack context." ) << endl; + } + + // Hook/Ring rebuild are done as a post-process. + update( stack, triangle ); +} + + +// ------------------------------------------------------------------- +// Class : "Polygon::Points_Manhattan". + + Polygon::Points_Manhattan::Locator::Locator ( const Polygon* polygon ) + : PointHL () + , _polygon(polygon) + , _iEdge (0) + , _iPoint (0) + { } + + + PointHL* Polygon::Points_Manhattan::Locator::getClone () const + { return new Locator(*this); } + + + Point Polygon::Points_Manhattan::Locator::getElement () const + { return _polygon->getEdges()[_iEdge]->getPoint(_iPoint); } + + + bool Polygon::Points_Manhattan::Locator::isValid () const + { return (_iEdge < _polygon->getEdges().size()); } + + + void Polygon::Points_Manhattan::Locator::progress () + { + if (isValid()) { + if (_iPoint + 1 >= _polygon->getEdges()[_iEdge]->getSize()) { + ++_iEdge; + _iPoint = 0; + } else { + ++_iPoint; + } + } + } + + + string Polygon::Points_Manhattan::Locator::_getString () const + { + string s = "<" + _TName("Points_Manhattan::Locator") + + getString(getElement()) + + ">"; + return s; + } + + + PointHC* Polygon::Points_Manhattan::getClone () const + { return new Points_Manhattan(*this); } + + + PointHL* Polygon::Points_Manhattan::getLocator () const + { return new Locator(_polygon); } + + + string Polygon::Points_Manhattan::_getString () const + { + string s = "<" + _TName("Points_Manhattan") + " " + + getString(_polygon) + + ">"; + return s; + } + + +} // Hurricane namespace. diff --git a/hurricane/src/hurricane/Technology.cpp b/hurricane/src/hurricane/Technology.cpp index d5cb74a5..e2841352 100644 --- a/hurricane/src/hurricane/Technology.cpp +++ b/hurricane/src/hurricane/Technology.cpp @@ -298,10 +298,7 @@ ViaLayers Technology::getViaLayers() const void Technology::_onDbuChange ( float scale ) - { - forEach ( Layer*, layer, getLayers() ) - layer->_onDbuChange ( scale ); - } + { for ( Layer* layer : getLayers() ) layer->_onDbuChange( scale ); } void Technology::setName(const Name& name) diff --git a/hurricane/src/hurricane/Triangle.cpp b/hurricane/src/hurricane/Triangle.cpp deleted file mode 100644 index c35e4657..00000000 --- a/hurricane/src/hurricane/Triangle.cpp +++ /dev/null @@ -1,227 +0,0 @@ -// -*- C++ -*- -// -// Copyright (c) BULL S.A. 2000-2018, All Rights Reserved -// -// This file is part of Hurricane. -// -// Hurricane is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// Hurricane is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU -// General Public License for more details. -// -// You should have received a copy of the Lesser GNU General Public -// License along with Hurricane. If not, see -// . -// -// +-----------------------------------------------------------------+ -// | H U R R I C A N E | -// | V L S I B a c k e n d D a t a - B a s e | -// | | -// | Author : Jean-Paul Chaput | -// | E-mail : Jean-Paul.Chaput@lip6.fr | -// | =============================================================== | -// | C++ Module : "./Triangle.cpp" | -// +-----------------------------------------------------------------+ - - -#include "hurricane/DataBase.h" -#include "hurricane/Technology.h" -#include "hurricane/Triangle.h" -#include "hurricane/Net.h" -#include "hurricane/BasicLayer.h" -#include "hurricane/Layer.h" -#include "hurricane/Error.h" - - -namespace Hurricane { - - - Triangle::Triangle ( Net* net, const Layer* layer, const Point& a, const Point& b, const Point& c ) - : Super (net) - , _layer (layer) - , _points() - { - if (not _layer) - throw Error("Can't create " + _TName("Triangle") + " : null layer"); - - _points[0] = a; - _points[1] = b; - _points[2] = c; - } - - - Triangle* Triangle::create ( Net* net, const Layer* layer, const Point& a, const Point& b, const Point& c ) - { - Triangle* triangle = new Triangle ( net, layer, a, b, c ); - triangle->_postCreate(); - return triangle; - } - - - const Layer* Triangle::getLayer () const - { return _layer; }; - - - DbU::Unit Triangle::getX () const - { - DbU::Unit center = 0; - for ( Point p : _points ) center += p.getX(); - return center/3; - } - - - DbU::Unit Triangle::getY () const - { - DbU::Unit center = 0; - for ( Point p : _points ) center += p.getY(); - return center/3; - } - - - Box Triangle::getBoundingBox() const - { - DbU::Unit xmin = DbU::Max; - DbU::Unit ymin = DbU::Max; - DbU::Unit xmax = DbU::Min; - DbU::Unit ymax = DbU::Min; - - for ( Point p : _points ) { - xmin = std::min( xmin, p.getX() ); - ymin = std::min( ymin, p.getY() ); - xmax = std::max( xmax, p.getX() ); - ymax = std::max( ymax, p.getY() ); - } - - return Box( xmin, ymin, xmax, ymax ); - } - - - Box Triangle::getBoundingBox ( const BasicLayer* basicLayer ) const - { - if (not _layer->contains(basicLayer)) return Box(); - return getBoundingBox(); - } - - - void Triangle::translate ( const DbU::Unit& dx, const DbU::Unit& dy ) - { - if ((dx != 0) or (dy != 0)) { - invalidate(true); - for ( Point p : _points ) p.translate( dx, dy ); - } - } - - - void Triangle::setLayer ( const Layer* layer ) - { - if (not layer) throw Error("Can't set layer : null layer"); - - if (layer != _layer) { - invalidate(false); - _layer = layer; - } - } - - - void Triangle::setPoints ( const Point& a, const Point& b, const Point& c ) - { - invalidate(true); - _points[0] = a; - _points[1] = b; - _points[2] = c; - } - - - void Triangle::_toJson ( JsonWriter* writer ) const - { - Super::_toJson( writer ); - - jsonWrite( writer, "_layer" , _layer->getName() ); - jsonWrite( writer, "_points[0]", &_points[0] ); - jsonWrite( writer, "_points[1]", &_points[1] ); - jsonWrite( writer, "_points[2]", &_points[2] ); - } - - - string Triangle::_getTypeName () const - { return _TName( "Triangle" ); }; - - - string Triangle::_getString() const - { - string s = Super::_getString(); - s.insert( s.length() - 1, " " + getString(_layer->getName())); - s.insert( s.length() - 1, " " + getString(_points[0])); - s.insert( s.length() - 1, " " + getString(_points[1])); - s.insert( s.length() - 1, " " + getString(_points[2])); - return s; - } - - - Record* Triangle::_getRecord() const - { - Record* record = Inherit::_getRecord(); - if (record) { - record->add( getSlot("_layer" , _layer ) ); - record->add( getSlot("_points", &_points) ); - } - return record; - } - - - Initializer jsonTriangleInit ( 0 ); - - - void JsonTriangle::initialize () - { JsonTypes::registerType( new JsonTriangle (JsonWriter::RegisterMode) ); } - - - JsonTriangle::JsonTriangle ( unsigned long flags ) - : JsonComponent(flags) - { - add( "_layer" , typeid(string) ); - add( "_point[0]", typeid(Point) ); - add( "_point[1]", typeid(Point) ); - add( "_point[2]", typeid(Point) ); - } - - - string JsonTriangle::getTypeName () const - { return "Triangle"; } - - - JsonTriangle* JsonTriangle::clone ( unsigned long flags ) const - { return new JsonTriangle ( flags ); } - - - void JsonTriangle::toData ( JsonStack& stack ) - { - check( stack, "JsonTriangle::toData" ); - unsigned int jsonId = presetId( stack ); - - Triangle* triangle = Triangle::create - ( get(stack,".Net") - , DataBase::getDB()->getTechnology()->getLayer( get(stack,"_layer") ) - , get(stack,".Point") - , get(stack,".Point") - , get(stack,".Point") - ); - - JsonNet* jnet = jget( stack ); - if (jnet) { - jnet->addHookLink( triangle->getBodyHook(), jsonId, get(stack,"_bodyHook" ) ); - } else { - cerr << Error( "JsonTriangle::toData(): Missing (Json)Net in stack context." ) << endl; - } - - // Hook/Ring rebuild are done as a post-process. - update( stack, triangle ); -} - - -} // Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/DbU.h b/hurricane/src/hurricane/hurricane/DbU.h index 6da410ab..c65a7cbc 100644 --- a/hurricane/src/hurricane/hurricane/DbU.h +++ b/hurricane/src/hurricane/hurricane/DbU.h @@ -40,8 +40,11 @@ namespace Hurricane { + class DataBase; + class DbU { + friend class DataBase; public: enum FunctionFlags { NoFlags = 0 , NoTechnoUpdate = (1<<0) @@ -85,11 +88,14 @@ namespace Hurricane { static unsigned int getMaximalPrecision (); static double getResolution (); static void setPrecision ( unsigned int precision, unsigned int flags=NoFlags ); - // Founder Grid Managment. + // Foundry Grid Managment. static double getUnitPower ( UnitPower p ); static void setPhysicalsPerGrid ( double gridsPerLambda, UnitPower p ); static double getPhysicalsPerGrid (); static double physicalToGrid ( double physical, UnitPower p ); + // Huge Polygon Step Managment. + static inline DbU::Unit getPolygonStep (); + static inline void setPolygonStep ( DbU::Unit ); // Lamba Managment. static void setGridsPerLambda ( double gridsPerLambda, unsigned int flags=NoFlags ); static double getGridsPerLambda (); @@ -142,6 +148,7 @@ namespace Hurricane { static DbU::UnitPower _stringModeUnitPower; static DbU::Unit _realSnapGridStep; static DbU::Unit _symbolicSnapGridStep; + static DbU::Unit _polygonStep; static double _gridMax; static double _lambdaMax; static double _physicalMax; @@ -161,6 +168,7 @@ namespace Hurricane { inline double DbU::toLambda ( double u ) { return toGrid(u)/_gridsPerLambda; } inline double DbU::toPhysical ( DbU::Unit u, UnitPower p ) { return (_physicalsPerGrid*_resolution*(double)u)/getUnitPower(p); } inline double DbU::toPhysical ( double u, UnitPower p ) { return (_physicalsPerGrid*_resolution*u)/getUnitPower(p); } + inline DbU::Unit DbU::getPolygonStep () { return _polygonStep; } // Old converter naming scheme. inline DbU::Unit DbU::db ( DbU::Unit value ) { return fromDb(value); } @@ -177,6 +185,7 @@ namespace Hurricane { inline void DbU::setRealSnapGridStep ( DbU::Unit step ) { _realSnapGridStep = step; } inline void DbU::setSymbolicSnapGridStep ( DbU::Unit step ) { _symbolicSnapGridStep = step; } + inline void DbU::setPolygonStep ( DbU::Unit step ) { _polygonStep = step; } inline DbU::Unit DbU::getOnPhysicalGrid ( DbU::Unit u, SnapMode mode ) { return getOnCustomGrid(u, grid(1), mode); } @@ -226,4 +235,26 @@ inline Hurricane::Record* getRecord ( const std::array& } +template<> +inline std::string getString ( const std::vector* v ) +{ + std::string name = "const std::vector:"; + return name + getString(v->size()); +} + + +template<> +inline Hurricane::Record* getRecord ( const std::vector* v ) +{ + Hurricane::Record* record = NULL; + record = new Hurricane::Record ( "const vector" ); + + for ( size_t i=0 ; isize() ; ++i ) { + std::string label = "[" + getString(i) + "] "; + record->add( Hurricane::DbU::getValueSlot(label, &(*v)[i]) ); + } + return record; +} + + #endif // HURRICANE_DBU_H diff --git a/hurricane/src/hurricane/hurricane/Polygon.h b/hurricane/src/hurricane/hurricane/Polygon.h new file mode 100644 index 00000000..28450d32 --- /dev/null +++ b/hurricane/src/hurricane/hurricane/Polygon.h @@ -0,0 +1,200 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2000-2018, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricane/Polygon.h" | +// +-----------------------------------------------------------------+ + + +#ifndef HURRICANE_POLYGON_H +#define HURRICANE_POLYGON_H + +#include "hurricane/Points.h" +#include "hurricane/Component.h" +#include "hurricane/Polygons.h" + + +namespace Hurricane { + + class Layer; + + + typedef Hurricane::Filter PointHF; + typedef Hurricane::Locator PointHL; + typedef Hurricane::Collection PointHC; + + + class Polygon : public Component { + public: + typedef Component Super; + public: + static const uint32_t Above = (1<<0); + static const uint32_t YSteps = (1<<1); + static const uint32_t XSteps = (1<<2); + static const uint32_t XIncrease = (1<<3); + 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 { + public: + Edge ( Point origin, Point extremity, uint32_t flags ); + 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; + inline bool isXSteps () const; + inline bool isYSteps () const; + void translate ( DbU::Unit dx, DbU::Unit dy ); + string _getTypeName () const; + string _getString () const; + Record* _getRecord () const; + private: + uint32_t _flags; + DbU::Unit _xyOrigin; + vector _steps; + }; + + public: + class Points_Manhattan : public PointHC { + public: + class Locator : public PointHL { + public: + Locator ( const Polygon* ); + inline Locator ( const Locator& ); + virtual Point getElement () const; + virtual PointHL* getClone () const; + virtual bool isValid () const; + virtual void progress (); + virtual string _getString () const; + protected: + const Polygon* _polygon; + size_t _iEdge; + size_t _iPoint; + }; + public: + inline Points_Manhattan ( const Polygon* ); + inline Points_Manhattan ( const Points_Manhattan& ); + virtual PointHC* getClone () const; + virtual PointHL* getLocator () const; + virtual string _getString () const; + protected: + const Polygon* _polygon; + }; + + public: + static Polygon* create ( Net*, const Layer*, const std::vector& ); + static float getSlope ( const Point&, const Point& ); + public: + inline bool isManhattanized () const; + virtual DbU::Unit getX () const; + virtual DbU::Unit getY () const; + inline const vector& getPoints () const; + inline const vector& getEdges () const; + inline const Point& getPoint ( size_t ) const; + virtual Box getBoundingBox () const; + virtual Box getBoundingBox ( const BasicLayer* ) const; + virtual const Layer* getLayer () const; + void setLayer ( const Layer* layer ); + virtual void translate ( const DbU::Unit& dx, const DbU::Unit& dy ); + void setPoints ( const vector& ); + static float getSign ( const vector&, size_t ); + float getSlope ( size_t i ) const; + void manhattanize (); + inline Points getContour () const; + virtual void _toJson ( JsonWriter* ) const; + static JsonObject* getJsonObject ( unsigned long flags ); + virtual string _getTypeName () const; + virtual string _getString () const; + virtual Record* _getRecord () const; + protected: + Polygon ( Net*, const Layer*, const std::vector& ); + ~Polygon (); + private: + const Layer* _layer; + std::vector _points; + std::vector _edges; + }; + + + inline bool Polygon::isManhattanized () const { return not _edges.empty(); } + inline const vector& Polygon::getEdges () const { return _edges; } + inline const vector& Polygon::getPoints () const { return _points; } + inline const Point& Polygon::getPoint ( size_t i ) const { return _points[ (i<_points.size()) ? i : 0 ]; } + inline Points Polygon::getContour () const { return Points_Manhattan(this); } + + 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) ); } + inline bool Polygon::Edge::isHV () const { return (_flags & (Polygon::Horizontal|Polygon::Vertical)); } + inline bool Polygon::Edge::isXSteps () const { return (_flags & Polygon::XSteps); } + inline bool Polygon::Edge::isYSteps () const { return (_flags & Polygon::YSteps); } + inline size_t Polygon::Edge::getSize () const { if (isHV() or (_steps.size() < 2)) return 1; return (_steps.size() - 1)*2; } + + + inline Polygon::Points_Manhattan::Locator::Locator ( const Locator &locator ) + : PointHL () + , _polygon(locator._polygon) + , _iEdge (locator._iEdge) + , _iPoint (locator._iPoint) + { } + + + inline Polygon::Points_Manhattan::Points_Manhattan ( const Polygon* polygon ) + : PointHC () + , _polygon(polygon) + { } + + + inline Polygon::Points_Manhattan::Points_Manhattan ( const Points_Manhattan& other ) + : PointHC() + , _polygon(other._polygon) + { } + + + class JsonPolygon : public JsonComponent { + public: + static void initialize (); + JsonPolygon ( unsigned long flags ); + virtual string getTypeName () const; + virtual JsonPolygon* clone ( unsigned long ) const; + virtual void toData ( JsonStack& ); + }; + + +} // Hurricane namespace. + + +INSPECTOR_P_SUPPORT(Hurricane::Polygon::Edge); +INSPECTOR_P_SUPPORT(Hurricane::Polygon); + +#endif // HURRICANE_POLYGON_H diff --git a/hurricane/src/hurricane/hurricane/Triangles.h b/hurricane/src/hurricane/hurricane/Polygons.h similarity index 100% rename from hurricane/src/hurricane/hurricane/Triangles.h rename to hurricane/src/hurricane/hurricane/Polygons.h diff --git a/hurricane/src/hurricane/hurricane/Triangle.h b/hurricane/src/hurricane/hurricane/Triangle.h deleted file mode 100644 index 336810ce..00000000 --- a/hurricane/src/hurricane/hurricane/Triangle.h +++ /dev/null @@ -1,90 +0,0 @@ -// -*- C++ -*- -// -// Copyright (c) BULL S.A. 2000-2018, All Rights Reserved -// -// This file is part of Hurricane. -// -// Hurricane is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// Hurricane is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU -// General Public License for more details. -// -// You should have received a copy of the Lesser GNU General Public -// License along with Hurricane. If not, see -// . -// -// +-----------------------------------------------------------------+ -// | H U R R I C A N E | -// | V L S I B a c k e n d D a t a - B a s e | -// | | -// | Author : Jean-Paul Chaput | -// | E-mail : Jean-Paul.Chaput@lip6.fr | -// | =============================================================== | -// | C++ Header : "./hurricane/Triangle.h" | -// +-----------------------------------------------------------------+ - - -#ifndef HURRICANE_TRIANGLE_H -#define HURRICANE_TRIANGLE_H - -#include "hurricane/Component.h" -#include "hurricane/Triangles.h" - - -namespace Hurricane { - - class Layer; - - - class Triangle : public Component { - public: - typedef Component Super; - public: - static Triangle* create ( Net*, const Layer*, const Point&, const Point&, const Point& ); - public: - virtual DbU::Unit getX () const; - virtual DbU::Unit getY () const; - inline const Point& getPoint ( size_t ) const; - virtual Box getBoundingBox () const; - virtual Box getBoundingBox ( const BasicLayer* ) const; - virtual const Layer* getLayer () const; - void setLayer ( const Layer* layer ); - virtual void translate ( const DbU::Unit& dx, const DbU::Unit& dy ); - void setPoints ( const Point&, const Point&, const Point& ); - virtual void _toJson ( JsonWriter* ) const; - static JsonObject* getJsonObject ( unsigned long flags ); - virtual string _getTypeName () const; - virtual string _getString () const; - virtual Record* _getRecord () const; - protected: - Triangle ( Net*, const Layer*, const Point&, const Point&, const Point& ); - private: - const Layer* _layer; - std::array _points; - }; - - - inline const Point& Triangle::getPoint ( size_t i ) const { return _points[ (i<3) ? i : 0 ]; } - - - class JsonTriangle : public JsonComponent { - public: - static void initialize (); - JsonTriangle ( unsigned long flags ); - virtual string getTypeName () const; - virtual JsonTriangle* clone ( unsigned long ) const; - virtual void toData ( JsonStack& ); - }; - - -} // Hurricane namespace. - - -INSPECTOR_P_SUPPORT(Hurricane::Triangle); - -#endif // HURRICANE_TRIANGLE_H diff --git a/hurricane/src/isobar/CMakeLists.txt b/hurricane/src/isobar/CMakeLists.txt index 197475e0..e6842b7b 100644 --- a/hurricane/src/isobar/CMakeLists.txt +++ b/hurricane/src/isobar/CMakeLists.txt @@ -66,7 +66,7 @@ PySegmentCollection.cpp PyTechnology.cpp PyTransformation.cpp - PyTriangle.cpp + PyPolygon.cpp PyOrientation.cpp PyDbU.cpp PyUpdateSession.cpp @@ -133,7 +133,7 @@ hurricane/isobar/PySegmentCollection.h hurricane/isobar/PyTechnology.h hurricane/isobar/PyTransformation.h - hurricane/isobar/PyTriangle.h + hurricane/isobar/PyPolygon.h hurricane/isobar/PyOrientation.h hurricane/isobar/PyDbU.h hurricane/isobar/PyUpdateSession.h diff --git a/hurricane/src/isobar/PyDbU.cpp b/hurricane/src/isobar/PyDbU.cpp index eef41632..9c3609e8 100644 --- a/hurricane/src/isobar/PyDbU.cpp +++ b/hurricane/src/isobar/PyDbU.cpp @@ -177,11 +177,11 @@ extern "C" { } - extern PyObject* PyDbU_getPrecision ( PyObject* ) + static PyObject* PyDbU_getPrecision ( PyObject* ) { return Py_BuildValue("I",DbU::getPrecision()); } - extern PyObject* PyDbU_getMaximalPrecision ( PyObject* ) + static PyObject* PyDbU_getMaximalPrecision ( PyObject* ) { return Py_BuildValue("I",DbU::getMaximalPrecision()); } @@ -189,7 +189,7 @@ extern "C" { { return Py_BuildValue("d",DbU::getResolution()); } - extern PyObject* PyDbU_setPrecision ( PyObject* , PyObject* args ) + static PyObject* PyDbU_setPrecision ( PyObject* , PyObject* args ) { unsigned int precision = 0; @@ -204,8 +204,32 @@ extern "C" { Py_RETURN_NONE; } + + static PyObject* PyDbU_getPolygonStep ( PyObject*, PyObject* args ) + { return PyDbU_FromLong( DbU::getPolygonStep() ); } - extern PyObject* PyDbU_getUnitPower ( PyObject* , PyObject* args ) + + static PyObject* PyDbU_setPolygonStep ( PyObject* , PyObject* args ) + { + HTRY + PyObject* pyStep = NULL; + __cs.init( "DbU.setPolygonStep" ); + if (not PyArg_ParseTuple(args,"O&:DbU.setPolygonStep", Converter, &pyStep) ) { + PyErr_SetString ( ConstructorError, "DbU.setPolygonStep(): Invalid/bad type parameters ." ); + return NULL; + } + if (__cs.getObjectIds() == INT_ARG) DbU::setPolygonStep( PyAny_AsLong(pyStep) ); + else { + PyErr_SetString( ConstructorError, "DbU.setPolygonStep(): Invalid type for parameter(s)." ); + return NULL; + } + HCATCH + + Py_RETURN_NONE; + } + + + static PyObject* PyDbU_getUnitPower ( PyObject* , PyObject* args ) { double value = 0.0; unsigned int power = 0; @@ -222,7 +246,7 @@ extern "C" { } - extern PyObject* PyDbU_setPhysicalsPerGrid ( PyObject* , PyObject* args ) + static PyObject* PyDbU_setPhysicalsPerGrid ( PyObject* , PyObject* args ) { double physicalsPerGrid = 0.0; unsigned int power = 0; @@ -239,11 +263,11 @@ extern "C" { } - extern PyObject* PyDbU_getPhysicalsPerGrid ( PyObject* ) + static PyObject* PyDbU_getPhysicalsPerGrid ( PyObject* ) { return Py_BuildValue("d",DbU::getPhysicalsPerGrid()); } - extern PyObject* PyDbU_physicalToGrid ( PyObject* , PyObject* args ) + static PyObject* PyDbU_physicalToGrid ( PyObject* , PyObject* args ) { double value = 0.0; int power = DbU::Micro; @@ -261,7 +285,7 @@ extern "C" { } - extern PyObject* PyDbU_setGridsPerLambda ( PyObject* , PyObject* args ) + static PyObject* PyDbU_setGridsPerLambda ( PyObject* , PyObject* args ) { double gridsPerLambda = 0.0; @@ -277,15 +301,15 @@ extern "C" { } - extern PyObject* PyDbU_getGridsPerLambda ( PyObject* ) + static PyObject* PyDbU_getGridsPerLambda ( PyObject* ) { return Py_BuildValue("d",DbU::getGridsPerLambda()); } - extern PyObject* PyDbU_getRealSnapGridStep ( PyObject* ) + static PyObject* PyDbU_getRealSnapGridStep ( PyObject* ) { return PyDbU_FromLong(DbU::getRealSnapGridStep()); } - extern PyObject* PyDbU_getOnRealSnapGrid ( PyObject* , PyObject* args ) + static PyObject* PyDbU_getOnRealSnapGrid ( PyObject* , PyObject* args ) { PyObject* value = NULL; int snap = DbU::Nearest; @@ -303,7 +327,7 @@ extern "C" { } - extern PyObject* PyDbU_setRealSnapGridStep ( PyObject* , PyObject* args ) + static PyObject* PyDbU_setRealSnapGridStep ( PyObject* , PyObject* args ) { PyObject* step = NULL; @@ -319,11 +343,11 @@ extern "C" { } - extern PyObject* PyDbU_getSymbolicSnapGridStep ( PyObject* ) + static PyObject* PyDbU_getSymbolicSnapGridStep ( PyObject* ) { return PyDbU_FromLong(DbU::getSymbolicSnapGridStep()); } - extern PyObject* PyDbU_getOnSymbolicSnapGrid ( PyObject* , PyObject* args ) + static PyObject* PyDbU_getOnSymbolicSnapGrid ( PyObject* , PyObject* args ) { PyObject* pyValue = NULL; int snap = DbU::Nearest; @@ -341,7 +365,7 @@ extern "C" { } - extern PyObject* PyDbU_setSymbolicSnapGridStep ( PyObject* , PyObject* args ) + static PyObject* PyDbU_setSymbolicSnapGridStep ( PyObject* , PyObject* args ) { PyObject* step = NULL; @@ -357,7 +381,7 @@ extern "C" { } - extern PyObject* PyDbU_getOnCustomGrid ( PyObject* , PyObject* args ) + static PyObject* PyDbU_getOnCustomGrid ( PyObject* , PyObject* args ) { PyObject* pyValue = NULL; PyObject* pyStep = NULL; @@ -427,7 +451,7 @@ extern "C" { } - extern PyObject* PyDbU_getValueString ( PyObject* , PyObject* args ) + static PyObject* PyDbU_getValueString ( PyObject* , PyObject* args ) { PyObject* value = NULL; int mode = DbU::SmartTruncate; @@ -445,7 +469,7 @@ extern "C" { } - extern PyObject* PyDbU_setStringMode ( PyObject* , PyObject* args ) + static PyObject* PyDbU_setStringMode ( PyObject* , PyObject* args ) { unsigned int mode = 0; unsigned int power = DbU::Nano; @@ -525,6 +549,11 @@ extern "C" { , "Convert a DbU into a human readable string." } , { "setStringMode" , (PyCFunction)PyDbU_setStringMode , METH_VARARGS|METH_STATIC , "Tells what unit to use when converting a DbU into a string." } + // Polygon Step Managment. + , { "setPolygonStep" , (PyCFunction)PyDbU_setPolygonStep , METH_VARARGS|METH_STATIC + , "Set the approximation step for Polygons." } + , { "getPolygonStep" , (PyCFunction)PyDbU_getPolygonStep , METH_NOARGS|METH_STATIC + , "Returns the approximation step used for Polygons." } , {NULL, NULL, 0, NULL} /* sentinel */ }; diff --git a/hurricane/src/isobar/PyHurricane.cpp b/hurricane/src/isobar/PyHurricane.cpp index 9eccce76..b0b5017a 100644 --- a/hurricane/src/isobar/PyHurricane.cpp +++ b/hurricane/src/isobar/PyHurricane.cpp @@ -72,7 +72,7 @@ #include "hurricane/isobar/PyHorizontal.h" #include "hurricane/isobar/PyVertical.h" #include "hurricane/isobar/PyPad.h" -#include "hurricane/isobar/PyTriangle.h" +#include "hurricane/isobar/PyPolygon.h" #include "hurricane/isobar/PyPath.h" #include "hurricane/isobar/PyOccurrence.h" #include "hurricane/isobar/PyOccurrenceCollection.h" @@ -570,9 +570,9 @@ extern "C" { PyHorizontal_LinkPyType (); PyContact_LinkPyType (); PyPin_LinkPyType (); - PyTriangle_LinkPyType (); + PyPolygon_LinkPyType (); PyPlug_LinkPyType (); - PyTriangle_LinkPyType (); + PyPolygon_LinkPyType (); PyBreakpoint_LinkPyType (); PyQuery_LinkPyType (); PyQueryMask_LinkPyType (); @@ -655,7 +655,7 @@ extern "C" { PYTYPE_READY_SUB ( Pin , Contact ) PYTYPE_READY_SUB ( Plug , Component) PYTYPE_READY_SUB ( Pad , Component) - PYTYPE_READY_SUB ( Triangle , Component) + PYTYPE_READY_SUB ( Polygon , Component) // Identifier string can take up to 10 characters ! __cs.addType ( "intv" , &PyTypeInterval , "" , false ); @@ -707,7 +707,7 @@ extern "C" { __cs.addType ( "rp" , &PyTypeRoutingPad , "" , false, "comp" ); __cs.addType ( "segment" , &PyTypeSegment , "" , false, "comp" ); __cs.addType ( "pad " , &PyTypePad , "" , false, "comp" ); - __cs.addType ( "triangle" , &PyTypeTriangle , "" , false, "comp" ); + __cs.addType ( "polygon" , &PyTypePolygon , "" , false, "comp" ); __cs.addType ( "segmentCol" , &PyTypeSegmentCollection , "" , false ); __cs.addType ( "db" , &PyTypeDataBase , "" , false ); __cs.addType ( "techno" , &PyTypeTechnology , "" , false ); @@ -806,8 +806,8 @@ extern "C" { PyModule_AddObject ( module, "Pin" , (PyObject*)&PyTypePin ); Py_INCREF ( &PyTypePad ); PyModule_AddObject ( module, "Pad" , (PyObject*)&PyTypePad ); - Py_INCREF ( &PyTypeTriangle ); - PyModule_AddObject ( module, "Triangle" , (PyObject*)&PyTypeTriangle ); + Py_INCREF ( &PyTypePolygon ); + PyModule_AddObject ( module, "Polygon" , (PyObject*)&PyTypePolygon ); PyObject* dictionnary = PyModule_GetDict ( module ); diff --git a/hurricane/src/isobar/PyLayer.cpp b/hurricane/src/isobar/PyLayer.cpp index 7edc4e60..c264b837 100644 --- a/hurricane/src/isobar/PyLayer.cpp +++ b/hurricane/src/isobar/PyLayer.cpp @@ -483,6 +483,19 @@ extern "C" { } + extern bool IsPyDerivedLayer ( PyObject* pyObject ) + { + if (IsPyLayer(pyObject) ) return true; + if (IsPyBasicLayer(pyObject) ) return true; + if (IsPyContactLayer(pyObject) ) return true; + if (IsPyViaLayer(pyObject) ) return true; + if (IsPyDiffusionLayer(pyObject) ) return true; + if (IsPyRegularLayer(pyObject) ) return true; + if (IsPyTransistorLayer(pyObject)) return true; + return false; + } + + #endif // End of Shared Library Code Part. } // extern "C". diff --git a/hurricane/src/isobar/PyPolygon.cpp b/hurricane/src/isobar/PyPolygon.cpp new file mode 100644 index 00000000..78376739 --- /dev/null +++ b/hurricane/src/isobar/PyPolygon.cpp @@ -0,0 +1,209 @@ +// -*- 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/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& v ) + { + if (not PyList_Check(list)) return false; + + int length = PyList_Size( list ); + for ( int i=0 ; iob_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; + } + + +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 points; + if (not ListToVector(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_setPoints ( PyPolygon *self, PyObject* args ) + { + cdebug_log(20,0) << "Polygon.setPoints()" << endl; + + HTRY + METHOD_HEAD( "Polygon.setPoints()" ) + + PyObject* arg0 = NULL; + PyObject* arg1 = NULL; + PyObject* arg2 = NULL; + if (not PyArg_ParseTuple( args, "O:Polygon.setPoints", &arg0 )) { + PyErr_SetString( ConstructorError, "Invalid number of parameters for Polygon.setPoints()." ); + return NULL; + } + + vector points; + if (not ListToVector(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; + } + + + // --------------------------------------------------------------- + // 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." } + , { "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. diff --git a/hurricane/src/isobar/PyTriangle.cpp b/hurricane/src/isobar/PyTriangle.cpp deleted file mode 100644 index 29b8c784..00000000 --- a/hurricane/src/isobar/PyTriangle.cpp +++ /dev/null @@ -1,206 +0,0 @@ -// -*- 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 : "./PyTriangle.cpp" | -// +-----------------------------------------------------------------+ - - -#include "hurricane/isobar/PyPoint.h" -#include "hurricane/isobar/PyNet.h" -#include "hurricane/isobar/PyLayer.h" -#include "hurricane/isobar/PyBox.h" -#include "hurricane/isobar/PyTriangle.h" - - -namespace Isobar { - -using namespace Hurricane; - -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(Triangle,triangle,function) - - -// +=================================================================+ -// | "PyTriangle" Python Module Code Part | -// +=================================================================+ - -#if defined(__PYTHON_MODULE__) - - // Standard Accessors (Attributes). - DirectGetLongAttribute(PyTriangle_getX, getX, PyTriangle, Triangle) - DirectGetLongAttribute(PyTriangle_getY, getY, PyTriangle, Triangle) - - // Standard Destroy (Attribute). - DBoDestroyAttribute(PyTriangle_destroy, PyTriangle) - - - static PyObject* PyTriangle_create ( PyObject*, PyObject *args ) - { - cdebug_log(20,0) << "PyTriangle_create()" << endl; - - PyObject* arg0 = NULL; - PyObject* arg1 = NULL; - PyObject* arg2 = NULL; - PyObject* arg3 = NULL; - PyObject* arg4 = NULL; - Triangle* triangle = NULL; - - HTRY - __cs.init( "Triangle.create" ); - if (!PyArg_ParseTuple(args,"O&O&O&O&O&:Triangle.create" - ,Converter,&arg0 - ,Converter,&arg1 - ,Converter,&arg2 - ,Converter,&arg3 - ,Converter,&arg4 - )) { - PyErr_SetString( ConstructorError, "Invalid number of parameters for Triangle constructor." ); - return NULL; - } - - if (__cs.getObjectIds() == ":ent:layer:point:point:point") { - triangle = Triangle::create( PYNET_O (arg0) - , PYLAYER_O(arg1) - , *PYPOINT_O(arg2) - , *PYPOINT_O(arg3) - , *PYPOINT_O(arg4) - ); - } else { - PyErr_SetString( ConstructorError, "Bad type(s) of parameters for Triangle constructor." ); - return NULL; - } - HCATCH - - return PyTriangle_Link(triangle); - } - - - static PyObject* PyTriangle_getBoundingBox ( PyTriangle *self ) - { - cdebug_log(20,0) << "PyTriangle_getBoundingBox()" << endl; - - METHOD_HEAD( "Triangle.BoundingBox()" ) - - PyBox* pyBox = PyObject_NEW( PyBox, &PyTypeBox ); - if (pyBox == NULL) { return NULL; } - - HTRY - pyBox->_object = new Box ( triangle->getBoundingBox() ); - HCATCH - - return (PyObject*)pyBox; - } - - - static PyObject* PyTriangle_setPoints ( PyTriangle *self, PyObject* args ) - { - cdebug_log(20,0) << "Triangle.setPoints()" << endl; - - HTRY - METHOD_HEAD( "Triangle.setPoints()" ) - - PyObject* arg0 = NULL; - PyObject* arg1 = NULL; - PyObject* arg2 = NULL; - if (not PyArg_ParseTuple( args,"O&O&O&:Triangle.setPoints" - ,Converter,&arg0 - ,Converter,&arg1 - ,Converter,&arg2 - )) { - PyErr_SetString( ConstructorError, "Invalid number of parameters for Triangle.setPoints()." ); - return NULL; - } - - if (__cs.getObjectIds() == ":point:point:point") { - triangle->setPoints( *PYPOINT_O(arg0) - , *PYPOINT_O(arg1) - , *PYPOINT_O(arg2) - ); - } else { - PyErr_SetString( ConstructorError, "Bad type(s) of parameters for Triangle.setPoints()." ); - return NULL; - } - HCATCH - - Py_RETURN_NONE; - } - - - static PyObject* PyTriangle_translate ( PyTriangle *self, PyObject* args ) - { - cdebug_log(20,0) << "PyTriangle_translate ()" << endl; - - HTRY - METHOD_HEAD ( "Triangle.translate()" ) - PyObject* arg0 = NULL; - PyObject* arg1 = NULL; - __cs.init ("Triangle.translate"); - if (PyArg_ParseTuple(args,"O&O&:Triangle.translate", Converter, &arg0, Converter, &arg1)) { - if (__cs.getObjectIds() == INTS2_ARG) triangle->translate( PyAny_AsLong(arg0), PyAny_AsLong(arg1) ); - else { - PyErr_SetString ( ConstructorError, "Triangle.translate(): Invalid type for parameter(s)." ); - return NULL; - } - } else { - PyErr_SetString ( ConstructorError, "Triangle.translate(): Invalid number of parameters." ); - return NULL; - } - HCATCH - - Py_RETURN_NONE; - } - - - // --------------------------------------------------------------- - // PyTriangle Attribute Method table. - - PyMethodDef PyTriangle_Methods[] = - { { "create" , (PyCFunction)PyTriangle_create , METH_VARARGS|METH_STATIC - , "Create a new Triangle." } - , { "getX" , (PyCFunction)PyTriangle_getX , METH_NOARGS , "Return the Triangle X value." } - , { "getY" , (PyCFunction)PyTriangle_getY , METH_NOARGS , "Return the Triangle Y value." } - , { "getBoundingBox", (PyCFunction)PyTriangle_getBoundingBox, METH_NOARGS , "Return the Triangle Bounding Box." } - , { "setPoints" , (PyCFunction)PyTriangle_setPoints , METH_VARARGS, "Sets the Triangle Bounding Box." } - , { "translate" , (PyCFunction)PyTriangle_translate , METH_VARARGS, "Translates the Triangle of dx and dy." } - , { "destroy" , (PyCFunction)PyTriangle_destroy , METH_NOARGS - , "Destroy associated hurricane object, the python object remains." } - , {NULL, NULL, 0, NULL} /* sentinel */ - }; - - - DBoDeleteMethod(Triangle) - PyTypeObjectLinkPyType(Triangle) - - -#else // Python Module Code Part. - - -// +=================================================================+ -// | "PyTriangle" Shared Library Code Part | -// +=================================================================+ - - - // Link/Creation Method. - DBoLinkCreateMethod(Triangle) - PyTypeInheritedObjectDefinitions(Triangle,Component) - -#endif // Shared Library Code Part. - -} // extern "C". - -} // Isobar namespace. diff --git a/hurricane/src/isobar/hurricane/isobar/PyLayer.h b/hurricane/src/isobar/hurricane/isobar/PyLayer.h index a095baff..6ccb640c 100644 --- a/hurricane/src/isobar/hurricane/isobar/PyLayer.h +++ b/hurricane/src/isobar/hurricane/isobar/PyLayer.h @@ -47,6 +47,7 @@ extern "C" { extern void PyLayer_LinkPyType (); extern void PyLayer_postModuleInit (); extern Layer* PYDERIVEDLAYER_O ( PyObject* ); + extern bool IsPyDerivedLayer ( PyObject* ); # define IsPyLayer(v) ( (v)->ob_type == &PyTypeLayer ) # define PYLAYER(v) ( (PyLayer*)(v) ) diff --git a/hurricane/src/isobar/hurricane/isobar/PyTriangle.h b/hurricane/src/isobar/hurricane/isobar/PyPolygon.h similarity index 63% rename from hurricane/src/isobar/hurricane/isobar/PyTriangle.h rename to hurricane/src/isobar/hurricane/isobar/PyPolygon.h index a9594d21..4516b856 100644 --- a/hurricane/src/isobar/hurricane/isobar/PyTriangle.h +++ b/hurricane/src/isobar/hurricane/isobar/PyPolygon.h @@ -10,15 +10,15 @@ // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | -// | C++ Header : "./hurricane/isobar/PyTriangle.h" | +// | C++ Header : "./hurricane/isobar/PyPolygon.h" | // +-----------------------------------------------------------------+ -#ifndef PY_TRIANGLE_H -#define PY_TRIANGLE_H +#ifndef PY_POLYGON_H +#define PY_POLYGON_H #include "hurricane/isobar/PyComponent.h" -#include "hurricane/Triangle.h" +#include "hurricane/Polygon.h" namespace Isobar { @@ -27,30 +27,30 @@ namespace Isobar { // ------------------------------------------------------------------- -// Python Object : "PyTriangle". +// Python Object : "PyPolygon". typedef struct { PyComponent _baseObject; - } PyTriangle; + } PyPolygon; // ------------------------------------------------------------------- // Functions & Types exported to "PyHurricane.ccp". - extern PyTypeObject PyTypeTriangle; - extern PyMethodDef PyTriangle_Methods[]; + extern PyTypeObject PyTypePolygon; + extern PyMethodDef PyPolygon_Methods[]; - extern PyObject* PyTriangle_Link ( Hurricane::Triangle* object ); - extern void PyTriangle_LinkPyType (); + extern PyObject* PyPolygon_Link ( Hurricane::Polygon* object ); + extern void PyPolygon_LinkPyType (); -#define IsPyTriangle(v) ( (v)->ob_type == &PyTypeTriangle ) -#define PYTRIANGLE(v) ( (PyTriangle*)(v) ) -#define PYTRIANGLE_O(v) ( PYTRIANGLE(v)->_baseObject._baseObject._object ) +#define IsPyPolygon(v) ( (v)->ob_type == &PyTypePolygon ) +#define PYPOLYGON(v) ( (PyPolygon*)(v) ) +#define PYPOLYGON_O(v) ( PYPOLYGON(v)->_baseObject._baseObject._object ) } // extern "C". } // Isobar namespace. -#endif // PY_TRIANGLE_H +#endif // PY_POLYGON_H diff --git a/hurricane/src/viewer/CellWidget.cpp b/hurricane/src/viewer/CellWidget.cpp index 7a0e336c..8c4e02c2 100644 --- a/hurricane/src/viewer/CellWidget.cpp +++ b/hurricane/src/viewer/CellWidget.cpp @@ -39,7 +39,7 @@ #include "hurricane/Vertical.h" #include "hurricane/Contact.h" #include "hurricane/Pad.h" -#include "hurricane/Triangle.h" +#include "hurricane/Polygon.h" #include "hurricane/RoutingPad.h" #include "hurricane/ExtensionGo.h" @@ -665,17 +665,23 @@ namespace Hurricane { static QRect rectangle; static unsigned int state; - const Triangle* triangle = dynamic_cast(go); - if (triangle) { + const Polygon* polygon = dynamic_cast(go); + if (polygon) { _goCount++; - Box bb = transformation.getBox(triangle->getBoundingBox(basicLayer)); + Box bb = transformation.getBox(polygon->getBoundingBox(basicLayer)); rectangle = _cellWidget->dbuToScreenRect( bb ); if ( (rectangle.width() > 4) and (rectangle.height() > 4) ) { - QPoint points[3]; - points[0] = _cellWidget->dbuToScreenPoint( triangle->getPoint(0) ); - points[1] = _cellWidget->dbuToScreenPoint( triangle->getPoint(1) ); - points[2] = _cellWidget->dbuToScreenPoint( triangle->getPoint(2) ); - _cellWidget->drawScreenPolygon( points, 3 ); + QPolygon contour; + const vector& points = polygon->getPoints(); + for ( Point point : points ) contour << _cellWidget->dbuToScreenPoint( point ); + _cellWidget->drawScreenPolygon( contour ); + contour.clear(); + + if (_cellWidget->dbuToScreenLength(DbU::getPolygonStep()) > 4) { + for ( Point point : polygon->getContour() ) + contour << _cellWidget->dbuToScreenPoint( point ); + _cellWidget->drawScreenPolygon( contour ); + } } return; } @@ -1731,6 +1737,12 @@ namespace Hurricane { } + void CellWidget::drawScreenPolygon ( const QPolygon& polygon, size_t plane ) + { + _drawingPlanes.painter(plane).drawConvexPolygon ( polygon ); + } + + void CellWidget::drawScreenPolyline ( const QPoint* points, int count, int width, size_t plane ) { _drawingPlanes.painter(plane).save (); diff --git a/hurricane/src/viewer/hurricane/viewer/CellWidget.h b/hurricane/src/viewer/hurricane/viewer/CellWidget.h index 204a9d58..5fc41f07 100644 --- a/hurricane/src/viewer/hurricane/viewer/CellWidget.h +++ b/hurricane/src/viewer/hurricane/viewer/CellWidget.h @@ -190,6 +190,7 @@ namespace Hurricane { void drawDisplayText ( const QRect& , const char*, unsigned int flags=0 ); void drawDisplayText ( const QPoint&, const char*, unsigned int flags=0, int angle=0 ); void drawScreenPolygon ( const QPoint*, int count, size_t plane=PlaneId::Working ); + void drawScreenPolygon ( const QPolygon&, size_t plane=PlaneId::Working ); void drawScreenLine ( const QPoint&, const QPoint&, size_t plane=PlaneId::Working, bool mode=true ); void drawScreenRect ( const QPoint&, const QPoint&, size_t plane=PlaneId::Working ); void drawScreenRect ( const QRect& , size_t plane=PlaneId::Working );