WIP: DXF keep layer names option, refactoring, added tests, UI, XML serialization.

This commit is contained in:
Matthias Koefferlein 2018-04-16 19:47:12 +02:00
parent 085a2ee2b1
commit 86a90571e6
17 changed files with 980 additions and 814 deletions

View File

@ -139,7 +139,7 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
"The value is given in micrometer units. The default value is 1nm (0.001)."
)
<< tl::arg (group +
"#--" + m_long_prefix + "keep-layer-names", &GenericReaderOptions::set_read_named_layers, "Keeps layer names",
"#--" + m_long_prefix + "keep-layer-names", this, &GenericReaderOptions::set_read_named_layers, "Keeps layer names",
"If this option is used, layers names are kept as pure names and no attempt is made to\n"
"translate them into GDS layer/datatypes."
)
@ -234,8 +234,8 @@ void GenericReaderOptions::set_layer_map (const std::string &lm)
void GenericReaderOptions::set_read_named_layers (bool f)
{
m_dxf_reader_options.read_named_layers = f;
m_cif_reader_options.read_named_layers = f;
m_dxf_reader_options.keep_layer_names = f;
m_cif_reader_options.keep_layer_names = f;
}
void GenericReaderOptions::set_dbu (double dbu)

View File

@ -101,7 +101,6 @@ private:
std::string m_prefix, m_long_prefix, m_group_prefix;
db::LayerMap m_layer_map;
bool m_create_other_layers;
bool m_read_named_layers;
db::CommonReaderOptions m_common_reader_options;
db::GDS2ReaderOptions m_gds2_reader_options;
db::OASISReaderOptions m_oasis_reader_options;

View File

@ -129,7 +129,8 @@ SOURCES = \
gsiDeclDbVector.cc \
gsiDeclDbLayoutDiff.cc \
gsiDeclDbGlyphs.cc \
dbVariableWidthPath.cc
dbVariableWidthPath.cc \
dbNamedLayerReader.cc
HEADERS = \
dbArray.h \
@ -230,7 +231,8 @@ HEADERS = \
dbCommonReader.h \
dbGlyphs.h \
dbCommon.h \
dbVariableWidthPath.h
dbVariableWidthPath.h \
dbNamedLayerReader.h
RESOURCES = \
dbResources.qrc

View File

