mirror of https://github.com/KLayout/klayout.git
696 lines
22 KiB
C++
696 lines
22 KiB
C++
|
|
/*
|
|
|
|
KLayout Layout Viewer
|
|
Copyright (C) 2006-2021 Matthias Koefferlein
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
|
#include "dbHierarchyBuilder.h"
|
|
#include "dbReader.h"
|
|
#include "dbTestSupport.h"
|
|
#include "dbRegion.h"
|
|
#include "tlUnitTest.h"
|
|
#include "tlStream.h"
|
|
|
|
TEST(1)
|
|
{
|
|
db::Layout ly;
|
|
{
|
|
std::string fn (tl::testdata ());
|
|
fn += "/algo/hierarchy_builder_l1.gds";
|
|
tl::InputStream stream (fn);
|
|
db::Reader reader (stream);
|
|
reader.read (ly);
|
|
}
|
|
|
|
db::Layout target;
|
|
db::HierarchyBuilder builder (&target);
|
|
|
|
for (db::Layout::layer_iterator li = ly.begin_layers (); li != ly.end_layers (); ++li) {
|
|
|
|
unsigned int li1 = (*li).first;
|
|
unsigned int target_layer = target.insert_layer (*(*li).second);
|
|
builder.set_target_layer (target_layer);
|
|
|
|
db::cell_index_type top_cell_index = *ly.begin_top_down ();
|
|
db::RecursiveShapeIterator iter (ly, ly.cell (top_cell_index), li1);
|
|
|
|
iter.push (&builder);
|
|
|
|
}
|
|
|
|
CHECKPOINT();
|
|
db::compare_layouts (_this, target, tl::testdata () + "/algo/hierarchy_builder_au1.gds");
|
|
}
|
|
|
|
TEST(1_WithEmptyLayer)
|
|
{
|
|
db::Layout ly;
|
|
{
|
|
std::string fn (tl::testdata ());
|
|
fn += "/algo/hierarchy_builder_l1.gds";
|
|
tl::InputStream stream (fn);
|
|
db::Reader reader (stream);
|
|
reader.read (ly);
|
|
}
|
|
|
|
db::cell_index_type top_cell_index = *ly.begin_top_down ();
|
|
|
|
db::Layout target;
|
|
db::HierarchyBuilder builder (&target);
|
|
|
|
db::RecursiveShapeIterator iter (ly, ly.cell (top_cell_index), std::set<unsigned int> ());
|
|
iter.push (&builder);
|
|
|
|
for (db::Layout::layer_iterator li = ly.begin_layers (); li != ly.end_layers (); ++li) {
|
|
|
|
unsigned int li1 = (*li).first;
|
|
unsigned int target_layer = target.insert_layer (*(*li).second);
|
|
builder.set_target_layer (target_layer);
|
|
|
|
db::RecursiveShapeIterator iter (ly, ly.cell (top_cell_index), li1);
|
|
|
|
iter.push (&builder);
|
|
|
|
}
|
|
|
|
CHECKPOINT();
|
|
db::compare_layouts (_this, target, tl::testdata () + "/algo/hierarchy_builder_au1.gds");
|
|
}
|
|
|
|
TEST(2_WithoutClip)
|
|
{
|
|
db::Layout ly;
|
|
{
|
|
std::string fn (tl::testdata ());
|
|
fn += "/algo/hierarchy_builder_l1.gds";
|
|
tl::InputStream stream (fn);
|
|
db::Reader reader (stream);
|
|
reader.read (ly);
|
|
}
|
|
|
|
db::Layout target;
|
|
db::HierarchyBuilder builder (&target);
|
|
|
|
db::cell_index_type target_top = target.add_cell ("CLIP_TOP");
|
|
|
|
for (db::Layout::layer_iterator li = ly.begin_layers (); li != ly.end_layers (); ++li) {
|
|
|
|
builder.reset ();
|
|
|
|
unsigned int li1 = (*li).first;
|
|
unsigned int target_layer = target.insert_layer (*(*li).second);
|
|
builder.set_target_layer (target_layer);
|
|
|
|
db::cell_index_type top_cell_index = *ly.begin_top_down ();
|
|
db::RecursiveShapeIterator iter (ly, ly.cell (top_cell_index), li1, db::Box (5000, -2000, 18500, 6000));
|
|
|
|
iter.push (&builder);
|
|
|
|
target.cell (target_top).insert (db::CellInstArray (db::CellInst (builder.initial_cell ()->cell_index ()), db::Trans ()));
|
|
|
|
}
|
|
|
|
CHECKPOINT();
|
|
db::compare_layouts (_this, target, tl::testdata () + "/algo/hierarchy_builder_au2a.gds");
|
|
}
|
|
|
|
TEST(2_WithClip)
|
|
{
|
|
db::Layout ly;
|
|
{
|
|
std::string fn (tl::testdata ());
|
|
fn += "/algo/hierarchy_builder_l1.gds";
|
|
tl::InputStream stream (fn);
|
|
db::Reader reader (stream);
|
|
reader.read (ly);
|
|
}
|
|
|
|
db::Layout target;
|
|
db::ClippingHierarchyBuilderShapeReceiver clip;
|
|
db::HierarchyBuilder builder (&target, db::ICplxTrans (), &clip);
|
|
|
|
db::cell_index_type target_top = target.add_cell ("CLIP_TOP");
|
|
|
|
for (db::Layout::layer_iterator li = ly.begin_layers (); li != ly.end_layers (); ++li) {
|
|
|
|
builder.reset ();
|
|
|
|
unsigned int li1 = (*li).first;
|
|
unsigned int target_layer = target.insert_layer (*(*li).second);
|
|
builder.set_target_layer (target_layer);
|
|
|
|
db::cell_index_type top_cell_index = *ly.begin_top_down ();
|
|
db::RecursiveShapeIterator iter (ly, ly.cell (top_cell_index), li1, db::Box (5000, -2000, 18500, 6000));
|
|
|
|
iter.push (&builder);
|
|
|
|
target.cell (target_top).insert (db::CellInstArray (db::CellInst (builder.initial_cell ()->cell_index ()), db::Trans ()));
|
|
|
|
}
|
|
|
|
CHECKPOINT();
|
|
db::compare_layouts (_this, target, tl::testdata () + "/algo/hierarchy_builder_au2b.gds");
|
|
}
|
|
|
|
TEST(2_WithClipAndSimplification)
|
|
{
|
|
db::Layout ly;
|
|
{
|
|
std::string fn (tl::testdata ());
|
|
fn += "/algo/hierarchy_builder_l1.gds";
|
|
tl::InputStream stream (fn);
|
|
db::Reader reader (stream);
|
|
reader.read (ly);
|
|
}
|
|
|
|
db::Layout target;
|
|
db::ReducingHierarchyBuilderShapeReceiver red(0, 1.2, 4);
|
|
db::ClippingHierarchyBuilderShapeReceiver clip(&red);
|
|
db::HierarchyBuilder builder (&target, db::ICplxTrans (), &clip);
|
|
|
|
db::cell_index_type target_top = target.add_cell ("CLIP_TOP");
|
|
|
|
for (db::Layout::layer_iterator li = ly.begin_layers (); li != ly.end_layers (); ++li) {
|
|
|
|
builder.reset ();
|
|
|
|
unsigned int li1 = (*li).first;
|
|
unsigned int target_layer = target.insert_layer (*(*li).second);
|
|
builder.set_target_layer (target_layer);
|
|
|
|
db::cell_index_type top_cell_index = *ly.begin_top_down ();
|
|
db::RecursiveShapeIterator iter (ly, ly.cell (top_cell_index), li1, db::Box (5000, -2000, 18500, 6000));
|
|
|
|
iter.push (&builder);
|
|
|
|
target.cell (target_top).insert (db::CellInstArray (db::CellInst (builder.initial_cell ()->cell_index ()), db::Trans ()));
|
|
|
|
}
|
|
|
|
CHECKPOINT();
|
|
db::compare_layouts (_this, target, tl::testdata () + "/algo/hierarchy_builder_au2c.gds");
|
|
}
|
|
|
|
TEST(2_WithClipAndRefGeneration)
|
|
{
|
|
db::Layout ly;
|
|
{
|
|
std::string fn (tl::testdata ());
|
|
fn += "/algo/hierarchy_builder_l1.gds";
|
|
tl::InputStream stream (fn);
|
|
db::Reader reader (stream);
|
|
reader.read (ly);
|
|
}
|
|
|
|
db::Layout target;
|
|
db::PolygonReferenceHierarchyBuilderShapeReceiver ref(&target);
|
|
db::ClippingHierarchyBuilderShapeReceiver clip(&ref);
|
|
db::HierarchyBuilder builder (&target, db::ICplxTrans (), &clip);
|
|
|
|
db::cell_index_type target_top = target.add_cell ("CLIP_TOP");
|
|
|
|
for (db::Layout::layer_iterator li = ly.begin_layers (); li != ly.end_layers (); ++li) {
|
|
|
|
builder.reset ();
|
|
|
|
unsigned int li1 = (*li).first;
|
|
unsigned int target_layer = target.insert_layer (*(*li).second);
|
|
builder.set_target_layer (target_layer);
|
|
|
|
db::cell_index_type top_cell_index = *ly.begin_top_down ();
|
|
db::RecursiveShapeIterator iter (ly, ly.cell (top_cell_index), li1, db::Box (5000, -2000, 18500, 6000));
|
|
|
|
iter.push (&builder);
|
|
|
|
target.cell (target_top).insert (db::CellInstArray (db::CellInst (builder.initial_cell ()->cell_index ()), db::Trans ()));
|
|
|
|
}
|
|
|
|
CHECKPOINT();
|
|
db::compare_layouts (_this, target, tl::testdata () + "/algo/hierarchy_builder_au2d.gds");
|
|
}
|
|
|
|
TEST(2_WithEmptyResult)
|
|
{
|
|
db::Layout ly;
|
|
{
|
|
std::string fn (tl::testdata ());
|
|
fn += "/algo/hierarchy_builder_l1.gds";
|
|
tl::InputStream stream (fn);
|
|
db::Reader reader (stream);
|
|
reader.read (ly);
|
|
}
|
|
|
|
db::Layout target;
|
|
db::PolygonReferenceHierarchyBuilderShapeReceiver ref(&target);
|
|
db::ClippingHierarchyBuilderShapeReceiver clip(&ref);
|
|
db::HierarchyBuilder builder (&target, db::ICplxTrans (), &clip);
|
|
|
|
db::cell_index_type target_top = target.add_cell ("CLIP_TOP");
|
|
|
|
for (db::Layout::layer_iterator li = ly.begin_layers (); li != ly.end_layers (); ++li) {
|
|
|
|
builder.reset ();
|
|
|
|
unsigned int li1 = (*li).first;
|
|
unsigned int target_layer = target.insert_layer (*(*li).second);
|
|
builder.set_target_layer (target_layer);
|
|
|
|
db::cell_index_type top_cell_index = *ly.begin_top_down ();
|
|
db::RecursiveShapeIterator iter (ly, ly.cell (top_cell_index), li1, db::Box (5000, 10000, 18500, 15000));
|
|
|
|
iter.push (&builder);
|
|
|
|
target.cell (target_top).insert (db::CellInstArray (db::CellInst (builder.initial_cell ()->cell_index ()), db::Trans ()));
|
|
|
|
}
|
|
|
|
CHECKPOINT();
|
|
db::compare_layouts (_this, target, tl::testdata () + "/algo/hierarchy_builder_au2e.gds");
|
|
}
|
|
|
|
TEST(2_WithClipAndSimplificationAndEmptyLayer)
|
|
{
|
|
db::Layout ly;
|
|
{
|
|
std::string fn (tl::testdata ());
|
|
fn += "/algo/hierarchy_builder_l1.gds";
|
|
tl::InputStream stream (fn);
|
|
db::Reader reader (stream);
|
|
reader.read (ly);
|
|
}
|
|
|
|
db::Layout target;
|
|
db::ReducingHierarchyBuilderShapeReceiver red(0, 1.2, 4);
|
|
db::ClippingHierarchyBuilderShapeReceiver clip(&red);
|
|
db::HierarchyBuilder builder (&target, db::ICplxTrans (), &clip);
|
|
|
|
db::cell_index_type target_top = target.add_cell ("CLIP_TOP");
|
|
|
|
db::Box clip_box (5000, -2000, 18500, 6000);
|
|
|
|
builder.set_target_layer (target.insert_layer (db::LayerProperties (100, 0)));
|
|
|
|
db::cell_index_type top_cell_index = *ly.begin_top_down ();
|
|
db::RecursiveShapeIterator iter (ly, ly.cell (top_cell_index), std::set<unsigned int> (), clip_box);
|
|
|
|
iter.push (&builder);
|
|
|
|
target.cell (target_top).insert (db::CellInstArray (db::CellInst (builder.initial_cell ()->cell_index ()), db::Trans ()));
|
|
|
|
for (db::Layout::layer_iterator li = ly.begin_layers (); li != ly.end_layers (); ++li) {
|
|
|
|
builder.reset ();
|
|
|
|
unsigned int li1 = (*li).first;
|
|
unsigned int target_layer = target.insert_layer (*(*li).second);
|
|
builder.set_target_layer (target_layer);
|
|
|
|
db::cell_index_type top_cell_index = *ly.begin_top_down ();
|
|
db::RecursiveShapeIterator iter (ly, ly.cell (top_cell_index), li1, clip_box);
|
|
|
|
iter.push (&builder);
|
|
|
|
target.cell (target_top).insert (db::CellInstArray (db::CellInst (builder.initial_cell ()->cell_index ()), db::Trans ()));
|
|
|
|
}
|
|
|
|
CHECKPOINT();
|
|
db::compare_layouts (_this, target, tl::testdata () + "/algo/hierarchy_builder_au2f.gds");
|
|
}
|
|
|
|
TEST(3_ComplexRegionWithClip)
|
|
{
|
|
db::Layout ly;
|
|
{
|
|
std::string fn (tl::testdata ());
|
|
fn += "/algo/hierarchy_builder_l2.gds";
|
|
tl::InputStream stream (fn);
|
|
db::Reader reader (stream);
|
|
reader.read (ly);
|
|
}
|
|
|
|
db::Layout target;
|
|
db::ClippingHierarchyBuilderShapeReceiver clip;
|
|
db::HierarchyBuilder builder (&target, db::ICplxTrans (), &clip);
|
|
|
|
db::cell_index_type target_top = target.add_cell ("CLIP_TOP");
|
|
|
|
for (db::Layout::layer_iterator li = ly.begin_layers (); li != ly.end_layers (); ++li) {
|
|
|
|
builder.reset ();
|
|
|
|
unsigned int li1 = (*li).first;
|
|
unsigned int target_layer = target.insert_layer (*(*li).second);
|
|
builder.set_target_layer (target_layer);
|
|
|
|
db::cell_index_type top_cell_index = *ly.begin_top_down ();
|
|
db::Region reg;
|
|
reg.insert (db::Box (5000, 13000, 18500, 20000));
|
|
reg.insert (db::Box (11000, 20000, 18500, 36000));
|
|
reg.merge ();
|
|
db::RecursiveShapeIterator iter (ly, ly.cell (top_cell_index), li1, reg);
|
|
|
|
iter.push (&builder);
|
|
|
|
target.cell (target_top).insert (db::CellInstArray (db::CellInst (builder.initial_cell ()->cell_index ()), db::Trans ()));
|
|
|
|
}
|
|
|
|
CHECKPOINT();
|
|
db::compare_layouts (_this, target, tl::testdata () + "/algo/hierarchy_builder_au3a.gds");
|
|
}
|
|
|
|
TEST(4_ComplexRegionAndLayoutWithClip)
|
|
{
|
|
db::Layout ly;
|
|
{
|
|
std::string fn (tl::testdata ());
|
|
fn += "/algo/hierarchy_builder_l3.gds";
|
|
tl::InputStream stream (fn);
|
|
db::Reader reader (stream);
|
|
reader.read (ly);
|
|
}
|
|
|
|
db::Layout target;
|
|
db::ClippingHierarchyBuilderShapeReceiver clip;
|
|
db::HierarchyBuilder builder (&target, db::ICplxTrans (), &clip);
|
|
|
|
db::cell_index_type target_top = target.add_cell ("CLIP_TOP");
|
|
|
|
for (db::Layout::layer_iterator li = ly.begin_layers (); li != ly.end_layers (); ++li) {
|
|
|
|
builder.reset ();
|
|
|
|
unsigned int li1 = (*li).first;
|
|
unsigned int target_layer = target.insert_layer (*(*li).second);
|
|
builder.set_target_layer (target_layer);
|
|
|
|
db::cell_index_type top_cell_index = *ly.begin_top_down ();
|
|
db::Region reg;
|
|
reg.insert (db::Box (5000, 13000, 18500, 20000));
|
|
reg.insert (db::Box (11000, 20000, 18500, 36000));
|
|
reg.merge ();
|
|
db::RecursiveShapeIterator iter (ly, ly.cell (top_cell_index), li1, reg);
|
|
|
|
iter.push (&builder);
|
|
|
|
target.cell (target_top).insert (db::CellInstArray (db::CellInst (builder.initial_cell ()->cell_index ()), db::Trans ()));
|
|
|
|
}
|
|
|
|
CHECKPOINT();
|
|
db::compare_layouts (_this, target, tl::testdata () + "/algo/hierarchy_builder_au4a.gds");
|
|
}
|
|
|
|
TEST(5_CompareRecursiveShapeIterators)
|
|
{
|
|
db::Layout ly;
|
|
db::cell_index_type ci = ly.add_cell ("TOP");
|
|
db::cell_index_type ci1 = ly.add_cell ("TOPA");
|
|
|
|
db::Layout ly2;
|
|
db::cell_index_type ci2 = ly2.add_cell ("TOP");
|
|
|
|
{
|
|
db::RecursiveShapeIterator iter1 (ly, ly.cell (ci), 0);
|
|
db::RecursiveShapeIterator iter2 (ly2, ly2.cell (ci2), 0);
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2) != 0, true);
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2) != db::compare_iterators_with_respect_to_target_hierarchy (iter2, iter1), true);
|
|
}
|
|
|
|
{
|
|
db::RecursiveShapeIterator iter1 (ly, ly.cell (ci), 0);
|
|
db::RecursiveShapeIterator iter2 (ly, ly.cell (ci1), 0);
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2) != 0, true);
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2) != db::compare_iterators_with_respect_to_target_hierarchy (iter2, iter1), true);
|
|
}
|
|
|
|
{
|
|
db::RecursiveShapeIterator iter1 (ly, ly.cell (ci), 0);
|
|
db::RecursiveShapeIterator iter2 (ly, ly.cell (ci), 1);
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2), 0);
|
|
}
|
|
|
|
{
|
|
std::vector<unsigned int> ll1;
|
|
ll1.push_back (100);
|
|
ll1.push_back (101);
|
|
db::RecursiveShapeIterator iter1 (ly, ly.cell (ci), ll1);
|
|
db::RecursiveShapeIterator iter2 (ly, ly.cell (ci), 1);
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2), 0);
|
|
}
|
|
|
|
{
|
|
db::RecursiveShapeIterator iter1 (ly, ly.cell (ci), 0);
|
|
iter1.max_depth (1);
|
|
db::RecursiveShapeIterator iter2 (ly, ly.cell (ci), 0);
|
|
iter2.max_depth (1);
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2), 0);
|
|
|
|
iter2.max_depth (2);
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2) != 0, true);
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2) != db::compare_iterators_with_respect_to_target_hierarchy (iter2, iter1), true);
|
|
}
|
|
|
|
{
|
|
db::RecursiveShapeIterator iter1 (ly, ly.cell (ci), 0, db::Box (0, 1000, 2000, 3000));
|
|
db::RecursiveShapeIterator iter2 (ly, ly.cell (ci), 0);
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2) != 0, true);
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2) != db::compare_iterators_with_respect_to_target_hierarchy (iter2, iter1), true);
|
|
}
|
|
|
|
{
|
|
db::RecursiveShapeIterator iter1 (ly, ly.cell (ci), 0, db::Box (0, 1000, 2000, 3000));
|
|
db::RecursiveShapeIterator iter2 (ly, ly.cell (ci), 0, db::Box (0, 1000, 2000, 3000));
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2), 0);
|
|
}
|
|
|
|
{
|
|
db::RecursiveShapeIterator iter1 (ly, ly.cell (ci), 0, db::Box (0, 1000, 2000, 3000));
|
|
db::RecursiveShapeIterator iter2 (ly, ly.cell (ci), 1, db::Box (0, 1000, 2000, 3000));
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2) != 0, true);
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2) != db::compare_iterators_with_respect_to_target_hierarchy (iter2, iter1), true);
|
|
}
|
|
|
|
{
|
|
std::vector<unsigned int> ll1;
|
|
ll1.push_back (100);
|
|
ll1.push_back (101);
|
|
|
|
db::RecursiveShapeIterator iter1 (ly, ly.cell (ci), 0, db::Box (0, 1000, 2000, 3000));
|
|
db::RecursiveShapeIterator iter2 (ly, ly.cell (ci), ll1, db::Box (0, 1000, 2000, 3000));
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2) != 0, true);
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2) != db::compare_iterators_with_respect_to_target_hierarchy (iter2, iter1), true);
|
|
}
|
|
|
|
{
|
|
db::RecursiveShapeIterator iter1 (ly, ly.cell (ci), 0, db::Box (0, 1000, 2000, 3000));
|
|
db::RecursiveShapeIterator iter2 (ly, ly.cell (ci), 0, db::Box (0, 1000, 2000, 3001));
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2) != 0, true);
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2) != db::compare_iterators_with_respect_to_target_hierarchy (iter2, iter1), true);
|
|
}
|
|
|
|
{
|
|
db::Region r1;
|
|
r1.insert (db::Box (0, 1000, 2000, 3000));
|
|
db::RecursiveShapeIterator iter1 (ly, ly.cell (ci), 0, r1);
|
|
db::RecursiveShapeIterator iter2 (ly, ly.cell (ci), 0, db::Box (0, 1000, 2000, 3000));
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2), 0);
|
|
}
|
|
|
|
{
|
|
db::Region r1;
|
|
r1.insert (db::Box (0, 1000, 2000, 3000));
|
|
r1.insert (db::Box (0, 4000, 2000, 6000));
|
|
db::RecursiveShapeIterator iter1 (ly, ly.cell (ci), 0, r1);
|
|
db::RecursiveShapeIterator iter2 (ly, ly.cell (ci), 0, db::Box (0, 1000, 2000, 3000));
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2) != 0, true);
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2) != db::compare_iterators_with_respect_to_target_hierarchy (iter2, iter1), true);
|
|
}
|
|
|
|
{
|
|
db::Region r1;
|
|
r1.insert (db::Box (0, 1000, 2000, 3000));
|
|
r1.insert (db::Box (0, 4000, 2000, 6000));
|
|
db::RecursiveShapeIterator iter1 (ly, ly.cell (ci), 0, r1);
|
|
db::Region r2;
|
|
r2.insert (db::Box (0, 1000, 2000, 3000));
|
|
r2.insert (db::Box (0, 4000, 2000, 6000));
|
|
db::RecursiveShapeIterator iter2 (ly, ly.cell (ci), 0, r2);
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2), 0);
|
|
}
|
|
|
|
{
|
|
db::Region r1;
|
|
r1.insert (db::Box (0, 1000, 2000, 3000));
|
|
r1.insert (db::Box (0, 4000, 2000, 6000));
|
|
db::RecursiveShapeIterator iter1 (ly, ly.cell (ci), 0, r1);
|
|
db::Region r2;
|
|
r2.insert (db::Box (0, 1000, 2000, 3000));
|
|
r2.insert (db::Box (0, 4000, 2000, 6001));
|
|
db::RecursiveShapeIterator iter2 (ly, ly.cell (ci), 0, r2);
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2) != 0, true);
|
|
EXPECT_EQ (db::compare_iterators_with_respect_to_target_hierarchy (iter1, iter2) != db::compare_iterators_with_respect_to_target_hierarchy (iter2, iter1), true);
|
|
}
|
|
}
|
|
|
|
TEST(6_DisjunctLayersPerHierarchyBranch)
|
|
{
|
|
db::Layout ly;
|
|
{
|
|
std::string fn (tl::testdata ());
|
|
fn += "/algo/hierarchy_builder_l4.gds";
|
|
tl::InputStream stream (fn);
|
|
db::Reader reader (stream);
|
|
reader.read (ly);
|
|
}
|
|
|
|
db::Layout target;
|
|
db::HierarchyBuilder builder (&target);
|
|
|
|
for (db::Layout::layer_iterator li = ly.begin_layers (); li != ly.end_layers (); ++li) {
|
|
|
|
unsigned int li1 = (*li).first;
|
|
unsigned int target_layer = target.insert_layer (*(*li).second);
|
|
builder.set_target_layer (target_layer);
|
|
|
|
db::cell_index_type top_cell_index = *ly.begin_top_down ();
|
|
db::RecursiveShapeIterator iter (ly, ly.cell (top_cell_index), li1);
|
|
|
|
iter.push (&builder);
|
|
|
|
}
|
|
|
|
CHECKPOINT();
|
|
db::compare_layouts (_this, target, tl::testdata () + "/algo/hierarchy_builder_au_l4.gds");
|
|
}
|
|
|
|
TEST(7_DetachFromOriginalLayout)
|
|
{
|
|
// using OASIS means we create a lot of references to array
|
|
// and shape repo - we check here whether these references get
|
|
// translated or resolved in the hierarchy builder.
|
|
std::unique_ptr<db::Layout> ly (new db::Layout (false));
|
|
{
|
|
std::string fn (tl::testdata ());
|
|
fn += "/algo/hierarchy_builder_l5.oas.gz";
|
|
tl::InputStream stream (fn);
|
|
db::Reader reader (stream);
|
|
reader.read (*ly);
|
|
}
|
|
|
|
db::Layout target;
|
|
db::HierarchyBuilder builder (&target);
|
|
|
|
for (db::Layout::layer_iterator li = ly->begin_layers (); li != ly->end_layers (); ++li) {
|
|
|
|
unsigned int li1 = (*li).first;
|
|
unsigned int target_layer = target.insert_layer (*(*li).second);
|
|
builder.set_target_layer (target_layer);
|
|
|
|
db::cell_index_type top_cell_index = *ly->begin_top_down ();
|
|
db::RecursiveShapeIterator iter (*ly, ly->cell (top_cell_index), li1);
|
|
|
|
iter.push (&builder);
|
|
|
|
}
|
|
|
|
// make sure there is no connection to original layout
|
|
ly.reset (0);
|
|
|
|
CHECKPOINT();
|
|
db::compare_layouts (_this, target, tl::testdata () + "/algo/hierarchy_builder_au_l5.gds");
|
|
}
|
|
|
|
TEST(8a_SimpleWithTrans)
|
|
{
|
|
db::Layout ly;
|
|
{
|
|
std::string fn (tl::testdata ());
|
|
fn += "/algo/hierarchy_builder_l1.gds";
|
|
tl::InputStream stream (fn);
|
|
db::Reader reader (stream);
|
|
reader.read (ly);
|
|
}
|
|
|
|
db::Layout target;
|
|
db::HierarchyBuilder builder (&target, db::ICplxTrans (2.0, 45.0, false, db::Vector ()));
|
|
|
|
for (db::Layout::layer_iterator li = ly.begin_layers (); li != ly.end_layers (); ++li) {
|
|
|
|
unsigned int li1 = (*li).first;
|
|
unsigned int target_layer = target.insert_layer (*(*li).second);
|
|
builder.set_target_layer (target_layer);
|
|
|
|
db::cell_index_type top_cell_index = *ly.begin_top_down ();
|
|
db::RecursiveShapeIterator iter (ly, ly.cell (top_cell_index), li1);
|
|
|
|
iter.push (&builder);
|
|
|
|
}
|
|
|
|
CHECKPOINT();
|
|
db::compare_layouts (_this, target, tl::testdata () + "/algo/hierarchy_builder_au8a.gds");
|
|
}
|
|
|
|
TEST(8b_ComplexRegionWithTransformation)
|
|
{
|
|
db::Layout ly;
|
|
{
|
|
std::string fn (tl::testdata ());
|
|
fn += "/algo/hierarchy_builder_l2.gds";
|
|
tl::InputStream stream (fn);
|
|
db::Reader reader (stream);
|
|
reader.read (ly);
|
|
}
|
|
|
|
db::Layout target;
|
|
db::ClippingHierarchyBuilderShapeReceiver clip;
|
|
db::HierarchyBuilder builder (&target, db::ICplxTrans (2.0, 45.0, false, db::Vector ()), &clip);
|
|
|
|
db::cell_index_type target_top = target.add_cell ("CLIP_TOP");
|
|
|
|
for (db::Layout::layer_iterator li = ly.begin_layers (); li != ly.end_layers (); ++li) {
|
|
|
|
builder.reset ();
|
|
|
|
unsigned int li1 = (*li).first;
|
|
unsigned int target_layer = target.insert_layer (*(*li).second);
|
|
builder.set_target_layer (target_layer);
|
|
|
|
db::cell_index_type top_cell_index = *ly.begin_top_down ();
|
|
db::Region reg;
|
|
reg.insert (db::Box (5000, 13000, 18500, 20000));
|
|
reg.insert (db::Box (11000, 20000, 18500, 36000));
|
|
reg.merge ();
|
|
db::RecursiveShapeIterator iter (ly, ly.cell (top_cell_index), li1, reg);
|
|
|
|
iter.push (&builder);
|
|
|
|
target.cell (target_top).insert (db::CellInstArray (db::CellInst (builder.initial_cell ()->cell_index ()), db::Trans ()));
|
|
|
|
}
|
|
|
|
CHECKPOINT();
|
|
db::compare_layouts (_this, target, tl::testdata () + "/algo/hierarchy_builder_au8b.gds");
|
|
}
|
|
|