klayout/src/pex/unit_tests/pexSquareCountingRExtractor...

189 lines
5.5 KiB
C++

/*
KLayout Layout Viewer
Copyright (C) 2006-2025 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 "pexSquareCountingRExtractor.h"
#include "tlUnitTest.h"
namespace
{
class TestableSquareCountingRExtractor
: public pex::SquareCountingRExtractor
{
public:
TestableSquareCountingRExtractor ()
: pex::SquareCountingRExtractor (0.001)
{ }
using pex::SquareCountingRExtractor::PortDefinition;
using pex::SquareCountingRExtractor::do_extract;
};
}
TEST(basic)
{
db::Point contour[] = {
db::Point (0, 0),
db::Point (0, 100),
db::Point (1000, 1000),
db::Point (2100, 1000),
db::Point (2100, 0)
};
db::Polygon poly;
poly.assign_hull (contour + 0, contour + sizeof (contour) / sizeof (contour[0]));
TestableSquareCountingRExtractor rex;
pex::RNetwork rn;
TestableSquareCountingRExtractor::PortDefinition pd1 (pex::RNode::Internal, db::Point (-50, 50), 0);
TestableSquareCountingRExtractor::PortDefinition pd2 (pex::RNode::Internal, db::Point (1000, 100), 1);
TestableSquareCountingRExtractor::PortDefinition pd3 (pex::RNode::Internal, db::Point (1000, 500), 2);
TestableSquareCountingRExtractor::PortDefinition pd4 (pex::RNode::Internal, db::Point (2000, 500), 3);
std::vector<TestableSquareCountingRExtractor::PortDefinition> pds;
pds.push_back (TestableSquareCountingRExtractor::PortDefinition (pex::RNode::Internal, db::Point (0, 50), 0));
pds.push_back (TestableSquareCountingRExtractor::PortDefinition (pex::RNode::Internal, db::Point (1000, 100), 1));
pds.push_back (TestableSquareCountingRExtractor::PortDefinition (pex::RNode::Internal, db::Point (1000, 500), 2));
pds.push_back (TestableSquareCountingRExtractor::PortDefinition (pex::RNode::Internal, db::Point (2000, 500), 3));
std::vector<std::pair<TestableSquareCountingRExtractor::PortDefinition, pex::RNode *> > ports;
for (auto pd = pds.begin (); pd != pds.end (); ++pd) {
ports.push_back (std::make_pair (*pd, rn.create_node (pd->type, pd->port_index)));
}
rex.do_extract (poly, ports, rn);
EXPECT_EQ (rn.to_string (),
"R $0 $1 2.55843\n" // w ramp w=100 to 1000 over x=0 to 1000 (squares = (x2-x1)/(w2-w1)*log(w2/w1) by integration)
"R $1 $2 0\n" // transition from y=50 to y=500 parallel to current direction
"R $2 $3 1" // 1 square between x=1000 and 2000 (w=1000)
);
// After rotation
rn.clear ();
db::Trans r90 (db::Trans::r90);
poly.transform (r90);
ports.clear ();
for (auto pd = pds.begin (); pd != pds.end (); ++pd) {
ports.push_back (std::make_pair (*pd, rn.create_node (pd->type, pd->port_index)));
ports.back ().first.location.transform (r90);
}
rex.do_extract (poly, ports, rn);
// Same network, but opposite order. $1 and $2 are shorted, hence can be swapped.
EXPECT_EQ (rn.to_string (),
"R $1 $3 1\n"
"R $1 $2 0\n"
"R $0 $2 2.55843"
);
}
TEST(extraction)
{
db::Point contour[] = {
db::Point (0, 0),
db::Point (0, 100),
db::Point (1000, 100),
db::Point (1000, 1000),
db::Point (1100, 1000),
db::Point (1100, 100),
db::Point (1700, 100),
db::Point (1700, 0)
};
db::Polygon poly;
poly.assign_hull (contour + 0, contour + sizeof (contour) / sizeof (contour[0]));
double dbu = 0.001;
pex::RNetwork rn;
pex::SquareCountingRExtractor rex (dbu);
std::vector<db::Point> vertex_ports;
vertex_ports.push_back (db::Point (0, 50)); // V0
vertex_ports.push_back (db::Point (1650, 50)); // V1
std::vector<db::Polygon> polygon_ports;
polygon_ports.push_back (db::Polygon (db::Box (1000, 900, 1100, 1000))); // P0
rex.extract (poly, vertex_ports, polygon_ports, rn);
EXPECT_EQ (rn.to_string (),
"R $0 V0 10.5\n"
"R $0 V1 6\n"
"R $0 P0 8.5"
)
}
TEST(extraction_meander)
{
db::Point contour[] = {
db::Point (0, 0),
db::Point (0, 1000),
db::Point (1600, 1000),
db::Point (1600, 600),
db::Point (2000, 600),
db::Point (2000, 1000),
db::Point (3600, 1000),
db::Point (3600, 600),
db::Point (4000, 600),
db::Point (4000, 1000),
db::Point (4600, 1000),
db::Point (4600, 0),
db::Point (3000, 0),
db::Point (3000, 400),
db::Point (2600, 400),
db::Point (2600, 0),
db::Point (1000, 0),
db::Point (1000, 400),
db::Point (600, 400),
db::Point (600, 0)
};
db::Polygon poly;
poly.assign_hull (contour + 0, contour + sizeof (contour) / sizeof (contour[0]));
double dbu = 0.001;
pex::RNetwork rn;
pex::SquareCountingRExtractor rex (dbu);
std::vector<db::Point> vertex_ports;
vertex_ports.push_back (db::Point (300, 0)); // V0
vertex_ports.push_back (db::Point (4300, 1000)); // V1
std::vector<db::Polygon> polygon_ports;
rex.extract (poly, vertex_ports, polygon_ports, rn);
EXPECT_EQ (rn.to_string (),
"R V0 V1 10.0544" // that is pretty much the length of the center line / width :)
)
}