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 );