From 64406522fe27474458acd52025c32055eb39e6cc Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 5 Mar 2022 19:42:57 +0100 Subject: [PATCH] WIP: basic debugging, functionality. --- src/drc/drc/built-in-macros/_drc_engine.rb | 48 ++++ src/laybasic/laybasic/layParsedLayerSource.h | 2 +- .../tools/view_25d/lay_plugin/D25View.ui | 39 +++- .../lay_plugin/built-in-macros/_d25_engine.rb | 126 ++++++----- .../built-in-macros/d25_interpreters.lym | 2 + .../view_25d/lay_plugin/gsiDeclLayD25View.cc | 85 ++++++++ .../tools/view_25d/lay_plugin/layD25View.cc | 100 +++++++-- .../tools/view_25d/lay_plugin/layD25View.h | 15 ++ .../view_25d/lay_plugin/layD25ViewWidget.cc | 205 +++++++++++++++--- .../view_25d/lay_plugin/layD25ViewWidget.h | 48 ++-- .../tools/view_25d/lay_plugin/lay_plugin.pro | 1 + 11 files changed, 543 insertions(+), 128 deletions(-) create mode 100644 src/plugins/tools/view_25d/lay_plugin/gsiDeclLayD25View.cc diff --git a/src/drc/drc/built-in-macros/_drc_engine.rb b/src/drc/drc/built-in-macros/_drc_engine.rb index 3600355ca..9bf0556a0 100644 --- a/src/drc/drc/built-in-macros/_drc_engine.rb +++ b/src/drc/drc/built-in-macros/_drc_engine.rb @@ -1626,6 +1626,54 @@ CODE nil end + # %DRC% + # @name region_touch + # @brief Specifies region selected input in "touch mode" + # @synopsis region_touch(args) + # See \Source#touching for a description of that function. + # + # The following code will select shapes touching a 500x600 micron rectangle (lower left corner at 0,0) + # from the input layout. The shapes will not be clipped: + # + # @code + # region_touch(0.mm, 0.mm, 0.5.mm, 0.6.mm) + # # shapes will now be the ones touching the rectangular region + # l1 = input(1, 0) + # @/code + # + # To remove this condition, call "region_touch" without any arguments. + + def region_touch(*args) + self._context("region_touch") do + @def_source = layout.touching(*args) + end + nil + end + + # %DRC% + # @name region_overlap + # @brief Specifies region selected input in "overlap mode" + # @synopsis region_overlap(args) + # See \Source#overlapping for a description of that function. + # + # The following code will select shapes overlapping a 500x600 micron rectangle (lower left corner at 0,0) + # from the input layout. The shapes will not be clipped: + # + # @code + # region_overlapping(0.mm, 0.mm, 0.5.mm, 0.6.mm) + # # shapes will now be the ones overlapping the rectangular region + # l1 = input(1, 0) + # @/code + # + # To remove this condition, call "region_overlapping" without any arguments. + + def region_overlap(*args) + self._context("region_overlap") do + @def_source = layout.overlapping(*args) + end + nil + end + # %DRC% # @name global_transform # @brief Gets or sets a global transformation diff --git a/src/laybasic/laybasic/layParsedLayerSource.h b/src/laybasic/laybasic/layParsedLayerSource.h index 7bc862d42..e3bbfa511 100644 --- a/src/laybasic/laybasic/layParsedLayerSource.h +++ b/src/laybasic/laybasic/layParsedLayerSource.h @@ -35,8 +35,8 @@ namespace db { - struct LayerProperties; class Layout; + struct LayerProperties; } namespace lay diff --git a/src/plugins/tools/view_25d/lay_plugin/D25View.ui b/src/plugins/tools/view_25d/lay_plugin/D25View.ui index 75301397d..056823f0c 100644 --- a/src/plugins/tools/view_25d/lay_plugin/D25View.ui +++ b/src/plugins/tools/view_25d/lay_plugin/D25View.ui @@ -358,7 +358,44 @@ 0 - + + + QFrame::NoFrame + + + QFrame::Plain + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + + + 1 + 0 + + + + + + + + diff --git a/src/plugins/tools/view_25d/lay_plugin/built-in-macros/_d25_engine.rb b/src/plugins/tools/view_25d/lay_plugin/built-in-macros/_d25_engine.rb index 591ea4085..5af1d8468 100644 --- a/src/plugins/tools/view_25d/lay_plugin/built-in-macros/_d25_engine.rb +++ b/src/plugins/tools/view_25d/lay_plugin/built-in-macros/_d25_engine.rb @@ -42,9 +42,11 @@ module D25 @zstack = [] # clip to layout view - if RBA::LayoutView::current - self.clip(RBA::LayoutView::current.box) - end + if ! RBA::LayoutView::current + raise "No layout loaded for running 2.5d view on" + end + + self.region_overlap(RBA::LayoutView::current.box) end @@ -126,7 +128,7 @@ module D25 raise("No layer specified") end - info = D25ZInfo::new(layer.data, zstart, zstop, @display || D25Display::new) + info = D25ZInfo::new(layer, zstart, zstop, @display || D25Display::new) @zstack << info return info @@ -137,78 +139,91 @@ module D25 def display(*args, &block) - display = D25Display::new + begin - args.each do |a| + display = D25Display::new + @display = display - if a.is_a?(D25ZInfo) + args.each do |a| - @zstack.each do |z| - if z == a - z.display = display + if a.is_a?(D25ZInfo) + + @zstack.each do |z| + if z == a + z.display = display + end end - end - elsif a.is_a?(Hash) + elsif a.is_a?(Hash) - hollow_fill = 0xffffffff + hollow_fill = 0xffffffff - if a[:color] - if !a[:color].is_a?(0xffffff.class) - raise("'color' must be a color value (an integer)") + if a[:color] + if !a[:color].is_a?(0xffffff.class) + raise("'color' must be a color value (an integer)") + end + display.fill = a[:color] + display.frame = a[:color] end - display.fill = a[:color] - display.frame = a[:color] - end - if a[:frame] - if !a[:frame].is_a?(0xffffff.class) - raise("'frame' must be a color value (an integer)") + if a[:frame] + if !a[:frame].is_a?(0xffffff.class) + raise("'frame' must be a color value (an integer)") + end + display.frame = a[:frame] end - display.frame = a[:frame] - end - if a[:fill] - if !a[:fill].is_a?(0xffffff.class) - raise("'fill' must be a color value (an integer)") + if a[:fill] + if !a[:fill].is_a?(0xffffff.class) + raise("'fill' must be a color value (an integer)") + end + display.fill = a[:fill] end - display.fill = a[:fill] - end - if a[:hollow] if a[:hollow] - display.fill = hollow_fill + if a[:hollow] + display.fill = hollow_fill + end end - end - if a[:like] - li = nil - if a[:like].is_a?(String) - li = RBA::LayerInfo::from_string(a[:like]) - elsif a[:like].is_a?(RBA::LayerInfo) - li = a[:like] - else - raise("'like' must be a string or LayerInfo object") + if a[:like] + li = nil + if a[:like].is_a?(String) + li = RBA::LayerInfo::from_string(a[:like]) + elsif a[:like].is_a?(RBA::LayerInfo) + li = a[:like] + else + raise("'like' must be a string or LayerInfo object") + end + display.like = li end - display.like = li - end - invalid_keys = a.keys.select { |k| ![ :fill, :frame, :color, :hollow, :like ].member?(k) } - if invalid_keys.size > 0 - raise("Keyword argument(s) not understood: #{invalid_keys.collect(&:to_s).join(',')}") - end + invalid_keys = a.keys.select { |k| ![ :fill, :frame, :color, :hollow, :like ].member?(k) } + if invalid_keys.size > 0 + raise("Keyword argument(s) not understood: #{invalid_keys.collect(&:to_s).join(',')}") + end - else - raise("Argument not understood: #{a.inspect}") + else + raise("Argument not understood: #{a.inspect}") + end + end - + + yield + + ensure + @display = nil + end + + end + + def _check + + if @zstack.empty? + raise("No z calls made in 2.5d script") end end def _finish(final = true) - if final && @zstack.empty? - raise("No z calls made in 2.5d script") - end - super(final) if final @@ -217,6 +232,8 @@ module D25 begin + view.clear + displays = {} @zstack.each do |z| @@ -227,7 +244,7 @@ module D25 display = zz[0].display view.open_display(display.frame, display.fill, display.like) zz.each do |z| - view.entry(z.layer, z.start, z.zstop) + view.entry(z.layer.data, self.dbu, z.zstart, z.zstop) end view.close_display end @@ -235,6 +252,7 @@ module D25 view.finish rescue => ex + view.clear view.close raise ex end diff --git a/src/plugins/tools/view_25d/lay_plugin/built-in-macros/d25_interpreters.lym b/src/plugins/tools/view_25d/lay_plugin/built-in-macros/d25_interpreters.lym index e85d1a45f..368ad0080 100644 --- a/src/plugins/tools/view_25d/lay_plugin/built-in-macros/d25_interpreters.lym +++ b/src/plugins/tools/view_25d/lay_plugin/built-in-macros/d25_interpreters.lym @@ -50,6 +50,8 @@ module D25 end + @d25._check + nil end diff --git a/src/plugins/tools/view_25d/lay_plugin/gsiDeclLayD25View.cc b/src/plugins/tools/view_25d/lay_plugin/gsiDeclLayD25View.cc new file mode 100644 index 000000000..8a728555b --- /dev/null +++ b/src/plugins/tools/view_25d/lay_plugin/gsiDeclLayD25View.cc @@ -0,0 +1,85 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2022 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 "gsiDecl.h" +#include "gsiDeclBasic.h" + +#include "layD25View.h" +#include "layLayoutView.h" + +#include "dbLayerProperties.h" +#include "dbRegion.h" + +#include + +#if defined(HAVE_QTBINDINGS) + +# include "gsiQtGuiExternals.h" +# include "gsiQtWidgetsExternals.h" + +FORCE_LINK_GSI_QTGUI +FORCE_LINK_GSI_QTWIDGETS // for Qt5 + +#else +# define QT_EXTERNAL_BASE(x) +#endif + +namespace gsi +{ + +static lay::D25View *open_d25_view (lay::LayoutView *view) +{ + return lay::D25View::open (view); +} + +ClassExt decl_LayoutViewExt ( + gsi::method_ext ("open_d25_view", &open_d25_view, + "@brief Opens the 2.5d view window and returns a reference to the D25View object.\n" + "This method has been introduced in version 0.28.\n" + ) +); + +Class decl_D25View (QT_EXTERNAL_BASE (QDialog) "lay", "D25View", + gsi::method ("clear", &lay::D25View::clear, + "@brief Clears all display entries in the view" + ) + + gsi::method ("open_display", &lay::D25View::open_display, gsi::arg ("frame_color"), gsi::arg ("fill_color"), gsi::arg ("like"), + "@brief Creates a new display group" + ) + + gsi::method ("entry", &lay::D25View::entry, gsi::arg ("data"), gsi::arg ("dbu"), gsi::arg ("zstart"), gsi::arg ("zstop"), + "@brief Creates a new display entry in the group opened with \\open_display" + ) + + gsi::method ("close_display", &lay::D25View::close_display, + "@brief Finishes the display group" + ) + + gsi::method ("finish", &lay::D25View::finish, + "@brief Finishes the view - call this after the display groups have been created" + ) + + gsi::method ("close", &lay::D25View::close, + "@brief Closes the view" + ), + "@brief The 2.5d View Dialog\n" + "\n" + "This class is used internally to implement the 2.5d feature.\n" +); + +} diff --git a/src/plugins/tools/view_25d/lay_plugin/layD25View.cc b/src/plugins/tools/view_25d/lay_plugin/layD25View.cc index af10a8621..37aba4a81 100644 --- a/src/plugins/tools/view_25d/lay_plugin/layD25View.cc +++ b/src/plugins/tools/view_25d/lay_plugin/layD25View.cc @@ -43,19 +43,19 @@ D25View::D25View (lay::Dispatcher *root, lay::LayoutView *view) mp_ui->d25_view->setFocusPolicy (Qt::StrongFocus); mp_ui->d25_view->setFocus (); - connect (mp_ui->fit_back, SIGNAL (clicked ()), this, SLOT (fit_button_clicked ())); - connect (mp_ui->fit_front, SIGNAL (clicked ()), this, SLOT (fit_button_clicked ())); - connect (mp_ui->fit_left, SIGNAL (clicked ()), this, SLOT (fit_button_clicked ())); - connect (mp_ui->fit_right, SIGNAL (clicked ()), this, SLOT (fit_button_clicked ())); - connect (mp_ui->fit_top, SIGNAL (clicked ()), this, SLOT (fit_button_clicked ())); - connect (mp_ui->fit_bottom, SIGNAL (clicked ()), this, SLOT (fit_button_clicked ())); - connect (mp_ui->zoom_slider, SIGNAL (valueChanged (int)), this, SLOT (scale_slider_changed (int))); - connect (mp_ui->vzoom_slider, SIGNAL (valueChanged (int)), this, SLOT (vscale_slider_changed (int))); - connect (mp_ui->zoom_factor, SIGNAL (editingFinished ()), this, SLOT (scale_value_edited ())); - connect (mp_ui->vzoom_factor, SIGNAL (editingFinished ()), this, SLOT (vscale_value_edited ())); - connect (mp_ui->d25_view, SIGNAL (scale_factor_changed (double)), this, SLOT (scale_factor_changed (double))); - connect (mp_ui->d25_view, SIGNAL (vscale_factor_changed (double)), this, SLOT (vscale_factor_changed (double))); - connect (mp_ui->d25_view, SIGNAL (init_failed ()), this, SLOT (init_failed ())); + connect (mp_ui->fit_back, SIGNAL (clicked()), this, SLOT (fit_button_clicked())); + connect (mp_ui->fit_front, SIGNAL (clicked()), this, SLOT (fit_button_clicked())); + connect (mp_ui->fit_left, SIGNAL (clicked()), this, SLOT (fit_button_clicked())); + connect (mp_ui->fit_right, SIGNAL (clicked()), this, SLOT (fit_button_clicked())); + connect (mp_ui->fit_top, SIGNAL (clicked()), this, SLOT (fit_button_clicked())); + connect (mp_ui->fit_bottom, SIGNAL (clicked()), this, SLOT (fit_button_clicked())); + connect (mp_ui->zoom_slider, SIGNAL (valueChanged(int)), this, SLOT (scale_slider_changed(int))); + connect (mp_ui->vzoom_slider, SIGNAL (valueChanged(int)), this, SLOT (vscale_slider_changed(int))); + connect (mp_ui->zoom_factor, SIGNAL (editingFinished()), this, SLOT (scale_value_edited())); + connect (mp_ui->vzoom_factor, SIGNAL (editingFinished()), this, SLOT (vscale_value_edited())); + connect (mp_ui->d25_view, SIGNAL (scale_factor_changed(double)), this, SLOT (scale_factor_changed(double))); + connect (mp_ui->d25_view, SIGNAL (vscale_factor_changed(double)), this, SLOT (vscale_factor_changed(double))); + connect (mp_ui->d25_view, SIGNAL (init_failed()), this, SLOT (init_failed())); mp_ui->gl_stack->setCurrentIndex (0); @@ -84,7 +84,7 @@ D25View::cellviews_changed () void D25View::layer_properties_changed (int) { - mp_ui->d25_view->refresh_view (); + // @@@ mp_ui->d25_view->refresh_view (); } void @@ -113,6 +113,71 @@ D25View::menu_activated (const std::string &symbol) } } +D25View * +D25View::open (lay::LayoutView *view) +{ + D25View *d25_view = view->get_plugin (); + if (d25_view) { + + d25_view->show (); + d25_view->activateWindow (); + d25_view->raise (); + + try { + d25_view->activate (); + } catch (...) { + d25_view->deactivate (); + throw; + } + + } + + return d25_view; +} + +void +D25View::close () +{ + hide (); +} + +void +D25View::clear () +{ + mp_ui->d25_view->clear (); +} + +void +D25View::open_display (const color_t *frame_color, const color_t *fill_color, const db::LayerProperties *like) +{ + mp_ui->d25_view->open_display (frame_color, fill_color, like); +} + +void +D25View::close_display () +{ + mp_ui->d25_view->close_display (); +} + +void +D25View::entry (const db::Region &data, double dbu, double zstart, double zstop) +{ + mp_ui->d25_view->entry (data, dbu, zstart, zstop); +} + +void +D25View::finish () +{ + mp_ui->d25_view->finish (); + + // @@@ install + + mp_ui->d25_view->reset (); + mp_ui->d25_view->set_cam_azimuth (0.0); + mp_ui->d25_view->set_cam_elevation (-initial_elevation); + mp_ui->d25_view->fit (); +} + static QString scale_factor_to_string (double f) { return QString (QString::fromUtf8 ("%1")).arg (f, 0, 'g', 3); @@ -198,12 +263,7 @@ D25View::deactivated () void D25View::activated () { - bool any = mp_ui->d25_view->attach_view (view ()); - if (! any) { - mp_ui->d25_view->attach_view (0); - throw tl::Exception (tl::to_string (tr ("No z data configured for the layers in this view.\nUse \"Tools/Manage Technologies\" to set up a z stack or check if it applies to the layers here."))); - } - + mp_ui->d25_view->attach_view (view ()); mp_ui->d25_view->reset (); mp_ui->d25_view->set_cam_azimuth (0.0); mp_ui->d25_view->set_cam_elevation (-initial_elevation); diff --git a/src/plugins/tools/view_25d/lay_plugin/layD25View.h b/src/plugins/tools/view_25d/lay_plugin/layD25View.h index a4e420576..9976b15cf 100644 --- a/src/plugins/tools/view_25d/lay_plugin/layD25View.h +++ b/src/plugins/tools/view_25d/lay_plugin/layD25View.h @@ -27,6 +27,7 @@ #include "tlObject.h" #include "layBrowser.h" +#include "layViewOp.h" namespace Ui { @@ -38,6 +39,12 @@ namespace lay class LayoutView; } +namespace db +{ + class Region; + struct LayerProperties; +} + namespace lay { @@ -54,6 +61,14 @@ public: virtual void deactivated (); virtual void activated (); + static D25View *open (lay::LayoutView *view); + void close (); + void clear (); + void open_display (const color_t *frame_color, const color_t *fill_color, const db::LayerProperties *like); + void close_display (); + void entry (const db::Region &data, double dbu, double zstart, double zstop); + void finish (); + protected: void accept (); void reject (); diff --git a/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc b/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc index 57812aeb6..5150dc008 100644 --- a/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc +++ b/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.cc @@ -31,6 +31,8 @@ #include "dbPolygonGenerators.h" #include "dbPolygonTools.h" #include "dbClip.h" +#include "dbRegion.h" +#include "dbOriginalLayerRegion.h" #include "tlException.h" #include "tlProgress.h" @@ -200,6 +202,8 @@ D25ViewWidget::D25ViewWidget (QWidget *parent) setFormat (format); m_zmin = m_zmax = 0.0; + m_zset = false; + m_display_open = false; mp_view = 0; reset_viewport (); @@ -496,17 +500,146 @@ D25ViewWidget::aspect_ratio () const return double (width ()) / double (height ()); } -bool +void +D25ViewWidget::clear () +{ + m_layers.clear (); + m_layer_to_info.clear (); + m_vertex_chunks.clear (); + m_line_chunks.clear (); + + m_zset = false; + m_zmin = m_zmax = 0.0; + m_display_open = false; + + if (! mp_view) { + m_bbox = db::DBox (-1.0, -1.0, 1.0, 1.0); + } else { + m_bbox = mp_view->viewport ().box (); + } +} + +static void color_to_gl (color_t color, GLfloat (&gl_color) [4]) +{ + gl_color[0] = ((color >> 16) & 0xff) / 255.0f; + gl_color[1] = ((color >> 8) & 0xff) / 255.0f; + gl_color[2] = (color & 0xff) / 255.0f; + gl_color[3] = 1.0f; +} + +static void color_to_gl (const color_t *color, GLfloat (&gl_color) [4]) +{ + if (! color) { + for (unsigned int i = 0; i < 4; ++i) { + gl_color [i] = 0.0; + } + } else { + color_to_gl (*color, gl_color); + } +} + +static void lp_to_info (const lay::LayerPropertiesNode &lp, D25ViewWidget::LayerInfo &info) +{ + color_to_gl (lp.fill_color (true), info.fill_color); + if (lp.dither_pattern (true) == 1 /*hollow*/) { + info.fill_color [3] = 0.0f; + } + + color_to_gl (lp.frame_color (true), info.frame_color); + if (lp.frame_color (true) == lp.fill_color (true) && info.fill_color [3] > 0.5) { + // optimize: don't draw wire frame unless required + info.frame_color [3] = 0.0f; + } + + info.visible = lp.visible (true); +} + +void +D25ViewWidget::open_display (const color_t *frame_color, const color_t *fill_color, const db::LayerProperties *like) +{ + m_vertex_chunks.push_back (triangle_chunks_type ()); + m_line_chunks.push_back (line_chunks_type ()); + + LayerInfo info; + + info.visible = true; + color_to_gl (frame_color, info.frame_color); + color_to_gl (fill_color, info.fill_color); + info.vertex_chunk = &m_vertex_chunks.back (); + info.line_chunk = &m_line_chunks.back (); + + if (like && mp_view) { + for (lay::LayerPropertiesConstIterator lp = mp_view->begin_layers (); ! lp.at_end (); ++lp) { + if (! lp->has_children () && lp->source (true).layer_props ().log_equal (*like)) { + lp_to_info (*lp, info); + break; + } + } + } + + m_layers.push_back (info); + m_display_open = true; +} + +void +D25ViewWidget::close_display () +{ + m_display_open = false; +} + +void +D25ViewWidget::entry (const db::Region &data, double dbu, double zstart, double zstop) +{ + tl_assert (m_display_open); + + // try to establish a default color from the region's origin if required + const db::OriginalLayerRegion *original_region = dynamic_cast (data.delegate ()); + if (mp_view && m_layers.back ().fill_color [3] == 0.0 && m_layers.back ().frame_color [3] == 0.0) { + + if (original_region) { + + const db::RecursiveShapeIterator *iter = original_region->iter (); + if (iter && iter->layout () && iter->layout ()->is_valid_layer (iter->layer ())) { + + db::LayerProperties like = iter->layout ()->get_properties (iter->layer ()); + + for (lay::LayerPropertiesConstIterator lp = mp_view->begin_layers (); ! lp.at_end (); ++lp) { + if (! lp->has_children () && lp->source (true).layer_props ().log_equal (like)) { + lp_to_info (*lp, m_layers.back ()); + break; + } + } + + } + + } else { + + // sequential assignment + lay::color_t color = mp_view->get_palette ().luminous_color_by_index (m_layers.size ()); + color_to_gl (color, m_layers.back ().frame_color); + color_to_gl (color, m_layers.back ().fill_color); + + } + + } + + tl::AbsoluteProgress progress (tl::to_string (tr ("Rendering ..."))); + render_region (progress, *m_layers.back ().vertex_chunk, *m_layers.back ().line_chunk, data, dbu, db::CplxTrans (dbu).inverted () * m_bbox, zstart, zstop); +} + +void +D25ViewWidget::finish () +{ + // @@@ +} + +void D25ViewWidget::attach_view (LayoutView *view) { mp_view = view; - - bool any = prepare_view (); - reset (); - - return any; } +#if 0 // @@@ namespace { class ZDataCache @@ -578,31 +711,6 @@ namespace { } -static void color_to_gl (color_t color, GLfloat (&gl_color) [4]) -{ - gl_color[0] = ((color >> 16) & 0xff) / 255.0f; - gl_color[1] = ((color >> 8) & 0xff) / 255.0f; - gl_color[2] = (color & 0xff) / 255.0f; - gl_color[3] = 1.0f; -} - -void -D25ViewWidget::lp_to_info (const lay::LayerPropertiesNode &lp, LayerInfo &info) -{ - color_to_gl (lp.fill_color (true), info.color); - if (lp.dither_pattern (true) == 1 /*hollow*/) { - info.color [3] = 0.0f; - } - - color_to_gl (lp.frame_color (true), info.frame_color); - if (lp.frame_color (true) == lp.fill_color (true) && info.color [3] > 0.5) { - // optimize: don't draw wire frame unless required - info.frame_color [3] = 0.0f; - } - - info.visible = lp.visible (true); -} - bool D25ViewWidget::prepare_view () { @@ -712,6 +820,9 @@ D25ViewWidget::refresh_view () refresh (); } +// ----------------------- +#endif + void D25ViewWidget::render_polygon (D25ViewWidget::triangle_chunks_type &chunks, D25ViewWidget::line_chunks_type &line_chunks, const db::Polygon &poly, double dbu, double zstart, double zstop) { @@ -792,6 +903,8 @@ D25ViewWidget::render_wall (D25ViewWidget::triangle_chunks_type &chunks, D25View line_chunks.add (edge.p1 ().x () * dbu, zstop, edge.p1 ().y () * dbu); } +// @@@ +#if 0 void D25ViewWidget::render_layout (tl::AbsoluteProgress &progress, D25ViewWidget::triangle_chunks_type &chunks, D25ViewWidget::line_chunks_type &line_chunks, const db::Layout &layout, const db::Cell &cell, const db::Box &clip_box, unsigned int layer, double zstart, double zstop) { @@ -824,6 +937,32 @@ D25ViewWidget::render_layout (tl::AbsoluteProgress &progress, D25ViewWidget::tri } } +#endif + +void +D25ViewWidget::render_region (tl::AbsoluteProgress &progress, D25ViewWidget::triangle_chunks_type &chunks, D25ViewWidget::line_chunks_type &line_chunks, const db::Region ®ion, double dbu, const db::Box &clip_box, double zstart, double zstop) +{ + std::vector poly_heap; + + for (db::Region::const_iterator p = region.begin (); !p.at_end (); ++p) { + + poly_heap.clear (); + db::clip_poly (*p, clip_box, poly_heap, false /*keep holes*/); + + for (std::vector::const_iterator p = poly_heap.begin (); p != poly_heap.end (); ++p) { + + ++progress; + + render_polygon (chunks, line_chunks, *p, dbu, zstart, zstop); + + for (db::Polygon::polygon_edge_iterator e = p->begin_edge (); ! e.at_end (); ++e) { + render_wall (chunks, line_chunks, *e, dbu, zstart, zstop); + } + + } + + } +} static std::pair find_grid (double v) { @@ -1098,8 +1237,8 @@ D25ViewWidget::paintGL () glEnableVertexAttribArray (positions); for (std::vector::const_iterator l = m_layers.begin (); l != m_layers.end (); ++l) { - if (l->visible && l->color [3] > 0.5) { - m_shapes_program->setUniformValue ("color", l->color [0], l->color [1], l->color [2], l->color [3]); + if (l->visible && l->fill_color [3] > 0.5) { + m_shapes_program->setUniformValue ("color", l->fill_color [0], l->fill_color [1], l->fill_color [2], l->fill_color [3]); l->vertex_chunk->draw_to (this, positions, GL_TRIANGLES); } } diff --git a/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.h b/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.h index 63b069463..5b7879517 100644 --- a/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.h +++ b/src/plugins/tools/view_25d/lay_plugin/layD25ViewWidget.h @@ -27,6 +27,7 @@ #include "layD25MemChunks.h" #include "layD25Camera.h" +#include "layViewOp.h" #include #include @@ -41,8 +42,8 @@ namespace db { - class Layout; - class Cell; + class Region; + struct LayerProperties; } namespace tl @@ -78,6 +79,18 @@ class D25ViewWidget Q_OBJECT public: + typedef lay::mem_chunks triangle_chunks_type; + typedef lay::mem_chunks line_chunks_type; + + struct LayerInfo + { + triangle_chunks_type *vertex_chunk; + line_chunks_type *line_chunk; + GLfloat fill_color [4]; + GLfloat frame_color [4]; + bool visible; + }; + D25ViewWidget (QWidget *parent); ~D25ViewWidget (); @@ -88,8 +101,8 @@ public: void mouseReleaseEvent (QMouseEvent *event); void mouseMoveEvent (QMouseEvent *event); - bool attach_view(lay::LayoutView *view); - void refresh_view (); + void attach_view(lay::LayoutView *view); + // @@@ void refresh_view (); QVector3D hit_point_with_scene(const QVector3D &line_dir); void refresh (); @@ -129,6 +142,12 @@ public: return m_error; } + void clear (); + void open_display (const color_t *frame_color, const color_t *fill_color, const db::LayerProperties *like); + void close_display (); + void entry (const db::Region &data, double dbu, double zstart, double zstop); + void finish (); + signals: void scale_factor_changed (double f); void vscale_factor_changed (double f); @@ -143,9 +162,6 @@ public slots: void fit (); private: - typedef lay::mem_chunks triangle_chunks_type; - typedef lay::mem_chunks line_chunks_type; - std::unique_ptr mp_mode; QOpenGLShaderProgram *m_shapes_program, *m_lines_program, *m_gridplane_program; std::string m_error; @@ -155,32 +171,26 @@ private: lay::LayoutView *mp_view; db::DBox m_bbox; double m_zmin, m_zmax; + bool m_zset; + bool m_display_open; std::list m_vertex_chunks; std::list m_line_chunks; - struct LayerInfo { - const triangle_chunks_type *vertex_chunk; - const line_chunks_type *line_chunk; - GLfloat color [4]; - GLfloat frame_color [4]; - bool visible; - }; - std::vector m_layers; - std::multimap, size_t> m_layer_to_info; + std::multimap, size_t> m_layer_to_info; // @@@ void initializeGL (); void paintGL (); void resizeGL (int w, int h); void do_initialize_gl (); - bool prepare_view(); - void render_layout (tl::AbsoluteProgress &progress, D25ViewWidget::triangle_chunks_type &vertex_chunks, D25ViewWidget::line_chunks_type &line_chunks, const db::Layout &layout, const db::Cell &cell, const db::Box &clip_box, unsigned int layer, double zstart, double zstop); + // @@@ bool prepare_view(); + // @@@ void render_layout (tl::AbsoluteProgress &progress, D25ViewWidget::triangle_chunks_type &vertex_chunks, D25ViewWidget::line_chunks_type &line_chunks, const db::Layout &layout, const db::Cell &cell, const db::Box &clip_box, unsigned int layer, double zstart, double zstop); + void render_region (tl::AbsoluteProgress &progress, D25ViewWidget::triangle_chunks_type &vertex_chunks, D25ViewWidget::line_chunks_type &line_chunks, const db::Region ®ion, double dbu, const db::Box &clip_box, double zstart, double zstop); void render_polygon (D25ViewWidget::triangle_chunks_type &vertex_chunks, D25ViewWidget::line_chunks_type &line_chunks, const db::Polygon &poly, double dbu, double zstart, double zstop); void render_wall (D25ViewWidget::triangle_chunks_type &vertex_chunks, D25ViewWidget::line_chunks_type &line_chunks, const db::Edge &poly, double dbu, double zstart, double zstop); void reset_viewport (); - static void lp_to_info (const lay::LayerPropertiesNode &lp, D25ViewWidget::LayerInfo &info); }; } diff --git a/src/plugins/tools/view_25d/lay_plugin/lay_plugin.pro b/src/plugins/tools/view_25d/lay_plugin/lay_plugin.pro index cc6063840..aeac20510 100644 --- a/src/plugins/tools/view_25d/lay_plugin/lay_plugin.pro +++ b/src/plugins/tools/view_25d/lay_plugin/lay_plugin.pro @@ -16,6 +16,7 @@ HEADERS = \ layD25Camera.h SOURCES = \ + gsiDeclLayD25View.cc \ layD25View.cc \ layD25ViewWidget.cc \ layD25Plugin.cc \