mirror of https://github.com/KLayout/klayout.git
First implementation of deep mode for XOR tool.
This commit is contained in:
parent
26f8fc5c83
commit
c95a0652cc
|
|
@ -231,19 +231,78 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QCheckBox" name="axorb_cb">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item row="5" column="2">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>A XOR B (differences)</string>
|
||||
<string>Tolerances (t1,t2,..) in micron</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Threads</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1" colspan="2">
|
||||
<widget class="QFrame" name="frame_2">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="threads">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Used for tiles and layers</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Tolerances</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Compare modes </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -263,6 +322,22 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QCheckBox" name="axorb_cb">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>A XOR B (differences)</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1" colspan="2">
|
||||
<widget class="QCheckBox" name="summarize_cb">
|
||||
<property name="text">
|
||||
|
|
@ -273,42 +348,27 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Tolerances</string>
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="QCheckBox" name="bnota_cb">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Compare modes </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Tolerances (t1,t2,..) in micron</string>
|
||||
<string>B NOT A (in B but not in A)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Threads</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Tiling</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1" colspan="2">
|
||||
<item row="7" column="1" colspan="2">
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
|
|
@ -365,66 +425,6 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1" colspan="2">
|
||||
<widget class="QFrame" name="frame_2">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="threads">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Used for tiles and layers</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="QCheckBox" name="bnota_cb">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>B NOT A (in B but not in A)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="tolerances">
|
||||
<property name="sizePolicy">
|
||||
|
|
@ -435,6 +435,20 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>Hierarchical</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1" colspan="2">
|
||||
<widget class="QCheckBox" name="deep">
|
||||
<property name="text">
|
||||
<string>consider hierarchy (experimental)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
|||
|
|
@ -25,11 +25,13 @@
|
|||
#include "layXORProgress.h"
|
||||
#include "antService.h"
|
||||
#include "rdb.h"
|
||||
#include "rdbUtils.h"
|
||||
#include "dbShapeProcessor.h"
|
||||
#include "dbRecursiveShapeIterator.h"
|
||||
#include "dbClip.h"
|
||||
#include "dbLayoutUtils.h"
|
||||
#include "dbRegion.h"
|
||||
#include "dbDeepShapeStore.h"
|
||||
#include "tlTimer.h"
|
||||
#include "tlProgress.h"
|
||||
#include "tlThreadedWorkers.h"
|
||||
|
|
@ -58,6 +60,7 @@ std::string cfg_xor_anotb ("xor-anotb");
|
|||
std::string cfg_xor_bnota ("xor-bnota");
|
||||
std::string cfg_xor_summarize ("xor-summarize");
|
||||
std::string cfg_xor_tolerances ("xor-tolerances");
|
||||
std::string cfg_xor_deep ("xor-deep");
|
||||
std::string cfg_xor_tiling ("xor-tiling");
|
||||
std::string cfg_xor_tiling_heal ("xor-tiling-heal");
|
||||
std::string cfg_xor_region_mode ("xor-region-mode");
|
||||
|
|
@ -169,6 +172,7 @@ XORToolDialog::XORToolDialog (QWidget *parent)
|
|||
|
||||
connect (mp_ui->input_layers_cbx, SIGNAL (currentIndexChanged (int)), this, SLOT (input_changed (int)));
|
||||
connect (mp_ui->output_cbx, SIGNAL (currentIndexChanged (int)), this, SLOT (output_changed (int)));
|
||||
connect (mp_ui->deep, SIGNAL (clicked ()), this, SLOT (deep_changed ()));
|
||||
|
||||
input_changed (0);
|
||||
output_changed (0);
|
||||
|
|
@ -251,6 +255,12 @@ XORToolDialog::exec_dialog (lay::LayoutView *view)
|
|||
mp_ui->tolerances->setText (tl::to_qstring (tol));
|
||||
}
|
||||
|
||||
bool deep = false;
|
||||
if (config_root->config_get (cfg_xor_deep, deep)) {
|
||||
mp_ui->deep->setChecked (deep);
|
||||
}
|
||||
deep_changed ();
|
||||
|
||||
std::string tiling;
|
||||
if (config_root->config_get (cfg_xor_tiling, tiling)) {
|
||||
mp_ui->tiling->setText (tl::to_qstring (tiling));
|
||||
|
|
@ -335,6 +345,7 @@ BEGIN_PROTECTED
|
|||
config_root->config_set (cfg_xor_layer_offset, tl::to_string (mp_ui->layer_offset_le->text ()));
|
||||
config_root->config_set (cfg_xor_summarize, mp_ui->summarize_cb->isChecked ());
|
||||
config_root->config_set (cfg_xor_tolerances, tl::to_string (mp_ui->tolerances->text ()));
|
||||
config_root->config_set (cfg_xor_deep, mp_ui->deep->isChecked ());
|
||||
config_root->config_set (cfg_xor_tiling, tl::to_string (mp_ui->tiling->text ()));
|
||||
config_root->config_set (cfg_xor_tiling_heal, mp_ui->heal_cb->isChecked ());
|
||||
config_root->config_end ();
|
||||
|
|
@ -344,6 +355,14 @@ BEGIN_PROTECTED
|
|||
END_PROTECTED
|
||||
}
|
||||
|
||||
void
|
||||
XORToolDialog::deep_changed ()
|
||||
{
|
||||
bool deep = mp_ui->deep->isChecked ();
|
||||
mp_ui->tiling->setEnabled (!deep);
|
||||
mp_ui->heal_cb->setEnabled (!deep);
|
||||
}
|
||||
|
||||
void
|
||||
XORToolDialog::input_changed (int /*index*/)
|
||||
{
|
||||
|
|
@ -510,6 +529,28 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void issue_region (unsigned int tol_index, unsigned int layer_index, const db::Region ®ion)
|
||||
{
|
||||
QMutexLocker locker (&m_mutex);
|
||||
db::CplxTrans trans (dbu ());
|
||||
|
||||
if (m_output_mode == OMMarkerDatabase) {
|
||||
|
||||
rdb::Category *layercat = m_layer_categories[tol_index][layer_index];
|
||||
|
||||
std::pair<db::RecursiveShapeIterator, db::ICplxTrans> it = region.begin_iter ();
|
||||
rdb::scan_layer (layercat, m_rdb_cell, trans * it.second, it.first, false);
|
||||
|
||||
} else {
|
||||
|
||||
db::Cell *output_cell = m_sub_cells[tol_index];
|
||||
unsigned int output_layer = m_sub_output_layers[tol_index][layer_index];
|
||||
|
||||
region.insert_into (output_cell->layout (), output_cell->cell_index (), output_layer);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void issue_polygon (unsigned int tol_index, unsigned int layer_index, const db::Polygon &polygon, bool touches_border = false)
|
||||
{
|
||||
QMutexLocker locker (&m_mutex);
|
||||
|
|
@ -588,12 +629,17 @@ class XORTask
|
|||
: public tl::Task
|
||||
{
|
||||
public:
|
||||
XORTask (const std::string &tile_desc, const db::Box &clip_box, const db::Box ®ion_a, const db::Box ®ion_b, unsigned int layer_index, const db::LayerProperties &lp, const std::vector<unsigned int> &la, const std::vector<unsigned int> &lb, int ix, int iy)
|
||||
: m_tile_desc (tile_desc), m_clip_box (clip_box), m_region_a (region_a), m_region_b (region_b), m_layer_index (layer_index), m_lp (lp), m_la (la), m_lb (lb), m_ix (ix), m_iy (iy)
|
||||
XORTask (bool deep, const std::string &tile_desc, const db::Box &clip_box, const db::Box ®ion_a, const db::Box ®ion_b, unsigned int layer_index, const db::LayerProperties &lp, const std::vector<unsigned int> &la, const std::vector<unsigned int> &lb, int ix, int iy)
|
||||
: m_deep (deep), m_tile_desc (tile_desc), m_clip_box (clip_box), m_region_a (region_a), m_region_b (region_b), m_layer_index (layer_index), m_lp (lp), m_la (la), m_lb (lb), m_ix (ix), m_iy (iy)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
bool deep () const
|
||||
{
|
||||
return m_deep;
|
||||
}
|
||||
|
||||
const std::string &tile_desc () const
|
||||
{
|
||||
return m_tile_desc;
|
||||
|
|
@ -645,6 +691,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
bool m_deep;
|
||||
std::string m_tile_desc;
|
||||
db::Box m_clip_box, m_region_a, m_region_b;
|
||||
unsigned int m_layer_index;
|
||||
|
|
@ -675,10 +722,117 @@ private:
|
|||
XORJob *mp_job;
|
||||
|
||||
void do_perform (const XORTask *task);
|
||||
void do_perform_tiled (const XORTask *task);
|
||||
void do_perform_deep (const XORTask *task);
|
||||
};
|
||||
|
||||
void
|
||||
XORWorker::do_perform (const XORTask *xor_task)
|
||||
{
|
||||
if (xor_task->deep ()) {
|
||||
do_perform_deep (xor_task);
|
||||
} else {
|
||||
do_perform_tiled (xor_task);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XORWorker::do_perform_deep (const XORTask *xor_task)
|
||||
{
|
||||
db::DeepShapeStore dss;
|
||||
db::Region rr;
|
||||
|
||||
unsigned int tol_index = 0;
|
||||
for (std::vector <db::Coord>::const_iterator t = mp_job->tolerances ().begin (); t != mp_job->tolerances ().end (); ++t, ++tol_index) {
|
||||
|
||||
const std::vector<unsigned int> &la = xor_task->la ();
|
||||
const std::vector<unsigned int> &lb = xor_task->lb ();
|
||||
|
||||
if ((!la.empty () && !lb.empty ()) || mp_job->el_handling () != XORJob::EL_summarize) {
|
||||
|
||||
if (tl::verbosity () >= 10) {
|
||||
tl::info << "XOR tool (hierarchical): layer " << xor_task->lp ().to_string () << ", tolerance " << *t * mp_job->dbu ();
|
||||
}
|
||||
|
||||
tl::SelfTimer timer (tl::verbosity () >= 11, "Elapsed time");
|
||||
|
||||
if (tol_index == 0) {
|
||||
|
||||
if ((!la.empty () && !lb.empty ()) || mp_job->el_handling () == XORJob::EL_process) {
|
||||
|
||||
tl::SelfTimer timer (tl::verbosity () >= 21, "Boolean part");
|
||||
|
||||
db::RecursiveShapeIterator s_a (mp_job->cva ()->layout (), mp_job->cva ()->layout ().cell (mp_job->cva ().cell_index ()), la, xor_task->region_a ());
|
||||
db::RecursiveShapeIterator s_b (mp_job->cvb ()->layout (), mp_job->cvb ()->layout ().cell (mp_job->cvb ().cell_index ()), lb, xor_task->region_b ());
|
||||
|
||||
db::Region ra (s_a, dss, db::ICplxTrans (mp_job->cva ()->layout ().dbu () / mp_job->dbu ()));
|
||||
db::Region rb (s_b, dss, db::ICplxTrans (mp_job->cvb ()->layout ().dbu () / mp_job->dbu ()));
|
||||
|
||||
if (mp_job->op () == db::BooleanOp::Xor) {
|
||||
rr = ra ^ rb;
|
||||
} else if (mp_job->op () == db::BooleanOp::ANotB) {
|
||||
rr = ra - rb;
|
||||
} else if (mp_job->op () == db::BooleanOp::BNotA) {
|
||||
rr = rb - ra;
|
||||
}
|
||||
|
||||
} else if (mp_job->op () == db::BooleanOp::Xor ||
|
||||
(mp_job->op () == db::BooleanOp::ANotB && !la.empty ()) ||
|
||||
(mp_job->op () == db::BooleanOp::BNotA && !lb.empty ())) {
|
||||
|
||||
tl::SelfTimer timer (tl::verbosity () >= 21, "Boolean part (shortcut)");
|
||||
|
||||
db::RecursiveShapeIterator s;
|
||||
db::ICplxTrans dbu_scale;
|
||||
|
||||
if (!la.empty ()) {
|
||||
s = db::RecursiveShapeIterator (mp_job->cva ()->layout (), *mp_job->cva ().cell (), la, xor_task->region_a ());
|
||||
dbu_scale = db::ICplxTrans (mp_job->cva ()->layout ().dbu () / mp_job->dbu ());
|
||||
} else if (!lb.empty ()) {
|
||||
s = db::RecursiveShapeIterator (mp_job->cvb ()->layout (), *mp_job->cvb ().cell (), lb, xor_task->region_b ());
|
||||
dbu_scale = db::ICplxTrans (mp_job->cvb ()->layout ().dbu () / mp_job->dbu ());
|
||||
}
|
||||
|
||||
rr = db::Region (s, dss, dbu_scale);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (*t > 0) {
|
||||
tl::SelfTimer timer (tl::verbosity () >= 21, "Sizing part");
|
||||
rr.size (-((*t + 1) / 2), (unsigned int)2, false);
|
||||
rr.size (((*t + 1) / 2), (unsigned int)2, false);
|
||||
}
|
||||
|
||||
// TODO: no clipping for hieararchical mode yet
|
||||
mp_job->issue_region (tol_index, xor_task->layer_index (), rr);
|
||||
|
||||
mp_job->add_results (xor_task->lp (), *t, rr.size (), xor_task->ix (), xor_task->iy ());
|
||||
|
||||
} else if (mp_job->op () == db::BooleanOp::Xor ||
|
||||
(mp_job->op () == db::BooleanOp::ANotB && !la.empty ()) ||
|
||||
(mp_job->op () == db::BooleanOp::BNotA && !lb.empty ())) {
|
||||
|
||||
if (!la.empty ()) {
|
||||
mp_job->issue_string (tol_index, xor_task->layer_index (), tl::to_string (QObject::tr ("Layer not present at all in layout B")));
|
||||
mp_job->add_results (xor_task->lp (), *t, missing_in_b, 0, 0);
|
||||
}
|
||||
|
||||
if (!lb.empty ()) {
|
||||
mp_job->issue_string (tol_index, xor_task->layer_index (), tl::to_string (QObject::tr ("Layer not present at all in layout A")));
|
||||
mp_job->add_results (xor_task->lp (), *t, missing_in_a, 0, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mp_job->next_progress ();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XORWorker::do_perform_tiled (const XORTask *xor_task)
|
||||
{
|
||||
db::ShapeProcessor sp (true);
|
||||
|
||||
|
|
@ -927,6 +1081,8 @@ XORToolDialog::run_xor ()
|
|||
bool anotb = mp_ui->anotb_cb->isChecked ();
|
||||
bool bnota = mp_ui->bnota_cb->isChecked ();
|
||||
|
||||
bool deep = mp_ui->deep->isChecked ();
|
||||
|
||||
bool summarize = mp_ui->summarize_cb->isChecked ();
|
||||
// TODO: make this a user interface feature later
|
||||
bool process_el = lay::ApplicationBase::instance ()->special_app_flag ("ALWAYS_DO_XOR");
|
||||
|
|
@ -1018,7 +1174,7 @@ XORToolDialog::run_xor ()
|
|||
double tile_size = 0; // in micron units
|
||||
bool tile_heal = mp_ui->heal_cb->isChecked ();
|
||||
|
||||
{
|
||||
if (! deep) {
|
||||
std::string text (tl::to_string (mp_ui->tiling->text ()));
|
||||
tl::Extractor ex (text.c_str ());
|
||||
double t = 0.0;
|
||||
|
|
@ -1357,7 +1513,7 @@ XORToolDialog::run_xor ()
|
|||
|
||||
unsigned int layer_index = 0;
|
||||
for (std::map<db::LayerProperties, std::pair<std::vector<unsigned int>, std::vector<unsigned int> >, db::LPLogicalLessFunc>::const_iterator l = layers.begin (); l != layers.end (); ++l, ++layer_index) {
|
||||
job.schedule (new XORTask (tile_desc, clip_box, region_a, region_b, layer_index, l->first, l->second.first, l->second.second, int (nw), int (nh)));
|
||||
job.schedule (new XORTask (deep, tile_desc, clip_box, region_a, region_b, layer_index, l->first, l->second.first, l->second.second, int (nw), int (nh)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ protected:
|
|||
void run_xor ();
|
||||
|
||||
protected slots:
|
||||
void deep_changed ();
|
||||
void input_changed (int index);
|
||||
void output_changed (int index);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue