mirror of https://github.com/KLayout/klayout.git
commit
85448966d8
|
|
@ -119,6 +119,7 @@ D25TechnologyComponent::D25TechnologyComponent ()
|
|||
// provide some explanation for the initialization
|
||||
m_src =
|
||||
"# Provide z stack information here\n"
|
||||
"#\n"
|
||||
"# Each line is one layer. The specification consists of a layer specification, a colon and arguments.\n"
|
||||
"# The arguments are named (like \"x=...\") or in serial. Parameters are separated by comma or blanks.\n"
|
||||
"# Named arguments are:\n"
|
||||
|
|
@ -127,7 +128,7 @@ D25TechnologyComponent::D25TechnologyComponent ()
|
|||
"# zstop The upper z position of the extruded layer in µm\n"
|
||||
"# height The height of the extruded layer in µm\n"
|
||||
"#\n"
|
||||
"# 'height', 'zstart' and 'zstop' can be used in any combination. If no value is given for 'zstart', "
|
||||
"# 'height', 'zstart' and 'zstop' can be used in any combination. If no value is given for 'zstart',\n"
|
||||
"# the upper level of the previous layer will be used.\n"
|
||||
"#\n"
|
||||
"# If a single unnamed parameter is given, it corresponds to 'height'. Two parameters correspond to\n"
|
||||
|
|
@ -139,25 +140,52 @@ D25TechnologyComponent::D25TechnologyComponent ()
|
|||
"# 1: zstop=1.5, zstart=0.5 # same with named parameters\n"
|
||||
"# 1: height=1.0, zstop=1.5 # same with z stop minus height\n"
|
||||
"# 1: 1.0 zstop=1.5 # same with height as unnamed parameter\n"
|
||||
"#\n"
|
||||
"# VARIABLES\n"
|
||||
"#\n"
|
||||
"# You can declare variables with:\n"
|
||||
"# var name = value\n"
|
||||
"#\n"
|
||||
"# You can use variables inside numeric expressions.\n"
|
||||
"# Example:\n"
|
||||
"# var hmetal = 0.48\n"
|
||||
"# 7/0: 0.5 0.5+hmetal*2 # 2x thick metal\n"
|
||||
"#\n"
|
||||
"# You cannot use variables inside layer specifications currently.\n"
|
||||
"#\n"
|
||||
"# CONDITIONALS\n"
|
||||
"#\n"
|
||||
"# You can enable or disable branches of the table using 'if', 'else', 'elseif' and 'end':\n"
|
||||
"# Example:\n"
|
||||
"# var thick_m1 = true\n"
|
||||
"# if thickm1\n"
|
||||
"# 1: 0.5 1.5\n"
|
||||
"# else\n"
|
||||
"# 1: 0.5 1.2\n"
|
||||
"# end\n"
|
||||
"\n"
|
||||
;
|
||||
}
|
||||
|
||||
D25TechnologyComponent::D25TechnologyComponent (const D25TechnologyComponent &d)
|
||||
: db::TechnologyComponent (d25_component_name (), d25_description ())
|
||||
{
|
||||
m_layers = d.m_layers;
|
||||
m_src = d.m_src;
|
||||
}
|
||||
|
||||
void
|
||||
D25TechnologyComponent::compile_from_source (const std::string &src)
|
||||
D25TechnologyComponent::layers_type
|
||||
D25TechnologyComponent::compile_from_source () const
|
||||
{
|
||||
layers_type layers;
|
||||
|
||||
int current_line = 0;
|
||||
m_layers.clear ();
|
||||
|
||||
try {
|
||||
|
||||
std::vector<std::string> lines = tl::split (src, "\n");
|
||||
tl::Eval eval;
|
||||
std::vector<bool> conditional_stack;
|
||||
|
||||
std::vector<std::string> lines = tl::split (m_src, "\n");
|
||||
for (std::vector<std::string>::const_iterator l = lines.begin (); l != lines.end (); ++l) {
|
||||
|
||||
++current_line;
|
||||
|
|
@ -168,12 +196,86 @@ D25TechnologyComponent::compile_from_source (const std::string &src)
|
|||
// ignore comments
|
||||
} else if (ex.at_end ()) {
|
||||
// ignore empty lines
|
||||
|
||||
} else if (ex.test ("if")) {
|
||||
|
||||
tl::Expression x;
|
||||
eval.parse (x, ex);
|
||||
conditional_stack.push_back (x.execute ().to_bool ());
|
||||
|
||||
ex.expect_end ();
|
||||
|
||||
} else if (ex.test ("else")) {
|
||||
|
||||
if (conditional_stack.empty ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("'else' without 'if'")));
|
||||
}
|
||||
|
||||
conditional_stack.back () = ! conditional_stack.back ();
|
||||
|
||||
ex.expect_end ();
|
||||
|
||||
} else if (ex.test ("end")) {
|
||||
|
||||
if (conditional_stack.empty ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("'end' without 'if'")));
|
||||
}
|
||||
|
||||
conditional_stack.pop_back ();
|
||||
|
||||
ex.expect_end ();
|
||||
|
||||
} else if (ex.test ("elsif")) {
|
||||
|
||||
if (conditional_stack.empty ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("'elsif' without 'if'")));
|
||||
}
|
||||
|
||||
tl::Expression x;
|
||||
eval.parse (x, ex);
|
||||
conditional_stack.back () = x.execute ().to_bool ();
|
||||
|
||||
ex.expect_end ();
|
||||
|
||||
} else if (! conditional_stack.empty () && ! conditional_stack.back ()) {
|
||||
|
||||
continue;
|
||||
|
||||
} else if (ex.test ("var")) {
|
||||
|
||||
std::string n;
|
||||
ex.read_name (n);
|
||||
|
||||
ex.expect ("=");
|
||||
|
||||
tl::Expression x;
|
||||
eval.parse (x, ex);
|
||||
eval.set_var (n, x.execute ());
|
||||
|
||||
ex.expect_end ();
|
||||
|
||||
} else if (ex.test ("print")) {
|
||||
|
||||
tl::Expression x;
|
||||
eval.parse (x, ex);
|
||||
ex.expect_end ();
|
||||
|
||||
tl::info << x.execute ().to_string ();
|
||||
|
||||
} else if (ex.test ("error")) {
|
||||
|
||||
tl::Expression x;
|
||||
eval.parse (x, ex);
|
||||
ex.expect_end ();
|
||||
|
||||
throw tl::Exception (x.execute ().to_string ());
|
||||
|
||||
} else {
|
||||
|
||||
db::D25LayerInfo info;
|
||||
if (! m_layers.empty ()) {
|
||||
info.set_zstart (m_layers.back ().zstop ());
|
||||
info.set_zstop (m_layers.back ().zstop ());
|
||||
if (! layers.empty ()) {
|
||||
info.set_zstart (layers.back ().zstop ());
|
||||
info.set_zstop (layers.back ().zstop ());
|
||||
}
|
||||
|
||||
tl::Variant z0, z1, h;
|
||||
|
|
@ -191,16 +293,18 @@ D25TechnologyComponent::compile_from_source (const std::string &src)
|
|||
break;
|
||||
}
|
||||
|
||||
double pv = 0.0;
|
||||
tl::Expression pvx;
|
||||
|
||||
std::string pn;
|
||||
if (ex.try_read_name (pn)) {
|
||||
ex.expect ("=");
|
||||
ex.read (pv);
|
||||
eval.parse (pvx, ex);
|
||||
} else {
|
||||
ex.read (pv);
|
||||
eval.parse (pvx, ex);
|
||||
}
|
||||
|
||||
double pv = pvx.execute ().to_double ();
|
||||
|
||||
ex.test (",");
|
||||
|
||||
if (pn.empty ()) {
|
||||
|
|
@ -220,7 +324,7 @@ D25TechnologyComponent::compile_from_source (const std::string &src)
|
|||
if (args.size () == 0) {
|
||||
if (z0.is_nil () && z1.is_nil ()) {
|
||||
if (! h.is_nil ()) {
|
||||
info.set_zstop (info.zstart () + h.to_double ());
|
||||
info.set_zstop (info.zstop () + h.to_double ());
|
||||
}
|
||||
} else if (z0.is_nil ()) {
|
||||
info.set_zstop (z1.to_double ());
|
||||
|
|
@ -239,28 +343,28 @@ D25TechnologyComponent::compile_from_source (const std::string &src)
|
|||
} else if (args.size () == 1) {
|
||||
if (! h.is_nil ()) {
|
||||
if (! z0.is_nil ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Rundundant parameters: zstart already given")));
|
||||
throw tl::Exception (tl::to_string (tr ("Redundant parameters: zstart already given")));
|
||||
}
|
||||
if (! z1.is_nil ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Rundundant parameters: zstop implicitly given")));
|
||||
throw tl::Exception (tl::to_string (tr ("Redundant parameters: zstop implicitly given")));
|
||||
}
|
||||
info.set_zstart (args[0]);
|
||||
info.set_zstop (args[0] + h.to_double ());
|
||||
} else {
|
||||
if (! z1.is_nil ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Rundundant parameters: zstop implicitly given")));
|
||||
throw tl::Exception (tl::to_string (tr ("Redundant parameters: zstop implicitly given")));
|
||||
}
|
||||
info.set_zstop ((! z0.is_nil () ? z0.to_double () : info.zstart ()) + args[0]);
|
||||
}
|
||||
} else if (args.size () == 2) {
|
||||
if (! z0.is_nil ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Rundundant parameters: zstart already given")));
|
||||
throw tl::Exception (tl::to_string (tr ("Redundant parameters: zstart already given")));
|
||||
}
|
||||
if (! z1.is_nil ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Rundundant parameters: zstop already given")));
|
||||
throw tl::Exception (tl::to_string (tr ("Redundant parameters: zstop already given")));
|
||||
}
|
||||
if (! h.is_nil ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Rundundant parameters: height implicitly given")));
|
||||
throw tl::Exception (tl::to_string (tr ("Redundant parameters: height implicitly given")));
|
||||
}
|
||||
info.set_zstart (args[0]);
|
||||
info.set_zstop (args[1]);
|
||||
|
|
@ -268,25 +372,30 @@ D25TechnologyComponent::compile_from_source (const std::string &src)
|
|||
throw tl::Exception (tl::to_string (tr ("Too many parameters (max 2)")));
|
||||
}
|
||||
|
||||
m_layers.push_back (info);
|
||||
layers.push_back (info);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (! conditional_stack.empty ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("'if', 'else' or 'elsif' without matching 'end'")));
|
||||
}
|
||||
|
||||
} catch (tl::Exception &ex) {
|
||||
throw tl::Exception (ex.msg () + tl::sprintf (tl::to_string (tr (" in line %d")), current_line));
|
||||
}
|
||||
|
||||
m_src = src;
|
||||
return layers;
|
||||
}
|
||||
|
||||
std::string
|
||||
D25TechnologyComponent::to_string () const
|
||||
{
|
||||
layers_type layers = compile_from_source ();
|
||||
std::string res;
|
||||
|
||||
for (const_iterator i = begin (); i != end (); ++i) {
|
||||
for (layers_type::const_iterator i = layers.begin (); i != layers.end (); ++i) {
|
||||
if (! res.empty ()) {
|
||||
res += "\n";
|
||||
}
|
||||
|
|
@ -317,11 +426,6 @@ public:
|
|||
virtual tl::XMLElementBase *xml_element () const
|
||||
{
|
||||
return new db::TechnologyComponentXMLElement<D25TechnologyComponent> (d25_component_name (),
|
||||
tl::make_element ((D25TechnologyComponent::const_iterator (D25TechnologyComponent::*) () const) &D25TechnologyComponent::begin, (D25TechnologyComponent::const_iterator (D25TechnologyComponent::*) () const) &D25TechnologyComponent::end, &D25TechnologyComponent::add, "layer",
|
||||
tl::make_member (&D25LayerInfo::layer_as_string, &D25LayerInfo::set_layer_from_string, "layer") +
|
||||
tl::make_member (&D25LayerInfo::zstart, &D25LayerInfo::set_zstart, "zstart") +
|
||||
tl::make_member (&D25LayerInfo::zstop, &D25LayerInfo::set_zstop, "zstop")
|
||||
) +
|
||||
tl::make_member (&D25TechnologyComponent::src, &D25TechnologyComponent::set_src, "src")
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,55 +76,8 @@ public:
|
|||
D25TechnologyComponent (const D25TechnologyComponent &d);
|
||||
|
||||
typedef std::list<D25LayerInfo> layers_type;
|
||||
typedef layers_type::const_iterator const_iterator;
|
||||
typedef layers_type::iterator iterator;
|
||||
|
||||
void compile_from_source (const std::string &src);
|
||||
|
||||
const_iterator begin () const
|
||||
{
|
||||
return m_layers.begin ();
|
||||
}
|
||||
|
||||
iterator begin ()
|
||||
{
|
||||
return m_layers.begin ();
|
||||
}
|
||||
|
||||
const_iterator end () const
|
||||
{
|
||||
return m_layers.end ();
|
||||
}
|
||||
|
||||
iterator end ()
|
||||
{
|
||||
return m_layers.end ();
|
||||
}
|
||||
|
||||
void clear ()
|
||||
{
|
||||
m_layers.clear ();
|
||||
}
|
||||
|
||||
void erase (iterator p)
|
||||
{
|
||||
m_layers.erase (p);
|
||||
}
|
||||
|
||||
void insert (iterator p, const D25LayerInfo &info)
|
||||
{
|
||||
m_layers.insert (p, info);
|
||||
}
|
||||
|
||||
void add (const D25LayerInfo &info)
|
||||
{
|
||||
m_layers.push_back (info);
|
||||
}
|
||||
|
||||
size_t size () const
|
||||
{
|
||||
return m_layers.size ();
|
||||
}
|
||||
layers_type compile_from_source () const;
|
||||
|
||||
const std::string &src () const
|
||||
{
|
||||
|
|
@ -145,7 +98,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
layers_type m_layers;
|
||||
std::string m_src;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -30,44 +30,73 @@ TEST(1)
|
|||
{
|
||||
db::D25TechnologyComponent comp;
|
||||
|
||||
comp.compile_from_source ("1/0: 1.0 1.5 # a comment");
|
||||
comp.set_src ("1/0: 1.0 1.5 # a comment");
|
||||
comp.compile_from_source ();
|
||||
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5");
|
||||
|
||||
comp.compile_from_source ("1/0: zstart=1.0 zstop=1.5");
|
||||
comp.set_src ("1/0: zstart=1.0 zstop=1.5");
|
||||
comp.compile_from_source ();
|
||||
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5");
|
||||
|
||||
comp.compile_from_source ("1/0: zstart=1.0 height=0.5");
|
||||
comp.set_src ("1/0: zstart=1.0 height=0.5");
|
||||
comp.compile_from_source ();
|
||||
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5");
|
||||
|
||||
comp.compile_from_source ("1/0: 1.0 height=0.5");
|
||||
comp.set_src ("1/0: 1.0 height=0.5");
|
||||
comp.compile_from_source ();
|
||||
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5");
|
||||
|
||||
comp.compile_from_source ("1/0: zstop=1.5 height=0.5");
|
||||
comp.set_src ("1/0: zstop=1.5 height=0.5");
|
||||
comp.compile_from_source ();
|
||||
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5");
|
||||
|
||||
comp.compile_from_source ("1/0: zstart=1.0 zstop=1.5\nname: height=3");
|
||||
comp.set_src ("1/0: zstart=1.0 zstop=1.5\nname: height=3");
|
||||
comp.compile_from_source ();
|
||||
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5\nname: zstart=1.5, zstop=4.5");
|
||||
|
||||
comp.compile_from_source ("1/0: zstart=1.0 zstop=1.5\nname: zstart=4.0 height=3\n\n# a comment line");
|
||||
comp.set_src ("1/0: zstart=1.0 zstop=1.5\nname: zstart=4.0 height=3\n\n# a comment line");
|
||||
comp.compile_from_source ();
|
||||
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5\nname: zstart=4, zstop=7");
|
||||
|
||||
comp.set_src ("var x=1.0\n1/0: zstart=x zstop=x+0.5\nname: zstart=4.0 height=3\n\n# a comment line");
|
||||
comp.compile_from_source ();
|
||||
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5\nname: zstart=4, zstop=7");
|
||||
|
||||
comp.set_src ("var x=1.0\nif x == 1.0\n1/0: zstart=x zstop=x+0.5\nelse\n1/0: zstart=0 zstop=0\nend\nname: zstart=4.0 height=3\n\n# a comment line");
|
||||
comp.compile_from_source ();
|
||||
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5\nname: zstart=4, zstop=7");
|
||||
|
||||
comp.set_src ("var x=2.0\nif x == 1.0\n1/0: zstart=x zstop=x+0.5\nelse\n1/0: zstart=0 zstop=0\nend\nname: zstart=4.0 height=3\n\n# a comment line");
|
||||
comp.compile_from_source ();
|
||||
EXPECT_EQ (comp.to_string (), "1/0: zstart=0, zstop=0\nname: zstart=4, zstop=7");
|
||||
|
||||
try {
|
||||
comp.compile_from_source ("blabla");
|
||||
comp.set_src ("blabla");
|
||||
comp.compile_from_source ();
|
||||
EXPECT_EQ (false, true);
|
||||
} catch (...) { }
|
||||
|
||||
try {
|
||||
comp.compile_from_source ("1/0: 1 2 3");
|
||||
comp.set_src ("1/0: 1 2 3");
|
||||
comp.compile_from_source ();
|
||||
EXPECT_EQ (false, true);
|
||||
} catch (...) { }
|
||||
|
||||
try {
|
||||
comp.compile_from_source ("1/0: foo=1 bar=2");
|
||||
comp.set_src ("1/0: foo=1 bar=2");
|
||||
comp.compile_from_source ();
|
||||
EXPECT_EQ (false, true);
|
||||
} catch (...) { }
|
||||
|
||||
try {
|
||||
comp.compile_from_source ("1/0: 1;2");
|
||||
comp.set_src ("1/0: 1;*2");
|
||||
comp.compile_from_source ();
|
||||
EXPECT_EQ (false, true);
|
||||
} catch (...) { }
|
||||
|
||||
try {
|
||||
comp.set_src ("error 42");
|
||||
comp.compile_from_source ();
|
||||
EXPECT_EQ (false, true);
|
||||
} catch (...) { }
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
|
|
@ -0,0 +1,147 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE language SYSTEM "klayout_doc.dtd">
|
||||
|
||||
<doc>
|
||||
|
||||
<title>The 2.5d View</title>
|
||||
<keyword name="2.5d"/>
|
||||
<keyword name="3d"/>
|
||||
<keyword name="2.5d View"/>
|
||||
<keyword name="z-Stack"/>
|
||||
|
||||
<h2-index/>
|
||||
|
||||
<p>
|
||||
The "2.5d view" offers a semi-3d view of the layout. It's not a full 3d view as the layers are only extruded vertically
|
||||
into layers with a certain thickness. The view cannot model process topology, but it can visualize
|
||||
wiring congestions in a three-dimensional space or the vertical relative dimensions of features of the process stack.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To open the view, use "Tools/2.5d View". Currently, the performance is limited, a rough number for a
|
||||
practical limit is around 100k polygons. The 2.5d view is only available, if KLayout was compiled with
|
||||
OpenGL support.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<img src="/about/25d_screenshot.png"/>
|
||||
</p>
|
||||
|
||||
<h2>Setup</h2>
|
||||
|
||||
<p>
|
||||
The 2.5d view needs a technology setup explaining the way the layers are transformed into planes.
|
||||
The setup is provided within a technology. Open the technology manager (File/Manage Technologies) and
|
||||
navigate to the "Z Stack (2.5d)" component. The setup is basically a list of entries listing the
|
||||
layer from which to take the shapes and the depth information.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Each entry is a single line. Empty lines are ignored. Everything after a '#' character is
|
||||
considered a comment.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Each specification line consists of a layer specification, a colon and arguments.
|
||||
The arguments are named (like "x=...") or in serial. Parameters are separated by comma or blanks.
|
||||
Named arguments are:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li> <b>zstart</b>: The lower z position of the extruded layer in µm </li>
|
||||
<li> <b>zstop</b>: The upper z position of the extruded layer in µm </li>
|
||||
<li> <b>height</b>: The height of the extruded layer in µm </li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
'height', 'zstart' and 'zstop' can be used in any combination. If no value is given for 'zstart',
|
||||
the upper level of the previous layer will be used.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If a single unnamed parameter is given, it corresponds to 'height'. Two parameters correspond to
|
||||
'zstart' and 'zstop'.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Here are some examples:
|
||||
</p>
|
||||
|
||||
<pre>1: 0.5 1.5 # extrude layer 1/0 from 0.5 to 1.5 vertically\n"
|
||||
1/0: 0.5 1.5 # same with explicit datatype\n"
|
||||
1: zstop=1.5, zstart=0.5 # same with named parameters\n"
|
||||
1: height=1.0, zstop=1.5 # same with z stop minus height\n"
|
||||
1: 1.0 zstop=1.5 # same with height as unnamed parameter\n"
|
||||
</pre>
|
||||
|
||||
<h4>Variables</h4>
|
||||
|
||||
<p>
|
||||
You can declare variables inside the setup files and use them in formulas for
|
||||
computed values. Variables are defined and set with the "var" keyword on a single line.
|
||||
The notation follows the "expression" syntax used in many other places inside KLayout
|
||||
(<link href="/about/expressions.xml"/>).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Here is an example:
|
||||
</p>
|
||||
|
||||
<pre>var hmetal = 0.48\n"
|
||||
7/0: 0.5 0.5+hmetal*2 # 2x thick metal\n"
|
||||
</pre>
|
||||
|
||||
<h4>Conditionals</h4>
|
||||
|
||||
<p>
|
||||
For more flexibility, but of little practical use for now, conditionals are provided.
|
||||
"if", "else", "elsif" and "end" for as in other languages, e.g. Ruby:
|
||||
</p>
|
||||
|
||||
<pre>var thick_m1 = true
|
||||
if thickm1
|
||||
1: 0.5 1.5
|
||||
else
|
||||
1: 0.5 1.2
|
||||
end
|
||||
</pre>
|
||||
|
||||
<h2>Navigating the 2.5d View</h2>
|
||||
<keyword>navigation</keyword>
|
||||
<keyword>2.5d navigation</keyword>
|
||||
|
||||
<p>
|
||||
The navigation is based on the movement of the camera while the scene is
|
||||
formed by the extruded layout. The scene can be scaled to provide zoom features.
|
||||
Scaling and rotation is relative to the pivot point which is indicated by the
|
||||
compass icon on the ground plane.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This is a short list of the navigation controls which act on the camera:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li> Dragging with the right mouse button down: change azimuth and elevation angle </li>
|
||||
<li> Dragging with the middle mouse button down: move the pivot up and down or left and right </li>
|
||||
<li> Mouse wheel: moves the pivot forward and backward </li>
|
||||
<li> Control key + mouse wheel: magnify or shrink the layout </li>
|
||||
<li> Press and hold shift key: switch to top level view (see below) </li>
|
||||
<li> Up/down keys: move the pivot forward or backward </li>
|
||||
<li> Left/right keys: move the pivot to the left or the right </li>
|
||||
<li> Control + up/down keys: change the elevation angle </li>
|
||||
<li> Control + left/right keys: change the azimuth angle </li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
In top level view, the navigation is slightly different:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li> Dragging with the right mouse button down: change azimuth angle </li>
|
||||
<li> mouse wheel: magnify or shrink the layout </li>
|
||||
<li> Up/down/left/right keys: move the pivot on the horizontal plane </li>
|
||||
</ul>
|
||||
|
||||
</doc>
|
||||
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
<topic href="/about/variant_notation.xml"/>
|
||||
<topic href="/about/lef_def_import.xml"/>
|
||||
<topic href="/about/connectivity.xml"/>
|
||||
<topic href="/about/25d_view.xml"/>
|
||||
<topic href="/about/symbolic_layers.xml"/>
|
||||
<topic href="/about/layer_sources.xml"/>
|
||||
<topic href="/about/macro_editor.xml"/>
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@
|
|||
<file alias="lvs_ref_global.xml">doc/about/lvs_ref_global.xml</file>
|
||||
<file alias="lvs_ref_netter.xml">doc/about/lvs_ref_netter.xml</file>
|
||||
<file alias="packages.xml">doc/about/packages.xml</file>
|
||||
<file alias="25d_view.xml">doc/about/25d_view.xml</file>
|
||||
<file alias="25d_screenshot.png">doc/about/25d_screenshot.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/help/manual">
|
||||
<file alias="adjust_origin.xml">doc/manual/adjust_origin.xml</file>
|
||||
|
|
|
|||
|
|
@ -3942,7 +3942,7 @@ MainWindow::menu_activated (const std::string &symbol)
|
|||
if (current_view ()) {
|
||||
current_view ()->menu_activated (symbol);
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("No view is active")));
|
||||
throw tl::Exception (tl::to_string (QObject::tr ("This function needs a layout but none was available")));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,12 @@
|
|||
<family>Monospace</family>
|
||||
</font>
|
||||
</property>
|
||||
<property name="lineWrapMode">
|
||||
<enum>QTextEdit::NoWrap</enum>
|
||||
</property>
|
||||
<property name="acceptRichText">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ BookmarkItem::to_string () const
|
|||
BrowserPanel::BrowserPanel (QWidget *parent)
|
||||
: QWidget (parent),
|
||||
m_back_dm (this, &BrowserPanel::back),
|
||||
m_new_url_dm (this, &BrowserPanel::new_url),
|
||||
mp_dispatcher (0)
|
||||
{
|
||||
init ();
|
||||
|
|
@ -125,6 +126,7 @@ BrowserPanel::init ()
|
|||
|
||||
mp_ui->browser->addAction (mp_ui->action_find);
|
||||
mp_ui->browser->addAction (mp_ui->action_bookmark);
|
||||
mp_ui->browser->setOpenLinks (false);
|
||||
|
||||
mp_ui->browser_bookmark_view->addAction (mp_ui->action_delete_bookmark);
|
||||
mp_ui->browser_bookmark_view->setContextMenuPolicy (Qt::ActionsContextMenu);
|
||||
|
|
@ -138,7 +140,8 @@ BrowserPanel::init ()
|
|||
connect (mp_ui->search_edit, SIGNAL (textEdited (const QString &)), this, SLOT (search_text_changed (const QString &)));
|
||||
connect (mp_ui->search_edit, SIGNAL (returnPressed ()), this, SLOT (search_edited ()));
|
||||
connect (mp_ui->search_button, SIGNAL (clicked ()), this, SLOT (search_edited ()));
|
||||
connect (mp_ui->browser, SIGNAL (textChanged ()), this, SLOT (text_changed ()));
|
||||
connect (mp_ui->browser, SIGNAL (sourceChanged (const QUrl &)), this, SLOT (source_changed ()));
|
||||
connect (mp_ui->browser, SIGNAL (anchorClicked (const QUrl &)), this, SLOT (anchor_clicked (const QUrl &)));
|
||||
connect (mp_ui->browser, SIGNAL (backwardAvailable (bool)), mp_ui->back_pb, SLOT (setEnabled (bool)));
|
||||
connect (mp_ui->browser, SIGNAL (forwardAvailable (bool)), mp_ui->forward_pb, SLOT (setEnabled (bool)));
|
||||
connect (mp_ui->outline_tree, SIGNAL (itemActivated (QTreeWidgetItem *, int)), this, SLOT (outline_item_clicked (QTreeWidgetItem *)));
|
||||
|
|
@ -218,7 +221,7 @@ BrowserPanel::title () const
|
|||
std::string
|
||||
BrowserPanel::url () const
|
||||
{
|
||||
return m_cached_url;
|
||||
return tl::to_string (mp_ui->browser->source ().toString ());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -416,13 +419,24 @@ BrowserPanel::search_text_changed (const QString &text)
|
|||
}
|
||||
|
||||
void
|
||||
BrowserPanel::text_changed ()
|
||||
BrowserPanel::source_changed ()
|
||||
{
|
||||
m_new_url_dm ();
|
||||
}
|
||||
|
||||
void
|
||||
BrowserPanel::anchor_clicked (const QUrl &url)
|
||||
{
|
||||
mp_ui->browser->setSource (url);
|
||||
source_changed ();
|
||||
}
|
||||
|
||||
void
|
||||
BrowserPanel::new_url ()
|
||||
{
|
||||
QString title = mp_ui->browser->document ()->metaInformation (QTextDocument::DocumentTitle);
|
||||
if (title != m_current_title) {
|
||||
m_current_title = title;
|
||||
emit title_changed (title);
|
||||
}
|
||||
m_current_title = title;
|
||||
emit title_changed (title);
|
||||
|
||||
// refresh on-page search
|
||||
page_search_edited ();
|
||||
|
|
|
|||
|
|
@ -441,7 +441,9 @@ protected slots:
|
|||
void page_search_next();
|
||||
void search_text_changed(const QString &text);
|
||||
void search_edited ();
|
||||
void text_changed ();
|
||||
void source_changed ();
|
||||
void anchor_clicked (const QUrl &url);
|
||||
void new_url ();
|
||||
void outline_item_clicked (QTreeWidgetItem *item);
|
||||
void bookmark_item_selected (QTreeWidgetItem *item);
|
||||
void delete_bookmark ();
|
||||
|
|
@ -462,6 +464,7 @@ private:
|
|||
Ui::BrowserPanel *mp_ui;
|
||||
bool m_schedule_back;
|
||||
tl::DeferredMethod<BrowserPanel> m_back_dm;
|
||||
tl::DeferredMethod<BrowserPanel> m_new_url_dm;
|
||||
std::string m_search_url, m_search_query_item;
|
||||
QString m_current_title;
|
||||
QList<QTextEdit::ExtraSelection> m_search_selection;
|
||||
|
|
|
|||
|
|
@ -72,7 +72,13 @@ D25TechnologyComponentEditor::commit ()
|
|||
}
|
||||
|
||||
std::string src = tl::to_string (src_te->toPlainText ());
|
||||
data->compile_from_source (src);
|
||||
|
||||
// test-compile before setting it
|
||||
db::D25TechnologyComponent tc;
|
||||
tc.set_src (src);
|
||||
tc.compile_from_source ();
|
||||
|
||||
data->set_src (src);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -5,13 +5,35 @@
|
|||
|
||||
<highlighting>
|
||||
|
||||
<list name="Control Keywords">
|
||||
<item> zstart </item>
|
||||
<item> zstop </item>
|
||||
<item> height </item>
|
||||
</list>
|
||||
|
||||
<list name="Expression Keywords">
|
||||
<item> true </item>
|
||||
<item> false </item>
|
||||
<item> nil </item>
|
||||
</list>
|
||||
|
||||
<contexts>
|
||||
|
||||
<context name="Normal" attribute="Normal Text">
|
||||
<context name="Normal" attribute="Normal Text" fallthrough="true" fallthroughContext="Error" lineEndContext="Normal">
|
||||
|
||||
<RegExpr attribute="Normal" String="\s*" context="#stay"/>
|
||||
|
||||
<StringDetect attribute="Symbol" String="var" context="Expect Assignment"/>
|
||||
<StringDetect attribute="Symbol" String="print" context="Expression"/>
|
||||
<StringDetect attribute="Symbol" String="error" context="Expression"/>
|
||||
<StringDetect attribute="Symbol" String="if" context="Expression"/>
|
||||
<StringDetect attribute="Symbol" String="elsif" context="Expression"/>
|
||||
<StringDetect attribute="Symbol" String="else" context="Expect Lineend"/>
|
||||
<StringDetect attribute="Symbol" String="end" context="Expect Lineend"/>
|
||||
|
||||
<DetectChar attribute="String" char=""" context="Quoted String"/>
|
||||
<DetectChar attribute="String" char="'" context="Apostrophed String"/>
|
||||
<DetectChar attribute="Comment" char="#" context="Comment"/>
|
||||
<DetectChar attribute="Raw String" char="'" context="Apostrophed String"/>
|
||||
|
||||
<RegExpr attribute="Normal" String=":" context="After LD"/>
|
||||
|
||||
|
|
@ -22,22 +44,52 @@
|
|||
<DetectChar attribute="Normal" char="/" context="#stay"/>
|
||||
<RegExpr attribute="Raw String" String="[_a-zA-Z]\w*" context="#stay"/>
|
||||
|
||||
<RegExpr attribute="Error" String="[^\s]" context="Error"/>
|
||||
|
||||
</context>
|
||||
|
||||
<context name="Comment" attribute="Comment" lineEndContext="Normal">
|
||||
</context>
|
||||
|
||||
<context name="After LD" attribute="Normal" lineEndContext="Normal">
|
||||
<context name="Expect Lineend" attribute="Normal" lineEndContext="Normal" fallthrough="true" fallthroughContext="Error">
|
||||
<RegExpr attribute="Normal" String="\s*" context="#stay"/>
|
||||
<DetectChar attribute="Comment" char="#" context="Comment"/>
|
||||
</context>
|
||||
|
||||
<context name="Expression" fallthrough="true" fallthroughContext="Error" lineEndContext="Normal">
|
||||
|
||||
<RegExpr attribute="Normal" String="\s*" context="#stay"/>
|
||||
<DetectChar attribute="Comment" char="#" context="Comment"/>
|
||||
|
||||
<keyword attribute="Symbol" String="Expression Keywords" context="#stay"/>
|
||||
<keyword attribute="Symbol" String="Control Keywords" context="Expect Expression"/>
|
||||
|
||||
<DetectChar attribute="String" char=""" context="Quoted String"/>
|
||||
<DetectChar attribute="String" char="'" context="Apostrophed String"/>
|
||||
<RegExpr attribute="Name" String="[_a-zA-Z]\w*" context="#stay"/>
|
||||
<RegExpr attribute="Float" String="\-?[0-9]([0-9]|_[0-9])*(\.[0-9]([0-9]|_[0-9])*)?([eE]\-?[1-9]([0-9]|_[0-9])*(\.[0-9]*)?)?" context="#stay"/>
|
||||
|
||||
<DetectChar attribute="Normal" char="," context="#stay"/>
|
||||
<DetectChar attribute="Normal" char="=" context="#stay"/>
|
||||
<StringDetect attribute="Symbol" String="zstart" context="#stay"/>
|
||||
<StringDetect attribute="Symbol" String="zstop" context="#stay"/>
|
||||
<StringDetect attribute="Symbol" String="height" context="#stay"/>
|
||||
<RegExpr attribute="Error" String="[^\s]" context="Error"/>
|
||||
<DetectChar attribute="Normal" char="(" context="#stay"/>
|
||||
<DetectChar attribute="Normal" char=")" context="#stay"/>
|
||||
<DetectChar attribute="Normal" char="[" context="#stay"/>
|
||||
<DetectChar attribute="Normal" char="]" context="#stay"/>
|
||||
|
||||
<RegExpr attribute="Normal" String="[\^\*\.\+\-%/!=<>&|,\?:]" context="#stay"/>
|
||||
|
||||
</context>
|
||||
|
||||
<context name="Expect Expression" attribute="Normal" lineEndContext="Error" fallthrough="true" fallthroughContext="Error">
|
||||
<RegExpr attribute="Normal" String="\s*" context="#stay"/>
|
||||
<DetectChar attribute="Normal" char="=" context="Expression"/>
|
||||
</context>
|
||||
|
||||
<context name="Expect Assignment" attribute="Normal" lineEndContext="Error" fallthrough="true" fallthroughContext="Error">
|
||||
<RegExpr attribute="Normal" String="\s*" context="#stay"/>
|
||||
<RegExpr attribute="Name" String="[_a-zA-Z]\w*" context="Expect Expression"/>
|
||||
</context>
|
||||
|
||||
<context name="After LD" attribute="Normal" lineEndContext="Error" fallthrough="true" fallthroughContext="Expression">
|
||||
<RegExpr attribute="Normal" String="\s*" context="#stay"/>
|
||||
<DetectChar attribute="Comment" char="#" context="Error"/>
|
||||
</context>
|
||||
|
||||
<context name="Error" attribute="Error" lineEndContext="Normal">
|
||||
|
|
@ -46,19 +98,21 @@
|
|||
<context name="Quoted String" attribute="String" lineEndContext="Error">
|
||||
<StringDetect attribute="String" String="\\" context="#stay"/>
|
||||
<RegExpr attribute="String" String="\\\"" context="#stay"/>
|
||||
<DetectChar char=""" attribute="String" context="Normal"/>
|
||||
<DetectChar char=""" attribute="String" context="#pop"/>
|
||||
</context>
|
||||
|
||||
<context name="Apostrophed String" attribute="Raw String" lineEndContext="Error">
|
||||
<StringDetect attribute="String" String="\\" context="#stay"/>
|
||||
<RegExpr attribute="String" String="\\\'" context="#stay"/>
|
||||
<DetectChar char="'" attribute="Raw String" context="Normal"/>
|
||||
<DetectChar char="'" attribute="Raw String" context="#pop"/>
|
||||
</context>
|
||||
|
||||
</contexts>
|
||||
|
||||
<itemDatas>
|
||||
|
||||
<itemData name="Normal Text" defStyleNum="dsNormal"/>
|
||||
<itemData name="Name" defStyleNum="dsNormal"/>
|
||||
|
||||
<itemData name="Comment" defStyleNum="dsComment"/>
|
||||
<itemData name="Float" defStyleNum="dsFloat"/>
|
||||
|
|
@ -73,4 +127,12 @@
|
|||
</itemDatas>
|
||||
|
||||
</highlighting>
|
||||
|
||||
<general>
|
||||
<comments>
|
||||
<comment name="singleLine" start="#"/>
|
||||
</comments>
|
||||
<keywords casesensitive="1" weakDeliminator="!?"/>
|
||||
</general>
|
||||
|
||||
</language>
|
||||
|
|
|
|||
|
|
@ -350,9 +350,9 @@
|
|||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<widget class="QLabel" name="doc_label">
|
||||
<property name="text">
|
||||
<string>Press and hold SHIFT for top view</string>
|
||||
<string>Press and hold SHIFT for top view (<a href="int:/about/25d_view.xml">more</a>)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ D25Camera::~D25Camera ()
|
|||
void
|
||||
D25Camera::init ()
|
||||
{
|
||||
m_fov = 90.0;
|
||||
m_fov = 45.0;
|
||||
m_cam_azimuth = m_cam_elevation = 0.0;
|
||||
m_top_view = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ public:
|
|||
virtual void get_menu_entries (std::vector<lay::MenuEntry> &menu_entries) const
|
||||
{
|
||||
lay::PluginDeclaration::get_menu_entries (menu_entries);
|
||||
menu_entries.push_back (lay::menu_item ("lay::d25_view", "d25_view:edit", "tools_menu.post_verification_group", tl::to_string (QObject::tr ("2.5d View"))));
|
||||
menu_entries.push_back (lay::menu_item ("lay::d25_view", "d25_view:edit", "tools_menu.post_verification_group", tl::to_string (QObject::tr ("2.5d View - experimental"))));
|
||||
}
|
||||
|
||||
virtual bool configure (const std::string & /*name*/, const std::string & /*value*/)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "layD25View.h"
|
||||
#include "layLayoutView.h"
|
||||
#include "layQtTools.h"
|
||||
|
||||
#include "ui_D25View.h"
|
||||
|
||||
|
|
@ -53,6 +54,8 @@ D25View::D25View (QWidget *parent)
|
|||
connect (mp_ui->d25_view, SIGNAL (init_failed ()), this, SLOT (init_failed ()));
|
||||
|
||||
mp_ui->gl_stack->setCurrentIndex (0);
|
||||
|
||||
lay::activate_help_links (mp_ui->doc_label);
|
||||
}
|
||||
|
||||
D25View::~D25View ()
|
||||
|
|
|
|||
|
|
@ -246,40 +246,23 @@ D25ViewWidget::wheelEvent (QWheelEvent *event)
|
|||
|
||||
} else {
|
||||
|
||||
// compute vector of line of sight
|
||||
std::pair<QVector3D, QVector3D> ray = camera_normal (cam_perspective () * cam_trans (), px, py);
|
||||
|
||||
// by definition the ray goes through the camera position
|
||||
QVector3D hp = hit_point_with_scene (ray.second);
|
||||
double d = event->angleDelta ().y () * (1.0 / (90 * 16));
|
||||
|
||||
if (! (event->modifiers () & Qt::ControlModifier)) {
|
||||
|
||||
// No Ctrl is closeup
|
||||
// No Ctrl is "move horizontally along the azimuth axis"
|
||||
|
||||
double f = event->angleDelta ().y () * (1.0 / (90 * 8));
|
||||
m_displacement += -((f / m_scale_factor) * std::min (cam_dist (), double ((cam_position () - hp).length ()))) * ray.second;
|
||||
QMatrix4x4 t;
|
||||
t.rotate (cam_azimuth (), 0.0, 1.0, 0.0);
|
||||
QVector3D cd = t.inverted ().map (QVector3D (0, 0, cam_dist ()));
|
||||
|
||||
m_displacement += d * cd;
|
||||
|
||||
} else {
|
||||
|
||||
// "Ctrl" is zoom
|
||||
|
||||
double f = exp (event->angleDelta ().y () * (1.0 / (90 * 8)));
|
||||
|
||||
QVector3D initial_displacement = m_displacement;
|
||||
QVector3D displacement = m_displacement;
|
||||
|
||||
m_scale_factor *= f;
|
||||
displacement += hp * (1.0 - f) / m_scale_factor;
|
||||
|
||||
// normalize the scene translation so the scene does not "flee"
|
||||
|
||||
QMatrix4x4 ct = cam_trans ();
|
||||
initial_displacement = ct.map (initial_displacement);
|
||||
displacement = ct.map (displacement);
|
||||
|
||||
lay::normalize_scene_trans (cam_perspective (), displacement, m_scale_factor, initial_displacement.z ());
|
||||
|
||||
m_displacement = ct.inverted ().map (displacement);
|
||||
m_scale_factor *= exp (d);
|
||||
|
||||
emit scale_factor_changed (m_scale_factor);
|
||||
|
||||
|
|
@ -294,8 +277,65 @@ void
|
|||
D25ViewWidget::keyPressEvent (QKeyEvent *event)
|
||||
{
|
||||
if (event->key () == Qt::Key_Shift) {
|
||||
|
||||
mp_mode.reset (0);
|
||||
set_top_view (true);
|
||||
|
||||
} else if (event->key () == Qt::Key_Up || event->key () == Qt::Key_Down) {
|
||||
|
||||
if (! top_view () && (event->modifiers () & Qt::ControlModifier) != 0) {
|
||||
|
||||
// Ctrl + up/down changes elevation
|
||||
|
||||
double d = (event->key () == Qt::Key_Up ? 2 : -2);
|
||||
|
||||
set_cam_elevation (std::max (-90.0, std::min (90.0, cam_elevation () + d)));
|
||||
|
||||
} else {
|
||||
|
||||
// Move "into" or "out"
|
||||
|
||||
double d = (event->key () == Qt::Key_Up ? 0.1 : -0.1);
|
||||
|
||||
QMatrix4x4 t;
|
||||
t.rotate (cam_azimuth (), 0.0, 1.0, 0.0);
|
||||
QVector3D cd = t.inverted ().map (QVector3D (0, 0, cam_dist ()));
|
||||
|
||||
set_displacement (displacement () + d * cd);
|
||||
|
||||
}
|
||||
|
||||
} else if (event->key () == Qt::Key_Left || event->key () == Qt::Key_Right) {
|
||||
|
||||
if (! top_view () && (event->modifiers () & Qt::ControlModifier) != 0) {
|
||||
|
||||
// Ctrl + left/right changes azumith
|
||||
|
||||
double d = (event->key () == Qt::Key_Right ? 2 : -2);
|
||||
|
||||
double a = cam_azimuth () + d;
|
||||
if (a < -180.0) {
|
||||
a += 360.0;
|
||||
} else if (a > 180.0) {
|
||||
a -= 360.0;
|
||||
}
|
||||
|
||||
set_cam_azimuth (a);
|
||||
|
||||
} else {
|
||||
|
||||
// Move "left" and "right"
|
||||
|
||||
double d = (event->key () == Qt::Key_Left ? 0.1 : -0.1);
|
||||
|
||||
QMatrix4x4 t;
|
||||
t.rotate (cam_azimuth (), 0.0, 1.0, 0.0);
|
||||
QVector3D cd = t.inverted ().map (QVector3D (cam_dist (), 0, 0));
|
||||
|
||||
set_displacement (displacement () + d * cd);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -435,17 +475,17 @@ namespace {
|
|||
|
||||
const db::D25LayerInfo *operator() (lay::LayoutView *view, int cv_index, int layer_index)
|
||||
{
|
||||
std::map<int, std::map<int, const db::D25LayerInfo *> >::const_iterator c = m_cache.find (cv_index);
|
||||
std::map<int, std::map<int, db::D25LayerInfo> >::const_iterator c = m_cache.find (cv_index);
|
||||
if (c != m_cache.end ()) {
|
||||
std::map<int, const db::D25LayerInfo *>::const_iterator l = c->second.find (layer_index);
|
||||
std::map<int, db::D25LayerInfo>::const_iterator l = c->second.find (layer_index);
|
||||
if (l != c->second.end ()) {
|
||||
return l->second;
|
||||
return &l->second;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::map<int, const db::D25LayerInfo *> &lcache = m_cache [cv_index];
|
||||
std::map<int, db::D25LayerInfo> &lcache = m_cache [cv_index];
|
||||
|
||||
const db::D25TechnologyComponent *comp = 0;
|
||||
|
||||
|
|
@ -457,16 +497,18 @@ namespace {
|
|||
|
||||
if (comp) {
|
||||
|
||||
std::map<db::LayerProperties, const db::D25LayerInfo *, db::LPLogicalLessFunc> 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-> ()));
|
||||
std::map<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)) {
|
||||
const db::LayerProperties &lp = ly.get_properties (l);
|
||||
std::map<db::LayerProperties, const db::D25LayerInfo *, db::LPLogicalLessFunc>::const_iterator z = zi_by_lp.find (lp);
|
||||
std::map<db::LayerProperties, db::D25LayerInfo, db::LPLogicalLessFunc>::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));
|
||||
|
|
@ -485,7 +527,7 @@ namespace {
|
|||
|
||||
|
||||
private:
|
||||
std::map<int, std::map<int, const db::D25LayerInfo *> > m_cache;
|
||||
std::map<int, std::map<int, db::D25LayerInfo> > m_cache;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -955,9 +997,12 @@ D25ViewWidget::paintGL ()
|
|||
|
||||
vertexes.add (-0.25 * compass_rad, 0.0, 0.6 * compass_rad);
|
||||
vertexes.add (0.0, 0.0, -0.8 * compass_rad);
|
||||
vertexes.add (0.0, 0.0, -0.8 * compass_rad);
|
||||
vertexes.add (0.25 * compass_rad, 0.0, 0.6 * compass_rad);
|
||||
vertexes.add (0.25 * compass_rad, 0.0, 0.6 * compass_rad);
|
||||
vertexes.add (-0.25 * compass_rad, 0.0, 0.6 * compass_rad);
|
||||
|
||||
vertexes.draw_to (this, positions, GL_TRIANGLES);
|
||||
vertexes.draw_to (this, positions, GL_LINES);
|
||||
|
||||
// draw base plane
|
||||
|
||||
|
|
@ -1029,8 +1074,8 @@ D25ViewWidget::paintGL ()
|
|||
|
||||
glDisable (GL_DEPTH_TEST);
|
||||
|
||||
int cube_size = 64;
|
||||
int cube_margin = 20;
|
||||
int cube_size = 32;
|
||||
int cube_margin = 40;
|
||||
|
||||
QMatrix4x4 into_top_right_corner;
|
||||
into_top_right_corner.translate (1.0 - 2.0 / width () * (cube_margin + cube_size / 2), 1.0 - 2.0 / height () * (cube_margin + cube_size / 2));
|
||||
|
|
|
|||
Loading…
Reference in New Issue