mirror of https://github.com/KLayout/klayout.git
Avoid turning DeepRegions into flat ones as this spoils hierarchical processing.
This commit is contained in:
parent
de4454a0d6
commit
6df333a05e
|
|
@ -50,6 +50,7 @@ SOURCES = \
|
||||||
dbManager.cc \
|
dbManager.cc \
|
||||||
dbMatrix.cc \
|
dbMatrix.cc \
|
||||||
dbMemStatistics.cc \
|
dbMemStatistics.cc \
|
||||||
|
dbMutableRegion.cc \
|
||||||
dbObject.cc \
|
dbObject.cc \
|
||||||
dbPath.cc \
|
dbPath.cc \
|
||||||
dbPCellDeclaration.cc \
|
dbPCellDeclaration.cc \
|
||||||
|
|
@ -258,6 +259,7 @@ HEADERS = \
|
||||||
dbMatrix.h \
|
dbMatrix.h \
|
||||||
dbMemStatistics.h \
|
dbMemStatistics.h \
|
||||||
dbMetaInfo.h \
|
dbMetaInfo.h \
|
||||||
|
dbMutableRegion.h \
|
||||||
dbObject.h \
|
dbObject.h \
|
||||||
dbObjectTag.h \
|
dbObjectTag.h \
|
||||||
dbObjectWithProperties.h \
|
dbObjectWithProperties.h \
|
||||||
|
|
|
||||||
|
|
@ -127,14 +127,14 @@ private:
|
||||||
// DeepRegion implementation
|
// DeepRegion implementation
|
||||||
|
|
||||||
DeepRegion::DeepRegion (const RecursiveShapeIterator &si, DeepShapeStore &dss, double area_ratio, size_t max_vertex_count)
|
DeepRegion::DeepRegion (const RecursiveShapeIterator &si, DeepShapeStore &dss, double area_ratio, size_t max_vertex_count)
|
||||||
: AsIfFlatRegion (), m_merged_polygons ()
|
: MutableRegion (), m_merged_polygons ()
|
||||||
{
|
{
|
||||||
set_deep_layer (dss.create_polygon_layer (si, area_ratio, max_vertex_count));
|
set_deep_layer (dss.create_polygon_layer (si, area_ratio, max_vertex_count));
|
||||||
init ();
|
init ();
|
||||||
}
|
}
|
||||||
|
|
||||||
DeepRegion::DeepRegion (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans, bool merged_semantics, double area_ratio, size_t max_vertex_count)
|
DeepRegion::DeepRegion (const RecursiveShapeIterator &si, DeepShapeStore &dss, const db::ICplxTrans &trans, bool merged_semantics, double area_ratio, size_t max_vertex_count)
|
||||||
: AsIfFlatRegion (), m_merged_polygons ()
|
: MutableRegion (), m_merged_polygons ()
|
||||||
{
|
{
|
||||||
set_deep_layer (dss.create_polygon_layer (si, area_ratio, max_vertex_count, trans));
|
set_deep_layer (dss.create_polygon_layer (si, area_ratio, max_vertex_count, trans));
|
||||||
init ();
|
init ();
|
||||||
|
|
@ -142,7 +142,7 @@ DeepRegion::DeepRegion (const RecursiveShapeIterator &si, DeepShapeStore &dss, c
|
||||||
}
|
}
|
||||||
|
|
||||||
DeepRegion::DeepRegion (const db::Region &other, DeepShapeStore &dss)
|
DeepRegion::DeepRegion (const db::Region &other, DeepShapeStore &dss)
|
||||||
: AsIfFlatRegion (), m_merged_polygons ()
|
: MutableRegion (), m_merged_polygons ()
|
||||||
{
|
{
|
||||||
set_deep_layer (dss.create_from_flat (other, false));
|
set_deep_layer (dss.create_from_flat (other, false));
|
||||||
|
|
||||||
|
|
@ -151,13 +151,13 @@ DeepRegion::DeepRegion (const db::Region &other, DeepShapeStore &dss)
|
||||||
}
|
}
|
||||||
|
|
||||||
DeepRegion::DeepRegion ()
|
DeepRegion::DeepRegion ()
|
||||||
: AsIfFlatRegion ()
|
: MutableRegion ()
|
||||||
{
|
{
|
||||||
init ();
|
init ();
|
||||||
}
|
}
|
||||||
|
|
||||||
DeepRegion::DeepRegion (const DeepLayer &dl)
|
DeepRegion::DeepRegion (const DeepLayer &dl)
|
||||||
: AsIfFlatRegion ()
|
: MutableRegion ()
|
||||||
{
|
{
|
||||||
set_deep_layer (dl);
|
set_deep_layer (dl);
|
||||||
init ();
|
init ();
|
||||||
|
|
@ -169,7 +169,7 @@ DeepRegion::~DeepRegion ()
|
||||||
}
|
}
|
||||||
|
|
||||||
DeepRegion::DeepRegion (const DeepRegion &other)
|
DeepRegion::DeepRegion (const DeepRegion &other)
|
||||||
: AsIfFlatRegion (other), DeepShapeCollectionDelegateBase (other),
|
: MutableRegion (other), DeepShapeCollectionDelegateBase (other),
|
||||||
m_merged_polygons_valid (other.m_merged_polygons_valid),
|
m_merged_polygons_valid (other.m_merged_polygons_valid),
|
||||||
m_is_merged (other.m_is_merged)
|
m_is_merged (other.m_is_merged)
|
||||||
{
|
{
|
||||||
|
|
@ -220,6 +220,74 @@ void DeepRegion::min_coherence_changed ()
|
||||||
set_is_merged (false);
|
set_is_merged (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeepRegion::do_insert (const db::Polygon &polygon)
|
||||||
|
{
|
||||||
|
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 ());
|
||||||
|
top_cell.shapes (deep_layer ().layer ()).insert (db::PolygonRef (polygon, layout.shape_repository ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
invalidate_bbox ();
|
||||||
|
set_is_merged (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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;
|
||||||
|
for (db::RecursiveShapeIterator iter (layout, top_cell, deep_layer.layer ()); !iter.at_end (); ++iter) {
|
||||||
|
flat_shapes.insert (iter->polygon ().transformed (t));
|
||||||
|
}
|
||||||
|
|
||||||
|
layout.clear_layer (deep_layer.layer ());
|
||||||
|
top_cell.shapes (deep_layer.layer ()).swap (flat_shapes);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeepRegion::do_transform (const db::Trans &t)
|
||||||
|
{
|
||||||
|
transform_deep_layer (deep_layer (), t);
|
||||||
|
invalidate_bbox ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeepRegion::do_transform (const db::ICplxTrans &t)
|
||||||
|
{
|
||||||
|
transform_deep_layer (deep_layer (), t);
|
||||||
|
invalidate_bbox ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeepRegion::reserve (size_t)
|
||||||
|
{
|
||||||
|
// Not implemented for deep regions
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeepRegion::flatten ()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
for (db::RecursiveShapeIterator iter (layout, top_cell, deep_layer ().layer ()); !iter.at_end (); ++iter) {
|
||||||
|
flat_shapes.insert (iter->polygon ());
|
||||||
|
}
|
||||||
|
|
||||||
|
layout.clear_layer (deep_layer ().layer ());
|
||||||
|
top_cell.shapes (deep_layer ().layer ()).swap (flat_shapes);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RegionIteratorDelegate *
|
RegionIteratorDelegate *
|
||||||
DeepRegion::begin () const
|
DeepRegion::begin () const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
#include "dbCommon.h"
|
#include "dbCommon.h"
|
||||||
|
|
||||||
#include "dbAsIfFlatRegion.h"
|
#include "dbMutableRegion.h"
|
||||||
#include "dbDeepShapeStore.h"
|
#include "dbDeepShapeStore.h"
|
||||||
|
|
||||||
namespace db {
|
namespace db {
|
||||||
|
|
@ -35,7 +35,7 @@ namespace db {
|
||||||
* @brief A deep, polygon-set delegate
|
* @brief A deep, polygon-set delegate
|
||||||
*/
|
*/
|
||||||
class DB_PUBLIC DeepRegion
|
class DB_PUBLIC DeepRegion
|
||||||
: public AsIfFlatRegion, public DeepShapeCollectionDelegateBase
|
: public MutableRegion, public DeepShapeCollectionDelegateBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef db::layer<db::Polygon, db::unstable_layer_tag> polygon_layer_type;
|
typedef db::layer<db::Polygon, db::unstable_layer_tag> polygon_layer_type;
|
||||||
|
|
@ -53,6 +53,15 @@ public:
|
||||||
|
|
||||||
RegionDelegate *clone () const;
|
RegionDelegate *clone () const;
|
||||||
|
|
||||||
|
virtual void do_insert (const db::Polygon &polygon);
|
||||||
|
|
||||||
|
virtual void do_transform (const db::Trans &t);
|
||||||
|
virtual void do_transform (const db::ICplxTrans &t);
|
||||||
|
|
||||||
|
virtual void flatten ();
|
||||||
|
|
||||||
|
virtual void reserve (size_t);
|
||||||
|
|
||||||
virtual RegionIteratorDelegate *begin () const;
|
virtual RegionIteratorDelegate *begin () const;
|
||||||
virtual RegionIteratorDelegate *begin_merged () const;
|
virtual RegionIteratorDelegate *begin_merged () const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ namespace db
|
||||||
// FlatRegion implementation
|
// FlatRegion implementation
|
||||||
|
|
||||||
FlatRegion::FlatRegion ()
|
FlatRegion::FlatRegion ()
|
||||||
: AsIfFlatRegion (), mp_polygons (new db::Shapes (false)), mp_merged_polygons (new db::Shapes (false))
|
: MutableRegion (), mp_polygons (new db::Shapes (false)), mp_merged_polygons (new db::Shapes (false))
|
||||||
{
|
{
|
||||||
init ();
|
init ();
|
||||||
}
|
}
|
||||||
|
|
@ -44,7 +44,7 @@ FlatRegion::~FlatRegion ()
|
||||||
}
|
}
|
||||||
|
|
||||||
FlatRegion::FlatRegion (const FlatRegion &other)
|
FlatRegion::FlatRegion (const FlatRegion &other)
|
||||||
: AsIfFlatRegion (other), mp_polygons (other.mp_polygons), mp_merged_polygons (other.mp_merged_polygons)
|
: MutableRegion (other), mp_polygons (other.mp_polygons), mp_merged_polygons (other.mp_merged_polygons)
|
||||||
{
|
{
|
||||||
init ();
|
init ();
|
||||||
|
|
||||||
|
|
@ -53,7 +53,7 @@ FlatRegion::FlatRegion (const FlatRegion &other)
|
||||||
}
|
}
|
||||||
|
|
||||||
FlatRegion::FlatRegion (const db::Shapes &polygons, bool is_merged)
|
FlatRegion::FlatRegion (const db::Shapes &polygons, bool is_merged)
|
||||||
: AsIfFlatRegion (), mp_polygons (new db::Shapes (polygons)), mp_merged_polygons (new db::Shapes (false))
|
: MutableRegion (), mp_polygons (new db::Shapes (polygons)), mp_merged_polygons (new db::Shapes (false))
|
||||||
{
|
{
|
||||||
init ();
|
init ();
|
||||||
|
|
||||||
|
|
@ -61,7 +61,7 @@ FlatRegion::FlatRegion (const db::Shapes &polygons, bool is_merged)
|
||||||
}
|
}
|
||||||
|
|
||||||
FlatRegion::FlatRegion (bool is_merged)
|
FlatRegion::FlatRegion (bool is_merged)
|
||||||
: AsIfFlatRegion (), mp_polygons (new db::Shapes (false)), mp_merged_polygons (new db::Shapes (false))
|
: MutableRegion (), mp_polygons (new db::Shapes (false)), mp_merged_polygons (new db::Shapes (false))
|
||||||
{
|
{
|
||||||
init ();
|
init ();
|
||||||
|
|
||||||
|
|
@ -410,39 +410,7 @@ void FlatRegion::insert_into (Layout *layout, db::cell_index_type into_cell, uns
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FlatRegion::insert (const db::Box &box)
|
FlatRegion::do_insert (const db::Polygon &polygon)
|
||||||
{
|
|
||||||
if (! box.empty () && box.width () > 0 && box.height () > 0) {
|
|
||||||
|
|
||||||
if (empty ()) {
|
|
||||||
|
|
||||||
mp_polygons->insert (db::Polygon (box));
|
|
||||||
m_is_merged = true;
|
|
||||||
update_bbox (box);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
mp_polygons->insert (db::Polygon (box));
|
|
||||||
m_is_merged = false;
|
|
||||||
invalidate_cache ();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
FlatRegion::insert (const db::Path &path)
|
|
||||||
{
|
|
||||||
if (path.points () > 0) {
|
|
||||||
mp_polygons->insert (path.polygon ());
|
|
||||||
m_is_merged = false;
|
|
||||||
invalidate_cache ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
FlatRegion::insert (const db::Polygon &polygon)
|
|
||||||
{
|
{
|
||||||
if (polygon.holes () > 0 || polygon.vertices () > 0) {
|
if (polygon.holes () > 0 || polygon.vertices () > 0) {
|
||||||
mp_polygons->insert (polygon);
|
mp_polygons->insert (polygon);
|
||||||
|
|
@ -451,29 +419,5 @@ FlatRegion::insert (const db::Polygon &polygon)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
FlatRegion::insert (const db::SimplePolygon &polygon)
|
|
||||||
{
|
|
||||||
if (polygon.vertices () > 0) {
|
|
||||||
db::Polygon poly;
|
|
||||||
poly.assign_hull (polygon.begin_hull (), polygon.end_hull ());
|
|
||||||
mp_polygons->insert (poly);
|
|
||||||
m_is_merged = false;
|
|
||||||
invalidate_cache ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
FlatRegion::insert (const db::Shape &shape)
|
|
||||||
{
|
|
||||||
if (shape.is_polygon () || shape.is_path () || shape.is_box ()) {
|
|
||||||
db::Polygon poly;
|
|
||||||
shape.polygon (poly);
|
|
||||||
mp_polygons->insert (poly);
|
|
||||||
m_is_merged = false;
|
|
||||||
invalidate_cache ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
#include "dbCommon.h"
|
#include "dbCommon.h"
|
||||||
|
|
||||||
#include "dbAsIfFlatRegion.h"
|
#include "dbMutableRegion.h"
|
||||||
#include "dbShapes.h"
|
#include "dbShapes.h"
|
||||||
#include "dbShapes2.h"
|
#include "dbShapes2.h"
|
||||||
#include "tlCopyOnWrite.h"
|
#include "tlCopyOnWrite.h"
|
||||||
|
|
@ -42,7 +42,7 @@ typedef generic_shapes_iterator_delegate<db::Polygon> FlatRegionIterator;
|
||||||
* @brief A flat, polygon-set delegate
|
* @brief A flat, polygon-set delegate
|
||||||
*/
|
*/
|
||||||
class DB_PUBLIC FlatRegion
|
class DB_PUBLIC FlatRegion
|
||||||
: public AsIfFlatRegion
|
: public MutableRegion
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef db::Polygon value_type;
|
typedef db::Polygon value_type;
|
||||||
|
|
@ -62,7 +62,7 @@ public:
|
||||||
return new FlatRegion (*this);
|
return new FlatRegion (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reserve (size_t);
|
virtual void reserve (size_t);
|
||||||
|
|
||||||
virtual RegionIteratorDelegate *begin () const;
|
virtual RegionIteratorDelegate *begin () const;
|
||||||
virtual RegionIteratorDelegate *begin_merged () const;
|
virtual RegionIteratorDelegate *begin_merged () const;
|
||||||
|
|
@ -97,51 +97,19 @@ public:
|
||||||
|
|
||||||
virtual const db::RecursiveShapeIterator *iter () const;
|
virtual const db::RecursiveShapeIterator *iter () const;
|
||||||
|
|
||||||
void insert (const db::Box &box);
|
void do_insert (const db::Polygon &polygon);
|
||||||
void insert (const db::Path &path);
|
|
||||||
void insert (const db::SimplePolygon &polygon);
|
|
||||||
void insert (const db::Polygon &polygon);
|
|
||||||
void insert (const db::Shape &shape);
|
|
||||||
|
|
||||||
template <class T>
|
void do_transform (const db::Trans &t)
|
||||||
void insert (const db::Shape &shape, const T &trans)
|
|
||||||
{
|
{
|
||||||
if (shape.is_polygon () || shape.is_path () || shape.is_box ()) {
|
transform_generic (t);
|
||||||
db::Polygon poly;
|
|
||||||
shape.polygon (poly);
|
|
||||||
poly.transform (trans);
|
|
||||||
insert (poly);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Iter>
|
void do_transform (const db::ICplxTrans &t)
|
||||||
void insert (const Iter &b, const Iter &e)
|
|
||||||
{
|
{
|
||||||
reserve (count () + (e - b));
|
transform_generic (t);
|
||||||
for (Iter i = b; i != e; ++i) {
|
|
||||||
insert (*i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Iter>
|
void flatten () { }
|
||||||
void insert_seq (const Iter &seq)
|
|
||||||
{
|
|
||||||
for (Iter i = seq; ! i.at_end (); ++i) {
|
|
||||||
insert (*i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Trans>
|
|
||||||
void transform (const Trans &trans)
|
|
||||||
{
|
|
||||||
if (! trans.is_unity ()) {
|
|
||||||
db::Shapes &polygons = *mp_polygons;
|
|
||||||
for (polygon_iterator_type p = polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().begin (); p != polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().end (); ++p) {
|
|
||||||
polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().replace (p, p->transformed (trans));
|
|
||||||
}
|
|
||||||
invalidate_cache ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
db::Shapes &raw_polygons () { return *mp_polygons; }
|
db::Shapes &raw_polygons () { return *mp_polygons; }
|
||||||
const db::Shapes &raw_polygons () const { return *mp_polygons; }
|
const db::Shapes &raw_polygons () const { return *mp_polygons; }
|
||||||
|
|
@ -166,6 +134,18 @@ private:
|
||||||
|
|
||||||
void init ();
|
void init ();
|
||||||
void ensure_merged_polygons_valid () const;
|
void ensure_merged_polygons_valid () const;
|
||||||
|
|
||||||
|
template <class Trans>
|
||||||
|
void transform_generic (const Trans &trans)
|
||||||
|
{
|
||||||
|
if (! trans.is_unity ()) {
|
||||||
|
db::Shapes &polygons = *mp_polygons;
|
||||||
|
for (polygon_iterator_type p = polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().begin (); p != polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().end (); ++p) {
|
||||||
|
polygons.get_layer<db::Polygon, db::unstable_layer_tag> ().replace (p, p->transformed (trans));
|
||||||
|
}
|
||||||
|
invalidate_cache ();
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
KLayout Layout Viewer
|
||||||
|
Copyright (C) 2006-2021 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 "dbMutableRegion.h"
|
||||||
|
|
||||||
|
namespace db
|
||||||
|
{
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------
|
||||||
|
// FlatRegion implementation
|
||||||
|
|
||||||
|
MutableRegion::MutableRegion ()
|
||||||
|
: AsIfFlatRegion ()
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
|
MutableRegion::MutableRegion (const MutableRegion &other)
|
||||||
|
: AsIfFlatRegion (other)
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
|
MutableRegion::~MutableRegion ()
|
||||||
|
{
|
||||||
|
// .. nothing yet ..
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MutableRegion::insert (const db::Box &box)
|
||||||
|
{
|
||||||
|
if (! box.empty () && box.width () > 0 && box.height () > 0) {
|
||||||
|
do_insert (db::Polygon (box));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MutableRegion::insert (const db::Path &path)
|
||||||
|
{
|
||||||
|
if (path.points () > 0) {
|
||||||
|
do_insert (path.polygon ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MutableRegion::insert (const db::SimplePolygon &polygon)
|
||||||
|
{
|
||||||
|
if (polygon.vertices () > 0) {
|
||||||
|
db::Polygon poly;
|
||||||
|
poly.assign_hull (polygon.begin_hull (), polygon.end_hull ());
|
||||||
|
do_insert (poly);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MutableRegion::insert (const db::Shape &shape)
|
||||||
|
{
|
||||||
|
if (shape.is_polygon () || shape.is_path () || shape.is_box ()) {
|
||||||
|
db::Polygon poly;
|
||||||
|
shape.polygon (poly);
|
||||||
|
insert (poly);
|
||||||
|
} else if (shape.is_path ()) {
|
||||||
|
insert (shape.path ());
|
||||||
|
} else if (shape.is_box ()) {
|
||||||
|
insert (shape.box ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
KLayout Layout Viewer
|
||||||
|
Copyright (C) 2006-2021 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_dbMutableRegion
|
||||||
|
#define HDR_dbMutableRegion
|
||||||
|
|
||||||
|
#include "dbCommon.h"
|
||||||
|
|
||||||
|
#include "dbAsIfFlatRegion.h"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
namespace db {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief An interface representing mutable regions
|
||||||
|
*
|
||||||
|
* Mutable Regions offer insert, transform, flatten and other manipulation functions.
|
||||||
|
*/
|
||||||
|
class DB_PUBLIC MutableRegion
|
||||||
|
: public AsIfFlatRegion
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MutableRegion ();
|
||||||
|
MutableRegion (const MutableRegion &other);
|
||||||
|
virtual ~MutableRegion ();
|
||||||
|
|
||||||
|
virtual void do_insert (const db::Polygon &polygon) = 0;
|
||||||
|
|
||||||
|
void transform (const db::UnitTrans &) { }
|
||||||
|
void transform (const db::Disp &t) { do_transform (db::Trans (t)); }
|
||||||
|
void transform (const db::Trans &t) { do_transform (t); }
|
||||||
|
void transform (const db::ICplxTrans &t) { do_transform (t); }
|
||||||
|
|
||||||
|
virtual void do_transform (const db::Trans &t) = 0;
|
||||||
|
virtual void do_transform (const db::ICplxTrans &t) = 0;
|
||||||
|
|
||||||
|
virtual void flatten () = 0;
|
||||||
|
|
||||||
|
virtual void reserve (size_t n) = 0;
|
||||||
|
|
||||||
|
void insert (const db::Polygon &polygon) { do_insert (polygon); }
|
||||||
|
void insert (const db::Box &box);
|
||||||
|
void insert (const db::Path &path);
|
||||||
|
void insert (const db::SimplePolygon &polygon);
|
||||||
|
|
||||||
|
void insert (const db::Shape &shape);
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void insert (const db::Shape &shape, const T &trans)
|
||||||
|
{
|
||||||
|
if (shape.is_polygon () || shape.is_path () || shape.is_box ()) {
|
||||||
|
db::Polygon poly;
|
||||||
|
shape.polygon (poly);
|
||||||
|
poly.transform (trans);
|
||||||
|
insert (poly);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Iter>
|
||||||
|
void insert (const Iter &b, const Iter &e)
|
||||||
|
{
|
||||||
|
reserve (count () + (e - b));
|
||||||
|
for (Iter i = b; i != e; ++i) {
|
||||||
|
insert (*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Iter>
|
||||||
|
void insert_seq (const Iter &seq)
|
||||||
|
{
|
||||||
|
for (Iter i = seq; ! i.at_end (); ++i) {
|
||||||
|
insert (*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
@ -131,13 +131,13 @@ Region::clear ()
|
||||||
void
|
void
|
||||||
Region::reserve (size_t n)
|
Region::reserve (size_t n)
|
||||||
{
|
{
|
||||||
flat_region ()->reserve (n);
|
mutable_region ()->reserve (n);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Region &Region::transform (const T &trans)
|
Region &Region::transform (const T &trans)
|
||||||
{
|
{
|
||||||
flat_region ()->transform (trans);
|
mutable_region ()->transform (trans);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -149,7 +149,7 @@ template DB_PUBLIC Region &Region::transform (const db::Disp &);
|
||||||
template <class Sh>
|
template <class Sh>
|
||||||
void Region::insert (const Sh &shape)
|
void Region::insert (const Sh &shape)
|
||||||
{
|
{
|
||||||
flat_region ()->insert (shape);
|
mutable_region ()->insert (shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
template DB_PUBLIC void Region::insert (const db::Box &);
|
template DB_PUBLIC void Region::insert (const db::Box &);
|
||||||
|
|
@ -159,31 +159,36 @@ template DB_PUBLIC void Region::insert (const db::Path &);
|
||||||
|
|
||||||
void Region::insert (const db::Shape &shape)
|
void Region::insert (const db::Shape &shape)
|
||||||
{
|
{
|
||||||
flat_region ()->insert (shape);
|
mutable_region ()->insert (shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void Region::insert (const db::Shape &shape, const T &trans)
|
void Region::insert (const db::Shape &shape, const T &trans)
|
||||||
{
|
{
|
||||||
flat_region ()->insert (shape, trans);
|
mutable_region ()->insert (shape, trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
template DB_PUBLIC void Region::insert (const db::Shape &, const db::ICplxTrans &);
|
template DB_PUBLIC void Region::insert (const db::Shape &, const db::ICplxTrans &);
|
||||||
template DB_PUBLIC void Region::insert (const db::Shape &, const db::Trans &);
|
template DB_PUBLIC void Region::insert (const db::Shape &, const db::Trans &);
|
||||||
template DB_PUBLIC void Region::insert (const db::Shape &, const db::Disp &);
|
template DB_PUBLIC void Region::insert (const db::Shape &, const db::Disp &);
|
||||||
|
|
||||||
FlatRegion *
|
MutableRegion *
|
||||||
Region::flat_region ()
|
Region::mutable_region ()
|
||||||
{
|
{
|
||||||
FlatRegion *region = dynamic_cast<FlatRegion *> (mp_delegate);
|
MutableRegion *region = dynamic_cast<MutableRegion *> (mp_delegate);
|
||||||
if (! region) {
|
if (! region) {
|
||||||
region = new FlatRegion ();
|
|
||||||
|
FlatRegion *flat_region = new FlatRegion ();
|
||||||
|
region = flat_region;
|
||||||
|
|
||||||
if (mp_delegate) {
|
if (mp_delegate) {
|
||||||
region->RegionDelegate::operator= (*mp_delegate); // copy basic flags
|
flat_region->RegionDelegate::operator= (*mp_delegate); // copy basic flags
|
||||||
region->insert_seq (begin ());
|
flat_region->insert_seq (begin ());
|
||||||
region->set_is_merged (mp_delegate->is_merged ());
|
flat_region->set_is_merged (mp_delegate->is_merged ());
|
||||||
}
|
}
|
||||||
set_delegate (region);
|
|
||||||
|
set_delegate (flat_region);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return region;
|
return region;
|
||||||
|
|
@ -274,6 +279,13 @@ Region::smoothed (coord_type d, bool keep_hv) const
|
||||||
return processed (SmoothingProcessor (d, keep_hv));
|
return processed (SmoothingProcessor (d, keep_hv));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db::Region &
|
||||||
|
Region::flatten ()
|
||||||
|
{
|
||||||
|
mutable_region ()->flatten ();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Region::snap (db::Coord gx, db::Coord gy)
|
Region::snap (db::Coord gx, db::Coord gy)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
namespace db {
|
namespace db {
|
||||||
|
|
||||||
class EdgeFilterBase;
|
class EdgeFilterBase;
|
||||||
class FlatRegion;
|
class MutableRegion;
|
||||||
class EmptyRegion;
|
class EmptyRegion;
|
||||||
class DeepShapeStore;
|
class DeepShapeStore;
|
||||||
class TransformationReducer;
|
class TransformationReducer;
|
||||||
|
|
@ -1644,11 +1644,7 @@ public:
|
||||||
*
|
*
|
||||||
* This method will turn any region into a flat shape collection.
|
* This method will turn any region into a flat shape collection.
|
||||||
*/
|
*/
|
||||||
db::Region &flatten ()
|
db::Region &flatten ();
|
||||||
{
|
|
||||||
flat_region ();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns true, if the region has valid polygons stored within itself
|
* @brief Returns true, if the region has valid polygons stored within itself
|
||||||
|
|
@ -1776,7 +1772,7 @@ private:
|
||||||
RegionDelegate *mp_delegate;
|
RegionDelegate *mp_delegate;
|
||||||
|
|
||||||
void set_delegate (RegionDelegate *delegate, bool keep_attributes = true);
|
void set_delegate (RegionDelegate *delegate, bool keep_attributes = true);
|
||||||
FlatRegion *flat_region ();
|
db::MutableRegion *mutable_region();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue