DXF: avoiding generating duplicates of zero layer during DXF read/write spin.

This commit is contained in:
Matthias Koefferlein 2026-08-07 00:12:52 +02:00
parent d7a41b860d
commit 22042a0b10
6 changed files with 1660 additions and 13 deletions

View File

@ -303,9 +303,9 @@ SaveLayoutOptions::get_valid_layers (const db::Layout &layout, std::vector <std:
for (auto l = all_layers.begin (); l != all_layers.end (); ++l) {
layers.push_back (*l);
if (l->second.name.empty ()) {
layers.back ().second = tl::sprintf ("L%dD%d", l->second.layer, l->second.datatype);
layers.back ().second.name = tl::sprintf ("L%dD%d", l->second.layer, l->second.datatype);
} else if (l->second.layer >= 0 && l->second.datatype >= 0) {
layers.back ().second = tl::sprintf ("L%dD%d", l->second.layer, l->second.datatype) + "_" + l->second.name;
layers.back ().second.name = tl::sprintf ("L%dD%d", l->second.layer, l->second.datatype) + "_" + l->second.name;
}
}
@ -314,9 +314,9 @@ SaveLayoutOptions::get_valid_layers (const db::Layout &layout, std::vector <std:
for (auto l = all_layers.begin (); l != all_layers.end (); ++l) {
layers.push_back (*l);
if (l->second.name.empty ()) {
layers.back ().second = tl::sprintf ("L%dD%d", l->second.layer, l->second.datatype);
layers.back ().second.name = tl::sprintf ("L%dD%d", l->second.layer, l->second.datatype);
} else if (l->second.layer >= 0 && l->second.datatype >= 0) {
layers.back ().second = l->second.name;
layers.back ().second.name = l->second.name;
}
}

View File

@ -118,7 +118,7 @@ struct LayerNameValidator
*/
std::string cif_layer_name (const db::LayerProperties &lp)
{
if (lp.is_named ()) {
if (! lp.name.empty ()) {
return lp.name;
} else if (lp.is_null ()) {
return std::string ();

View File

@ -153,14 +153,20 @@ DXFWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::SaveLa
for (std::vector <std::pair <unsigned int, db::LayerProperties> >::const_iterator l = layers.begin (); l != layers.end (); ++l) {
*this << 0 << endl << "LAYER" << endl;
*this << 70 << endl << 0 << endl; // flags: seems to be required by some tools
*this << 62 << endl << color << endl; // color
*this << 6 << endl << linestyle << endl; // line style
*this << 2 << endl;
emit_layer (l->second);
// skip the zero layer on the table, as it is not a "real" design layer
// this avoids replicating it as "L0D0_0" in a DXF read/write spin.
if (! (l->second.layer == 0 && l->second.datatype == 0 && l->second.name == "L0D0_0")) {
color += 1;
*this << 0 << endl << "LAYER" << endl;
*this << 70 << endl << 0 << endl; // flags: seems to be required by some tools
*this << 62 << endl << color << endl; // color
*this << 6 << endl << linestyle << endl; // line style
*this << 2 << endl;
emit_layer (l->second);
color += 1;
}
}
@ -255,7 +261,7 @@ DXFWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::SaveLa
void
DXFWriter::emit_layer(const db::LayerProperties &lp)
{
if (lp.layer == 0 && lp.datatype == 0 && lp.name == "L0D0") {
if (lp.layer == 0 && lp.datatype == 0 && lp.name == "L0D0_0") {
// zero layer
*this << "0" << endl;
} else {

View File

@ -245,3 +245,48 @@ TEST(Polygons4e)
opt.polygon_mode = 4;
do_run_test (_this, l, tl::testdata () + std::string ("/dxf/") + "dxf4e_au.dxf", opt);
}
TEST(FullSpinWithLayer0)
{
db::Layout l;
std::string fn = tl::testdata () + "/dxf/dxf5.dxf";
{
tl::InputStream stream (fn);
db::Reader reader (stream);
reader.read (l);
}
std::string tmp = tmp_file ("tmp.dxf");
{
db::SaveLayoutOptions options;
options.set_format ("DXF");
tl::OutputStream stream (tmp);
db::Writer writer (options);
writer.write (l, stream);
}
db::Layout l2;
{
tl::InputStream stream (tmp);
db::Reader reader (stream);
reader.read (l2);
}
std::string tmp2 = tmp_file ("tmp2.dxf");
{
db::SaveLayoutOptions options;
options.set_format ("DXF");
tl::OutputStream stream (tmp2);
db::Writer writer (options);
writer.write (l2, stream);
}
std::string fn_au = tl::testdata () + std::string ("/dxf/") + "dxf5_au.dxf";
compare_text_files (tmp2, fn_au);
}

774
testdata/dxf/dxf5.dxf vendored Executable file
View File

@ -0,0 +1,774 @@
0
SECTION
2
HEADER
0
ENDSEC
0
SECTION
2
TABLES
0
TABLE
2
VPORT
5
7
70
1
0
VPORT
5
15
2
*ACTIVE
70
0
10
0.0
20
0.0
11
1.0
21
1.0
12
0.0
22
0.0
13
0.0
23
0.0
14
5.0
24
5.0
15
5.0
25
5.0
16
0.166302654343
26
0.0
36
0.986074757388
17
1.57557801108
27
-0.970582369149
37
-0.262735491132
40
5.993471164309
41
1.648216482165
42
50.0
43
0.0
44
0.0
50
0.0
51
90.0
71
0
72
100
73
1
74
1
75
0
76
1
77
0
78
0
0
ENDTAB
0
TABLE
2
LTYPE
5
4
70
15
0
LTYPE
5
11
2
ByBlock
70
64
3
72
65
73
0
40
0.0
0
LTYPE
5
12
2
ByLayer
70
64
3
72
65
73
0
40
0.0
0
LTYPE
5
13
2
Continuous
70
64
3
Solid line
72
65
73
0
40
0.0
0
LTYPE
5
24
2
Durchgehend
70
0
3
Durchgehend
72
65
73
0
40
0.0
0
LTYPE
5
25
2
Rand
70
0
3
Rand
72
65
73
6
40
1.75
49
0.5
49
-0.25
49
0.5
49
-0.25
49
0.0
49
-0.25
0
LTYPE
5
26
2
Mitte
70
0
3
Mitte
72
65
73
4
40
2.0
49
1.25
49
-0.25
49
0.25
49
-0.25
0
LTYPE
5
27
2
Strichpunkt
70
0
3
Strichpunkt
72
65
73
4
40
1.0
49
0.5
49
-0.25
49
0.0
49
-0.25
0
LTYPE
5
28
2
Gestrichelt
70
0
3
Gestrichelt
72
65
73
2
40
0.75
49
0.5
49
-0.25
0
LTYPE
5
29
2
Teilen
70
0
3
Teilen
72
65
73
6
40
1.25
49
0.5
49
-0.25
49
0.0
49
-0.25
49
0.0
49
-0.25
0
LTYPE
5
2A
2
Punkt
70
0
3
Punkt
72
65
73
2
40
0.25
49
0.0
49
-0.25
0
LTYPE
5
2B
2
Verdeckt
70
0
3
Verdeckt
72
65
73
2
40
0.375
49
0.25
49
-0.125
0
LTYPE
5
2C
2
$INVISIBLE
70
0
3
$INVISIBLE
72
65
73
2
40
200.0
49
-100.0
49
-100.0
0
LTYPE
5
2D
2
$SNAPEXT
70
0
3
$SNAPEXT
72
65
73
2
40
0.04
49
0.02
49
-0.02
0
LTYPE
5
2E
2
$AUXILIARY
70
0
3
$AUXILIARY
72
65
73
2
40
0.1
49
0.05
49
-0.05
0
LTYPE
5
2F
2
$CONSTRUCTION
70
0
3
$CONSTRUCTION
72
65
73
4
40
0.3
49
0.2
49
-0.05
49
0.0
49
-0.05
0
ENDTAB
0
TABLE
2
LAYER
5
2
100
AcDbSymbolTable
70
5
0
LAYER
5
14
2
0
70
0
62
1
6
Durchgehend
0
LAYER
5
30
2
Metal
70
0
62
5
6
Durchgehend
0
LAYER
5
31
2
Bemassung
70
0
62
-7
6
Durchgehend
0
LAYER
5
32
2
$CONSTRUCTION
70
0
62
-9
6
$CONSTRUCTION
0
LAYER
5
33
2
Kommentare
70
0
62
-7
6
Durchgehend
0
ENDTAB
0
ENDSEC
0
SECTION
2
BLOCKS
0
BLOCK
2
Winkel
8
0
70
0
10
-0.51
20
0.51
30
0.0
0
SOLID
8
0
10
-0.26
20
0.76
30
0.0
11
-0.76
21
0.76
31
0.0
12
-0.26
22
0.64
32
0.0
13
-0.76
23
0.64
33
0.0
0
SOLID
8
0
10
-0.64
20
0.26
30
0.0
11
-0.76
21
0.26
31
0.0
12
-0.64
22
0.76
32
0.0
13
-0.76
23
0.76
33
0.0
0
ENDBLK
0
BLOCK
2
Winkel2
8
0
70
0
10
0.5
20
0
30
0.0
0
INSERT
8
0
2
Winkel
10
0.0
20
-0.5
30
0.0
0
INSERT
8
Metal2
2
Winkel
10
1.0
20
-0.5
30
0.0
0
ENDBLK
0
ENDSEC
0
SECTION
2
ENTITIES
0
INSERT
8
Metal
2
Winkel
10
-0.50
20
0.50
30
0.0
0
INSERT
8
Metal
2
Winkel2
10
-0.50
20
3
30
0.0
0
INSERT
8
0
2
Winkel2
10
2
20
3
30
0.0
0
INSERT
8
Metal
2
Winkel
10
0.5
20
0.5
30
0.0
50
90
0
INSERT
8
Metal
2
Winkel
10
1.5
20
0.5
30
0.0
50
90
41
-0.5
42
0.5
0
INSERT
8
Metal
2
Winkel
10
2.5
20
0.5
30
0.0
41
1.5
42
-1.5
0
INSERT
8
Metal
2
Winkel
10
4
20
0.5
30
0.0
70
3
71
2
44
1.0
45
1.5
41
1.5
42
-1.5
0
INSERT
8
Metal
2
Winkel
10
10
20
0.5
30
0.0
50
90
70
3
71
2
44
1.0
45
1.5
0
SOLID
8
Metal
10
-0.240436058144
20
0.3005230962
30
0.0
11
-0.119798742395
21
0.3005230962
31
0.0
12
-0.240436058144
22
-0.300507815882
32
0.0
13
-0.119798742395
23
-0.300507815882
33
0.0
0
ENDSEC
0
EOF

822
testdata/dxf/dxf5_au.dxf vendored Normal file
View File

@ -0,0 +1,822 @@
0
SECTION
2
HEADER
9
$ACADVER
1
AC1006
0
ENDSEC
0
SECTION
2
TABLES
0
TABLE
2
LAYER
70
6
0
LAYER
70
0
62
1
6
CONTINUOUS
2
Metal
0
LAYER
70
0
62
2
6
CONTINUOUS
2
Bemassung
0
LAYER
70
0
62
3
6
CONTINUOUS
2
$CONSTRUCTION
0
LAYER
70
0
62
4
6
CONTINUOUS
2
Kommentare
0
LAYER
70
0
62
5
6
CONTINUOUS
2
Metal2
0
ENDTAB
0
ENDSEC
0
SECTION
2
BLOCKS
0
BLOCK
2
Winkel$2
70
0
10
0
20
0
0
POLYLINE
8
0
70
1
40
0
41
0
66
1
0
VERTEX
8
0
10
-0.25
20
0.13
0
VERTEX
8
0
10
-0.25
20
0.25
0
VERTEX
8
0
10
0.25
20
0.25
0
VERTEX
8
0
10
0.25
20
0.13
0
SEQEND
0
POLYLINE
8
0
70
1
40
0
41
0
66
1
0
VERTEX
8
0
10
-0.25
20
-0.25
0
VERTEX
8
0
10
-0.25
20
0.25
0
VERTEX
8
0
10
-0.13
20
0.25
0
VERTEX
8
0
10
-0.13
20
-0.25
0
SEQEND
0
ENDBLK
0
BLOCK
2
Winkel
70
0
10
0
20
0
0
POLYLINE
8
Metal2
70
1
40
0
41
0
66
1
0
VERTEX
8
Metal2
10
-0.25
20
0.13
0
VERTEX
8
Metal2
10
-0.25
20
0.25
0
VERTEX
8
Metal2
10
0.25
20
0.25
0
VERTEX
8
Metal2
10
0.25
20
0.13
0
SEQEND
0
POLYLINE
8
Metal2
70
1
40
0
41
0
66
1
0
VERTEX
8
Metal2
10
-0.25
20
-0.25
0
VERTEX
8
Metal2
10
-0.25
20
0.25
0
VERTEX
8
Metal2
10
-0.13
20
0.25
0
VERTEX
8
Metal2
10
-0.13
20
-0.25
0
SEQEND
0
ENDBLK
0
BLOCK
2
Winkel$1
70
0
10
0
20
0
0
POLYLINE
8
Metal
70
1
40
0
41
0
66
1
0
VERTEX
8
Metal
10
-0.25
20
0.13
0
VERTEX
8
Metal
10
-0.25
20
0.25
0
VERTEX
8
Metal
10
0.25
20
0.25
0
VERTEX
8
Metal
10
0.25
20
0.13
0
SEQEND
0
POLYLINE
8
Metal
70
1
40
0
41
0
66
1
0
VERTEX
8
Metal
10
-0.25
20
-0.25
0
VERTEX
8
Metal
10
-0.25
20
0.25
0
VERTEX
8
Metal
10
-0.13
20
0.25
0
VERTEX
8
Metal
10
-0.13
20
-0.25
0
SEQEND
0
ENDBLK
0
BLOCK
2
Winkel2$1
70
0
10
0
20
0
0
INSERT
8
0
2
Winkel$2
10
-0.5
20
-0.5
41
1
42
1
50
0
0
INSERT
8
0
2
Winkel
10
0.5
20
-0.5
41
1
42
1
50
0
0
ENDBLK
0
BLOCK
2
Winkel2
70
0
10
0
20
0
0
INSERT
8
0
2
Winkel$1
10
-0.5
20
-0.5
41
1
42
1
50
0
0
INSERT
8
0
2
Winkel
10
0.5
20
-0.5
41
1
42
1
50
0
0
ENDBLK
0
ENDSEC
0
SECTION
2
ENTITIES
0
INSERT
8
0
2
Winkel$1
10
-0.5
20
0.5
41
1
42
1
50
0
0
INSERT
8
0
2
Winkel2
10
-0.5
20
3
41
1
42
1
50
0
0
INSERT
8
0
2
Winkel2$1
10
2
20
3
41
1
42
1
50
0
0
INSERT
8
0
2
Winkel$1
10
0.5
20
0.5
41
1
42
1
50
90
0
INSERT
8
0
2
Winkel$1
10
1.5
20
0.5
41
0.5
42
-0.5
50
270
0
INSERT
8
0
2
Winkel$1
10
2.5
20
0.5
41
1.5
42
-1.5
50
0
0
INSERT
8
0
2
Winkel$1
10
4
20
0.5
41
1.5
42
-1.5
50
0
0
INSERT
8
0
2
Winkel$1
10
5
20
0.5
41
1.5
42
-1.5
50
0
0
INSERT
8
0
2
Winkel$1
10
6
20
0.5
41
1.5
42
-1.5
50
0
0
INSERT
8
0
2
Winkel$1
10
4
20
2
41
1.5
42
-1.5
50
0
0
INSERT
8
0
2
Winkel$1
10
5
20
2
41
1.5
42
-1.5
50
0
0
INSERT
8
0
2
Winkel$1
10
6
20
2
41
1.5
42
-1.5
50
0
0
INSERT
8
0
2
Winkel$1
10
10
20
0.5
41
1
42
1
50
90
0
INSERT
8
0
2
Winkel$1
10
10
20
1.5
41
1
42
1
50
90
0
INSERT
8
0
2
Winkel$1
10
10
20
2.5
41
1
42
1
50
90
0
INSERT
8
0
2
Winkel$1
10
8.5
20
0.5
41
1
42
1
50
90
0
INSERT
8
0
2
Winkel$1
10
8.5
20
1.5
41
1
42
1
50
90
0
INSERT
8
0
2
Winkel$1
10
8.5
20
2.5
41
1
42
1
50
90
0
POLYLINE
8
Metal
70
1
40
0
41
0
66
1
0
VERTEX
8
Metal
10
-0.24
20
-0.301
0
VERTEX
8
Metal
10
-0.24
20
0.301
0
VERTEX
8
Metal
10
-0.12
20
0.301
0
VERTEX
8
Metal
10
-0.12
20
-0.301
0
SEQEND
0
ENDSEC
0
EOF