Add Rectilinear & "cut" support to the extractor.
Note about the managment of VIA & cuts: Components using a layer which is a ViaLayer, that is one containing more than one BasicLayer, multiple tiles are created in QueryTiles::goCallback(). Components that have a single BasicLayer of "cut" material will also have their multiples tiles created in QueryTiles::goCallback(). Rectilinear components will have their multiples tiles created in Tile::create(). Tile::create() return not all the tiles but the one used as root (for the union find). * New: In SweepLine::_buildCutConnexMap(), when using a "cut" layer in a standalone way, and not as part of a ViaLayer, we do not automatically know to which layer above & below they are connected. We build a table for each cut layer, based on the ViaLayer, to know all tops & belows layers they connect (this is cumulative, in the case of "cut" towards the substrate). Then in Tile::create(), we not only create the tile for the "cut" but also in thoses connected layers (and link them in the union find). * New: In Tile::create(), when we encounter a Rectilinear, break it into rectangles and make as many tiles. All tiles linked to the same root in the union find. * Bug: In Hurricane::Rectilinear, ambiguous specification of the set of points defining the shape. I did suppose that the start and and point where not the same the last edge being between them. But if FlexLib, it uses the GDSII inspired convention where the first and last point must be the same, to indicate a closed contour. This difference was not causing any difference with the drawing, but it was a problem for getAsRectangle(). This was creating a "false" extra vertical edge leading to a bigger rectangle. And this, in turn, was making "false" intersections in the tiling/sweepline of the extractor. Add a more thorough checking of the points vector.
This commit is contained in:
parent
52fd1c1c40
commit
c53fc01cb2
|
@ -182,7 +182,7 @@ namespace {
|
|||
void SweepLine::loadVEdges ()
|
||||
{
|
||||
const vector<Point>& points = _rectilinear->getPoints();
|
||||
for ( size_t i=0 ; i<points.size() ; ++i ) {
|
||||
for ( size_t i=0 ; i<points.size()-1 ; ++i ) {
|
||||
const Point& source = points[ i ];
|
||||
const Point& target = points[ (i+1) % points.size() ];
|
||||
DbU::Unit dx = target.getX() - source.getX();
|
||||
|
@ -337,8 +337,19 @@ namespace Hurricane {
|
|||
if (not layer)
|
||||
throw Error( "Rectilinear::create(): Can't create, NULL layer" );
|
||||
|
||||
if (points.size() < 4)
|
||||
throw Error( "Rectilinear::create(): Rectilinear polygons must at least contains 3 vertexes." );
|
||||
|
||||
if (points.size() > 1000)
|
||||
throw Error( "Rectilinear::create(): Rectlinear polygons must not exceed 1000 vertexes." );
|
||||
throw Error( "Rectilinear::create(): Rectilinear polygons must not exceed 1000 vertexes." );
|
||||
|
||||
if (points[0] != points[points.size()-1])
|
||||
throw Error( "Rectilinear::create(): First and last point must be the same.\n"
|
||||
"0:%s %d:%s"
|
||||
, getString(points[0]).c_str()
|
||||
, points.size()-1
|
||||
, getString(points[points.size()-1]).c_str()
|
||||
);
|
||||
|
||||
bool isRect = true;
|
||||
DbU::Unit oneGrid = DbU::fromGrid( 1.0 );
|
||||
|
|
|
@ -72,18 +72,32 @@ namespace Tramontana {
|
|||
|
||||
void QueryTiles::goCallback ( Go* go )
|
||||
{
|
||||
vector<Tile*> tiles;
|
||||
Tile* rootTile = nullptr;
|
||||
Component* component = dynamic_cast<Component*>( go );
|
||||
if (not component) return;
|
||||
if (isProcessed(component)) return;
|
||||
Occurrence occurrence = Occurrence( go, getPath() );
|
||||
for ( const BasicLayer* layer : _sweepLine->getExtracteds() ) {
|
||||
if (not component->getLayer()->getMask().intersect(layer->getMask())) continue;
|
||||
tiles.push_back( Tile::create( occurrence, layer ));
|
||||
_sweepLine->add( tiles.back() );
|
||||
if (tiles.size() > 1)
|
||||
tiles.back()->setParent( tiles[0] );
|
||||
Tile* tile = Tile::create( occurrence
|
||||
, layer
|
||||
, rootTile
|
||||
, _sweepLine );
|
||||
if (not rootTile) rootTile = tile;
|
||||
}
|
||||
|
||||
BasicLayer* cutLayer = component->getLayer()->getBasicLayers().getFirst();
|
||||
if (cutLayer->getMaterial() == BasicLayer::Material::cut) {
|
||||
const SweepLine::LayerSet& connexSet = _sweepLine->getCutConnexLayers( cutLayer );
|
||||
for ( const BasicLayer* connexLayer : connexSet ) {
|
||||
Tile::create( occurrence
|
||||
, connexLayer
|
||||
, rootTile
|
||||
, _sweepLine
|
||||
, Tile::ForceLayer );
|
||||
}
|
||||
}
|
||||
|
||||
_goMatchCount++;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "hurricane/DataBase.h"
|
||||
#include "hurricane/Technology.h"
|
||||
#include "hurricane/Layer.h"
|
||||
#include "hurricane/ViaLayer.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/Pad.h"
|
||||
#include "hurricane/Plug.h"
|
||||
|
@ -71,6 +72,7 @@ namespace Tramontana {
|
|||
using Hurricane::DataBase;
|
||||
using Hurricane::Technology;
|
||||
using Hurricane::Layer;
|
||||
using Hurricane::ViaLayer;
|
||||
using Hurricane::Entity;
|
||||
using Hurricane::Horizontal;
|
||||
using Hurricane::Vertical;
|
||||
|
@ -84,18 +86,24 @@ namespace Tramontana {
|
|||
|
||||
|
||||
SweepLine::SweepLine ( TramontanaEngine* tramontana )
|
||||
: _tramontana (tramontana)
|
||||
, _extracteds ()
|
||||
, _tiles ()
|
||||
, _intervalTrees()
|
||||
: _tramontana (tramontana)
|
||||
, _extracteds ()
|
||||
, _extractedsMask()
|
||||
, _connexityMap ()
|
||||
, _tiles ()
|
||||
, _intervalTrees ()
|
||||
{
|
||||
for ( const BasicLayer* bl : DataBase::getDB()->getTechnology()->getBasicLayers() ) {
|
||||
// HARDCODED. Should read the gauge.
|
||||
if (getString(bl->getName()).substr(0,6) == "gmetal") continue;
|
||||
if ( (bl->getMaterial() == BasicLayer::Material::metal)
|
||||
or (bl->getMaterial() == BasicLayer::Material::poly))
|
||||
or (bl->getMaterial() == BasicLayer::Material::poly)
|
||||
or (bl->getMaterial() == BasicLayer::Material::cut)) {
|
||||
_extracteds.push_back( bl );
|
||||
_extractedsMask |= bl->getMask();
|
||||
}
|
||||
}
|
||||
_buildCutConnexMap();
|
||||
|
||||
// _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal5" ));
|
||||
// _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal4" ));
|
||||
|
@ -110,16 +118,66 @@ namespace Tramontana {
|
|||
{ }
|
||||
|
||||
|
||||
void SweepLine::_buildCutConnexMap ()
|
||||
{
|
||||
for ( const ViaLayer* viaLayer : DataBase::getDB()->getTechnology()->getViaLayers() ) {
|
||||
const BasicLayer* cutLayer = nullptr;
|
||||
for ( const BasicLayer* layer : viaLayer->getBasicLayers() ) {
|
||||
if (layer->getMaterial() == BasicLayer::Material::cut) {
|
||||
cutLayer = layer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (not cutLayer) {
|
||||
cerr << Error( "SweepLine::_buildConnexityMap(): ViaLayer \"%s\" does not contains any *cut* (ignored)."
|
||||
, getString(viaLayer->getName()).c_str()
|
||||
) << endl;
|
||||
continue;
|
||||
}
|
||||
auto iCutMap = _connexityMap.find( cutLayer );
|
||||
if (iCutMap == _connexityMap.end()) {
|
||||
_connexityMap.insert( make_pair( cutLayer, LayerSet() ));
|
||||
iCutMap = _connexityMap.find( cutLayer );
|
||||
}
|
||||
for ( const BasicLayer* layer : viaLayer->getBasicLayers() ) {
|
||||
if ( (layer->getMaterial() != BasicLayer::Material::cut)
|
||||
and (_extractedsMask.intersect(layer->getMask())) ) {
|
||||
iCutMap->second.insert( layer );
|
||||
}
|
||||
}
|
||||
}
|
||||
// for ( auto item : _connexityMap ) {
|
||||
// cerr << "BasicLayers connex to cut: " << item.first << endl;
|
||||
// for ( const BasicLayer* bl : item.second ) {
|
||||
// cerr << "| " << bl << endl;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
const SweepLine::LayerSet& SweepLine::getCutConnexLayers ( const BasicLayer* cutLayer ) const
|
||||
{
|
||||
static LayerSet emptySet;
|
||||
auto iCutMap = _connexityMap.find( cutLayer );
|
||||
if (iCutMap == _connexityMap.end())
|
||||
return emptySet;
|
||||
return iCutMap->second;
|
||||
}
|
||||
|
||||
|
||||
void SweepLine::run ()
|
||||
{
|
||||
//DebugSession::open( 160, 169 );
|
||||
cdebug_log(160,1) << "SweepLine::run()" << endl;
|
||||
loadTiles();
|
||||
//bool debugOn = false;
|
||||
bool written = false;
|
||||
//bool written = false;
|
||||
for ( Element& element : _tiles ) {
|
||||
Tile* tile = element.getTile();
|
||||
TileIntv tileIntv ( tile, tile->getYMin(), tile->getYMax() );
|
||||
// if (tile->getOccurrence().getEntity()->getId() == 3348) {
|
||||
// DebugSession::open( 160, 169 );
|
||||
// }
|
||||
// if (getString(tile->getNet()->getName()) == "a(13)") {
|
||||
// cerr << tile << endl;
|
||||
// }
|
||||
|
@ -143,9 +201,8 @@ namespace Tramontana {
|
|||
continue;
|
||||
}
|
||||
if (element.isLeftEdge()) {
|
||||
// if (tile->getId() == 46055) {
|
||||
// DebugSession::open( 0, 169 );
|
||||
// if (not written) intvTree->second.write( "tree-before.gv" );
|
||||
// if (tile->getOccurrence().getEntity()->getId() == 3348) {
|
||||
// //if (not written) intvTree->second.write( "tree-before.gv" );
|
||||
// cdebug_log(160,0) << " Interval tree *before* insertion." << endl;
|
||||
// for ( auto elt : intvTree->second.getElements() ) {
|
||||
// cdebug_log(160,0) << " | in tree:" << elt << endl;
|
||||
|
@ -167,11 +224,10 @@ namespace Tramontana {
|
|||
// cerr << " | insert " << tile << endl;
|
||||
// }
|
||||
intvTree->second.insert( tileIntv );
|
||||
// if (tile->getId() == 46055) {
|
||||
// if (not written) intvTree->second.write( "tree-after.gv" );
|
||||
// written = true;
|
||||
// DebugSession::close();
|
||||
// }
|
||||
if (tile->getOccurrence().getEntity()->getId() == 3348) {
|
||||
//if (not written) intvTree->second.write( "tree-after.gv" );
|
||||
//written = true;
|
||||
}
|
||||
} else {
|
||||
// if (tile->getId() == 289) {
|
||||
// DebugSession::open( 0, 169 );
|
||||
|
@ -218,7 +274,10 @@ namespace Tramontana {
|
|||
// }
|
||||
}
|
||||
//intvTree->second.checkVMax();
|
||||
cdebug_tabw(160,-1);
|
||||
// cdebug_tabw(160,-1);
|
||||
// if (tile->getOccurrence().getEntity()->getId() == 3348) {
|
||||
// DebugSession::close();
|
||||
// }
|
||||
}
|
||||
//if (debugOn) DebugSession::close();
|
||||
cdebug_tabw(160,-1);
|
||||
|
|
|
@ -33,10 +33,14 @@
|
|||
#include "hurricane/Instance.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "hurricane/Diagonal.h"
|
||||
#include "hurricane/Rectilinear.h"
|
||||
#include "hurricane/Polygon.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "crlcore/Utilities.h"
|
||||
#include "tramontana/Tile.h"
|
||||
#include "tramontana/Equipotential.h"
|
||||
#include "tramontana/SweepLine.h"
|
||||
|
||||
|
||||
namespace Tramontana {
|
||||
|
@ -68,7 +72,10 @@ namespace Tramontana {
|
|||
using Hurricane::Entity;
|
||||
using Hurricane::Horizontal;
|
||||
using Hurricane::Vertical;
|
||||
using Hurricane::RoutingPad;
|
||||
using Hurricane::Vertical;
|
||||
using Hurricane::Diagonal;
|
||||
using Hurricane::Rectilinear;
|
||||
using Hurricane::Polygon;
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::Instance;
|
||||
|
||||
|
@ -82,14 +89,14 @@ namespace Tramontana {
|
|||
vector<Tile*> Tile::_allocateds;
|
||||
|
||||
|
||||
Tile::Tile ( Occurrence occurrence, const BasicLayer* layer, const Box& boundingBox )
|
||||
Tile::Tile ( Occurrence occurrence, const BasicLayer* layer, const Box& boundingBox, Tile* parent )
|
||||
: _id (_idCounter++)
|
||||
, _occurrence (occurrence)
|
||||
, _layer (layer)
|
||||
, _boundingBox (boundingBox)
|
||||
, _equipotential(nullptr)
|
||||
, _flags (0)
|
||||
, _parent (nullptr)
|
||||
, _parent (parent)
|
||||
, _rank (0)
|
||||
, _timeStamp (0)
|
||||
{
|
||||
|
@ -97,7 +104,11 @@ namespace Tramontana {
|
|||
}
|
||||
|
||||
|
||||
Tile* Tile::create ( Occurrence occurrence, const BasicLayer* layer )
|
||||
Tile* Tile::create ( Occurrence occurrence
|
||||
, const BasicLayer* layer
|
||||
, Tile* rootTile
|
||||
, SweepLine* sweepLine
|
||||
, uint32_t flags )
|
||||
{
|
||||
Component* component = dynamic_cast<Component*>( occurrence.getEntity() );
|
||||
if (not component) {
|
||||
|
@ -107,22 +118,72 @@ namespace Tramontana {
|
|||
) << endl;
|
||||
return nullptr;
|
||||
}
|
||||
if (not component->getLayer()->contains(layer)) {
|
||||
cerr << Error( "Tile::create(): Component layer does not contains \"%s\".\n"
|
||||
if (not (flags & ForceLayer) and not component->getLayer()->contains(layer)) {
|
||||
cerr << "Intersect:" << component->getLayer()->getMask().intersect(layer->getMask()) << endl;
|
||||
cerr << Error( "Tile::create(): Component layer \"%s\" does not contains \"%s\".\n"
|
||||
" (%s)\n"
|
||||
" component :%s\n"
|
||||
" basicLayer:%s"
|
||||
, getString(component->getLayer()->getName()).c_str()
|
||||
, getString(layer->getName()).c_str()
|
||||
, getString(occurrence).c_str()
|
||||
, getString(component->getLayer()->getMask()).c_str()
|
||||
, getString(layer->getMask()).c_str()
|
||||
) << endl;
|
||||
return nullptr;
|
||||
}
|
||||
if (dynamic_cast<Polygon*>(component)) {
|
||||
cerr << Error( "Tile::create(): Polygon are not supported for extraction.\n"
|
||||
" (%s)"
|
||||
, getString(occurrence).c_str()
|
||||
) << endl;
|
||||
return nullptr;
|
||||
}
|
||||
if (dynamic_cast<Diagonal*>(component)) {
|
||||
cerr << Error( "Tile::create(): Diagonal are not supported for extraction.\n"
|
||||
" (%s)"
|
||||
, getString(layer).c_str()
|
||||
, getString(occurrence).c_str()
|
||||
) << endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Occurrence childEqui = occurrence;
|
||||
if (not childEqui.getPath().isEmpty())
|
||||
childEqui = Equipotential::getChildEqui( occurrence );
|
||||
|
||||
Rectilinear* rectilinear = dynamic_cast<Rectilinear*>( component );
|
||||
if (rectilinear) {
|
||||
if (not rectilinear->isRectilinear()) {
|
||||
cerr << Error( "Tile::create(): Rectilinear with 45/135 edges are not supported for extraction.\n"
|
||||
" (%s)"
|
||||
, getString(occurrence).c_str()
|
||||
) << endl;
|
||||
return nullptr;
|
||||
}
|
||||
if (rectilinear->getId() == 3367) {
|
||||
DebugSession::open( 160, 169 );
|
||||
cdebug_log(160,0) << "Tiling: " << rectilinear << endl;
|
||||
}
|
||||
vector<Box> boxes;
|
||||
rectilinear->getAsRectangles( boxes );
|
||||
for ( Box bb : boxes ) {
|
||||
occurrence.getPath().getTransformation().applyOn( bb );
|
||||
Tile* tile = new Tile ( childEqui, layer, bb, rootTile );
|
||||
sweepLine->add( tile );
|
||||
cdebug_log(160,0) << "| " << tile << endl;
|
||||
if (not rootTile) rootTile = tile;
|
||||
}
|
||||
if (rectilinear->getId() == 3367) {
|
||||
DebugSession::close();
|
||||
}
|
||||
return rootTile;
|
||||
}
|
||||
|
||||
Box bb = component->getBoundingBox( layer );
|
||||
occurrence.getPath().getTransformation().applyOn( bb );
|
||||
|
||||
if (not occurrence.getPath().isEmpty())
|
||||
occurrence = Equipotential::getChildEqui( occurrence );
|
||||
Tile* tile = new Tile ( occurrence, layer, bb );
|
||||
|
||||
Tile* tile = new Tile ( childEqui, layer, bb, rootTile );
|
||||
sweepLine->add( tile );
|
||||
return tile;
|
||||
}
|
||||
|
||||
|
@ -238,7 +299,8 @@ namespace Tramontana {
|
|||
string Tile::_getString () const
|
||||
{
|
||||
ostringstream os;
|
||||
os << "<Tile " << _boundingBox << " " << _layer->getName() << " " << _occurrence << ">";
|
||||
os << "<Tile tid:" << _id
|
||||
<< " " << _boundingBox << " " << _layer->getName() << " " << _occurrence << ">";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#pragma once
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include "hurricane/BasicLayer.h"
|
||||
namespace Hurricane {
|
||||
|
@ -33,6 +34,7 @@ namespace Tramontana {
|
|||
using Hurricane::Record;
|
||||
using Hurricane::Box;
|
||||
using Hurricane::DbU;
|
||||
using Hurricane::DBo;
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::Layer;
|
||||
using Hurricane::BasicLayer;
|
||||
|
@ -43,7 +45,10 @@ namespace Tramontana {
|
|||
|
||||
class SweepLine {
|
||||
private:
|
||||
typedef std::map<Layer::Mask,TileIntvTree> IntervalTrees;
|
||||
typedef std::map<Layer::Mask, TileIntvTree> IntervalTrees;
|
||||
public:
|
||||
typedef std::set<const BasicLayer*, DBo::CompareById> LayerSet;
|
||||
typedef std::map<const BasicLayer*, LayerSet, DBo::CompareById> ConnexityMap;
|
||||
private:
|
||||
class Element {
|
||||
public:
|
||||
|
@ -66,6 +71,8 @@ namespace Tramontana {
|
|||
inline Cell* getCell ();
|
||||
inline const std::vector<const BasicLayer*>&
|
||||
getExtracteds () const;
|
||||
inline Layer::Mask getExtractedMask () const;
|
||||
const LayerSet& getCutConnexLayers ( const BasicLayer* ) const;
|
||||
void run ();
|
||||
void loadTiles ();
|
||||
inline void add ( Tile* );
|
||||
|
@ -76,9 +83,12 @@ namespace Tramontana {
|
|||
private:
|
||||
SweepLine ( const SweepLine& ) = delete;
|
||||
SweepLine& operator= ( const SweepLine& ) = delete;
|
||||
void _buildCutConnexMap ();
|
||||
private:
|
||||
TramontanaEngine* _tramontana;
|
||||
std::vector<const BasicLayer*> _extracteds;
|
||||
Layer::Mask _extractedsMask;
|
||||
ConnexityMap _connexityMap;
|
||||
std::vector<Element> _tiles;
|
||||
IntervalTrees _intervalTrees;
|
||||
};
|
||||
|
@ -109,7 +119,8 @@ namespace Tramontana {
|
|||
|
||||
// SweepLine.
|
||||
inline Cell* SweepLine::getCell () { return _tramontana->getCell(); }
|
||||
inline const std::vector<const BasicLayer*>& SweepLine::getExtracteds () const { return _extracteds; }
|
||||
inline const std::vector<const BasicLayer*>& SweepLine::getExtracteds () const { return _extracteds; }
|
||||
inline Layer::Mask SweepLine::getExtractedMask () const { return _extractedsMask; }
|
||||
|
||||
inline void SweepLine::add ( Tile* tile )
|
||||
{
|
||||
|
|
|
@ -44,6 +44,7 @@ namespace Tramontana {
|
|||
using Hurricane::IntervalData;
|
||||
using Hurricane::IntervalTree;
|
||||
class Equipotential;
|
||||
class SweepLine;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -51,15 +52,20 @@ namespace Tramontana {
|
|||
|
||||
class Tile {
|
||||
public:
|
||||
static const uint32_t NoFlags = 0;
|
||||
static const uint32_t LeftEdge = (1<<0);
|
||||
static const uint32_t RightEdge = (1<<1);
|
||||
static const uint32_t Compress = (1<<2);
|
||||
static const uint32_t MergeEqui = (1<<3);
|
||||
static const uint32_t NoFlags = 0;
|
||||
static const uint32_t LeftEdge = (1<<0);
|
||||
static const uint32_t RightEdge = (1<<1);
|
||||
static const uint32_t Compress = (1<<2);
|
||||
static const uint32_t MergeEqui = (1<<3);
|
||||
static const uint32_t ForceLayer = (1<<4);
|
||||
public:
|
||||
static inline const std::vector<Tile*> getAllTiles ();
|
||||
static inline void timeTick ();
|
||||
static Tile* create ( Occurrence, const BasicLayer* );
|
||||
static Tile* create ( Occurrence
|
||||
, const BasicLayer*
|
||||
, Tile* rootTile
|
||||
, SweepLine*
|
||||
, uint32_t flags=NoFlags );
|
||||
void destroy ();
|
||||
inline bool isUpToDate () const;
|
||||
inline unsigned int getId () const;
|
||||
|
@ -88,7 +94,7 @@ namespace Tramontana {
|
|||
std::string _getString () const;
|
||||
std::string _getTypeName () const;
|
||||
private:
|
||||
Tile ( Occurrence, const BasicLayer*, const Box& );
|
||||
Tile ( Occurrence, const BasicLayer*, const Box&, Tile* parent );
|
||||
~Tile ();
|
||||
private:
|
||||
Tile ( const Tile& ) = delete;
|
||||
|
|
|
@ -48,7 +48,8 @@ def testRectilinear ( editor ):
|
|||
, Point( l( 20.0), l( 30.0) )
|
||||
, Point( l( 30.0), l( 30.0) )
|
||||
, Point( l( 30.0), l( 20.0) )
|
||||
, Point( l( 10.0), l( 0.0) ) ]
|
||||
, Point( l( 10.0), l( 0.0) )
|
||||
, Point( l( 0.0), l( 0.0) ) ]
|
||||
r = Rectilinear.create( net, metal2, points )
|
||||
|
||||
#print( 'Normalized and manhattanized contour:' )
|
||||
|
@ -72,7 +73,9 @@ def testRectilinear ( editor ):
|
|||
# , Point( l( 90.0), l( 0.0) ) # 12
|
||||
# , Point( l( 20.0), l( 0.0) ) # 13
|
||||
# , Point( l( 20.0), l( 20.0) ) # 14
|
||||
# , Point( l( 0.0), l( 20.0) ) ] # 15
|
||||
# , Point( l( 0.0), l( 20.0) ) # 15
|
||||
# , Point( l( 0.0), l( 40.0) ) ] # 16
|
||||
# Super-test rectilinear.
|
||||
points = [ Point( l( 0.0), l( 0.0) ) # 0
|
||||
, Point( l( 0.0), l( 20.0) ) # 1
|
||||
, Point( l( 10.0), l( 20.0) ) # 2
|
||||
|
@ -83,7 +86,7 @@ def testRectilinear ( editor ):
|
|||
, Point( l( 40.0), l( 80.0) ) # 7
|
||||
, Point( l( 20.0), l( 80.0) ) # 8
|
||||
, Point( l( 20.0), l( 70.0) ) # 9
|
||||
|
||||
|
||||
, Point( l( 10.0), l( 70.0) ) # 10
|
||||
, Point( l( 10.0), l( 60.0) ) # 11
|
||||
, Point( l( 0.0), l( 60.0) ) # 12
|
||||
|
@ -94,7 +97,7 @@ def testRectilinear ( editor ):
|
|||
, Point( l( 20.0), l(100.0) ) # 17
|
||||
, Point( l( 40.0), l(100.0) ) # 18
|
||||
, Point( l( 40.0), l(140.0) ) # 19
|
||||
|
||||
|
||||
, Point( l( 20.0), l(140.0) ) # 20
|
||||
, Point( l( 20.0), l(150.0) ) # 21
|
||||
, Point( l( 10.0), l(150.0) ) # 22
|
||||
|
@ -105,7 +108,7 @@ def testRectilinear ( editor ):
|
|||
, Point( l( 40.0), l(170.0) ) # 27
|
||||
, Point( l( 50.0), l(170.0) ) # 28
|
||||
, Point( l( 50.0), l(160.0) ) # 29
|
||||
|
||||
|
||||
, Point( l(150.0), l(160.0) ) # 30
|
||||
, Point( l(150.0), l(150.0) ) # 31
|
||||
, Point( l(130.0), l(150.0) ) # 32
|
||||
|
@ -116,7 +119,7 @@ def testRectilinear ( editor ):
|
|||
, Point( l(110.0), l(110.0) ) # 37
|
||||
, Point( l(120.0), l(110.0) ) # 38
|
||||
, Point( l(120.0), l(100.0) ) # 39
|
||||
|
||||
|
||||
, Point( l(130.0), l(100.0) ) # 40
|
||||
, Point( l(130.0), l( 90.0) ) # 41
|
||||
, Point( l(150.0), l( 90.0) ) # 42
|
||||
|
@ -127,7 +130,7 @@ def testRectilinear ( editor ):
|
|||
, Point( l(110.0), l( 50.0) ) # 47
|
||||
, Point( l(120.0), l( 50.0) ) # 48
|
||||
, Point( l(120.0), l( 40.0) ) # 49
|
||||
|
||||
|
||||
, Point( l(130.0), l( 40.0) ) # 50
|
||||
, Point( l(130.0), l( 30.0) ) # 51
|
||||
, Point( l(150.0), l( 30.0) ) # 52
|
||||
|
@ -135,7 +138,15 @@ def testRectilinear ( editor ):
|
|||
, Point( l( 50.0), l( 20.0) ) # 54
|
||||
, Point( l( 50.0), l( 10.0) ) # 55
|
||||
, Point( l( 40.0), l( 10.0) ) # 56
|
||||
, Point( l( 40.0), l( 0.0) ) ] # 57
|
||||
, Point( l( 40.0), l( 0.0) ) # 57
|
||||
, Point( l( 0.0), l( 0.0) ) ] # 57
|
||||
#points = [ Point( l( 0.0), l( 0.0) ) # 0
|
||||
# , Point( l( 0.0), l( 80.0) ) # 1
|
||||
# , Point( l( 40.0), l( 80.0) ) # 2
|
||||
# , Point( l( 40.0), l( 60.0) ) # 3
|
||||
# , Point( l( 20.0), l( 60.0) ) # 4
|
||||
# , Point( l( 20.0), l( 0.0) ) # 5
|
||||
# , Point( l( 0.0), l( 0.0) ) ] # 6
|
||||
r = Rectilinear.create( net, metal2, points )
|
||||
|
||||
boxes = []
|
||||
|
|
Loading…
Reference in New Issue