@ -43,9 +43,8 @@ namespace db
CIFReader::CIFReader (tl::InputStream &s)
: m_stream (s),
m_create_layers (true),
m_progress (tl::to_string (QObject::tr ("Reading CIF file")), 1000),
m_dbu (0.001), m_wire_mode (0), m_next_layer_index (0)
m_dbu (0.001), m_wire_mode (0)
{
m_progress.set_format (tl::to_string (QObject::tr ("%.0fk lines")));
m_progress.set_format_unit (1000.0);
@ -60,19 +59,22 @@ CIFReader::~CIFReader ()
const LayerMap &
CIFReader::read (db::Layout &layout, const db::LoadLayoutOptions &options)
{
m_dbu = 0.001;
m_wire_mode = 0;
m_next_layer_index = 0;
prepare_layers ();
const db::CIFReaderOptions &specific_options = options.get_options<db::CIFReaderOptions> ();
m_wire_mode = specific_options.wire_mode;
m_dbu = specific_options.dbu;
m_layer_map = specific_options.layer_map;
m_layer_map.prepare (layout);
m_create_layers = specific_options.create_other_layers;
db::LayerMap lm = specific_options.layer_map;
lm.prepare (layout);
set_layer_map (lm);
set_create_layers (specific_options.create_other_layers);
set_keep_layer_names (specific_options.keep_layer_names);
do_read (layout);
return m_layer_map;
finish_layers (layout);
return layer_map ();
}
const LayerMap &
@ -342,61 +344,6 @@ CIFReader::read_double ()
return v;
}
static bool
extract_plain_layer (const char *s, int &l)
{
l = 0;
if (! *s) {
return false;
}
while (*s && isdigit (*s)) {
l = l * 10 + (unsigned int) (*s - '0');
++s;
}
return (*s == 0);
}
static bool
extract_ld (const char *s, int &l, int &d, std::string &n)
{
l = d = 0;
if (*s == 'L') {
++s;
}
if (! *s || ! isdigit (*s)) {
return false;
}
while (*s && isdigit (*s)) {
l = l * 10 + (unsigned int) (*s - '0');
++s;
}
if (*s == 'D' || *s == '.') {
++s;
if (! *s || ! isdigit (*s)) {
return false;
}
while (*s && isdigit (*s)) {
d = d * 10 + (unsigned int) (*s - '0');
++s;
}
}
if (*s && (isspace (*s) || *s == '_')) {
++s;
n = s;
return true;
} else if (*s == 0) {
n.clear ();
return true;
} else {
return false;
}
}
bool
CIFReader::read_cell (db::Layout &layout, db::Cell &cell, double sf, int level)
{
@ -598,60 +545,11 @@ CIFReader::read_cell (db::Layout &layout, db::Cell &cell, double sf, int level)
error ("Missing layer name in 'L' command");
}
std::pair<bool, unsigned int> ll = m_layer_map.logical (name);
std::pair<bool, unsigned int> ll = open_layer (layout, name);
if (! ll.first) {
int l = -1, d = -1;
std::string on;
if (extract_plain_layer (name.c_str (), l)) {
db::LayerProperties lp;
lp.layer = l;
lp.datatype = 0;
ll = m_layer_map.logical (lp);
} else if (extract_ld (name.c_str (), l, d, on)) {
db::LayerProperties lp;
lp.layer = l;
lp.datatype = d;
lp.name = on;
ll = m_layer_map.logical (lp);
}
}
if (ll.first) {
// create the layer if it is not part of the layout yet.
if (! layout.is_valid_layer (ll.second)) {
layout.insert_layer (ll.second, m_layer_map.mapping (ll.second));
}
layer = int (ll.second);
} else if (! m_create_layers) {
layer = -1; // ignore geometric objects on this layer
} else {
std::map <std::string, unsigned int>::const_iterator nl = m_new_layers.find (name);
if (nl == m_new_layers.end ()) {
unsigned int ll = m_next_layer_index++;
layout.insert_layer (ll, db::LayerProperties ());
m_new_layers.insert (std::make_pair (name, ll));
layer = int (ll);
} else {
layer = int (nl->second);
}
layer = int (ll.second);
}
expect_semi ();
@ -928,8 +826,6 @@ CIFReader::do_read (db::Layout &layout)
layout.dbu (m_dbu);
m_cellname = "{CIF top level}";
m_next_layer_index = m_layer_map.next_index ();
m_new_layers.clear ();
db::Cell &cell = layout.cell (layout.add_cell ());
@ -948,76 +844,6 @@ CIFReader::do_read (db::Layout &layout)
warn ("E command is followed by more text");
}
// assign layer numbers to new layers
if (! m_new_layers.empty ()) {
std::set<std::pair<int, int> > used_ld;
for (db::Layout::layer_iterator l = layout.begin_layers (); l != layout.end_layers (); ++l) {
used_ld.insert (std::make_pair((*l).second->layer, (*l).second->datatype));
}
// assign fixed layer numbers for all layers whose name is a fixed number unless there is already a layer with that number
for (std::map<std::string, unsigned int>::iterator i = m_new_layers.begin (); i != m_new_layers.end (); ) {
std::map<std::string, unsigned int>::iterator ii = i;
++ii;
int l = -1;
if (extract_plain_layer (i->first.c_str (), l) && used_ld.find (std::make_pair (l, 0)) == used_ld.end ()) {
used_ld.insert (std::make_pair (l, 0));
db::LayerProperties lp;
lp.layer = l;
lp.datatype = 0;
layout.set_properties (i->second, lp);
m_layer_map.map (lp, i->second);
m_new_layers.erase (i);
}
i = ii;
}
// assign fixed layer numbers for all layers whose name is a LxDy or Lx notation unless there is already a layer with that layer/datatype
for (std::map<std::string, unsigned int>::iterator i = m_new_layers.begin (); i != m_new_layers.end (); ) {
std::map<std::string, unsigned int>::iterator ii = i;
++ii;
int l = -1, d = -1;
std::string n;
if (extract_ld (i->first.c_str (), l, d, n) && used_ld.find (std::make_pair (l, d)) == used_ld.end ()) {
used_ld.insert (std::make_pair (l, d));
db::LayerProperties lp;
lp.layer = l;
lp.datatype = d;
lp.name = n;
layout.set_properties (i->second, lp);
m_layer_map.map (lp, i->second);
m_new_layers.erase (i);
}
i = ii;
}
for (std::map<std::string, unsigned int>::const_iterator i = m_new_layers.begin (); i != m_new_layers.end (); ++i) {
db::LayerProperties lp;
lp.name = i->first;
layout.set_properties (i->second, lp);
m_layer_map.map (lp, i->second);
}
}
} catch (db::CIFReaderException &ex) {
throw ex;
} catch (tl::Exception &ex) {

View File

@ -30,8 +30,8 @@
#include "tlProgress.h"
#include "tlString.h"
#include "dbNamedLayerReader.h"
#include "dbLayout.h"
#include "dbReader.h"
#include "dbCIF.h"
#include "tlStream.h"
#include "dbStreamLayers.h"
@ -56,7 +56,8 @@ public:
CIFReaderOptions ()
: wire_mode (0),
dbu (0.001),
create_other_layers (true)
create_other_layers (true),
keep_layer_names (false)
{
// .. nothing yet ..
}
@ -96,6 +97,16 @@ public:
*/
bool create_other_layers;
/**
* @brief A flag indicating whether the names of layers shall be kept as such
*
* If this flag is set to false (the default), layer name translation happens.
* If set to true, translation will not happen.
* Name translation will try to extract GDS layer/datatype numbers from the
* layer names. If this value is set to true, no name translation happens.
*/
bool keep_layer_names;
/**
* @brief Implementation of FormatSpecificReaderOptions
*/
@ -130,7 +141,7 @@ public:
* @brief The CIF format stream reader
*/
class DB_PUBLIC CIFReader
: public ReaderBase,
: public NamedLayerReader,
public CIFDiagnostics
{
public:
@ -202,16 +213,12 @@ public:
private:
tl::TextInputStream m_stream;
bool m_create_layers;
LayerMap m_layer_map;
tl::AbsoluteProgress m_progress;
double m_dbu;
unsigned int m_wire_mode;
std::string m_cellname;
std::string m_cmd_buffer;
std::map <unsigned int, db::cell_index_type> m_cells_by_id;
unsigned int m_next_layer_index;
std::map <std::string, unsigned int> m_new_layers;
void do_read (db::Layout &layout);

View File

@ -20,8 +20,6 @@
*/
#include "dbDXFReader.h"
#include "dbStream.h"
#include "dbObjectWithProperties.h"
@ -50,237 +48,6 @@
namespace db
{
// ---------------------------------------------------------------
// NamedLayerReader
NamedLayerReader::NamedLayerReader ()
: m_create_layers (true), m_read_named_layers (false), m_next_layer_index (0)
{
// .. nothing yet ..
}
void
NamedLayerReader::set_create_layers (bool f)
{
m_create_layers = f;
}
void
NamedLayerReader::set_read_named_layers (bool f)
{
m_read_named_layers = f;
}
void NamedLayerReader::set_layer_map (const LayerMap &lm)
{
m_layer_map = lm;
}
static bool
extract_plain_layer (const char *s, int &l)
{
l = 0;
if (! *s) {
return false;
}
while (*s && isdigit (*s)) {
l = l * 10 + (unsigned int) (*s - '0');
++s;
}
return (*s == 0);
}
static bool
extract_ld (const char *s, int &l, int &d, std::string &n)
{
l = d = 0;
if (*s == 'L') {
++s;
}
if (! *s || ! isdigit (*s)) {
return false;
}
while (*s && isdigit (*s)) {
l = l * 10 + (unsigned int) (*s - '0');
++s;
}
if (*s == 'D' || *s == '.') {
++s;
if (! *s || ! isdigit (*s)) {
return false;
}
while (*s && isdigit (*s)) {
d = d * 10 + (unsigned int) (*s - '0');
++s;
}
}
if (*s && (isspace (*s) || *s == '_')) {
++s;
n = s;
return true;
} else if (*s == 0) {
n.clear ();
return true;
} else {
return false;
}
}
std::pair <bool, unsigned int>
NamedLayerReader::open_layer (db::Layout &layout, const std::string &n)
{
int l = -1, d = -1;
std::string on;
std::pair<bool, unsigned int> ll (false, 0);
ll = m_layer_map.logical (n);
if (! ll.first && !m_read_named_layers) {
if (extract_plain_layer (n.c_str (), l)) {
db::LayerProperties lp;
lp.layer = l;
lp.datatype = 0;
ll = m_layer_map.logical (lp);
} else if (extract_ld (n.c_str (), l, d, on)) {
db::LayerProperties lp;
lp.layer = l;
lp.datatype = d;
lp.name = on;
ll = m_layer_map.logical (lp);
}
}
if (ll.first) {
// create the layer if it is not part of the layout yet.
if (! layout.is_valid_layer (ll.second)) {
layout.insert_layer (ll.second, m_layer_map.mapping (ll.second));
}
return ll;
} else if (! m_create_layers) {
return std::pair<bool, unsigned int> (false, 0);
} else {
std::map <std::string, unsigned int>::const_iterator nl = m_new_layers.find (n);
if (nl == m_new_layers.end ()) {
unsigned int ll = m_next_layer_index++;
layout.insert_layer (ll, db::LayerProperties ());
m_new_layers.insert (std::make_pair (n, ll));
return std::pair<bool, unsigned int> (true, ll);
} else {
return std::pair<bool, unsigned int> (true, nl->second);
}
}
}
void
NamedLayerReader::map_layer (const std::string &name, unsigned int layer)
{
m_layer_map.map (name, layer);
}
void
NamedLayerReader::prepare_layers ()
{
m_new_layers.clear ();
m_next_layer_index = m_layer_map.next_index ();
}
void
NamedLayerReader::finish_layers (db::Layout &layout)
{
// assign layer numbers to new layers
if (! m_new_layers.empty () && !m_read_named_layers) {
std::set<std::pair<int, int> > used_ld;
for (db::Layout::layer_iterator l = layout.begin_layers (); l != layout.end_layers (); ++l) {
used_ld.insert (std::make_pair((*l).second->layer, (*l).second->datatype));
}
// assign fixed layer numbers for all layers whose name is a fixed number unless there is already a layer with that number
for (std::map<std::string, unsigned int>::iterator i = m_new_layers.begin (); i != m_new_layers.end (); ) {
std::map<std::string, unsigned int>::iterator ii = i;
++ii;
int l = -1;
if (extract_plain_layer (i->first.c_str (), l) && used_ld.find (std::make_pair (l, 0)) == used_ld.end ()) {
used_ld.insert (std::make_pair (l, 0));
db::LayerProperties lp;
lp.layer = l;
lp.datatype = 0;
layout.set_properties (i->second, lp);
m_layer_map.map (lp, i->second);
m_new_layers.erase (i);
}
i = ii;
}
// assign fixed layer numbers for all layers whose name is a LxDy or Lx notation unless there is already a layer with that layer/datatype
for (std::map<std::string, unsigned int>::iterator i = m_new_layers.begin (); i != m_new_layers.end (); ) {
std::map<std::string, unsigned int>::iterator ii = i;
++ii;
int l = -1, d = -1;
std::string n;
if (extract_ld (i->first.c_str (), l, d, n) && used_ld.find (std::make_pair (l, d)) == used_ld.end ()) {
used_ld.insert (std::make_pair (l, d));
db::LayerProperties lp;
lp.layer = l;
lp.datatype = d;
lp.name = n;
layout.set_properties (i->second, lp);
m_layer_map.map (lp, i->second);
m_new_layers.erase (i);
}
i = ii;
}
}
// insert the remaining ones
for (std::map<std::string, unsigned int>::const_iterator i = m_new_layers.begin (); i != m_new_layers.end (); ++i) {
db::LayerProperties lp;
lp.name = i->first;
layout.set_properties (i->second, lp);
m_layer_map.map (lp, i->second);
}
}
// ---------------------------------------------------------------
// DXFReader
@ -553,7 +320,7 @@ DXFReader::read (db::Layout &layout, const db::LoadLayoutOptions &options)
lm.prepare (layout);
set_layer_map (lm);
set_create_layers (specific_options.create_other_layers);
set_read_named_layers (specific_options.read_named_layers);
set_keep_layer_names (specific_options.keep_layer_names);
db::cell_index_type top = layout.add_cell("TOP"); // TODO: make variable ..

View File

@ -31,7 +31,7 @@
#include "tlString.h"
#include "dbLayout.h"
#include "dbReader.h"
#include "dbNamedLayerReader.h"
#include "dbDXF.h"
#include "tlStream.h"
#include "dbStreamLayers.h"
@ -66,7 +66,7 @@ public:
render_texts_as_polygons (false),
keep_other_cells (false),
create_other_layers (true),
read_named_layers (false)
keep_layer_names (false)
{
// .. nothing yet ..
}
@ -134,8 +134,8 @@ public:
* @brief Accuracy for closing polylines
*
* When polylines need to be connected or closed, this
* value is used to indicate the accuracy. This is the value
* by while points may be separated and still be considered
* value is used to indicate the accuracy. This is the value (in DXF units)
* by which points may be separated and still be considered
* connected. The default is 0.0 which implies exact
* (within one DBU) closing.
*/
@ -174,12 +174,14 @@ public:
bool create_other_layers;
/**
* @brief A flag indicating whether the names of layers shall be read (maintained)
* @brief A flag indicating whether the names of layers shall be kept as such
*
* If this flag is set to false (the default), layer name translation happens.
* If set to true, translation will not happen.
* Name translation will try to extract GDS layer/datatype numbers from the
* layer names. If this value is set to true, no name translation happens.
*/
bool read_named_layers;
bool keep_layer_names;
/**
* @brief Implementation of FormatSpecificReaderOptions
@ -215,106 +217,6 @@ public:
{ }
};
/**
* @brief A reader base class for streams with named-only layers
*
* This class implements the layer name translation logic.
* Specifically:
* - a number is translated to the corresponding layer, datatype 0
* - Lx is translated to layer x, datatype 0
* - Lx_SUFFIX is translated to layer x, datatype 0, name "SUFFIX"
* - LxDy is translated to layer x, datatype y
* - LxDy_SUFFIX is translated to layer x, datatype y, name "SUFFIX"
*
* Furthermore, the layer map and creation of new layers is handled in this
* base class.
*/
class DB_PUBLIC NamedLayerReader
: public ReaderBase
{
public:
/**
* @brief The constructor
*/
NamedLayerReader ();
/**
* @brief Sets a value indicating whether to create new layers
*/
void set_create_layers (bool f);
/**
* @brief Gets a value indicating whether to create new layers
*/
bool create_layers () const
{
return m_create_layers;
}
/**
* @brief Sets the layer map
*/
void set_layer_map (const LayerMap &lm);
/**
* @brief Gets the layer map
*/
const LayerMap &layer_map ()
{
return m_layer_map;
}
/**
* @brief Sets a value indicating whether layer names are kept
* If set to true, no name translation is performed and layers are
* always named only. If set the false (the default), layer names will
* be translated to GDS layer/datatypes if possible.
*/
void set_read_named_layers (bool f);
/**
* @brief Gets a value indicating whether layer names are kept
*/
bool read_named_layers () const
{
return m_read_named_layers;
}
protected:
/**
* @brief Opens a new layer
* This method will create or locate a layer for a given name.
* The result's first attribute is true, if such a layer could be found
* or created. In this case, the second attribute is the layer index.
*/
std::pair <bool, unsigned int> open_layer (db::Layout &layout, const std::string &name);
/**
* @brief Force mapping of a name to a layer index
*/
void map_layer (const std::string &name, unsigned int layer);
/**
* @brief Finish reading
* This method must be called after the reading has been done.
* It will finalize the layers.
*/
void finish_layers (db::Layout &layout);
/**
* @brief Prepares reading
* This method must be called before the reading is done.
*/
void prepare_layers ();
private:
bool m_create_layers;
bool m_read_named_layers;
LayerMap m_layer_map;
unsigned int m_next_layer_index;
std::map <std::string, unsigned int> m_new_layers;
};
/**
* @brief The DXF format stream reader
*/

View File

@ -0,0 +1,259 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2018 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 "dbNamedLayerReader.h"
namespace db
{
// ---------------------------------------------------------------
// NamedLayerReader
NamedLayerReader::NamedLayerReader ()
: m_create_layers (true), m_keep_layer_names (false), m_next_layer_index (0)
{
// .. nothing yet ..
}
void
NamedLayerReader::set_create_layers (bool f)
{
m_create_layers = f;
}
void
NamedLayerReader::set_keep_layer_names (bool f)
{
m_keep_layer_names = f;
}
void NamedLayerReader::set_layer_map (const LayerMap &lm)
{
m_layer_map = lm;
}
static bool
extract_plain_layer (const char *s, int &l)
{
l = 0;
if (! *s) {
return false;
}
while (*s && isdigit (*s)) {
l = l * 10 + (unsigned int) (*s - '0');
++s;
}
return (*s == 0);
}
static bool
extract_ld (const char *s, int &l, int &d, std::string &n)
{
l = d = 0;
if (*s == 'L') {
++s;
}
if (! *s || ! isdigit (*s)) {
return false;
}
while (*s && isdigit (*s)) {
l = l * 10 + (unsigned int) (*s - '0');
++s;
}
if (*s == 'D' || *s == '.') {
++s;
if (! *s || ! isdigit (*s)) {
return false;
}
while (*s && isdigit (*s)) {
d = d * 10 + (unsigned int) (*s - '0');
++s;
}
}
if (*s && (isspace (*s) || *s == '_')) {
++s;
n = s;
return true;
} else if (*s == 0) {
n.clear ();
return true;
} else {
return false;
}
}
std::pair <bool, unsigned int>
NamedLayerReader::open_layer (db::Layout &layout, const std::string &n)
{
int l = -1, d = -1;
std::string on;
std::pair<bool, unsigned int> ll (false, 0);
ll = m_layer_map.logical (n);
if (! ll.first && !m_keep_layer_names) {
if (extract_plain_layer (n.c_str (), l)) {
db::LayerProperties lp;
lp.layer = l;
lp.datatype = 0;
ll = m_layer_map.logical (lp);
} else if (extract_ld (n.c_str (), l, d, on)) {
db::LayerProperties lp;
lp.layer = l;
lp.datatype = d;
lp.name = on;
ll = m_layer_map.logical (lp);
}
}
if (ll.first) {
// create the layer if it is not part of the layout yet.
if (! layout.is_valid_layer (ll.second)) {
layout.insert_layer (ll.second, m_layer_map.mapping (ll.second));
}
return ll;
} else if (! m_create_layers) {
return std::pair<bool, unsigned int> (false, 0);
} else {
std::map <std::string, unsigned int>::const_iterator nl = m_new_layers.find (n);
if (nl == m_new_layers.end ()) {
unsigned int ll = m_next_layer_index++;
layout.insert_layer (ll, db::LayerProperties ());
m_new_layers.insert (std::make_pair (n, ll));
return std::pair<bool, unsigned int> (true, ll);
} else {
return std::pair<bool, unsigned int> (true, nl->second);
}
}
}
void
NamedLayerReader::map_layer (const std::string &name, unsigned int layer)
{
m_layer_map.map (name, layer);
}
void
NamedLayerReader::prepare_layers ()
{
m_new_layers.clear ();
m_next_layer_index = m_layer_map.next_index ();
}
void
NamedLayerReader::finish_layers (db::Layout &layout)
{
// assign layer numbers to new layers
if (! m_new_layers.empty () && !m_keep_layer_names) {
std::set<std::pair<int, int> > used_ld;
for (db::Layout::layer_iterator l = layout.begin_layers (); l != layout.end_layers (); ++l) {
used_ld.insert (std::make_pair((*l).second->layer, (*l).second->datatype));
}
// assign fixed layer numbers for all layers whose name is a fixed number unless there is already a layer with that number
for (std::map<std::string, unsigned int>::iterator i = m_new_layers.begin (); i != m_new_layers.end (); ) {
std::map<std::string, unsigned int>::iterator ii = i;
++ii;
int l = -1;
if (extract_plain_layer (i->first.c_str (), l) && used_ld.find (std::make_pair (l, 0)) == used_ld.end ()) {
used_ld.insert (std::make_pair (l, 0));
db::LayerProperties lp;
lp.layer = l;
lp.datatype = 0;
layout.set_properties (i->second, lp);
m_layer_map.map (lp, i->second);
m_new_layers.erase (i);
}
i = ii;
}
// assign fixed layer numbers for all layers whose name is a LxDy or Lx notation unless there is already a layer with that layer/datatype
for (std::map<std::string, unsigned int>::iterator i = m_new_layers.begin (); i != m_new_layers.end (); ) {
std::map<std::string, unsigned int>::iterator ii = i;
++ii;
int l = -1, d = -1;
std::string n;
if (extract_ld (i->first.c_str (), l, d, n) && used_ld.find (std::make_pair (l, d)) == used_ld.end ()) {
used_ld.insert (std::make_pair (l, d));
db::LayerProperties lp;
lp.layer = l;
lp.datatype = d;
lp.name = n;
layout.set_properties (i->second, lp);
m_layer_map.map (lp, i->second);
m_new_layers.erase (i);
}
i = ii;
}
}
// insert the remaining ones
for (std::map<std::string, unsigned int>::const_iterator i = m_new_layers.begin (); i != m_new_layers.end (); ++i) {
db::LayerProperties lp;
lp.name = i->first;
layout.set_properties (i->second, lp);
m_layer_map.map (lp, i->second);
}
}
}

View File

@ -0,0 +1,136 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2018 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
*/
#ifndef HDR_dbNamedLayerReader
#define HDR_dbNamedLayerReader
#include "dbCommon.h"
#include "dbReader.h"
namespace db
{
class Layout;
/**
* @brief A reader base class for streams with named-only layers
*
* This class implements the layer name translation logic.
* Specifically:
* - a number is translated to the corresponding layer, datatype 0
* - Lx is translated to layer x, datatype 0
* - Lx_SUFFIX is translated to layer x, datatype 0, name "SUFFIX"
* - LxDy is translated to layer x, datatype y
* - LxDy_SUFFIX is translated to layer x, datatype y, name "SUFFIX"
*
* Furthermore, the layer map and creation of new layers is handled in this
* base class.
*/
class DB_PUBLIC NamedLayerReader
: public ReaderBase
{
public:
/**
* @brief The constructor
*/
NamedLayerReader ();
/**
* @brief Sets a value indicating whether to create new layers
*/
void set_create_layers (bool f);
/**
* @brief Gets a value indicating whether to create new layers
*/
bool create_layers () const
{
return m_create_layers;
}
/**
* @brief Sets the layer map
*/
void set_layer_map (const LayerMap &lm);
/**
* @brief Gets the layer map
*/
const LayerMap &layer_map ()
{
return m_layer_map;
}
/**
* @brief Sets a value indicating whether layer names are kept
* If set to true, no name translation is performed and layers are
* always named only. If set the false (the default), layer names will
* be translated to GDS layer/datatypes if possible.
*/
void set_keep_layer_names (bool f);
/**
* @brief Gets a value indicating whether layer names are kept
*/
bool keep_layer_names () const
{
return m_keep_layer_names;
}
protected:
/**
* @brief Opens a new layer
* This method will create or locate a layer for a given name.
* The result's first attribute is true, if such a layer could be found
* or created. In this case, the second attribute is the layer index.
*/
std::pair <bool, unsigned int> open_layer (db::Layout &layout, const std::string &name);
/**
* @brief Force mapping of a name to a layer index
*/
void map_layer (const std::string &name, unsigned int layer);
/**
* @brief Finish reading
* This method must be called after the reading has been done.
* It will finalize the layers.
*/
void finish_layers (db::Layout &layout);
/**
* @brief Prepares reading
* This method must be called before the reading is done.
*/
void prepare_layers ();
private:
bool m_create_layers;
bool m_keep_layer_names;
LayerMap m_layer_map;
unsigned int m_next_layer_index;
std::map <std::string, unsigned int> m_new_layers;
};
}
#endif

View File

@ -27,17 +27,9 @@
#include <stdlib.h>
static void run_test (tl::TestBase *_this, const char *file, const char *file_au, const char *map = 0, double dbu = 0.001, double dxf_unit = 1, int mode = 0, int ncircle = 100, double acircle = 0.0)
static db::LayerMap string2lm (const char *map)
{
db::DXFReaderOptions *opt = new db::DXFReaderOptions();
opt->dbu = dbu;
opt->unit = dxf_unit;
opt->polyline_mode = mode;
opt->circle_points = ncircle;
opt->circle_accuracy = acircle;
db::LayerMap lm;
if (map) {
unsigned int ln = 0;
tl::Extractor ex (map);
while (! ex.at_end ()) {
@ -49,25 +41,52 @@ static void run_test (tl::TestBase *_this, const char *file, const char *file_au
ex.test (",");
lm.map (n, ln++, db::LayerProperties (l, 0));
}
opt->layer_map = lm;
opt->create_other_layers = true;
}
return lm;
}
static void do_run_test (tl::TestBase *_this, const std::string &fn, const std::string &fn_au, const db::DXFReaderOptions &opt, bool as_oas)
{
db::LoadLayoutOptions options;
options.set_options (opt);
options.set_options (new db::DXFReaderOptions (opt));
db::Layout layout;
{
std::string fn (tl::testsrc_private ());
fn += "/testdata/dxf/";
fn += file;
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (layout, options);
}
db::compare_layouts (_this, layout, tl::testsrc_private () + std::string ("/testdata/dxf/") + file_au, db::WriteGDS2, 1);
db::compare_layouts (_this, layout, fn_au, as_oas ? db::WriteOAS : db::WriteGDS2, 1);
}
static void run_test (tl::TestBase *_this, const char *file, const char *file_au, const db::DXFReaderOptions &opt = db::DXFReaderOptions (), bool as_oas = false)
{
std::string fn = tl::testsrc_private () + "/testdata/dxf/" + file;
std::string fn_au = tl::testsrc_private () + std::string ("/testdata/dxf/") + file_au;
do_run_test (_this, fn, fn_au, opt, as_oas);
}
static void run_test_public (tl::TestBase *_this, const char *file, const char *file_au, const db::DXFReaderOptions &opt = db::DXFReaderOptions (), bool as_oas = false)
{
std::string fn = tl::testsrc () + "/testdata/dxf/" + file;
std::string fn_au = tl::testsrc () + std::string ("/testdata/dxf/") + file_au;
do_run_test (_this, fn, fn_au, opt, as_oas);
}
TEST(KeepLN1)
{
db::DXFReaderOptions opt;
run_test_public (_this, "keep_ln.dxf.gz", "keep_ln1_au.oas.gz", opt, true /*because of layer names*/);
}
TEST(KeepLN2)
{
db::DXFReaderOptions opt;
opt.keep_layer_names = true;
run_test_public (_this, "keep_ln.dxf.gz", "keep_ln2_au.oas.gz", opt, true /*because of layer names*/);
}
TEST(1a)
@ -77,7 +96,10 @@ TEST(1a)
TEST(1b)
{
run_test (_this, "t1.dxf.gz", "t1b_au.gds.gz", 0, 0.01, 5.0);
db::DXFReaderOptions opt;
opt.dbu = 0.01;
opt.unit = 5.0;
run_test (_this, "t1.dxf.gz", "t1b_au.gds.gz", opt);
}
TEST(2)
@ -92,7 +114,10 @@ TEST(3)
TEST(4)
{
run_test (_this, "t4.dxf.gz", "t4_au.gds.gz", "Metal:1,Metal2:5");
db::DXFReaderOptions opt;
opt.layer_map = string2lm ("Metal:1,Metal2:5");
opt.create_other_layers = true;
run_test (_this, "t4.dxf.gz", "t4_au.gds.gz", opt);
}
TEST(5)
@ -112,17 +137,26 @@ TEST(7)
TEST(8)
{
run_test (_this, "t8.dxf.gz", "t8_au.gds.gz", "Metal:4,Kommentare:3,Bemassung:2");
db::DXFReaderOptions opt;
opt.layer_map = string2lm ("Metal:4,Kommentare:3,Bemassung:2");
opt.create_other_layers = true;
run_test (_this, "t8.dxf.gz", "t8_au.gds.gz", opt);
}
TEST(9)
{
run_test (_this, "t9.dxf.gz", "t9_au.gds.gz", "Bemassung:2,Metal:5,Kommentare:4");
db::DXFReaderOptions opt;
opt.layer_map = string2lm ("Bemassung:2,Metal:5,Kommentare:4");
opt.create_other_layers = true;
run_test (_this, "t9.dxf.gz", "t9_au.gds.gz", opt);
}
TEST(10)
{
run_test (_this, "t10.dxf.gz", "t10_au.gds.gz", "METAL:1,KOMMENTARE:4");
db::DXFReaderOptions opt;
opt.layer_map = string2lm ("METAL:1,KOMMENTARE:4");
opt.create_other_layers = true;
run_test (_this, "t10.dxf.gz", "t10_au.gds.gz", opt);
}
TEST(11)
@ -142,22 +176,34 @@ TEST(13)
TEST(14)
{
run_test (_this, "t14.dxf.gz", "t14_au.gds.gz", "'A11-STRUKTUR__E_TYP_':10,A21_NITRID:11,'B11-KONTAKT':9,'B11-STRUKTUR':3,HELLFELD:7,MASKE:5,NORM_MIN_MAX_WAFER:6,RASTER:2,_BEGRENZUNG_A11_A21_A31_B1:8");
db::DXFReaderOptions opt;
opt.layer_map = string2lm ("'A11-STRUKTUR__E_TYP_':10,A21_NITRID:11,'B11-KONTAKT':9,'B11-STRUKTUR':3,HELLFELD:7,MASKE:5,NORM_MIN_MAX_WAFER:6,RASTER:2,_BEGRENZUNG_A11_A21_A31_B1:8");
opt.create_other_layers = true;
run_test (_this, "t14.dxf.gz", "t14_au.gds.gz", opt);
}
TEST(15)
{
run_test (_this, "t15.dxf.gz", "t15_au.gds.gz", "TEXT:4,IGBT:5,Wire:7,Ceramic:11,LAYER_1:14,Diode:18,'DBC TOP Plate':19,'Terminal Position':20");
db::DXFReaderOptions opt;
opt.layer_map = string2lm ("TEXT:4,IGBT:5,Wire:7,Ceramic:11,LAYER_1:14,Diode:18,'DBC TOP Plate':19,'Terminal Position':20");
opt.create_other_layers = true;
run_test (_this, "t15.dxf.gz", "t15_au.gds.gz", opt);
}
TEST(16)
{
run_test (_this, "t16.dxf.gz", "t16_au.gds.gz", "TEXT:4,IGBT:5,Wire:7,Ceramic:11,LAYER_1:14,Diode:18,'DBC TOP Plate':19,'Terminal Position':20");
db::DXFReaderOptions opt;
opt.layer_map = string2lm ("TEXT:4,IGBT:5,Wire:7,Ceramic:11,LAYER_1:14,Diode:18,'DBC TOP Plate':19,'Terminal Position':20");
opt.create_other_layers = true;
run_test (_this, "t16.dxf.gz", "t16_au.gds.gz", opt);
}
TEST(17)
{
run_test (_this, "t17.dxf.gz", "t17_au.gds.gz", "TEXT:4,IGBT:5,Wire:7,Ceramic:11,LAYER_1:14,Diode:18,'DBC TOP Plate':19,'Terminal Position':20");
db::DXFReaderOptions opt;
opt.layer_map = string2lm ("TEXT:4,IGBT:5,Wire:7,Ceramic:11,LAYER_1:14,Diode:18,'DBC TOP Plate':19,'Terminal Position':20");
opt.create_other_layers = true;
run_test (_this, "t17.dxf.gz", "t17_au.gds.gz", opt);
}
TEST(18)
@ -187,77 +233,152 @@ TEST(22)
TEST(23a)
{
run_test (_this, "t23.dxf.gz", "t23a_au.gds.gz", 0, 0.001, 1, 0, 10);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1;
opt.polyline_mode = 0;
opt.circle_points = 10;
run_test (_this, "t23.dxf.gz", "t23a_au.gds.gz", opt);
}
TEST(23b)
{
run_test (_this, "t23.dxf.gz", "t23b_au.gds.gz", 0, 0.001, 1, 1, 10);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1;
opt.polyline_mode = 1;
opt.circle_points = 10;
run_test (_this, "t23.dxf.gz", "t23b_au.gds.gz", opt);
}
TEST(23c)
{
run_test (_this, "t23.dxf.gz", "t23c_au.gds.gz", 0, 0.001, 1, 2, 10);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1;
opt.polyline_mode = 2;
opt.circle_points = 10;
run_test (_this, "t23.dxf.gz", "t23c_au.gds.gz", opt);
}
TEST(23d)
{
run_test (_this, "t23.dxf.gz", "t23d_au.gds.gz", 0, 0.001, 1, 3, 10);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1;
opt.polyline_mode = 3;
opt.circle_points = 10;
run_test (_this, "t23.dxf.gz", "t23d_au.gds.gz", opt);
}
TEST(23e)
{
run_test (_this, "t23.dxf.gz", "t23e_au.gds.gz", 0, 0.001, 1, 4, 10);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1;
opt.polyline_mode = 4;
opt.circle_points = 10;
run_test (_this, "t23.dxf.gz", "t23e_au.gds.gz", opt);
}
TEST(26a)
{
run_test (_this, "t26.dxf.gz", "t26a_au.gds.gz", 0, 0.001, 1, 0, 100);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1;
opt.polyline_mode = 0;
opt.circle_points = 100;
run_test (_this, "t26.dxf.gz", "t26a_au.gds.gz", opt);
}
TEST(26b)
{
run_test (_this, "t26.dxf.gz", "t26b_au.gds.gz", 0, 0.001, 1, 1, 100);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1;
opt.polyline_mode = 1;
opt.circle_points = 100;
run_test (_this, "t26.dxf.gz", "t26b_au.gds.gz", opt);
}
TEST(26c)
{
run_test (_this, "t26.dxf.gz", "t26c_au.gds.gz", 0, 0.001, 1, 2, 100);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1;
opt.polyline_mode = 2;
opt.circle_points = 100;
run_test (_this, "t26.dxf.gz", "t26c_au.gds.gz", opt);
}
TEST(26d)
{
run_test (_this, "t26.dxf.gz", "t26d_au.gds.gz", 0, 0.001, 1, 3, 100);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1;
opt.polyline_mode = 3;
opt.circle_points = 100;
run_test (_this, "t26.dxf.gz", "t26d_au.gds.gz", opt);
}
TEST(26e)
{
run_test (_this, "t26.dxf.gz", "t26e_au.gds.gz", 0, 0.001, 1, 4, 100);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1;
opt.polyline_mode = 4;
opt.circle_points = 100;
run_test (_this, "t26.dxf.gz", "t26e_au.gds.gz", opt);
}
TEST(27a)
{
run_test (_this, "t27.dxf.gz", "t27a_au.gds.gz", 0, 0.001, 1, 0, 10);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1;
opt.polyline_mode = 0;
opt.circle_points = 10;
run_test (_this, "t27.dxf.gz", "t27a_au.gds.gz", opt);
}
TEST(27b)
{
run_test (_this, "t27.dxf.gz", "t27b_au.gds.gz", 0, 0.001, 1, 1, 10);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1;
opt.polyline_mode = 1;
opt.circle_points = 10;
run_test (_this, "t27.dxf.gz", "t27b_au.gds.gz", opt);
}
TEST(27c)
{
run_test (_this, "t27.dxf.gz", "t27c_au.gds.gz", 0, 0.001, 1, 2, 10);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1;
opt.polyline_mode = 2;
opt.circle_points = 10;
run_test (_this, "t27.dxf.gz", "t27c_au.gds.gz", opt);
}
TEST(27d)
{
run_test (_this, "t27.dxf.gz", "t27d_au.gds.gz", 0, 0.001, 1, 3, 10);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1;
opt.polyline_mode = 3;
opt.circle_points = 10;
run_test (_this, "t27.dxf.gz", "t27d_au.gds.gz", opt);
}
TEST(27e)
{
run_test (_this, "t27.dxf.gz", "t27e_au.gds.gz", 0, 0.001, 1, 4, 10);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1;
opt.polyline_mode = 4;
opt.circle_points = 10;
run_test (_this, "t27.dxf.gz", "t27e_au.gds.gz", opt);
}
TEST(28)
@ -272,26 +393,56 @@ TEST(29)
TEST(29a)
{
run_test (_this, "t29.dxf.gz", "t29a_au.gds.gz", 0, 0.001, 1, 4, 1000, 1);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1;
opt.polyline_mode = 4;
opt.circle_points = 1000;
opt.circle_accuracy = 1;
run_test (_this, "t29.dxf.gz", "t29a_au.gds.gz", opt);
}
TEST(29b)
{
run_test (_this, "t29.dxf.gz", "t29b_au.gds.gz", 0, 0.001, 1, 4, 1000, 0.1);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1;
opt.polyline_mode = 4;
opt.circle_points = 1000;
opt.circle_accuracy = 0.1;
run_test (_this, "t29.dxf.gz", "t29b_au.gds.gz", opt);
}
TEST(29c)
{
run_test (_this, "t29.dxf.gz", "t29c_au.gds.gz", 0, 0.001, 1, 4, 1000, 0.01);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1;
opt.polyline_mode = 4;
opt.circle_points = 1000;
opt.circle_accuracy = 0.01;
run_test (_this, "t29.dxf.gz", "t29c_au.gds.gz", opt);
}
TEST(29d)
{
run_test (_this, "t29.dxf.gz", "t29d_au.gds.gz", 0, 0.001, 1, 4, 1000, 0.001);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1;
opt.polyline_mode = 4;
opt.circle_points = 1000;
opt.circle_accuracy = 0.001;
run_test (_this, "t29.dxf.gz", "t29d_au.gds.gz", opt);
}
TEST(30)
{
run_test (_this, "t30.dxf.gz", "t30d_au.gds.gz", 0, 0.001, 1000, 4, 1000, 0.001);
db::DXFReaderOptions opt;
opt.dbu = 0.001;
opt.unit = 1000;
opt.polyline_mode = 4;
opt.circle_points = 1000;
opt.circle_accuracy = 0.001;
run_test (_this, "t30.dxf.gz", "t30d_au.gds.gz", opt);
}

View File

@ -35,30 +35,6 @@
<property name="spacing">
<number>6</number>
</property>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Database unit </string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Wire objects</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="dbu_le">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="wire_mode_cb">
<property name="sizePolicy">
@ -84,6 +60,13 @@
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Database unit </string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
@ -97,6 +80,37 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="dbu_le">
<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">
<property name="text">
<string>Wire objects</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QCheckBox" name="keep_names_cbx">
<property name="text">
<string>Don't attempt to translate into layer/datatype numbers</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Keep layer names</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>644</width>
<height>380</height>
<height>629</height>
</rect>
</property>
<property name="windowTitle">
@ -35,29 +35,6 @@
<property name="spacing">
<number>6</number>
</property>
<item row="2" column="1">
<widget class="QLineEdit" name="circle_points_le">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Number of points per full circle used for arc interpolation (the accuracy may reduce the number if less are required)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="dbu_le">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="unit_le">
<property name="sizePolicy">
@ -68,55 +45,10 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<item row="9" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>DXF file unit</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Arc interpolation</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Database unit </string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Keep all cells</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="text_scaling_le">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Text to polygon</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Text scaling</string>
<string>LINE / POLYLINE</string>
</property>
</widget>
</item>
@ -133,59 +65,14 @@
</property>
</widget>
</item>
<item row="6" column="1" colspan="3">
<widget class="QCheckBox" name="keep_other_cells_cbx">
<property name="text">
<string>Check this box to keep all cells, not only the top cell and it's children</string>
</property>
</widget>
</item>
<item row="5" column="2" colspan="2">
<widget class="QLabel" name="label_11">
<item row="9" column="1" colspan="2">
<widget class="QComboBox" name="polyline2poly_cbx">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Scaling factor in percent</string>
</property>
</widget>
</item>
<item row="8" column="0" colspan="4">
<widget class="QFrame" name="frame">
<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="QLabel" name="label">
<property name="text">
<string>LINE / POLYLINE</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="polyline2poly_cbx">
<item>
<property name="text">
<string>Automatic</string>
@ -213,52 +100,26 @@
</item>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>451</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="7" column="0" colspan="4">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="4" column="1" colspan="3">
<widget class="QCheckBox" name="render_texts_as_polygons_cbx">
<item row="5" column="1">
<widget class="QLineEdit" name="text_scaling_le">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Render texts as polygons and do not create text objects</string>
</property>
</widget>
</item>
<item row="1" column="2" colspan="2">
<widget class="QLabel" name="label_4">
<item row="2" column="2" colspan="2">
<widget class="QLabel" name="label_12">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>µm</string>
<string># of points</string>
</property>
</widget>
</item>
@ -275,6 +136,56 @@
</property>
</widget>
</item>
<item row="4" column="1" colspan="3">
<widget class="QCheckBox" name="render_texts_as_polygons_cbx">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Render texts as polygons and do not create text objects</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Arc interpolation</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Keep all cells</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="dbu_le">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="10" column="2" colspan="2">
<widget class="QLabel" name="label_15">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Line merge accuracy in DXF units</string>
</property>
</widget>
</item>
<item row="3" column="2" colspan="2">
<widget class="QLabel" name="label_7">
<property name="sizePolicy">
@ -288,8 +199,8 @@
</property>
</widget>
</item>
<item row="2" column="2" colspan="2">
<widget class="QLabel" name="label_12">
<item row="5" column="2" colspan="2">
<widget class="QLabel" name="label_11">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
@ -297,7 +208,106 @@
</sizepolicy>
</property>
<property name="text">
<string># of points</string>
<string>Scaling factor in percent</string>
</property>
</widget>
</item>
<item row="1" column="2" colspan="2">
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>µm</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QLineEdit" name="contour_accuracy_le">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>DXF file unit</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Text to polygon</string>
</property>
</widget>
</item>
<item row="7" column="1" colspan="3">
<widget class="QCheckBox" name="keep_names_cbx">
<property name="text">
<string>Don't attempt to translate into layer/datatype numbers</string>
</property>
</widget>
</item>
<item row="8" column="0" colspan="4">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="6" column="1" colspan="3">
<widget class="QCheckBox" name="keep_other_cells_cbx">
<property name="text">
<string>Check this box to keep all cells, not only the top cell and it's children</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Keep layer names</string>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>Merge accuracy</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Text scaling</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Database unit </string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="circle_points_le">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Number of points per full circle used for arc interpolation (the accuracy may reduce the number if less are required)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
@ -390,7 +400,6 @@
<tabstop>render_texts_as_polygons_cbx</tabstop>
<tabstop>text_scaling_le</tabstop>
<tabstop>keep_other_cells_cbx</tabstop>
<tabstop>polyline2poly_cbx</tabstop>
</tabstops>
<resources/>
<connections>

View File

@ -62,6 +62,7 @@ CIFReaderOptionPage::setup (const db::FormatSpecificReaderOptions *o, const lay:
mp_ui->dbu_le->setText (tl::to_qstring (tl::to_string (options->dbu)));
mp_ui->layer_map->set_layer_map (options->layer_map);
mp_ui->read_all_cbx->setChecked (options->create_other_layers);
mp_ui->keep_names_cbx->setChecked (options->keep_layer_names);
mp_ui->wire_mode_cb->setCurrentIndex (options->wire_mode);
}
@ -77,6 +78,7 @@ CIFReaderOptionPage::commit (db::FormatSpecificReaderOptions *o, const lay::Tech
options->wire_mode = mp_ui->wire_mode_cb->currentIndex ();
options->layer_map = mp_ui->layer_map->get_layer_map ();
options->create_other_layers = mp_ui->read_all_cbx->isChecked ();
options->keep_layer_names = mp_ui->keep_names_cbx->isChecked ();
}
}
@ -109,7 +111,8 @@ public:
tl::make_member (&db::CIFReaderOptions::wire_mode, "wire-mode") +
tl::make_member (&db::CIFReaderOptions::dbu, "dbu") +
tl::make_member (&db::CIFReaderOptions::layer_map, "layer-map") +
tl::make_member (&db::CIFReaderOptions::create_other_layers, "create-other-layers")
tl::make_member (&db::CIFReaderOptions::create_other_layers, "create-other-layers") +
tl::make_member (&db::CIFReaderOptions::keep_layer_names, "keep-layer-names")
);
}
};
@ -166,6 +169,16 @@ static void set_create_other_layers (db::LoadLayoutOptions *options, bool l)
options->get_options<db::CIFReaderOptions> ().create_other_layers = l;
}
static bool keep_layer_names (const db::LoadLayoutOptions *options)
{
return options->get_options<db::CIFReaderOptions> ().keep_layer_names;
}
static void set_keep_layer_names (db::LoadLayoutOptions *options, bool l)
{
options->get_options<db::CIFReaderOptions> ().keep_layer_names = l;
}
// extend lay::LoadLayoutOptions with the CIF options
static
gsi::ClassExt<db::LoadLayoutOptions> cif_reader_options (
@ -209,6 +222,24 @@ gsi::ClassExt<db::LoadLayoutOptions> cif_reader_options (
"This method has been added in version 0.25 and replaces the respective global option in \\LoadLayoutOptions "
"in a format-specific fashion."
) +
gsi::method_ext ("cif_keep_layer_names?", &keep_layer_names,
"@brief Gets a value indicating whether layer names are kept\n"
"@return True, if layer names are kept.\n"
"\n"
"When set to true, no attempt is made to translate "
"layer names to GDS layer/datatype numbers. If set to false (the default), a layer named \"L2D15\" will be translated "
"to GDS layer 2, datatype 15.\n"
"\n"
"This method has been added in version 0.25.3."
) +
gsi::method_ext ("cif_keep_layer_names=", &set_keep_layer_names, gsi::arg ("keep"),
"@brief Gets a value indicating whether layer names are kept\n"
"@param keep True, if layer names are to be kept.\n"
"\n"
"See \\cif_keep_layer_names? for a description of this property.\n"
"\n"
"This method has been added in version 0.25.3."
) +
gsi::method_ext ("cif_wire_mode=", &set_cif_wire_mode,
"@brief How to read 'W' objects\n"
"\n"

View File

@ -64,11 +64,13 @@ DXFReaderOptionPage::setup (const db::FormatSpecificReaderOptions *o, const lay:
mp_ui->text_scaling_le->setText (tl::to_qstring (tl::to_string (options->text_scaling)));
mp_ui->circle_points_le->setText (tl::to_qstring (tl::to_string (options->circle_points)));
mp_ui->circle_accuracy_le->setText (tl::to_qstring (tl::to_string (options->circle_accuracy)));
mp_ui->contour_accuracy_le->setText (tl::to_qstring (tl::to_string (options->contour_accuracy)));
mp_ui->render_texts_as_polygons_cbx->setChecked (options->render_texts_as_polygons);
mp_ui->keep_other_cells_cbx->setChecked (options->keep_other_cells);
mp_ui->polyline2poly_cbx->setCurrentIndex (options->polyline_mode);
mp_ui->layer_map->set_layer_map (options->layer_map);
mp_ui->read_all_cbx->setChecked (options->create_other_layers);
mp_ui->keep_names_cbx->setChecked (options->keep_layer_names);
}
void
@ -93,11 +95,13 @@ DXFReaderOptionPage::commit (db::FormatSpecificReaderOptions *o, const lay::Tech
throw tl::Exception (tl::to_string (QObject::tr ("Invalid value for the number of points for arc interpolation")));
}
tl::from_string (tl::to_string(mp_ui->circle_accuracy_le->text ()), options->circle_accuracy);
tl::from_string (tl::to_string(mp_ui->contour_accuracy_le->text ()), options->contour_accuracy);
options->polyline_mode = mp_ui->polyline2poly_cbx->currentIndex ();
options->render_texts_as_polygons = mp_ui->render_texts_as_polygons_cbx->isChecked ();
options->keep_other_cells = mp_ui->keep_other_cells_cbx->isChecked ();
options->layer_map = mp_ui->layer_map->get_layer_map ();
options->create_other_layers = mp_ui->read_all_cbx->isChecked ();
options->keep_layer_names = mp_ui->keep_names_cbx->isChecked ();
}
}
@ -132,9 +136,11 @@ public:
tl::make_member (&db::DXFReaderOptions::text_scaling, "text-scaling") +
tl::make_member (&db::DXFReaderOptions::circle_points, "circle-points") +
tl::make_member (&db::DXFReaderOptions::circle_accuracy, "circle-accuracy") +
tl::make_member (&db::DXFReaderOptions::contour_accuracy, "contour-accuracy") +
tl::make_member (&db::DXFReaderOptions::polyline_mode, "polyline-mode") +
tl::make_member (&db::DXFReaderOptions::render_texts_as_polygons, "render-texts-as-polygons") +
tl::make_member (&db::DXFReaderOptions::keep_other_cells, "keep-other-cells") +
tl::make_member (&db::DXFReaderOptions::keep_layer_names, "keep-layer-names") +
tl::make_member (&db::DXFReaderOptions::create_other_layers, "create-other-layers") +
tl::make_member (&db::DXFReaderOptions::layer_map, "layer-map")
);
@ -216,6 +222,16 @@ static double get_dxf_circle_accuracy (const db::LoadLayoutOptions *options)
return options->get_options<db::DXFReaderOptions> ().circle_accuracy;
}
static void set_dxf_contour_accuracy (db::LoadLayoutOptions *options, double contour_accuracy)
{
options->get_options<db::DXFReaderOptions> ().contour_accuracy = contour_accuracy;
}
static double get_dxf_contour_accuracy (const db::LoadLayoutOptions *options)
{
return options->get_options<db::DXFReaderOptions> ().contour_accuracy;
}
static void set_dxf_polyline_mode (db::LoadLayoutOptions *options, int mode)
{
if (mode < 0 || mode > 4) {
@ -257,6 +273,16 @@ static void set_create_other_layers (db::LoadLayoutOptions *options, bool l)
options->get_options<db::DXFReaderOptions> ().create_other_layers = l;
}
static bool keep_layer_names (const db::LoadLayoutOptions *options)
{
return options->get_options<db::DXFReaderOptions> ().keep_layer_names;
}
static void set_keep_layer_names (db::LoadLayoutOptions *options, bool l)
{
options->get_options<db::DXFReaderOptions> ().keep_layer_names = l;
}
// extend lay::LoadLayoutOptions with the DXF options
static
gsi::ClassExt<db::LoadLayoutOptions> dxf_reader_options (
@ -365,6 +391,25 @@ gsi::ClassExt<db::LoadLayoutOptions> dxf_reader_options (
"@brief Gets the accuracy of the circle approximation\n"
"\nThis property has been added in version 0.24.9.\n"
) +
gsi::method_ext ("dxf_contour_accuracy=", &set_dxf_contour_accuracy,
"@brief Specifies the accuracy for contour closing\n"
"@args accuracy\n"
"\n"
"When polylines need to be connected or closed, this\n"
"value is used to indicate the accuracy. This is the value (in DXF units)\n"
"by which points may be separated and still be considered\n"
"connected. The default is 0.0 which implies exact\n"
"(within one DBU) closing.\n"
"\n"
"This value is effective in polyline mode 3 and 4.\n"
"\n"
"\nThis property has been added in version 0.25.3.\n"
) +
gsi::method_ext ("dxf_contour_accuracy", &get_dxf_contour_accuracy,
"@brief Gets the accuracy for contour closing\n"
"\n"
"\nThis property has been added in version 0.25.3.\n"
) +
gsi::method_ext ("dxf_render_texts_as_polygons=", &set_dxf_render_texts_as_polygons,
"@brief If this option is set to true, text objects are rendered as polygons\n"
"@args value\n"
@ -374,6 +419,24 @@ gsi::ClassExt<db::LoadLayoutOptions> dxf_reader_options (
"@brief If this option is true, text objects are rendered as polygons\n"
"\nThis property has been added in version 0.21.15.\n"
) +
gsi::method_ext ("dxf_keep_layer_names?", &keep_layer_names,
"@brief Gets a value indicating whether layer names are kept\n"
"@return True, if layer names are kept.\n"
"\n"
"When set to true, no attempt is made to translate "
"layer names to GDS layer/datatype numbers. If set to false (the default), a layer named \"L2D15\" will be translated "
"to GDS layer 2, datatype 15.\n"
"\n"
"This method has been added in version 0.25.3."
) +
gsi::method_ext ("dxf_keep_layer_names=", &set_keep_layer_names, gsi::arg ("keep"),
"@brief Gets a value indicating whether layer names are kept\n"
"@param keep True, if layer names are to be kept.\n"
"\n"
"See \\cif_keep_layer_names? for a description of this property.\n"
"\n"
"This method has been added in version 0.25.3."
) +
gsi::method_ext ("dxf_keep_other_cells=", &set_dxf_keep_other_cells,
"@brief If this option is set to true, all cells are kept, not only the top cell and it's children\n"
"@args value\n"

BIN
testdata/dxf/keep_ln.dxf.gz vendored Normal file

Binary file not shown.

BIN
testdata/dxf/keep_ln1_au.oas.gz vendored Normal file

Binary file not shown.

BIN
testdata/dxf/keep_ln2_au.oas.gz vendored Normal file

Binary file not shown.