Fixed #1216 (issue with moved - internal error)

This issue is fixed. In addition the following problems were fixed/found:
* General issue with handling merged state in in-place transform (merge shadow region needs to be updated too)
* moved now is hierarchical (also for edges)
This commit is contained in:
Matthias Koefferlein 2022-12-08 20:23:52 +01:00
parent 92d0174711
commit 2c94179589
6 changed files with 154 additions and 24 deletions

View File

@ -171,7 +171,7 @@ DeepEdges::DeepEdges (const DeepEdges &other)
m_is_merged (other.m_is_merged)
{
if (m_merged_edges_valid) {
m_merged_edges = other.m_merged_edges;
m_merged_edges = other.m_merged_edges.copy ();
}
}
@ -186,7 +186,7 @@ DeepEdges::operator= (const DeepEdges &other)
m_merged_edges_valid = other.m_merged_edges_valid;
m_is_merged = other.m_is_merged;
if (m_merged_edges_valid) {
m_merged_edges = other.m_merged_edges;
m_merged_edges = other.m_merged_edges.copy ();
}
}
@ -227,20 +227,52 @@ void DeepEdges::do_insert (const db::Edge &edge)
template <class Trans>
static void transform_deep_layer (db::DeepLayer &deep_layer, const Trans &t)
{
// TODO: this is a pretty cheap implementation. At least a plain move can be done with orientation variants.
if (t.equal (Trans (db::Disp (t.disp ())))) {
db::Layout &layout = deep_layer.layout ();
if (layout.begin_top_down () != layout.end_top_down ()) {
// Plain move
db::Cell &top_cell = layout.cell (*layout.begin_top_down ());
// build cell variants for different orientations
db::OrientationReducer same_orientation;
db::VariantsCollectorBase vars (&same_orientation);
vars.collect (deep_layer.layout (), deep_layer.initial_cell ());
deep_layer.separate_variants (vars);
// process the variants
db::Layout &layout = deep_layer.layout ();
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
const std::map<db::ICplxTrans, size_t> &v = vars.variants (c->cell_index ());
tl_assert (v.size () == size_t (1));
db::Trans tr (v.begin ()->first.inverted () * t.disp ());
db::Shapes &shapes = c->shapes (deep_layer.layer ());
db::Shapes new_shapes (layout.manager (), c.operator-> (), layout.is_editable ());
new_shapes.insert_transformed (shapes, tr);
shapes.swap (new_shapes);
db::Shapes flat_shapes (layout.is_editable ());
for (db::RecursiveShapeIterator iter (layout, top_cell, deep_layer.layer ()); !iter.at_end (); ++iter) {
flat_shapes.insert (iter->edge ().transformed (iter.trans ()).transformed (t));
}
layout.clear_layer (deep_layer.layer ());
top_cell.shapes (deep_layer.layer ()).swap (flat_shapes);
} else {
// General transformation -> note that this is a flat implementation!
db::Layout &layout = deep_layer.layout ();
if (layout.begin_top_down () != layout.end_top_down ()) {
db::Cell &top_cell = layout.cell (*layout.begin_top_down ());
db::Shapes flat_shapes (layout.is_editable ());
for (db::RecursiveShapeIterator iter (layout, top_cell, deep_layer.layer ()); !iter.at_end (); ++iter) {
flat_shapes.insert (iter->edge ().transformed (iter.trans ()).transformed (t));
}
layout.clear_layer (deep_layer.layer ());
top_cell.shapes (deep_layer.layer ()).swap (flat_shapes);
}
}
}
@ -248,24 +280,36 @@ static void transform_deep_layer (db::DeepLayer &deep_layer, const Trans &t)
void DeepEdges::do_transform (const db::Trans &t)
{
transform_deep_layer (deep_layer (), t);
if (m_merged_edges_valid && m_merged_edges.layer () != deep_layer ().layer ()) {
transform_deep_layer (m_merged_edges, t);
}
invalidate_bbox ();
}
void DeepEdges::do_transform (const db::ICplxTrans &t)
{
transform_deep_layer (deep_layer (), t);
if (m_merged_edges_valid && m_merged_edges.layer () != deep_layer ().layer ()) {
transform_deep_layer (m_merged_edges, t);
}
invalidate_bbox ();
}
void DeepEdges::do_transform (const db::IMatrix2d &t)
{
transform_deep_layer (deep_layer (), t);
if (m_merged_edges_valid && m_merged_edges.layer () != deep_layer ().layer ()) {
transform_deep_layer (m_merged_edges, t);
}
invalidate_bbox ();
}
void DeepEdges::do_transform (const db::IMatrix3d &t)
{
transform_deep_layer (deep_layer (), t);
if (m_merged_edges_valid && m_merged_edges.layer () != deep_layer ().layer ()) {
transform_deep_layer (m_merged_edges, t);
}
invalidate_bbox ();
}

View File

@ -174,7 +174,7 @@ DeepRegion::DeepRegion (const DeepRegion &other)
m_is_merged (other.m_is_merged)
{
if (m_merged_polygons_valid) {
m_merged_polygons = other.m_merged_polygons;
m_merged_polygons = other.m_merged_polygons.copy ();
}
}
@ -189,7 +189,7 @@ DeepRegion::operator= (const DeepRegion &other)
m_merged_polygons_valid = other.m_merged_polygons_valid;
m_is_merged = other.m_is_merged;
if (m_merged_polygons_valid) {
m_merged_polygons = other.m_merged_polygons;
m_merged_polygons = other.m_merged_polygons.copy ();
}
}
@ -235,22 +235,56 @@ void DeepRegion::do_insert (const db::Polygon &polygon)
template <class Trans>
static void transform_deep_layer (db::DeepLayer &deep_layer, const Trans &t)
{
// TODO: this is a pretty cheap implementation. At least a plain move can be done with orientation variants.
if (t.equal (Trans (db::Disp (t.disp ())))) {
db::Layout &layout = deep_layer.layout ();
if (layout.begin_top_down () != layout.end_top_down ()) {
// Plain move
db::Cell &top_cell = layout.cell (*layout.begin_top_down ());
// build cell variants for different orientations
db::OrientationReducer same_orientation;
db::VariantsCollectorBase vars (&same_orientation);
vars.collect (deep_layer.layout (), deep_layer.initial_cell ());
deep_layer.separate_variants (vars);
// process the variants
db::Layout &layout = deep_layer.layout ();
for (db::Layout::iterator c = layout.begin (); c != layout.end (); ++c) {
const std::map<db::ICplxTrans, size_t> &v = vars.variants (c->cell_index ());
tl_assert (v.size () == size_t (1));
db::Trans tr (v.begin ()->first.inverted () * t.disp ());
db::Shapes &shapes = c->shapes (deep_layer.layer ());
db::Shapes new_shapes (layout.manager (), c.operator-> (), layout.is_editable ());
new_shapes.insert_transformed (shapes, tr);
shapes.swap (new_shapes);
db::Shapes flat_shapes (layout.is_editable ());
for (db::RecursiveShapeIterator iter (layout, top_cell, deep_layer.layer ()); !iter.at_end (); ++iter) {
db::Polygon poly;
iter->polygon (poly);
flat_shapes.insert (poly.transformed (iter.trans ()).transformed (t));
}
layout.clear_layer (deep_layer.layer ());
top_cell.shapes (deep_layer.layer ()).swap (flat_shapes);
} else {
// General transformation -> note that this is a flat implementation!
db::Layout &layout = deep_layer.layout ();
if (layout.begin_top_down () != layout.end_top_down ()) {
db::Cell &top_cell = layout.cell (*layout.begin_top_down ());
db::Shapes flat_shapes (layout.manager (), &top_cell, layout.is_editable ());
for (db::RecursiveShapeIterator iter (layout, top_cell, deep_layer.layer ()); !iter.at_end (); ++iter) {
db::Polygon poly;
iter->polygon (poly);
poly.transform (iter.trans ());
poly.transform (t);
flat_shapes.insert (db::PolygonRef (poly, layout.shape_repository ()));
}
layout.clear_layer (deep_layer.layer ());
top_cell.shapes (deep_layer.layer ()).swap (flat_shapes);
}
}
}
@ -258,24 +292,36 @@ static void transform_deep_layer (db::DeepLayer &deep_layer, const Trans &t)
void DeepRegion::do_transform (const db::Trans &t)
{
transform_deep_layer (deep_layer (), t);
if (m_merged_polygons_valid && m_merged_polygons.layer () != deep_layer ().layer ()) {
transform_deep_layer (m_merged_polygons, t);
}
invalidate_bbox ();
}
void DeepRegion::do_transform (const db::ICplxTrans &t)
{
transform_deep_layer (deep_layer (), t);
if (m_merged_polygons_valid && m_merged_polygons.layer () != deep_layer ().layer ()) {
transform_deep_layer (m_merged_polygons, t);
}
invalidate_bbox ();
}
void DeepRegion::do_transform (const db::IMatrix2d &t)
{
transform_deep_layer (deep_layer (), t);
if (m_merged_polygons_valid && m_merged_polygons.layer () != deep_layer ().layer ()) {
transform_deep_layer (m_merged_polygons, t);
}
invalidate_bbox ();
}
void DeepRegion::do_transform (const db::IMatrix3d &t)
{
transform_deep_layer (deep_layer (), t);
if (m_merged_polygons_valid && m_merged_polygons.layer () != deep_layer ().layer ()) {
transform_deep_layer (m_merged_polygons, t);
}
invalidate_bbox ();
}

View File

@ -1386,3 +1386,13 @@ TEST(58d_in_and_out)
{
run_test (_this, "58", true);
}
TEST(60_issue1216)
{
run_test (_this, "60", false);
}
TEST(60d_issue1216)
{
run_test (_this, "60", true);
}

30
testdata/drc/drcSimpleTests_60.drc vendored Normal file
View File

@ -0,0 +1,30 @@
# Moved implementation
source($drc_test_source)
target($drc_test_target)
if $drc_test_deep
deep
end
l8 = input(8, 0)
l9 = input(9, 0)
l8.output(8, 0)
l9.output(9, 0)
# NOTE: "sized" tests issue #1216
l8.sized(0.1, 0).moved(-0.1, 0).sized(0, 0.1).moved(0, -0.1).output(108, 0)
l9.sized(0.1, 0).moved(-0.1, 0).sized(0, 0.1).moved(0, -0.1).output(109, 0)
l8.edges.moved(-0.1, -0.1).extended_out(0.05).output(118, 0)
l9.edges.moved(-0.1, -0.1).extended_out(0.05).output(119, 0)
# NOTE: "sized" tests issue #1216
l8.rotated(90.0).sized(0, 0.1).output(208, 0)
l9.rotated(90.0).sized(0, 0.1).output(209, 0)
l8.edges.rotated(90.0).extended_out(0.05).output(218, 0)
l9.edges.rotated(90.0).extended_out(0.05).output(219, 0)

BIN
testdata/drc/drcSimpleTests_60.gds vendored Normal file

Binary file not shown.

BIN
testdata/drc/drcSimpleTests_au60.gds vendored Normal file

Binary file not shown.