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.
This commit is contained in:
parent
1a338f620c
commit
0902b21f23
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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:<viewerConfig>.')
|
||||
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 <technoConfig>, invalid DbU unit power for gridUnit, reseting to Micro.')
|
||||
else:
|
||||
raise ErrorMessage(1,'<technoConfig> has no <gridUnit> 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 <technoConfig>, <precision> must be of type int (and not: %s).'
|
||||
% helpers.stype(precision)
|
||||
])
|
||||
DbU.setPrecision(precision)
|
||||
else:
|
||||
raise ErrorMessage(1,'<technoConfig> has no <precision> 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 <technoConfig>, <gridValue> must be of type float (and not: %s).'
|
||||
% helpers.stype(gridValue)
|
||||
])
|
||||
DbU.setPhysicalsPerGrid(gridValue,gridUnit)
|
||||
else:
|
||||
raise ErrorMessage(1,'<technoConfig> has no <gridValue> 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 <technoConfig>, invalid DbU unit power for gridUnit, reseting to Micro.')
|
||||
else:
|
||||
raise ErrorMessage(1,'<technoConfig> has no <gridUnit> 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 <technoConfig>, <gridValue> must be of type float (and not: %s).'
|
||||
% helpers.stype(gridValue)
|
||||
])
|
||||
DbU.setPhysicalsPerGrid(gridValue,gridUnit)
|
||||
else:
|
||||
raise ErrorMessage(1,'<technoConfig> has no <gridValue> defined.')
|
||||
|
||||
elif key == 'gridsPerLambda':
|
||||
if technoConfig.has_key('gridsPerLambda'):
|
||||
gridsPerLambda = technoConfig['gridsPerLambda']
|
||||
if not isinstance(gridsPerLambda,int):
|
||||
raise ErrorMessage(1,['In <technoConfig>, <gridsPerLambda> 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 <technoConfig>, <gridsPerLambda> 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 <technoConfig>, <polygonStep> 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 <technoConfig>, <symbolicGridStep> 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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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<Point>& 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.
|
||||
*/
|
||||
|
||||
// \}
|
||||
|
||||
|
||||
}
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<DbU::Unit>::min();
|
||||
const DbU::Unit DbU::Max = std::numeric_limits<DbU::Unit>::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) );
|
||||
|
|
|
@ -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
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | 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 = "<Polygon::Edge ";
|
||||
if (isYSteps()) s += "YSteps:" + getString(_steps.size());
|
||||
if (isXSteps()) s += "XSteps:" + getString(_steps.size());
|
||||
if (isHV ()) s += "HV";
|
||||
s += ">";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
Record* Polygon::Edge::_getRecord() const
|
||||
{
|
||||
Record* record = new Record ( getString(this) );
|
||||
record->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<Point>& points )
|
||||
: Super (net)
|
||||
, _layer (layer)
|
||||
, _points(points)
|
||||
, _edges ()
|
||||
{ }
|
||||
|
||||
|
||||
Polygon* Polygon::create ( Net* net, const Layer* layer, const vector<Point>& 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<points.size() ; ++i ) {
|
||||
float nextSign = getSign( points, i );
|
||||
if ( (sign != 0.0) and ( (sign < 0.0) xor (nextSign < 0.0) ) )
|
||||
throw Error("Can't create " + _TName("Polygon") + " : non-convex polygon");
|
||||
|
||||
sign = nextSign;
|
||||
}
|
||||
|
||||
Polygon* triangle = new Polygon ( net, layer, points );
|
||||
triangle->_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<Point>& points )
|
||||
{
|
||||
invalidate( true );
|
||||
|
||||
vector<Point> 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<Point>& 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<JsonPolygon> 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<Point> points;
|
||||
points.push_back( get<Point>(stack,".Point") );
|
||||
points.push_back( get<Point>(stack,".Point") );
|
||||
points.push_back( get<Point>(stack,".Point") );
|
||||
|
||||
Polygon* triangle = Polygon::create
|
||||
( get<Net*>(stack,".Net")
|
||||
, DataBase::getDB()->getTechnology()->getLayer( get<const char*>(stack,"_layer") )
|
||||
, points
|
||||
);
|
||||
|
||||
JsonNet* jnet = jget<JsonNet>( stack );
|
||||
if (jnet) {
|
||||
jnet->addHookLink( triangle->getBodyHook(), jsonId, get<string>(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.
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | 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<JsonTriangle> 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<Net*>(stack,".Net")
|
||||
, DataBase::getDB()->getTechnology()->getLayer( get<const char*>(stack,"_layer") )
|
||||
, get<Point>(stack,".Point")
|
||||
, get<Point>(stack,".Point")
|
||||
, get<Point>(stack,".Point")
|
||||
);
|
||||
|
||||
JsonNet* jnet = jget<JsonNet>( stack );
|
||||
if (jnet) {
|
||||
jnet->addHookLink( triangle->getBodyHook(), jsonId, get<string>(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.
|
|
@ -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<Hurricane::DbU::Unit*,3>&
|
|||
}
|
||||
|
||||
|
||||
template<>
|
||||
inline std::string getString ( const std::vector<Hurricane::DbU::Unit>* v )
|
||||
{
|
||||
std::string name = "const std::vector<DbU::Unit>:";
|
||||
return name + getString<size_t>(v->size());
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
inline Hurricane::Record* getRecord ( const std::vector<Hurricane::DbU::Unit>* v )
|
||||
{
|
||||
Hurricane::Record* record = NULL;
|
||||
record = new Hurricane::Record ( "const vector<DbU::Unit>" );
|
||||
|
||||
for ( size_t i=0 ; i<v->size() ; ++i ) {
|
||||
std::string label = "[" + getString(i) + "] ";
|
||||
record->add( Hurricane::DbU::getValueSlot(label, &(*v)[i]) );
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
#endif // HURRICANE_DBU_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
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | 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<Point> PointHF;
|
||||
typedef Hurricane::Locator<Point> PointHL;
|
||||
typedef Hurricane::Collection<Point> 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<DbU::Unit> _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<Point>& );
|
||||
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<Point>& getPoints () const;
|
||||
inline const vector<Edge*>& 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<Point>& );
|
||||
static float getSign ( const vector<Point>&, 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<Point>& );
|
||||
~Polygon ();
|
||||
private:
|
||||
const Layer* _layer;
|
||||
std::vector<Point> _points;
|
||||
std::vector<Edge*> _edges;
|
||||
};
|
||||
|
||||
|
||||
inline bool Polygon::isManhattanized () const { return not _edges.empty(); }
|
||||
inline const vector<Polygon::Edge*>& Polygon::getEdges () const { return _edges; }
|
||||
inline const vector<Point>& 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
|
|
@ -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
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | 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<Point,3> _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
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
|
|
@ -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 , "<Interval>" , false );
|
||||
|
@ -707,7 +707,7 @@ extern "C" {
|
|||
__cs.addType ( "rp" , &PyTypeRoutingPad , "<RoutingPad>" , false, "comp" );
|
||||
__cs.addType ( "segment" , &PyTypeSegment , "<Segment>" , false, "comp" );
|
||||
__cs.addType ( "pad " , &PyTypePad , "<Pad>" , false, "comp" );
|
||||
__cs.addType ( "triangle" , &PyTypeTriangle , "<Triangle>" , false, "comp" );
|
||||
__cs.addType ( "polygon" , &PyTypePolygon , "<Polygon>" , false, "comp" );
|
||||
__cs.addType ( "segmentCol" , &PyTypeSegmentCollection , "<SegmentCollection>" , false );
|
||||
__cs.addType ( "db" , &PyTypeDataBase , "<DataBase>" , false );
|
||||
__cs.addType ( "techno" , &PyTypeTechnology , "<Technology>" , 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 );
|
||||
|
|
|
@ -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".
|
||||
|
|
|
@ -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<CppType>& v )
|
||||
{
|
||||
if (not PyList_Check(list)) return false;
|
||||
|
||||
int length = PyList_Size( list );
|
||||
for ( int i=0 ; i<length ; ++i ) {
|
||||
PyObject* item = PyList_GetItem( list, i );
|
||||
if ((item)->ob_type != itemType) {
|
||||
string message = "Polygon: Item at position " + getString(i) + "has wrong type.";
|
||||
PyErr_SetString( ConstructorError, message.c_str() );
|
||||
return false;
|
||||
}
|
||||
v.push_back( *PYPOINT_O(item) );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
||||
#undef ACCESS_OBJECT
|
||||
#undef ACCESS_CLASS
|
||||
#define ACCESS_OBJECT _baseObject._baseObject._object
|
||||
#define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject._baseObject)
|
||||
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Polygon,polygon,function)
|
||||
|
||||
|
||||
// +=================================================================+
|
||||
// | "PyPolygon" Python Module Code Part |
|
||||
// +=================================================================+
|
||||
|
||||
#if defined(__PYTHON_MODULE__)
|
||||
|
||||
// Standard Accessors (Attributes).
|
||||
DirectGetLongAttribute(PyPolygon_getX, getX, PyPolygon, Polygon)
|
||||
DirectGetLongAttribute(PyPolygon_getY, getY, PyPolygon, Polygon)
|
||||
|
||||
// Standard Destroy (Attribute).
|
||||
DBoDestroyAttribute(PyPolygon_destroy, PyPolygon)
|
||||
|
||||
|
||||
static PyObject* PyPolygon_create ( PyObject*, PyObject *args )
|
||||
{
|
||||
cdebug_log(20,0) << "PyPolygon_create()" << endl;
|
||||
|
||||
PyObject* arg0 = NULL;
|
||||
PyObject* arg1 = NULL;
|
||||
PyObject* arg2 = NULL;
|
||||
Polygon* polygon = NULL;
|
||||
|
||||
HTRY
|
||||
if (not PyArg_ParseTuple(args, "OOO:Polygon.create" ,&arg0 ,&arg1 ,&arg2 )) {
|
||||
PyErr_SetString( ConstructorError, "Invalid number of parameters for Polygon constructor." );
|
||||
return NULL;
|
||||
}
|
||||
if (not IsPyNet(arg0)) {
|
||||
PyErr_SetString( ConstructorError, "First parameter of Polygon constructor must be a Net." );
|
||||
return NULL;
|
||||
}
|
||||
if (not IsPyDerivedLayer(arg1)) {
|
||||
PyErr_SetString( ConstructorError, "Second parameter of Polygon constructor must be a Layer." );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vector<Point> points;
|
||||
if (not ListToVector<Point>(arg2,&PyTypePoint,points)) return NULL;
|
||||
|
||||
polygon = Polygon::create( PYNET_O(arg0), PYDERIVEDLAYER_O(arg1), points );
|
||||
HCATCH
|
||||
|
||||
return PyPolygon_Link(polygon);
|
||||
}
|
||||
|
||||
|
||||
static PyObject* PyPolygon_getBoundingBox ( PyPolygon *self )
|
||||
{
|
||||
cdebug_log(20,0) << "PyPolygon_getBoundingBox()" << endl;
|
||||
|
||||
METHOD_HEAD( "Polygon.BoundingBox()" )
|
||||
|
||||
PyBox* pyBox = PyObject_NEW( PyBox, &PyTypeBox );
|
||||
if (pyBox == NULL) { return NULL; }
|
||||
|
||||
HTRY
|
||||
pyBox->_object = new Box ( polygon->getBoundingBox() );
|
||||
HCATCH
|
||||
|
||||
return (PyObject*)pyBox;
|
||||
}
|
||||
|
||||
|
||||
static PyObject* PyPolygon_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<Point> points;
|
||||
if (not ListToVector<Point>(arg0,&PyTypePoint,points)) return NULL;
|
||||
|
||||
polygon->setPoints( points );
|
||||
HCATCH
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
static PyObject* PyPolygon_translate ( PyPolygon *self, PyObject* args )
|
||||
{
|
||||
cdebug_log(20,0) << "PyPolygon_translate ()" << endl;
|
||||
|
||||
HTRY
|
||||
METHOD_HEAD ( "Polygon.translate()" )
|
||||
PyObject* arg0 = NULL;
|
||||
PyObject* arg1 = NULL;
|
||||
__cs.init ("Polygon.translate");
|
||||
if (PyArg_ParseTuple(args,"O&O&:Polygon.translate", Converter, &arg0, Converter, &arg1)) {
|
||||
if (__cs.getObjectIds() == INTS2_ARG) polygon->translate( PyAny_AsLong(arg0), PyAny_AsLong(arg1) );
|
||||
else {
|
||||
PyErr_SetString ( ConstructorError, "Polygon.translate(): Invalid type for parameter(s)." );
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
PyErr_SetString ( ConstructorError, "Polygon.translate(): Invalid number of parameters." );
|
||||
return NULL;
|
||||
}
|
||||
HCATCH
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// 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.
|
|
@ -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.
|
|
@ -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) )
|
||||
|
|
|
@ -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
|
|
@ -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<const Triangle*>(go);
|
||||
if (triangle) {
|
||||
const Polygon* polygon = dynamic_cast<const Polygon*>(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<Point>& 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 ();
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in New Issue