Merge branch 'clipped-25d-view'

This commit is contained in:
Matthias Koefferlein 2021-06-20 21:02:40 +02:00
commit 2bbf6b6998
6 changed files with 229 additions and 172 deletions

View File

@ -1595,6 +1595,14 @@ EdgeProcessor::process (db::EdgeSink &es, EdgeEvaluatorBase &op)
process (procs);
}
void
EdgeProcessor::redo (db::EdgeSink &es, EdgeEvaluatorBase &op)
{
std::vector<std::pair<db::EdgeSink *, db::EdgeEvaluatorBase *> > procs;
procs.push_back (std::make_pair (&es, &op));
redo (procs);
}
namespace
{
@ -2137,8 +2145,20 @@ private:
}
void
EdgeProcessor::redo (const std::vector<std::pair<db::EdgeSink *, db::EdgeEvaluatorBase *> > &gen)
{
redo_or_process (gen, true);
}
void
EdgeProcessor::process (const std::vector<std::pair<db::EdgeSink *, db::EdgeEvaluatorBase *> > &gen)
{
redo_or_process (gen, false);
}
void
EdgeProcessor::redo_or_process (const std::vector<std::pair<db::EdgeSink *, db::EdgeEvaluatorBase *> > &gen, bool redo)
{
tl::SelfTimer timer (tl::verbosity () >= m_base_verbosity, "EdgeProcessor: process");
@ -2160,6 +2180,8 @@ EdgeProcessor::process (const std::vector<std::pair<db::EdgeSink *, db::EdgeEval
mp_cpvector->clear ();
// count the properties
property_type n_props = 0;
for (std::vector <WorkEdge>::iterator e = mp_work_edges->begin (); e != mp_work_edges->end (); ++e) {
if (e->prop > n_props) {
@ -2168,6 +2190,8 @@ EdgeProcessor::process (const std::vector<std::pair<db::EdgeSink *, db::EdgeEval
}
++n_props;
// prepare progress
size_t todo_max = 1000000;
std::unique_ptr<tl::AbsoluteProgress> progress;
@ -2186,6 +2210,19 @@ EdgeProcessor::process (const std::vector<std::pair<db::EdgeSink *, db::EdgeEval
todo_next += (todo_max - todo) / 5;
if (redo) {
// redo mode: skip the intersection detection step and clear the data
for (std::vector <WorkEdge>::iterator c = mp_work_edges->begin (); c != mp_work_edges->end (); ++c) {
c->data = 0;
}
todo = todo_next;
todo_next += (todo_max - todo) / 5;
} else {
// step 2: find intersections
std::sort (mp_work_edges->begin (), mp_work_edges->end (), edge_ymin_compare<db::Coord> ());
@ -2356,6 +2393,8 @@ EdgeProcessor::process (const std::vector<std::pair<db::EdgeSink *, db::EdgeEval
}
#endif
}
tl::SelfTimer timer2 (tl::verbosity () >= m_base_verbosity + 10, "EdgeProcessor: production");
@ -2579,7 +2618,7 @@ EdgeProcessor::process (const std::vector<std::pair<db::EdgeSink *, db::EdgeEval
if (ymax >= y) {
--current;
if (current != c) {
*current = *c;
std::swap (*current, *c);
}
}
if (ymax <= y) {

View File

@ -672,7 +672,7 @@ public:
}
/**
* @brief Clear all edges stored currently in this processor
* @brief Clears all edges stored currently in this processor
*/
void clear ();
@ -693,6 +693,24 @@ public:
*/
void process (const std::vector<std::pair<db::EdgeSink *, db::EdgeEvaluatorBase *> > &gen);
/**
* @brief Performs the actual processing again
*
* This method can be called after "process" was used and will re-run the
* scanline algorithm. This is somewhat more efficient as the initial
* sorting and edge clipping can be skipped.
*/
void redo (db::EdgeSink &es, EdgeEvaluatorBase &op);
/**
* @brief Performs the actual processing again
*
* This method can be called after "process" was used and will re-run the
* scanline algorithm. This is somewhat more efficient as the initial
* sorting and edge clipping can be skipped.
*/
void redo (const std::vector<std::pair<db::EdgeSink *, db::EdgeEvaluatorBase *> > &gen);
/**
* @brief Merge the given polygons in a simple "non-zero wrapcount" fashion
*
@ -996,6 +1014,8 @@ private:
}
return n;
}
void redo_or_process (const std::vector<std::pair<db::EdgeSink *, db::EdgeEvaluatorBase *> > &gen, bool redo);
};
}

View File

@ -2629,6 +2629,26 @@ TEST(103)
// elaborate hole treatment
EXPECT_EQ (out[0].to_string (), "(0,0;0,400;100,400;100,100;400,100;400,400;0,400;0,500;1500,500;1500,0;1000,0;1000,400;1100,400;1100,100;1400,100;1400,400;500,400;500,0)");
#endif
// test "redo" on this occasion
// @@@
db::PolygonContainer pc2 (out);
db::PolygonGenerator pg2 (pc2, true, true);
db::BooleanOp op2 (db::BooleanOp::ANotB);
out.clear ();
ep.redo (pg2, op2);
// @@@
EXPECT_EQ (out.size (), size_t (1));
#if 1
// fast hole treatment
EXPECT_EQ (out[0].to_string (), "(0,0;0,400;100,400;100,100;400,100;400,400;1100,400;1100,100;1400,100;1400,400;0,400;0,500;1500,500;1500,0;1000,0;1000,400;500,400;500,0)");
#else
// elaborate hole treatment
EXPECT_EQ (out[0].to_string (), "(0,0;0,400;100,400;100,100;400,100;400,400;0,400;0,500;1500,500;1500,0;1000,0;1000,400;1100,400;1100,100;1400,100;1400,400;500,400;500,0)");
#endif
}
// Bug 134

View File

@ -51,13 +51,7 @@ public:
void menu_activated (const std::string &symbol)
{
if (symbol == "lay::d25_view") {
if (mp_dialog->exec_dialog (mp_view)) {
// ... implementation is in layD25ToolDialog.cc ...
}
mp_dialog->exec_dialog (mp_view);
}
}

View File

@ -30,6 +30,7 @@
#include "dbEdgeProcessor.h"
#include "dbPolygonGenerators.h"
#include "dbPolygonTools.h"
#include "dbClip.h"
#include "tlException.h"
@ -538,7 +539,6 @@ D25ViewWidget::prepare_view ()
m_layers.clear ();
m_vertex_chunks.clear ();
m_bbox = db::DBox ();
bool zset = false;
m_zmin = m_zmax = 0.0;
@ -547,6 +547,8 @@ D25ViewWidget::prepare_view ()
return false;
}
m_bbox = mp_view->viewport ().box ();
ZDataCache zdata;
bool any = false;
@ -577,9 +579,7 @@ D25ViewWidget::prepare_view ()
m_layers.push_back (info);
const lay::CellView &cv = mp_view->cellview ((unsigned int) lp->cellview_index ());
render_layout (m_vertex_chunks.back (), cv->layout (), *cv.cell (), (unsigned int) lp->layer_index (), z0, z1);
m_bbox += db::DBox (cv.cell ()->bbox ((unsigned int) lp->layer_index ())) * cv->layout ().dbu ();
render_layout (m_vertex_chunks.back (), cv->layout (), *cv.cell (), db::CplxTrans (cv->layout ().dbu ()).inverted () * m_bbox, (unsigned int) lp->layer_index (), z0, z1);
if (! zset) {
m_zmin = z0;
@ -600,7 +600,22 @@ D25ViewWidget::prepare_view ()
void
D25ViewWidget::render_polygon (D25ViewWidget::chunks_type &chunks, const db::Polygon &poly, double dbu, double zstart, double zstop)
{
if (poly.hull ().size () > 4) {
if (poly.holes () > 0) {
std::vector<db::Polygon> poly_heap;
db::EdgeProcessor ep;
ep.insert_sequence (poly.begin_edge ());
db::PolygonContainer pc (poly_heap);
db::PolygonGenerator out (pc, true /*resolve holes*/, true /*min coherence*/);
db::SimpleMerge op;
ep.process (out, op);
for (std::vector<db::Polygon>::const_iterator p = poly_heap.begin (); p != poly_heap.end (); ++p) {
render_polygon (chunks, *p, dbu, zstart, zstop);
}
} else if (poly.hull ().size () > 4) {
std::vector<db::Polygon> poly_heap;
@ -654,13 +669,13 @@ D25ViewWidget::render_wall (D25ViewWidget::chunks_type &chunks, const db::Edge &
}
void
D25ViewWidget::render_layout (D25ViewWidget::chunks_type &chunks, const db::Layout &layout, const db::Cell &cell, unsigned int layer, double zstart, double zstop)
D25ViewWidget::render_layout (D25ViewWidget::chunks_type &chunks, const db::Layout &layout, const db::Cell &cell, const db::Box &clip_box, unsigned int layer, double zstart, double zstop)
{
db::EdgeProcessor ep;
std::vector<db::Polygon> poly_heap;
// TODO: hidden cells, hierarchy depth ...
db::RecursiveShapeIterator s (layout, cell, layer);
db::RecursiveShapeIterator s (layout, cell, layer, clip_box);
s.shape_flags (db::ShapeIterator::Polygons | db::ShapeIterator::Paths | db::ShapeIterator::Boxes);
for ( ; ! s.at_end (); ++s) {
@ -668,47 +683,16 @@ D25ViewWidget::render_layout (D25ViewWidget::chunks_type &chunks, const db::Layo
s->polygon (polygon);
polygon.transform (s.trans ());
if (polygon.holes () == 0 && polygon.hull ().size () <= 4) {
render_polygon (chunks, polygon, layout.dbu (), zstart, zstop);
for (db::Polygon::polygon_edge_iterator e = polygon.begin_edge (); ! e.at_end (); ++e) {
render_wall (chunks, *e, layout.dbu (), zstart, zstop);
}
} else {
poly_heap.clear ();
ep.clear ();
ep.insert_sequence (polygon.begin_edge ());
{
db::PolygonContainer pc (poly_heap);
db::PolygonGenerator out (pc, true /*resolve holes*/, false /*min coherence for splitting*/);
db::SimpleMerge op;
ep.process (out, op);
}
db::clip_poly (polygon, clip_box, poly_heap, false /*keep holes*/);
for (std::vector<db::Polygon>::const_iterator p = poly_heap.begin (); p != poly_heap.end (); ++p) {
render_polygon (chunks, *p, layout.dbu (), zstart, zstop);
}
poly_heap.clear ();
ep.clear ();
ep.insert_sequence (polygon.begin_edge ());
{
db::PolygonContainer pc (poly_heap);
db::PolygonGenerator out (pc, false /*don't resolve holes*/, false /*min coherence for splitting*/);
db::SimpleMerge op;
ep.process (out, op);
}
for (std::vector<db::Polygon>::const_iterator p = poly_heap.begin (); p != poly_heap.end (); ++p) {
for (db::Polygon::polygon_edge_iterator e = p->begin_edge (); ! e.at_end (); ++e) {
render_wall (chunks, *e, layout.dbu (), zstart, zstop);
}
}
}

View File

@ -149,7 +149,7 @@ private:
void do_initialize_gl ();
bool prepare_view();
void render_layout (D25ViewWidget::chunks_type &chunks, const db::Layout &layout, const db::Cell &cell, unsigned int layer, double zstart, double zstop);
void render_layout (D25ViewWidget::chunks_type &chunks, const db::Layout &layout, const db::Cell &cell, const db::Box &clip_box, unsigned int layer, double zstart, double zstop);
void render_polygon (D25ViewWidget::chunks_type &chunks, const db::Polygon &poly, double dbu, double zstart, double zstop);
void render_wall (D25ViewWidget::chunks_type &chunks, const db::Edge &poly, double dbu, double zstart, double zstop);
};