diff --git a/src/plugins/tools/view_25d/lay_plugin/layD25View.cc b/src/plugins/tools/view_25d/lay_plugin/layD25View.cc index 158e19f3f..f10ae46ac 100644 --- a/src/plugins/tools/view_25d/lay_plugin/layD25View.cc +++ b/src/plugins/tools/view_25d/lay_plugin/layD25View.cc @@ -89,7 +89,16 @@ int D25View::exec_dialog (lay::LayoutView *view) { mp_view.reset (view); - mp_ui->d25_view->attach_view (view); + bool any = mp_ui->d25_view->attach_view (view); + + if (! any) { + + mp_view.reset (0); + mp_ui->d25_view->attach_view (0); + + throw tl::Exception (tl::to_string (tr ("No z data configured for the layers in the view.\nUse \"Tools/Manage Technologies\" to set up a z stack."))); + + } mp_ui->d25_view->reset (); mp_ui->d25_view->set_cam_azimuth (0.0); @@ -98,6 +107,7 @@ D25View::exec_dialog (lay::LayoutView *view) int ret = QDialog::exec (); mp_ui->d25_view->attach_view (0); + mp_view.reset (0); return ret; } diff --git a/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc b/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc index 48ca09105..52fbd46ca 100644 --- a/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc +++ b/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc @@ -26,6 +26,7 @@ #include "layLayoutView.h" #include "dbRecursiveShapeIterator.h" +#include "dbD25TechnologyComponent.h" #include "dbEdgeProcessor.h" #include "dbPolygonGenerators.h" #include "dbPolygonTools.h" @@ -412,20 +413,88 @@ D25ViewWidget::aspect_ratio () const return double (width ()) / double (height ()); } -void +bool D25ViewWidget::attach_view (LayoutView *view) { + bool any = false; + if (mp_view != view) { mp_view = view; - prepare_view (); + any = prepare_view (); reset (); } + + return any; } -void +namespace { + + class ZDataCache + { + public: + ZDataCache () { } + + const db::D25LayerInfo *operator() (lay::LayoutView *view, int cv_index, int layer_index) + { + std::map >::const_iterator c = m_cache.find (cv_index); + if (c != m_cache.end ()) { + std::map::const_iterator l = c->second.find (layer_index); + if (l != c->second.end ()) { + return l->second; + } else { + return 0; + } + } + + std::map &lcache = m_cache [cv_index]; + + const db::D25TechnologyComponent *comp = 0; + + const lay::CellView &cv = view->cellview (cv_index); + if (cv.is_valid () && cv->technology ()) { + const db::Technology *tech = cv->technology (); + comp = dynamic_cast (tech->component_by_name ("d25")); + } + + if (comp) { + + std::map zi_by_lp; + for (db::D25TechnologyComponent::const_iterator i = comp->begin (); i != comp->end (); ++i) { + zi_by_lp.insert (std::make_pair (i->layer (), i.operator-> ())); + } + + const db::Layout &ly = cv->layout (); + for (int l = 0; l < int (ly.layers ()); ++l) { + if (ly.is_valid_layer (l)) { + const db::LayerProperties &lp = ly.get_properties (l); + std::map::const_iterator z = zi_by_lp.find (lp); + if (z == zi_by_lp.end () && ! lp.name.empty ()) { + // If possible, try by name only + z = zi_by_lp.find (db::LayerProperties (lp.name)); + } + if (z != zi_by_lp.end ()) { + lcache[l] = z->second; + } + } + } + + } + + return operator() (view, cv_index, layer_index); + + } + + + private: + std::map > m_cache; + }; + +} + +bool D25ViewWidget::prepare_view () { m_layers.clear (); @@ -437,14 +506,25 @@ D25ViewWidget::prepare_view () if (! mp_view) { m_bbox = db::DBox (-1.0, -1.0, 1.0, 1.0); - return; + return false; } - double z = 0.0, dz = 0.2; // @@@ + ZDataCache zdata; + bool any = false; for (lay::LayerPropertiesConstIterator lp = mp_view->begin_layers (); ! lp.at_end (); ++lp) { - if (! lp->has_children () && lp->visible (true) && lp->cellview_index () >= 0 && lp->cellview_index () < int (mp_view->cellviews ())) { + const db::D25LayerInfo *zi = 0; + if (! lp->has_children () && lp->visible (true)) { + zi = zdata (mp_view, lp->cellview_index (), lp->layer_index ()); + } + + if (zi) { + + any = true; + + double z0 = zi->zstart (); + double z1 = zi->zstop (); lay::color_t color = lp->fill_color (true); @@ -459,24 +539,24 @@ 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 (), z, z + dz); + 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 (); if (! zset) { - m_zmin = z; - m_zmax = z + dz; + m_zmin = z0; + m_zmax = z1; zset = true; } else { - m_zmin = std::min (z, m_zmin); - m_zmax = std::max (z + dz, m_zmax); + m_zmin = std::min (z0, m_zmin); + m_zmax = std::max (z1, m_zmax); } - z += dz; // @@@ - } } + + return any; } void diff --git a/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.h b/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.h index ea6d5c790..e23b068a5 100644 --- a/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.h +++ b/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.h @@ -82,7 +82,7 @@ public: void mouseReleaseEvent (QMouseEvent *event); void mouseMoveEvent (QMouseEvent *event); - void attach_view (lay::LayoutView *view); + bool attach_view(lay::LayoutView *view); QVector3D hit_point_with_scene(const QVector3D &line_dir); void refresh (); @@ -138,7 +138,7 @@ private: void paintGL (); void resizeGL (int w, int h); - void prepare_view (); + 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_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); diff --git a/src/plugins/tools/view_25d/unit_tests/layD25ViewUtilsTests.cc b/src/plugins/tools/view_25d/unit_tests/layD25ViewUtilsTests.cc index b24265b22..4e428c818 100644 --- a/src/plugins/tools/view_25d/unit_tests/layD25ViewUtilsTests.cc +++ b/src/plugins/tools/view_25d/unit_tests/layD25ViewUtilsTests.cc @@ -92,7 +92,8 @@ TEST(3_HitWithCuboid) EXPECT_EQ (v2s (r.second), "1,1,4"); r = lay::hit_point_with_cuboid (QVector3D (1, 1, 6), QVector3D (0, 0, 1), QVector3D (-1, -1, 3), QVector3D (2, 2, 2)); - EXPECT_EQ (r.first, false); + EXPECT_EQ (r.first, true); + EXPECT_EQ (v2s (r.second), "1,1,3"); r = lay::hit_point_with_cuboid (QVector3D (5, -6, 0), QVector3D (0, 0, 1), QVector3D (-1, -1, 3), QVector3D (2, 2, 2)); EXPECT_EQ (r.first, true); @@ -100,10 +101,19 @@ TEST(3_HitWithCuboid) r = lay::hit_point_with_cuboid (QVector3D (5, -6, 4), QVector3D (0, 0, 1), QVector3D (-1, -1, 3), QVector3D (2, 2, 2)); EXPECT_EQ (r.first, true); - EXPECT_EQ (v2s (r.second), "5,-6,5"); + EXPECT_EQ (v2s (r.second), "5,-6,3"); r = lay::hit_point_with_cuboid (QVector3D (5, -6, 6), QVector3D (0, 0, 1), QVector3D (-1, -1, 3), QVector3D (2, 2, 2)); - EXPECT_EQ (r.first, false); + EXPECT_EQ (r.first, true); + EXPECT_EQ (v2s (r.second), "5,-6,3"); + + r = lay::hit_point_with_cuboid (QVector3D (5, 0, 0), QVector3D (-1, 0, 0), QVector3D (-1, -1, 3), QVector3D (2, 2, 2)); + EXPECT_EQ (r.first, true); + EXPECT_EQ (v2s (r.second), "1,0,0"); + + r = lay::hit_point_with_cuboid (QVector3D (-5, 0, 0), QVector3D (1, 0, 0), QVector3D (-1, -1, 3), QVector3D (2, 2, 2)); + EXPECT_EQ (r.first, true); + EXPECT_EQ (v2s (r.second), "-1,0,0"); } TEST(4_CameraNormal)