mirror of https://github.com/KLayout/klayout.git
WIP: Some bug fixes, ongoing implementation
This commit is contained in:
parent
05c16c9024
commit
8c0498cc4c
|
|
@ -59,6 +59,39 @@
|
|||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolButton" name="rerun_button">
|
||||
<property name="toolTip">
|
||||
<string>Execute script again</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../lay/lay/layResources.qrc">
|
||||
<normaloff>:/run.png</normaloff>:/run.png</iconset>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="zoom_slider">
|
||||
<property name="sizePolicy">
|
||||
|
|
@ -456,6 +489,20 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_3">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="empty_label">
|
||||
<property name="text">
|
||||
<string>In order to use the 2.5d view you will need a script which generates the view.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ module D25
|
|||
raise("'color' must be a color value (an integer)")
|
||||
end
|
||||
display.fill = a[:color]
|
||||
display.frame = a[:color]
|
||||
display.frame = nil
|
||||
end
|
||||
if a[:frame]
|
||||
if !a[:frame].is_a?(0xffffff.class)
|
||||
|
|
@ -206,7 +206,7 @@ module D25
|
|||
|
||||
end
|
||||
|
||||
yield
|
||||
block && yield
|
||||
|
||||
ensure
|
||||
@display = nil
|
||||
|
|
@ -232,7 +232,7 @@ module D25
|
|||
|
||||
begin
|
||||
|
||||
view.clear
|
||||
view.begin(self._generator)
|
||||
|
||||
displays = {}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,9 @@ module D25
|
|||
|
||||
class D25Executable < RBA::Executable
|
||||
|
||||
def initialize(macro, generator, rdb_index = nil)
|
||||
def initialize(macro, generator)
|
||||
|
||||
@d25 = D25Engine::new
|
||||
@d25._rdb_index = rdb_index
|
||||
@d25._generator = generator
|
||||
|
||||
@macro = macro
|
||||
|
|
@ -148,7 +147,7 @@ module D25
|
|||
macro = RBA::Macro::macro_by_path(script)
|
||||
macro || raise("Can't find D25 script #{script} - unable to re-run")
|
||||
|
||||
D25Executable::new(macro, self.generator("script" => script), params["rdb_index"])
|
||||
D25Executable::new(macro, self.generator("script" => script))
|
||||
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,9 @@ Class<lay::D25View> decl_D25View (QT_EXTERNAL_BASE (QDialog) "lay", "D25View",
|
|||
gsi::method ("clear", &lay::D25View::clear,
|
||||
"@brief Clears all display entries in the view"
|
||||
) +
|
||||
gsi::method ("begin", &lay::D25View::begin, gsi::arg ("generator"),
|
||||
"@brief Initiates delivery of display groups"
|
||||
) +
|
||||
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"
|
||||
) +
|
||||
|
|
@ -80,6 +83,8 @@ Class<lay::D25View> decl_D25View (QT_EXTERNAL_BASE (QDialog) "lay", "D25View",
|
|||
"@brief The 2.5d View Dialog\n"
|
||||
"\n"
|
||||
"This class is used internally to implement the 2.5d feature.\n"
|
||||
"\n"
|
||||
"This class has been introduced in version 0.28."
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
*/
|
||||
|
||||
#include "tlExceptions.h"
|
||||
#include "tlRecipe.h"
|
||||
|
||||
#include "layD25View.h"
|
||||
#include "layLayoutView.h"
|
||||
|
|
@ -35,7 +37,8 @@ namespace lay
|
|||
const double initial_elevation = 15.0;
|
||||
|
||||
D25View::D25View (lay::Dispatcher *root, lay::LayoutView *view)
|
||||
: lay::Browser (root, view, "d25_view")
|
||||
: lay::Browser (root, view, "d25_view"),
|
||||
dm_rerun_macro (this, &D25View::rerun_macro)
|
||||
{
|
||||
mp_ui = new Ui::D25View ();
|
||||
mp_ui->setupUi (this);
|
||||
|
|
@ -56,10 +59,14 @@ D25View::D25View (lay::Dispatcher *root, lay::LayoutView *view)
|
|||
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->rerun_button, SIGNAL (clicked()), this, SLOT (rerun_button_pressed()));
|
||||
|
||||
mp_ui->gl_stack->setCurrentIndex (0);
|
||||
mp_ui->rerun_button->setEnabled (false);
|
||||
|
||||
mp_ui->gl_stack->setCurrentIndex (2);
|
||||
|
||||
lay::activate_help_links (mp_ui->doc_label);
|
||||
lay::activate_help_links (mp_ui->empty_label);
|
||||
|
||||
view->cellviews_changed_event.add (this, &D25View::cellviews_changed);
|
||||
view->layer_list_changed_event.add (this, &D25View::layer_properties_changed);
|
||||
|
|
@ -144,38 +151,67 @@ D25View::close ()
|
|||
void
|
||||
D25View::clear ()
|
||||
{
|
||||
mp_ui->d25_view->clear ();
|
||||
if (! mp_ui->d25_view->has_error ()) {
|
||||
mp_ui->gl_stack->setCurrentIndex (2);
|
||||
mp_ui->d25_view->clear ();
|
||||
}
|
||||
|
||||
mp_ui->rerun_button->setEnabled (false);
|
||||
m_generator.clear ();
|
||||
}
|
||||
|
||||
void
|
||||
D25View::begin (const std::string &generator)
|
||||
{
|
||||
clear ();
|
||||
|
||||
if (! mp_ui->d25_view->has_error ()) {
|
||||
m_generator = generator;
|
||||
mp_ui->rerun_button->setEnabled (true);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if (! mp_ui->d25_view->has_error ()) {
|
||||
mp_ui->d25_view->open_display (frame_color, fill_color, like);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
D25View::close_display ()
|
||||
{
|
||||
mp_ui->d25_view->close_display ();
|
||||
if (! mp_ui->d25_view->has_error ()) {
|
||||
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);
|
||||
if (! mp_ui->d25_view->has_error ()) {
|
||||
mp_ui->d25_view->entry (data, dbu, zstart, zstop);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
D25View::finish ()
|
||||
{
|
||||
mp_ui->d25_view->finish ();
|
||||
if (! mp_ui->d25_view->has_error ()) {
|
||||
|
||||
// @@@ install layer properties widget
|
||||
mp_ui->d25_view->finish ();
|
||||
|
||||
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 ();
|
||||
// @@@ install layer properties widget
|
||||
|
||||
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 ();
|
||||
|
||||
mp_ui->gl_stack->setCurrentIndex (0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static QString scale_factor_to_string (double f)
|
||||
|
|
@ -270,6 +306,26 @@ D25View::activated ()
|
|||
mp_ui->d25_view->fit ();
|
||||
}
|
||||
|
||||
void
|
||||
D25View::rerun_button_pressed ()
|
||||
{
|
||||
// NOTE: we use deferred execution, because otherwise the button won't get repainted properly
|
||||
dm_rerun_macro ();
|
||||
}
|
||||
|
||||
void
|
||||
D25View::rerun_macro ()
|
||||
{
|
||||
BEGIN_PROTECTED
|
||||
|
||||
if (! m_generator.empty ()) {
|
||||
std::map<std::string, tl::Variant> add_pars;
|
||||
tl::Recipe::make (m_generator, add_pars);
|
||||
}
|
||||
|
||||
END_PROTECTED
|
||||
}
|
||||
|
||||
void
|
||||
D25View::fit_button_clicked ()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ public:
|
|||
static D25View *open (lay::LayoutView *view);
|
||||
void close ();
|
||||
void clear ();
|
||||
void begin (const std::string &generator);
|
||||
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);
|
||||
|
|
@ -82,12 +83,16 @@ private slots:
|
|||
void vscale_slider_changed (int value);
|
||||
void vscale_value_edited ();
|
||||
void init_failed ();
|
||||
void rerun_button_pressed ();
|
||||
|
||||
private:
|
||||
Ui::D25View *mp_ui;
|
||||
tl::DeferredMethod<D25View> dm_rerun_macro;
|
||||
std::string m_generator;
|
||||
|
||||
void cellviews_changed ();
|
||||
void layer_properties_changed (int);
|
||||
void rerun_macro ();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,6 +205,7 @@ D25ViewWidget::D25ViewWidget (QWidget *parent)
|
|||
m_zset = false;
|
||||
m_display_open = false;
|
||||
mp_view = 0;
|
||||
m_has_error = false;
|
||||
|
||||
reset_viewport ();
|
||||
}
|
||||
|
|
@ -616,7 +617,6 @@ D25ViewWidget::entry (const db::Region &data, double dbu, double zstart, double
|
|||
|
||||
// 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);
|
||||
|
||||
}
|
||||
|
|
@ -639,190 +639,6 @@ D25ViewWidget::attach_view (LayoutView *view)
|
|||
mp_view = view;
|
||||
}
|
||||
|
||||
#if 0 // @@@
|
||||
namespace {
|
||||
|
||||
class ZDataCache
|
||||
{
|
||||
public:
|
||||
ZDataCache () { }
|
||||
|
||||
std::vector<db::D25LayerInfo> operator() (lay::LayoutView *view, int cv_index, int layer_index)
|
||||
{
|
||||
std::map<int, std::map<int, std::vector<db::D25LayerInfo> > >::const_iterator c = m_cache.find (cv_index);
|
||||
if (c != m_cache.end ()) {
|
||||
std::map<int, std::vector<db::D25LayerInfo> >::const_iterator l = c->second.find (layer_index);
|
||||
if (l != c->second.end ()) {
|
||||
return l->second;
|
||||
} else {
|
||||
return std::vector<db::D25LayerInfo> ();
|
||||
}
|
||||
}
|
||||
|
||||
std::map<int, std::vector<db::D25LayerInfo> > &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<const db::D25TechnologyComponent *> (tech->component_by_name ("d25"));
|
||||
}
|
||||
|
||||
if (comp) {
|
||||
|
||||
std::multimap<db::LayerProperties, db::D25LayerInfo, db::LPLogicalLessFunc> zi_by_lp;
|
||||
|
||||
db::D25TechnologyComponent::layers_type layers = comp->compile_from_source ();
|
||||
for (db::D25TechnologyComponent::layers_type::const_iterator i = layers.begin (); i != layers.end (); ++i) {
|
||||
zi_by_lp.insert (std::make_pair (i->layer (), *i));
|
||||
}
|
||||
|
||||
const db::Layout &ly = cv->layout ();
|
||||
for (int l = 0; l < int (ly.layers ()); ++l) {
|
||||
if (ly.is_valid_layer (l)) {
|
||||
db::LayerProperties lp = ly.get_properties (l);
|
||||
std::multimap<db::LayerProperties, db::D25LayerInfo, db::LPLogicalLessFunc>::const_iterator z = zi_by_lp.find (lp);
|
||||
if ((z == zi_by_lp.end () || ! z->first.log_equal (lp)) && ! lp.name.empty ()) {
|
||||
// If possible, try by name only
|
||||
lp = db::LayerProperties (lp.name);
|
||||
z = zi_by_lp.find (lp);
|
||||
}
|
||||
while (z != zi_by_lp.end () && z->first.log_equal (lp)) {
|
||||
lcache[l].push_back (z->second);
|
||||
++z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::map<int, std::vector<db::D25LayerInfo> >::const_iterator l = lcache.find (layer_index);
|
||||
if (l != lcache.end ()) {
|
||||
return l->second;
|
||||
} else {
|
||||
return std::vector<db::D25LayerInfo> ();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<int, std::map<int, std::vector<db::D25LayerInfo> > > m_cache;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
D25ViewWidget::prepare_view ()
|
||||
{
|
||||
m_layers.clear ();
|
||||
m_layer_to_info.clear ();
|
||||
m_vertex_chunks.clear ();
|
||||
m_line_chunks.clear ();
|
||||
|
||||
bool zset = false;
|
||||
m_zmin = m_zmax = 0.0;
|
||||
|
||||
if (! mp_view) {
|
||||
m_bbox = db::DBox (-1.0, -1.0, 1.0, 1.0);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_bbox = mp_view->viewport ().box ();
|
||||
|
||||
ZDataCache zdata;
|
||||
|
||||
// collect and confine to cell bbox
|
||||
db::DBox cell_bbox;
|
||||
for (lay::LayerPropertiesConstIterator lp = mp_view->begin_layers (); ! lp.at_end (); ++lp) {
|
||||
|
||||
std::vector<db::D25LayerInfo> zinfo;
|
||||
if (! lp->has_children ()) {
|
||||
zinfo = zdata (mp_view, lp->cellview_index (), lp->layer_index ());
|
||||
}
|
||||
|
||||
for (std::vector<db::D25LayerInfo>::const_iterator zi = zinfo.begin (); zi != zinfo.end (); ++zi) {
|
||||
const lay::CellView &cv = mp_view->cellview ((unsigned int) lp->cellview_index ());
|
||||
cell_bbox += db::CplxTrans (cv->layout ().dbu ()) * cv.cell ()->bbox ((unsigned int) lp->layer_index ());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool any = false;
|
||||
|
||||
tl::AbsoluteProgress progress (tl::to_string (tr ("Rendering ...")));
|
||||
|
||||
for (lay::LayerPropertiesConstIterator lp = mp_view->begin_layers (); ! lp.at_end (); ++lp) {
|
||||
|
||||
std::vector<db::D25LayerInfo> zinfo;
|
||||
if (! lp->has_children ()) {
|
||||
zinfo = zdata (mp_view, lp->cellview_index (), lp->layer_index ());
|
||||
}
|
||||
|
||||
for (std::vector<db::D25LayerInfo>::const_iterator zi = zinfo.begin (); zi != zinfo.end (); ++zi) {
|
||||
|
||||
any = true;
|
||||
|
||||
double z0 = zi->zstart ();
|
||||
double z1 = zi->zstop ();
|
||||
|
||||
m_vertex_chunks.push_back (triangle_chunks_type ());
|
||||
m_line_chunks.push_back (line_chunks_type ());
|
||||
|
||||
LayerInfo info;
|
||||
lp_to_info (*lp, info);
|
||||
info.vertex_chunk = &m_vertex_chunks.back ();
|
||||
info.line_chunk = &m_line_chunks.back ();
|
||||
|
||||
m_layer_to_info.insert (std::make_pair (std::make_pair (lp->cellview_index (), lp->layer_index ()), m_layers.size ()));
|
||||
m_layers.push_back (info);
|
||||
|
||||
const lay::CellView &cv = mp_view->cellview ((unsigned int) lp->cellview_index ());
|
||||
|
||||
render_layout (progress, m_vertex_chunks.back (), m_line_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;
|
||||
m_zmax = z1;
|
||||
zset = true;
|
||||
} else {
|
||||
m_zmin = std::min (z0, m_zmin);
|
||||
m_zmax = std::max (z1, m_zmax);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return any;
|
||||
}
|
||||
|
||||
void
|
||||
D25ViewWidget::refresh_view ()
|
||||
{
|
||||
if (! mp_view) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (lay::LayerPropertiesConstIterator lp = mp_view->begin_layers (); ! lp.at_end (); ++lp) {
|
||||
|
||||
std::pair<size_t, size_t> key = std::make_pair (lp->cellview_index (), lp->layer_index ());
|
||||
|
||||
std::multimap<std::pair<size_t, size_t>, size_t>::const_iterator l = m_layer_to_info.find (key);
|
||||
while (l != m_layer_to_info.end () && l->first == key) {
|
||||
if (l->second < m_layers.size ()) {
|
||||
lp_to_info (*lp, m_layers [l->second]);
|
||||
}
|
||||
++l;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -991,22 +807,22 @@ D25ViewWidget::initializeGL ()
|
|||
tl_assert (m_gridplane_program == 0);
|
||||
tl_assert (m_lines_program == 0);
|
||||
|
||||
bool error = false;
|
||||
m_has_error = false;
|
||||
|
||||
try {
|
||||
do_initialize_gl ();
|
||||
} catch (tl::Exception &ex) {
|
||||
m_error = ex.msg ();
|
||||
error = true;
|
||||
m_has_error = true;
|
||||
} catch (std::exception &ex) {
|
||||
m_error = ex.what ();
|
||||
error = true;
|
||||
m_has_error = true;
|
||||
} catch (...) {
|
||||
m_error = "(unspecific error)";
|
||||
error = true;
|
||||
m_has_error = true;
|
||||
}
|
||||
|
||||
if (error) {
|
||||
if (m_has_error) {
|
||||
|
||||
delete m_shapes_program;
|
||||
m_shapes_program = 0;
|
||||
|
|
|
|||
|
|
@ -142,6 +142,11 @@ public:
|
|||
return m_error;
|
||||
}
|
||||
|
||||
bool has_error () const
|
||||
{
|
||||
return m_has_error;
|
||||
}
|
||||
|
||||
void clear ();
|
||||
void open_display (const color_t *frame_color, const color_t *fill_color, const db::LayerProperties *like);
|
||||
void close_display ();
|
||||
|
|
@ -165,6 +170,7 @@ private:
|
|||
std::unique_ptr<D25InteractionMode> mp_mode;
|
||||
QOpenGLShaderProgram *m_shapes_program, *m_lines_program, *m_gridplane_program;
|
||||
std::string m_error;
|
||||
bool m_has_error;
|
||||
double m_scale_factor;
|
||||
double m_vscale_factor;
|
||||
QVector3D m_displacement;
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@
|
|||
# Options are:
|
||||
#
|
||||
# display(..., color: 0xff0000) use bright red for the material color (RGB)
|
||||
# display(..., frame: 0xff0000) use bright red for the frame color (combine with "color" for the fill)
|
||||
# display(..., hollow: true) use hollow style (only frame is drawn)
|
||||
# display(..., frame: 0xff0000) use bright red for the frame color (combine with "fill" for the fill color)
|
||||
# display(..., fill: 0x00ff00) use bright green for the fill color along (combine with "frame" for the frame color)
|
||||
# display(..., like: "7/0") borrow style from layout view's style for layer "7/0"
|
||||
#
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue