mirror of https://github.com/KLayout/klayout.git
commit
94b71cbf76
|
|
@ -185,6 +185,7 @@ SOURCES = \
|
|||
gsiDeclDbNetlistCrossReference.cc \
|
||||
gsiDeclDbLayoutVsSchematic.cc \
|
||||
dbNetlistObject.cc \
|
||||
dbD25TechnologyComponent.cc \
|
||||
gsiDeclDbTexts.cc \
|
||||
dbTexts.cc \
|
||||
dbDeepTexts.cc \
|
||||
|
|
@ -345,6 +346,7 @@ HEADERS = \
|
|||
dbLayoutVsSchematicFormatDefs.h \
|
||||
dbLayoutVsSchematic.h \
|
||||
dbNetlistObject.h \
|
||||
dbD25TechnologyComponent.h \
|
||||
dbTexts.h \
|
||||
dbDeepTexts.h \
|
||||
dbAsIfFlatTexts.h \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,332 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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 "dbD25TechnologyComponent.h"
|
||||
#include "tlClassRegistry.h"
|
||||
#include "tlString.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
std::string d25_component_name ()
|
||||
{
|
||||
return std::string ("d25");
|
||||
}
|
||||
|
||||
std::string d25_description ()
|
||||
{
|
||||
return tl::to_string (tr ("Z stack (2.5d)"));
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
// D25LayerInfo implementation
|
||||
|
||||
D25LayerInfo::D25LayerInfo ()
|
||||
: m_layer (), m_zstart (0.0), m_zstop (0.0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
D25LayerInfo::~D25LayerInfo ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
D25LayerInfo::D25LayerInfo (const D25LayerInfo &other)
|
||||
{
|
||||
operator= (other);
|
||||
}
|
||||
|
||||
D25LayerInfo &
|
||||
D25LayerInfo::operator= (const D25LayerInfo &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
m_layer = other.m_layer;
|
||||
m_zstart = other.m_zstart;
|
||||
m_zstop = other.m_zstop;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
D25LayerInfo::operator== (const D25LayerInfo &other) const
|
||||
{
|
||||
return fabs (m_zstart - other.m_zstart) < db::epsilon && fabs (m_zstop - other.m_zstop) < db::epsilon;
|
||||
}
|
||||
|
||||
void
|
||||
D25LayerInfo::set_layer (const db::LayerProperties &l)
|
||||
{
|
||||
m_layer = l;
|
||||
}
|
||||
|
||||
void
|
||||
D25LayerInfo::set_layer_from_string (const std::string &l)
|
||||
{
|
||||
db::LayerProperties lp;
|
||||
tl::Extractor ex (l.c_str ());
|
||||
try {
|
||||
lp.read (ex);
|
||||
} catch (tl::Exception &) {
|
||||
// ignore errors for now.
|
||||
}
|
||||
m_layer = lp;
|
||||
}
|
||||
|
||||
std::string
|
||||
D25LayerInfo::layer_as_string () const
|
||||
{
|
||||
return m_layer.to_string ();
|
||||
}
|
||||
|
||||
void
|
||||
D25LayerInfo::set_zstart (double z0)
|
||||
{
|
||||
m_zstart = z0;
|
||||
}
|
||||
|
||||
void
|
||||
D25LayerInfo::set_zstop (double z1)
|
||||
{
|
||||
m_zstop = z1;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
// D25TechnologyComponent implementation
|
||||
|
||||
D25TechnologyComponent::D25TechnologyComponent ()
|
||||
: db::TechnologyComponent (d25_component_name (), d25_description ())
|
||||
{
|
||||
// provide some explanation for the initialization
|
||||
m_src =
|
||||
"# Provide z stack information here\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"
|
||||
"#\n"
|
||||
"# zstart The lower z position of the extruded layer in µm\n"
|
||||
"# 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', "
|
||||
"# 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"
|
||||
"# 'zstart' and 'zstop'.\n"
|
||||
"#\n"
|
||||
"# Examples:\n"
|
||||
"# 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"
|
||||
;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int current_line = 0;
|
||||
m_layers.clear ();
|
||||
|
||||
try {
|
||||
|
||||
std::vector<std::string> lines = tl::split (src, "\n");
|
||||
for (std::vector<std::string>::const_iterator l = lines.begin (); l != lines.end (); ++l) {
|
||||
|
||||
++current_line;
|
||||
|
||||
tl::Extractor ex (l->c_str ());
|
||||
|
||||
if (ex.test ("#")) {
|
||||
// ignore comments
|
||||
} else if (ex.at_end ()) {
|
||||
// ignore empty lines
|
||||
} else {
|
||||
|
||||
db::D25LayerInfo info;
|
||||
if (! m_layers.empty ()) {
|
||||
info.set_zstart (m_layers.back ().zstop ());
|
||||
info.set_zstop (m_layers.back ().zstop ());
|
||||
}
|
||||
|
||||
tl::Variant z0, z1, h;
|
||||
std::vector<double> args;
|
||||
|
||||
db::LayerProperties lp;
|
||||
lp.read (ex);
|
||||
info.set_layer (lp);
|
||||
|
||||
ex.expect (":");
|
||||
|
||||
while (! ex.at_end ()) {
|
||||
|
||||
if (ex.test ("#")) {
|
||||
break;
|
||||
}
|
||||
|
||||
double pv = 0.0;
|
||||
|
||||
std::string pn;
|
||||
if (ex.try_read_name (pn)) {
|
||||
ex.expect ("=");
|
||||
ex.read (pv);
|
||||
} else {
|
||||
ex.read (pv);
|
||||
}
|
||||
|
||||
ex.test (",");
|
||||
|
||||
if (pn.empty ()) {
|
||||
args.push_back (pv);
|
||||
} else if (pn == "zstart") {
|
||||
z0 = pv;
|
||||
} else if (pn == "zstop") {
|
||||
z1 = pv;
|
||||
} else if (pn == "height") {
|
||||
h = pv;
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (tr ("Invalid parameter name: ")) + pn);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (args.size () == 0) {
|
||||
if (z0.is_nil () && z1.is_nil ()) {
|
||||
if (! h.is_nil ()) {
|
||||
info.set_zstop (info.zstart () + h.to_double ());
|
||||
}
|
||||
} else if (z0.is_nil ()) {
|
||||
info.set_zstop (z1.to_double ());
|
||||
if (! h.is_nil ()) {
|
||||
info.set_zstart (info.zstop () - h.to_double ());
|
||||
}
|
||||
} else if (z1.is_nil ()) {
|
||||
info.set_zstart (z0.to_double ());
|
||||
if (! h.is_nil ()) {
|
||||
info.set_zstop (info.zstart () + h.to_double ());
|
||||
}
|
||||
} else {
|
||||
info.set_zstart (z0.to_double ());
|
||||
info.set_zstop (z1.to_double ());
|
||||
}
|
||||
} 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")));
|
||||
}
|
||||
if (! z1.is_nil ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Rundundant 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")));
|
||||
}
|
||||
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")));
|
||||
}
|
||||
if (! z1.is_nil ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Rundundant parameters: zstop already given")));
|
||||
}
|
||||
if (! h.is_nil ()) {
|
||||
throw tl::Exception (tl::to_string (tr ("Rundundant parameters: height implicitly given")));
|
||||
}
|
||||
info.set_zstart (args[0]);
|
||||
info.set_zstop (args[1]);
|
||||
} else {
|
||||
throw tl::Exception (tl::to_string (tr ("Too many parameters (max 2)")));
|
||||
}
|
||||
|
||||
m_layers.push_back (info);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (tl::Exception &ex) {
|
||||
throw tl::Exception (ex.msg () + tl::sprintf (tl::to_string (tr (" in line %d")), current_line));
|
||||
}
|
||||
|
||||
m_src = src;
|
||||
}
|
||||
|
||||
std::string
|
||||
D25TechnologyComponent::to_string () const
|
||||
{
|
||||
std::string res;
|
||||
|
||||
for (const_iterator i = begin (); i != end (); ++i) {
|
||||
if (! res.empty ()) {
|
||||
res += "\n";
|
||||
}
|
||||
res += i->layer ().to_string () + ": zstart=" + tl::to_string (i->zstart ()) + ", zstop=" + tl::to_string (i->zstop ());
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
// D25TechnologyComponent technology component registration
|
||||
|
||||
class D25TechnologyComponentProvider
|
||||
: public db::TechnologyComponentProvider
|
||||
{
|
||||
public:
|
||||
D25TechnologyComponentProvider ()
|
||||
: db::TechnologyComponentProvider ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual db::TechnologyComponent *create_component () const
|
||||
{
|
||||
return new D25TechnologyComponent ();
|
||||
}
|
||||
|
||||
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")
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<db::TechnologyComponentProvider> tc_decl (new D25TechnologyComponentProvider (), 3100, d25_component_name ().c_str ());
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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
|
||||
|
||||
*/
|
||||
|
||||
#ifndef HDR_dbD25TechnologyComponent
|
||||
#define HDR_dbD25TechnologyComponent
|
||||
|
||||
#include "dbTechnology.h"
|
||||
#include "dbLayerProperties.h"
|
||||
|
||||
namespace db
|
||||
{
|
||||
|
||||
class DB_PUBLIC D25LayerInfo
|
||||
{
|
||||
public:
|
||||
D25LayerInfo ();
|
||||
~D25LayerInfo ();
|
||||
D25LayerInfo (const D25LayerInfo &other);
|
||||
D25LayerInfo &operator= (const D25LayerInfo &other);
|
||||
|
||||
bool operator== (const D25LayerInfo &other) const;
|
||||
|
||||
const db::LayerProperties &layer () const
|
||||
{
|
||||
return m_layer;
|
||||
}
|
||||
|
||||
void set_layer_from_string (const std::string &l);
|
||||
std::string layer_as_string () const;
|
||||
|
||||
void set_layer (const db::LayerProperties &l);
|
||||
|
||||
double zstart () const
|
||||
{
|
||||
return m_zstart;
|
||||
}
|
||||
|
||||
void set_zstart (double z0);
|
||||
|
||||
double zstop () const
|
||||
{
|
||||
return m_zstop;
|
||||
}
|
||||
|
||||
void set_zstop (double z1);
|
||||
|
||||
private:
|
||||
db::LayerProperties m_layer;
|
||||
double m_zstart, m_zstop;
|
||||
};
|
||||
|
||||
class DB_PUBLIC D25TechnologyComponent
|
||||
: public db::TechnologyComponent
|
||||
{
|
||||
public:
|
||||
D25TechnologyComponent ();
|
||||
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 ();
|
||||
}
|
||||
|
||||
const std::string &src () const
|
||||
{
|
||||
return m_src;
|
||||
}
|
||||
|
||||
// for persistency only, use "compile_from_source" to read from a source string
|
||||
void set_src (const std::string &s)
|
||||
{
|
||||
m_src = s;
|
||||
}
|
||||
|
||||
std::string to_string () const;
|
||||
|
||||
db::TechnologyComponent *clone () const
|
||||
{
|
||||
return new D25TechnologyComponent (*this);
|
||||
}
|
||||
|
||||
private:
|
||||
layers_type m_layers;
|
||||
std::string m_src;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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 "dbD25TechnologyComponent.h"
|
||||
#include "tlUnitTest.h"
|
||||
|
||||
|
||||
TEST(1)
|
||||
{
|
||||
db::D25TechnologyComponent comp;
|
||||
|
||||
comp.compile_from_source ("1/0: 1.0 1.5 # a comment");
|
||||
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5");
|
||||
|
||||
comp.compile_from_source ("1/0: zstart=1.0 zstop=1.5");
|
||||
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5");
|
||||
|
||||
comp.compile_from_source ("1/0: zstart=1.0 height=0.5");
|
||||
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5");
|
||||
|
||||
comp.compile_from_source ("1/0: 1.0 height=0.5");
|
||||
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5");
|
||||
|
||||
comp.compile_from_source ("1/0: zstop=1.5 height=0.5");
|
||||
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");
|
||||
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");
|
||||
EXPECT_EQ (comp.to_string (), "1/0: zstart=1, zstop=1.5\nname: zstart=4, zstop=7");
|
||||
|
||||
try {
|
||||
comp.compile_from_source ("blabla");
|
||||
EXPECT_EQ (false, true);
|
||||
} catch (...) { }
|
||||
|
||||
try {
|
||||
comp.compile_from_source ("1/0: 1 2 3");
|
||||
EXPECT_EQ (false, true);
|
||||
} catch (...) { }
|
||||
|
||||
try {
|
||||
comp.compile_from_source ("1/0: foo=1 bar=2");
|
||||
EXPECT_EQ (false, true);
|
||||
} catch (...) { }
|
||||
|
||||
try {
|
||||
comp.compile_from_source ("1/0: 1;2");
|
||||
EXPECT_EQ (false, true);
|
||||
} catch (...) { }
|
||||
}
|
||||
|
|
@ -34,6 +34,7 @@ SOURCES = \
|
|||
dbPolygonToolsTests.cc \
|
||||
dbTechnologyTests.cc \
|
||||
dbStreamLayerTests.cc \
|
||||
dbD25TechnologyComponentTests.cc \
|
||||
dbVectorTests.cc \
|
||||
dbVariableWidthPathTests.cc \
|
||||
dbTransTests.cc \
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 537 B |
Binary file not shown.
|
After Width: | Height: | Size: 530 B |
Binary file not shown.
|
After Width: | Height: | Size: 543 B |
Binary file not shown.
|
After Width: | Height: | Size: 548 B |
Binary file not shown.
|
After Width: | Height: | Size: 542 B |
Binary file not shown.
|
After Width: | Height: | Size: 526 B |
|
|
@ -127,6 +127,12 @@
|
|||
<file alias="folder_12.png">images/folder_12.png</file>
|
||||
<file alias="file_12.png">images/file_12.png</file>
|
||||
<file alias="empty_12.png">images/empty_12.png</file>
|
||||
<file alias="fit_front.png">images/fit_front.png</file>
|
||||
<file alias="fit_back.png">images/fit_back.png</file>
|
||||
<file alias="fit_left.png">images/fit_left.png</file>
|
||||
<file alias="fit_right.png">images/fit_right.png</file>
|
||||
<file alias="fit_top.png">images/fit_top.png</file>
|
||||
<file alias="fit_bottom.png">images/fit_bottom.png</file>
|
||||
<file alias="unlocked_16.png">images/unlocked_16.png</file>
|
||||
<file alias="locked_16.png">images/locked_16.png</file>
|
||||
</qresource>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>D25TechnologyComponentEditor</class>
|
||||
<widget class="QFrame" name="D25TechnologyComponentEditor">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>549</width>
|
||||
<height>434</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>2.5d Vertical Stack Information</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="lnum_label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Line</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QTextEdit" name="src_te">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Monospace</family>
|
||||
</font>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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 "laybasicConfig.h"
|
||||
#include "dbD25TechnologyComponent.h"
|
||||
#include "layD25TechnologyComponent.h"
|
||||
|
||||
#include <QResource>
|
||||
#include <QBuffer>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
D25TechnologyComponentEditor::D25TechnologyComponentEditor (QWidget *parent)
|
||||
: TechnologyComponentEditor (parent)
|
||||
{
|
||||
setupUi (this);
|
||||
|
||||
// TODO: activate_help_links (mp_ui->help_label);
|
||||
|
||||
QResource res (tl::to_qstring (":/syntax/d25_text.xml"));
|
||||
QByteArray data ((const char *) res.data (), int (res.size ()));
|
||||
if (res.isCompressed ()) {
|
||||
data = qUncompress (data);
|
||||
}
|
||||
|
||||
QBuffer input (&data);
|
||||
input.open (QIODevice::ReadOnly);
|
||||
mp_hl_basic_attributes.reset (new GenericSyntaxHighlighterAttributes ());
|
||||
mp_hl_attributes.reset (new GenericSyntaxHighlighterAttributes (mp_hl_basic_attributes.get ()));
|
||||
lay::GenericSyntaxHighlighter *hl = new GenericSyntaxHighlighter (src_te, input, mp_hl_attributes.get ());
|
||||
input.close ();
|
||||
|
||||
hl->setDocument (src_te->document ());
|
||||
|
||||
connect (src_te, SIGNAL (cursorPositionChanged ()), this, SLOT (cursor_position_changed ()));
|
||||
}
|
||||
|
||||
void
|
||||
D25TechnologyComponentEditor::cursor_position_changed ()
|
||||
{
|
||||
int line = src_te->textCursor ().block ().firstLineNumber () + 1;
|
||||
lnum_label->setText (tl::to_qstring (tl::sprintf (tl::to_string (tr ("Line %d")), line)));
|
||||
}
|
||||
|
||||
void
|
||||
D25TechnologyComponentEditor::commit ()
|
||||
{
|
||||
db::D25TechnologyComponent *data = dynamic_cast <db::D25TechnologyComponent *> (tech_component ());
|
||||
if (! data) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string src = tl::to_string (src_te->toPlainText ());
|
||||
data->compile_from_source (src);
|
||||
}
|
||||
|
||||
void
|
||||
D25TechnologyComponentEditor::setup ()
|
||||
{
|
||||
db::D25TechnologyComponent *data = dynamic_cast <db::D25TechnologyComponent *> (tech_component ());
|
||||
if (! data) {
|
||||
return;
|
||||
}
|
||||
|
||||
src_te->setPlainText (tl::to_qstring (data->src ()));
|
||||
}
|
||||
|
||||
class D25TechnologyComponentEditorProvider
|
||||
: public lay::TechnologyEditorProvider
|
||||
{
|
||||
public:
|
||||
virtual lay::TechnologyComponentEditor *create_editor (QWidget *parent) const
|
||||
{
|
||||
return new D25TechnologyComponentEditor (parent);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<lay::TechnologyEditorProvider> editor_decl (new D25TechnologyComponentEditorProvider (), 3100, "d25");
|
||||
|
||||
} // namespace lay
|
||||
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HDR_layD25TechnologyComponent
|
||||
#define HDR_layD25TechnologyComponent
|
||||
|
||||
#include "ui_D25TechnologyComponentEditor.h"
|
||||
#include "layTechnology.h"
|
||||
#include "layGenericSyntaxHighlighter.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace lay {
|
||||
|
||||
class D25TechnologyComponentEditor
|
||||
: public lay::TechnologyComponentEditor,
|
||||
public Ui::D25TechnologyComponentEditor
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
D25TechnologyComponentEditor (QWidget *parent);
|
||||
|
||||
void commit ();
|
||||
void setup ();
|
||||
|
||||
private slots:
|
||||
void cursor_position_changed ();
|
||||
|
||||
private:
|
||||
std::auto_ptr<lay::GenericSyntaxHighlighterAttributes> mp_hl_attributes, mp_hl_basic_attributes;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -73,7 +73,8 @@ FORMS = \
|
|||
NetInfoDialog.ui \
|
||||
NetExportDialog.ui \
|
||||
SelectCellViewForm.ui \
|
||||
LayoutStatistics.ui
|
||||
LayoutStatistics.ui \
|
||||
D25TechnologyComponentEditor.ui
|
||||
|
||||
RESOURCES = \
|
||||
laybasicResources.qrc \
|
||||
|
|
@ -184,6 +185,7 @@ SOURCES = \
|
|||
layDispatcher.cc \
|
||||
laySelectCellViewForm.cc \
|
||||
layLayoutStatisticsForm.cc \
|
||||
layD25TechnologyComponent.cc \
|
||||
gsiDeclLayNetlistBrowserDialog.cc
|
||||
|
||||
HEADERS = \
|
||||
|
|
@ -285,7 +287,8 @@ HEADERS = \
|
|||
layGenericSyntaxHighlighter.h \
|
||||
layDispatcher.h \
|
||||
laySelectCellViewForm.h \
|
||||
layLayoutStatisticsForm.h
|
||||
layLayoutStatisticsForm.h \
|
||||
layD25TechnologyComponent.h
|
||||
|
||||
INCLUDEPATH += $$TL_INC $$GSI_INC $$DB_INC $$RDB_INC $$LYM_INC
|
||||
DEPENDPATH += $$TL_INC $$GSI_INC $$DB_INC $$RDB_INC $$LYM_INC
|
||||
|
|
|
|||
|
|
@ -45,5 +45,6 @@
|
|||
<file>images/icon_device_bjt_24.png</file>
|
||||
<file>images/icon_device_bjt_16.png</file>
|
||||
<file>syntax/ur_text.xml</file>
|
||||
<file>syntax/d25_text.xml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE language SYSTEM "language.dtd">
|
||||
|
||||
<language name="UserPropertiesTextFormat">
|
||||
|
||||
<highlighting>
|
||||
|
||||
<contexts>
|
||||
|
||||
<context name="Normal" attribute="Normal Text">
|
||||
|
||||
<DetectChar attribute="String" char=""" context="Quoted String"/>
|
||||
<DetectChar attribute="Comment" char="#" context="Comment"/>
|
||||
<DetectChar attribute="Raw String" char="'" context="Apostrophed String"/>
|
||||
|
||||
<RegExpr attribute="Normal" String=":" context="After LD"/>
|
||||
|
||||
<RegExpr attribute="Dec" String="\-?[0-9]+" context="#stay"/>
|
||||
<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="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">
|
||||
<DetectChar attribute="Comment" char="#" context="Comment"/>
|
||||
<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"/>
|
||||
</context>
|
||||
|
||||
<context name="Error" attribute="Error" lineEndContext="Normal">
|
||||
</context>
|
||||
|
||||
<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"/>
|
||||
</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"/>
|
||||
</context>
|
||||
|
||||
</contexts>
|
||||
|
||||
<itemDatas>
|
||||
<itemData name="Normal Text" defStyleNum="dsNormal"/>
|
||||
|
||||
<itemData name="Comment" defStyleNum="dsComment"/>
|
||||
<itemData name="Float" defStyleNum="dsFloat"/>
|
||||
<itemData name="Dec" defStyleNum="dsDecVal"/>
|
||||
<itemData name="Symbol" defStyleNum="dsKeyword"/>
|
||||
<itemData name="String" defStyleNum="dsString"/>
|
||||
<itemData name="Raw String" defStyleNum="dsString" color="#DD4A4A" selColor="#DD4A4A"/>
|
||||
|
||||
<!-- use these to mark errors and alerts things -->
|
||||
<itemData name="Error" defStyleNum="dsAlert"/>
|
||||
|
||||
</itemDatas>
|
||||
|
||||
</highlighting>
|
||||
</language>
|
||||
|
|
@ -0,0 +1,325 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>D25View</class>
|
||||
<widget class="QDialog" name="D25View">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>854</width>
|
||||
<height>665</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>2.5d View</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QSlider" name="zoom_slider">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-300</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>300</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="zoom_factor">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>%</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="fit_left">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../lay/lay/layResources.qrc">
|
||||
<normaloff>:/fit_left.png</normaloff>:/fit_left.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="fit_front">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../lay/lay/layResources.qrc">
|
||||
<normaloff>:/fit_front.png</normaloff>:/fit_front.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="fit_right">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../lay/lay/layResources.qrc">
|
||||
<normaloff>:/fit_right.png</normaloff>:/fit_right.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="fit_back">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../lay/lay/layResources.qrc">
|
||||
<normaloff>:/fit_back.png</normaloff>:/fit_back.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="fit_top">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../lay/lay/layResources.qrc">
|
||||
<normaloff>:/fit_top.png</normaloff>:/fit_top.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="fit_bottom">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../lay/lay/layResources.qrc">
|
||||
<normaloff>:/fit_bottom.png</normaloff>:/fit_bottom.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="lay::D25ViewWidget" name="d25_view"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Press and hold SHIFT for top view</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>lay::D25ViewWidget</class>
|
||||
<extends>QOpenGLWidget</extends>
|
||||
<header>layD25ViewWidget.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../../../lay/lay/layResources.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>D25View</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>530</x>
|
||||
<y>626</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>443</x>
|
||||
<y>643</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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 "layD25Camera.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "math.h"
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
D25Camera::D25Camera ()
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
||||
D25Camera::~D25Camera ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
void
|
||||
D25Camera::init ()
|
||||
{
|
||||
m_fov = 90.0;
|
||||
m_cam_azimuth = m_cam_elevation = 0.0;
|
||||
m_top_view = false;
|
||||
}
|
||||
|
||||
void
|
||||
D25Camera::camera_reset ()
|
||||
{
|
||||
init ();
|
||||
camera_changed ();
|
||||
}
|
||||
|
||||
double
|
||||
D25Camera::cam_fov () const
|
||||
{
|
||||
return m_fov;
|
||||
}
|
||||
|
||||
double
|
||||
D25Camera::cam_dist () const
|
||||
{
|
||||
return 4.0;
|
||||
}
|
||||
|
||||
QVector3D
|
||||
D25Camera::cam_direction () const
|
||||
{
|
||||
return cam_trans ().inverted ().map (QVector3D (0, 0, -1));
|
||||
}
|
||||
|
||||
QVector3D
|
||||
D25Camera::cam_position () const
|
||||
{
|
||||
return cam_direction () * -cam_dist ();
|
||||
}
|
||||
|
||||
double
|
||||
D25Camera::cam_azimuth () const
|
||||
{
|
||||
return m_cam_azimuth;
|
||||
}
|
||||
|
||||
double
|
||||
D25Camera::cam_elevation () const
|
||||
{
|
||||
return m_top_view ? -90.0 : m_cam_elevation;
|
||||
}
|
||||
|
||||
QMatrix4x4
|
||||
D25Camera::cam_perspective () const
|
||||
{
|
||||
QMatrix4x4 t;
|
||||
t.perspective (cam_fov (), aspect_ratio (), 0.1f, 10000.0f);
|
||||
t.translate (QVector3D (0.0, 0.0, -cam_dist ()));
|
||||
return t;
|
||||
}
|
||||
|
||||
QMatrix4x4
|
||||
D25Camera::cam_trans () const
|
||||
{
|
||||
QMatrix4x4 t;
|
||||
t.rotate (-cam_elevation (), 1.0, 0.0, 0.0);
|
||||
t.rotate (cam_azimuth (), 0.0, 1.0, 0.0);
|
||||
return t;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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
|
||||
|
||||
*/
|
||||
|
||||
#ifndef HDR_layD25Camera
|
||||
#define HDR_layD25Camera
|
||||
|
||||
#include "layPluginCommon.h"
|
||||
|
||||
#include <QMatrix4x4>
|
||||
#include <QVector3D>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
class LAY_PLUGIN_PUBLIC D25Camera
|
||||
{
|
||||
public:
|
||||
D25Camera ();
|
||||
virtual ~D25Camera ();
|
||||
|
||||
/**
|
||||
* @brief Gets the position of the camera objective in the scene coordinate system
|
||||
*/
|
||||
QVector3D cam_position () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the direction the camera looks into in the scene coordinate system
|
||||
*/
|
||||
QVector3D cam_direction () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the perspective part of the transformation applied transform scene coordinates into the image plane
|
||||
* The full transformation for scene to image plane is cam_perspective * cam_trans.
|
||||
*/
|
||||
QMatrix4x4 cam_perspective () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the azimuth/elevation part of the transformation applied transform scene coordinates into the image plane
|
||||
* The full transformation for scene to image plane is cam_perspective * cam_trans.
|
||||
*/
|
||||
QMatrix4x4 cam_trans () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the distance of the objective in scene coordinates
|
||||
*/
|
||||
double cam_dist () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the field of view of the camera
|
||||
* The field of view is the objective opening angle.
|
||||
*/
|
||||
double cam_fov () const;
|
||||
|
||||
/**
|
||||
* @brief Gets a flag indicating whether top view is enabled
|
||||
* In "top view" mode, the elevation is fixed to -90 degree.
|
||||
*/
|
||||
bool top_view () const
|
||||
{
|
||||
return m_top_view;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a flag indicating whether top view is enabled
|
||||
*/
|
||||
void set_top_view (bool f)
|
||||
{
|
||||
m_top_view = f;
|
||||
camera_changed ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the elevation angle
|
||||
* A negative angle means the camera looks down, a positive angle means it looks up.
|
||||
*/
|
||||
double cam_elevation () const;
|
||||
|
||||
/**
|
||||
* @brief Sets the elevation angle
|
||||
*/
|
||||
void set_cam_elevation (double e)
|
||||
{
|
||||
m_cam_elevation = e;
|
||||
camera_changed ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the azimuth angle
|
||||
* A positive angle means we look from the left. A negative means we look from the right.
|
||||
*/
|
||||
double cam_azimuth () const;
|
||||
|
||||
/**
|
||||
* @brief Sets the azimuth angle
|
||||
*/
|
||||
void set_cam_azimuth (double a)
|
||||
{
|
||||
m_cam_azimuth = a;
|
||||
camera_changed ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets the camera's orientation
|
||||
*/
|
||||
void camera_reset ();
|
||||
|
||||
protected:
|
||||
virtual void camera_changed () { }
|
||||
virtual double aspect_ratio () const { return 1.0; }
|
||||
|
||||
private:
|
||||
double m_cam_azimuth, m_cam_elevation;
|
||||
bool m_top_view;
|
||||
QVector3D m_displacement;
|
||||
double m_fov;
|
||||
|
||||
void init ();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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 "layD25MemChunks.h"
|
||||
|
||||
|
|
@ -0,0 +1,266 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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
|
||||
|
||||
*/
|
||||
|
||||
#ifndef HDR_layD25MemChunks
|
||||
#define HDR_layD25MemChunks
|
||||
|
||||
#include <QDialog>
|
||||
#include <QOpenGLFunctions>
|
||||
|
||||
#include "tlObject.h"
|
||||
#include <string.h> // for memcpy
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
template <class Obj>
|
||||
struct gl_type2enum
|
||||
{
|
||||
GLenum operator() () const;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct gl_type2enum<float>
|
||||
{
|
||||
GLenum operator() () const { return GL_FLOAT; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Provides a semi-contiguous array of objects
|
||||
*
|
||||
* The objects are kept in chunks of ChunkLen items.
|
||||
* The blocks can be accessed individually. The array can be
|
||||
* cleared and new items can be added. No insert or delete.
|
||||
*
|
||||
* This object is intended to be used for keeping vertex,
|
||||
* color or point data for OpenGL.
|
||||
*/
|
||||
template <class Obj, size_t ChunkLen = 1024>
|
||||
class mem_chunks
|
||||
: public QDialog
|
||||
{
|
||||
public:
|
||||
|
||||
struct chunk {
|
||||
public:
|
||||
chunk ()
|
||||
: m_len (0), m_next (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
chunk (const chunk &other)
|
||||
: m_len (0), m_next (0)
|
||||
{
|
||||
operator= (other);
|
||||
}
|
||||
|
||||
chunk &operator= (const chunk &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
memcpy (&m_objects, &other.m_objects, sizeof (m_objects));
|
||||
m_len = other.m_len;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const Obj *front () const { return m_objects; }
|
||||
size_t size () const { return m_len; }
|
||||
const chunk *next () const { return m_next; }
|
||||
|
||||
private:
|
||||
friend class mem_chunks;
|
||||
|
||||
Obj m_objects [ChunkLen];
|
||||
size_t m_len;
|
||||
chunk *m_next;
|
||||
};
|
||||
|
||||
class iterator
|
||||
{
|
||||
public:
|
||||
iterator (chunk *ch = 0)
|
||||
: mp_chunk (ch)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
bool operator== (iterator other) const
|
||||
{
|
||||
return mp_chunk == other.mp_chunk;
|
||||
}
|
||||
|
||||
bool operator!= (iterator other) const
|
||||
{
|
||||
return mp_chunk != other.mp_chunk;
|
||||
}
|
||||
|
||||
const chunk &operator* () const
|
||||
{
|
||||
return *mp_chunk;
|
||||
}
|
||||
|
||||
const chunk *operator-> () const
|
||||
{
|
||||
return mp_chunk;
|
||||
}
|
||||
|
||||
void operator++ ()
|
||||
{
|
||||
mp_chunk = mp_chunk->next ();
|
||||
}
|
||||
|
||||
private:
|
||||
const chunk *mp_chunk;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Default constructor
|
||||
* Creates an empty array
|
||||
*/
|
||||
mem_chunks ()
|
||||
: mp_chunks (0), mp_last_chunk (0)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~mem_chunks ()
|
||||
{
|
||||
clear ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy constructor
|
||||
*/
|
||||
mem_chunks (const mem_chunks &other)
|
||||
: mp_chunks (0), mp_last_chunk (0)
|
||||
{
|
||||
operator= (other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Assignment
|
||||
*/
|
||||
mem_chunks &operator= (const mem_chunks &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
clear ();
|
||||
const chunk *ch = other.mp_chunks;
|
||||
while (ch) {
|
||||
if (! mp_chunks) {
|
||||
mp_last_chunk = mp_chunks = new chunk (*ch);
|
||||
} else {
|
||||
mp_last_chunk->m_next = new chunk (*ch);
|
||||
mp_last_chunk = mp_last_chunk->m_next;
|
||||
}
|
||||
ch = ch->next ();
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears the array
|
||||
*/
|
||||
void clear ()
|
||||
{
|
||||
chunk *ch = mp_chunks;
|
||||
mp_chunks = 0;
|
||||
mp_last_chunk = 0;
|
||||
while (ch) {
|
||||
chunk *del = ch;
|
||||
ch = ch->m_next;
|
||||
delete del;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds an element to the array
|
||||
*/
|
||||
void add (const Obj &element)
|
||||
{
|
||||
if (! mp_last_chunk) {
|
||||
mp_chunks = mp_last_chunk = new chunk ();
|
||||
}
|
||||
|
||||
if (mp_last_chunk->m_len >= ChunkLen) {
|
||||
mp_last_chunk->m_next = new chunk ();
|
||||
mp_last_chunk = mp_last_chunk->m_next;
|
||||
}
|
||||
|
||||
mp_last_chunk->m_objects [mp_last_chunk->m_len++] = element;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds two elements
|
||||
*/
|
||||
void add (const Obj &e1, const Obj &e2)
|
||||
{
|
||||
add (e1);
|
||||
add (e2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds three elements
|
||||
*/
|
||||
void add (const Obj &e1, const Obj &e2, const Obj &e3)
|
||||
{
|
||||
add (e1);
|
||||
add (e2);
|
||||
add (e3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief begin iterator
|
||||
*/
|
||||
iterator begin () const { return iterator (mp_chunks); }
|
||||
|
||||
/**
|
||||
* @brief end iterator
|
||||
*/
|
||||
iterator end () const { return iterator (); }
|
||||
|
||||
/**
|
||||
* @brief Draw to the given context
|
||||
*/
|
||||
void draw_to (QOpenGLFunctions *ctx, GLuint location, GLenum mode) const
|
||||
{
|
||||
for (iterator c = begin (); c != end (); ++c) {
|
||||
ctx->glVertexAttribPointer (location, 3, gl_type2enum<Obj> () (), GL_FALSE, 0, c->front ());
|
||||
ctx->glDrawArrays (mode, 0, c->size () / 3);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
chunk *mp_chunks;
|
||||
chunk *mp_last_chunk;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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 "layD25View.h"
|
||||
#include "layDispatcher.h"
|
||||
|
||||
#include "layPlugin.h"
|
||||
|
||||
#include <QSurfaceFormat>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
class D25Plugin
|
||||
: public lay::Plugin
|
||||
{
|
||||
public:
|
||||
D25Plugin (Plugin *parent, lay::LayoutView *view)
|
||||
: lay::Plugin (parent), mp_view (view)
|
||||
{
|
||||
mp_dialog = new lay::D25View (0);
|
||||
}
|
||||
|
||||
~D25Plugin ()
|
||||
{
|
||||
delete mp_dialog;
|
||||
mp_dialog = 0;
|
||||
}
|
||||
|
||||
void menu_activated (const std::string &symbol)
|
||||
{
|
||||
if (symbol == "lay::d25_view") {
|
||||
|
||||
if (mp_dialog->exec_dialog (mp_view)) {
|
||||
|
||||
// ... implementation is in layD25ToolDialog.cc ...
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
lay::LayoutView *mp_view;
|
||||
lay::D25View *mp_dialog;
|
||||
};
|
||||
|
||||
class D25PluginDeclaration
|
||||
: public lay::PluginDeclaration
|
||||
{
|
||||
public:
|
||||
D25PluginDeclaration ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual void get_options (std::vector < std::pair<std::string, std::string> > & /*options*/) const
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual lay::ConfigPage *config_page (QWidget * /*parent*/, std::string & /*title*/) const
|
||||
{
|
||||
// .. nothing yet ..
|
||||
return 0;
|
||||
}
|
||||
|
||||
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"))));
|
||||
}
|
||||
|
||||
virtual bool configure (const std::string & /*name*/, const std::string & /*value*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void config_finalize ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
lay::Plugin *create_plugin (db::Manager *, lay::Dispatcher *root, lay::LayoutView *view) const
|
||||
{
|
||||
return new D25Plugin (root, view);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<lay::PluginDeclaration> config_decl (new lay::D25PluginDeclaration (), 3100, "lay::D25Plugin");
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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 "layD25View.h"
|
||||
#include "layLayoutView.h"
|
||||
|
||||
#include "ui_D25View.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
const double initial_elevation = 3.0;
|
||||
|
||||
D25View::D25View (QWidget *parent)
|
||||
: QDialog (parent)
|
||||
{
|
||||
mp_ui = new Ui::D25View ();
|
||||
mp_ui->setupUi (this);
|
||||
|
||||
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->d25_view, SIGNAL (scale_factor_changed (double)), this, SLOT (scale_factor_changed (double)));
|
||||
}
|
||||
|
||||
D25View::~D25View ()
|
||||
{
|
||||
delete mp_ui;
|
||||
mp_ui = 0;
|
||||
}
|
||||
|
||||
static QString scale_factor_to_string (double f)
|
||||
{
|
||||
QString s;
|
||||
s.sprintf ("x %.3g", f);
|
||||
return s;
|
||||
}
|
||||
|
||||
void
|
||||
D25View::scale_slider_changed (int value)
|
||||
{
|
||||
double f = exp (log (10.0) * -0.01 * value);
|
||||
mp_ui->zoom_factor->setText (scale_factor_to_string (f));
|
||||
mp_ui->d25_view->set_scale_factor (f);
|
||||
}
|
||||
|
||||
void
|
||||
D25View::scale_factor_changed (double f)
|
||||
{
|
||||
mp_ui->zoom_factor->setText (scale_factor_to_string (f));
|
||||
int v = floor (0.5 - log10 (f) * 100.0);
|
||||
mp_ui->zoom_slider->blockSignals (true);
|
||||
mp_ui->zoom_slider->setValue (v);
|
||||
mp_ui->zoom_slider->blockSignals (false);
|
||||
}
|
||||
|
||||
int
|
||||
D25View::exec_dialog (lay::LayoutView *view)
|
||||
{
|
||||
mp_view.reset (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);
|
||||
mp_ui->d25_view->set_cam_elevation (initial_elevation);
|
||||
mp_ui->d25_view->fit ();
|
||||
|
||||
int ret = QDialog::exec ();
|
||||
|
||||
mp_ui->d25_view->attach_view (0);
|
||||
mp_view.reset (0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
D25View::fit_button_clicked ()
|
||||
{
|
||||
double azimuth = mp_ui->d25_view->cam_azimuth ();
|
||||
double elevation = mp_ui->d25_view->cam_elevation ();
|
||||
|
||||
if (sender () == mp_ui->fit_back) {
|
||||
azimuth = -180.0;
|
||||
elevation = -initial_elevation;
|
||||
} else if (sender () == mp_ui->fit_front) {
|
||||
azimuth = 0.0;
|
||||
elevation = -initial_elevation;
|
||||
} else if (sender () == mp_ui->fit_left) {
|
||||
azimuth = 90.0;
|
||||
elevation = -initial_elevation;
|
||||
} else if (sender () == mp_ui->fit_right) {
|
||||
azimuth = -90.0;
|
||||
elevation = -initial_elevation;
|
||||
} else if (sender () == mp_ui->fit_top) {
|
||||
elevation = -90;
|
||||
} else if (sender () == mp_ui->fit_bottom) {
|
||||
elevation = 90;
|
||||
}
|
||||
|
||||
mp_ui->d25_view->set_cam_azimuth (azimuth);
|
||||
mp_ui->d25_view->set_cam_elevation (elevation);
|
||||
|
||||
mp_ui->d25_view->fit ();
|
||||
}
|
||||
|
||||
void
|
||||
D25View::accept ()
|
||||
{
|
||||
QDialog::accept ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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
|
||||
|
||||
*/
|
||||
|
||||
#ifndef HDR_layD25View
|
||||
#define HDR_layD25View
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include "tlObject.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class D25View;
|
||||
}
|
||||
|
||||
namespace lay
|
||||
{
|
||||
class LayoutView;
|
||||
}
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
class D25View
|
||||
: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
D25View (QWidget *parent);
|
||||
~D25View ();
|
||||
|
||||
int exec_dialog (lay::LayoutView *view);
|
||||
|
||||
protected:
|
||||
void accept ();
|
||||
|
||||
private slots:
|
||||
void fit_button_clicked ();
|
||||
void scale_factor_changed (double f);
|
||||
void scale_slider_changed (int value);
|
||||
|
||||
private:
|
||||
Ui::D25View *mp_ui;
|
||||
tl::weak_ptr<lay::LayoutView> mp_view;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,228 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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 "layD25ViewUtils.h"
|
||||
|
||||
#include <QMatrix4x4>
|
||||
#include <QMatrix3x3>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
const double epsilon = 1e-10;
|
||||
|
||||
std::pair<bool, QVector3D>
|
||||
cutpoint_line_with_plane (const QVector3D &line, const QVector3D &dir, const QVector3D &plane, const QVector3D &plane_normal)
|
||||
{
|
||||
double dn = QVector3D::dotProduct (dir, plane_normal);
|
||||
if (fabs (dn) < epsilon) {
|
||||
return std::make_pair (false, QVector3D ());
|
||||
} else {
|
||||
return std::make_pair (true, line + dir * QVector3D::dotProduct (plane - line, plane_normal) / dn);
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<bool, QVector3D>
|
||||
cutpoint_line_with_face (const QVector3D &line, const QVector3D &dir, const QVector3D &plane, const QVector3D &u, const QVector3D &v)
|
||||
{
|
||||
QVector3D n = QVector3D::crossProduct (u, v);
|
||||
std::pair<bool, QVector3D> r = cutpoint_line_with_plane (line, dir, plane, n);
|
||||
if (! r.first) {
|
||||
return r;
|
||||
}
|
||||
|
||||
double pu = QVector3D::dotProduct (r.second - plane, u);
|
||||
double pv = QVector3D::dotProduct (r.second - plane, v);
|
||||
|
||||
// test whether the cut point is inside the face
|
||||
if (pu < -epsilon || pu > u.lengthSquared () + epsilon || pv < -epsilon || pv > v.lengthSquared () + epsilon) {
|
||||
return std::make_pair (false, QVector3D ());
|
||||
} else {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
static bool somewhat_perpendicular (const QVector3D &a, const QVector3D &b)
|
||||
{
|
||||
// returns true if a and b are perpendicular within +/-30 degree
|
||||
return fabs (QVector3D::dotProduct (a, b)) < 0.5 * a.length () * b.length ();
|
||||
}
|
||||
|
||||
static std::pair<bool, QVector3D> plane_or_face (const QVector3D &line, const QVector3D &line_dir, const QVector3D &corner, const QVector3D &u, const QVector3D &v, bool face)
|
||||
{
|
||||
if (face) {
|
||||
return cutpoint_line_with_face (line, line_dir, corner, u, v);
|
||||
} else if (somewhat_perpendicular (u, line_dir) && somewhat_perpendicular (v, line_dir)) {
|
||||
return cutpoint_line_with_plane (line, line_dir, corner, QVector3D::crossProduct (u, v));
|
||||
} else {
|
||||
return std::make_pair (false, QVector3D ());
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<bool, QVector3D>
|
||||
hit_point_with_cuboid (const QVector3D &line, const QVector3D &line_dir, const QVector3D &corner, const QVector3D &dim)
|
||||
{
|
||||
std::vector<std::pair<bool, QVector3D> > cutpoints;
|
||||
cutpoints.reserve (6); // 6 faces
|
||||
|
||||
for (int pass = 0; pass < 2; ++pass) {
|
||||
|
||||
bool face = (pass == 0);
|
||||
|
||||
if (face) {
|
||||
bool in_x = (line.x () > corner.x () - epsilon) && (line.x () < corner.x () + dim.x () + epsilon);
|
||||
bool in_y = (line.y () > corner.y () - epsilon) && (line.y () < corner.y () + dim.y () + epsilon);
|
||||
bool in_z = (line.z () > corner.z () - epsilon) && (line.z () < corner.z () + dim.z () + epsilon);
|
||||
if (in_x && in_y && in_z) {
|
||||
// inside cuboid
|
||||
return std::make_pair (true, line);
|
||||
}
|
||||
}
|
||||
|
||||
cutpoints.clear ();
|
||||
|
||||
// front
|
||||
cutpoints.push_back (plane_or_face (line, line_dir, corner, QVector3D (dim.x (), 0, 0), QVector3D (0, dim.y (), 0), face));
|
||||
// back
|
||||
cutpoints.push_back (plane_or_face (line, line_dir, corner + QVector3D (0, 0, dim.z ()), QVector3D (dim.x (), 0, 0), QVector3D (0, dim.y (), 0), face));
|
||||
// bottom
|
||||
cutpoints.push_back (plane_or_face (line, line_dir, corner, QVector3D (dim.x (), 0, 0), QVector3D (0, 0, dim.z ()), face));
|
||||
// top
|
||||
cutpoints.push_back (plane_or_face (line, line_dir, corner + QVector3D (0, dim.y (), 0), QVector3D (dim.x (), 0, 0), QVector3D (0, 0, dim.z ()), face));
|
||||
// left
|
||||
cutpoints.push_back (plane_or_face (line, line_dir, corner, QVector3D (0, 0, dim.z ()), QVector3D (0, dim.y (), 0), face));
|
||||
// right
|
||||
cutpoints.push_back (plane_or_face (line, line_dir, corner + QVector3D (dim.x (), 0, 0), QVector3D (0, 0, dim.z ()), QVector3D (0, dim.y (), 0), face));
|
||||
|
||||
double min_dist = 0.0;
|
||||
int min_dist_index = -1;
|
||||
QVector3D ld_norm = line_dir.normalized ();
|
||||
|
||||
for (std::vector<std::pair<bool, QVector3D> >::const_iterator i = cutpoints.begin (); i != cutpoints.end (); ++i) {
|
||||
if (i->first) {
|
||||
double dist = QVector3D::dotProduct (i->second - line, ld_norm);
|
||||
if (min_dist_index < 0) {
|
||||
min_dist = dist;
|
||||
min_dist_index = int (i - cutpoints.begin ());
|
||||
} else if (dist < min_dist) {
|
||||
min_dist = dist;
|
||||
min_dist_index = int (i - cutpoints.begin ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (min_dist_index >= 0) {
|
||||
return cutpoints [min_dist_index];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return std::make_pair (false, QVector3D ());
|
||||
}
|
||||
|
||||
std::pair<QVector3D, QVector3D>
|
||||
camera_normal (const QMatrix4x4 &camera_trans, double x, double y)
|
||||
{
|
||||
QVector3D p = camera_trans.inverted ().map (QVector3D (x, y, 1.0));
|
||||
|
||||
QVector4D pv = camera_trans.row (3);
|
||||
|
||||
QMatrix4x4 m (camera_trans);
|
||||
|
||||
float values[] = {
|
||||
float (x * pv.x ()), float (x * pv.y ()), float (x * pv.z ()), 0.0f,
|
||||
float (y * pv.x ()), float (y * pv.y ()), float (y * pv.z ()), 0.0f,
|
||||
float (pv.x ()), float (pv.y ()), float (pv.z ()), 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f
|
||||
};
|
||||
m -= QMatrix4x4 (values);
|
||||
|
||||
QMatrix3x3 nm = m.normalMatrix ();
|
||||
|
||||
QVector3D u (nm (2, 0), nm (2, 1), nm (2, 2));
|
||||
return (std::make_pair (p, u.normalized ()));
|
||||
}
|
||||
|
||||
void
|
||||
normalize_scene_trans (const QMatrix4x4 &cam_trans, QVector3D &displacement, double &scale, double ztarget)
|
||||
{
|
||||
// Here is the theory:
|
||||
// Let:
|
||||
// cam = ( M t ) M = 3x3 matrix, t = 3x1 translation vector, z = scalar, p = 1x3 perspective
|
||||
// ( p z )
|
||||
// and:
|
||||
// scene = ( S d*s ) S = s*U1 (s = scale factor, U1 = 3x3 unit matrix), d = 3x1 displacement vector
|
||||
// ( 0 1 )
|
||||
// then:
|
||||
// cam * scene = ( M*s M*d*s+t )
|
||||
// ( p*s p*d*s+z ) (p*d = dot product)
|
||||
//
|
||||
// this is image invariant (only x,y results are considered) against changes of s (s->s') if
|
||||
//
|
||||
// 1.) (p*d*s+z)/s = (p*d'*s'+z)/s' (because x and y will be devided by this value)
|
||||
// 2.) (M*d*s+t)/s = (M*d'*s'+t)/s' for [x] and [y]
|
||||
//
|
||||
// or
|
||||
//
|
||||
// 1.) p*d+z/s = p*d'+z/s'
|
||||
// 2.) M*d+t/s = M*d'+t/s'
|
||||
//
|
||||
// If we seek a solution with d'[z] == b (b = ztarget), we get these equations (f:=1/s')
|
||||
//
|
||||
// 2.) M[xx] * d'[x] + M[xy] * d'[y] + t[x] * f = (M*d)[x] + t[x]/s - M[xz]*b
|
||||
// M[yx] * d'[x] + M[yy] * d'[y] + t[y] * f = (M*d)[y] + t[y]/s - M[yz]*b
|
||||
// 1.) p[x] * d'[x] + p[y] * d'[y] + z * f = p*d + z/s - p[z]*b
|
||||
//
|
||||
// we can solve these equations for d'[x], d'[y] and f.
|
||||
// With p[x]=M[wx], p[y]=M[wy] and z=t[w], the above equation system can be written as
|
||||
//
|
||||
// M[ix] * d'[x] + M[iy] * d'[y] + t[i] * f = (M*d)[i] - M[iz]*b + t[i]/s i = x,y,w
|
||||
//
|
||||
|
||||
QMatrix4x4 m;
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (i != 2) {
|
||||
m (i, 0) = cam_trans (i, 0);
|
||||
m (i, 1) = cam_trans (i, 1);
|
||||
m (i, 3) = cam_trans (i, 3);
|
||||
}
|
||||
}
|
||||
|
||||
bool invertable = false;
|
||||
QMatrix4x4 minv = m.inverted (&invertable);
|
||||
if (! invertable) {
|
||||
return;
|
||||
}
|
||||
|
||||
QVector4D rhs = cam_trans.map (QVector4D (displacement.x (), displacement.y (), displacement.z () - ztarget, 1.0 / scale));
|
||||
QVector4D sol = minv.map (rhs);
|
||||
double f = sol.w ();
|
||||
if (f > 1e-6 /*skip weird solutions*/) {
|
||||
scale = 1.0 / f;
|
||||
displacement = QVector3D (sol.x (), sol.y (), ztarget);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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
|
||||
|
||||
*/
|
||||
|
||||
#ifndef HDR_layD25ViewUtils
|
||||
#define HDR_layD25ViewUtils
|
||||
|
||||
#include "layPluginCommon.h"
|
||||
|
||||
#include <QVector3D>
|
||||
#include <QMatrix4x4>
|
||||
#include <algorithm>
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Computes the cutpoint between a line and a plane
|
||||
*
|
||||
* The line is given by a point and a direction (line, line_dir).
|
||||
* The plane is given by a point and a normal vector (plane, plane_normal)
|
||||
* The "first" component of the returned pair is false if not hit is present.
|
||||
*/
|
||||
|
||||
LAY_PLUGIN_PUBLIC std::pair<bool, QVector3D>
|
||||
cutpoint_line_with_plane (const QVector3D &line, const QVector3D &line_dir, const QVector3D &plane, const QVector3D &plane_normal);
|
||||
|
||||
/**
|
||||
* @brief Computes the cutpoint between a line and a face
|
||||
*
|
||||
* The line is given by a point and a direction (line, line_dir).
|
||||
* The face is given by a plane point and two vectors spanning the face.
|
||||
* The "first" component of the returned pair is false if not hit is present.
|
||||
*/
|
||||
|
||||
LAY_PLUGIN_PUBLIC std::pair<bool, QVector3D>
|
||||
cutpoint_line_with_face (const QVector3D &line, const QVector3D &dir, const QVector3D &plane, const QVector3D &u, const QVector3D &v);
|
||||
|
||||
/**
|
||||
* @brief Determines a good hit point of a view line and a cuboid
|
||||
*
|
||||
* "corner, dim" are the coordinates for the cuboid (corner is the bottom, left, foremost corner, dim
|
||||
* is (width, height, depth)
|
||||
* "line, line_dir" is the view line where "line_dir" is pointing from the camera to the object.
|
||||
* The returned point is a suitable hit point.
|
||||
* The "first" component of the returned pair is false if no hit is present.
|
||||
*/
|
||||
LAY_PLUGIN_PUBLIC std::pair<bool, QVector3D>
|
||||
hit_point_with_cuboid (const QVector3D &line, const QVector3D &line_dir, const QVector3D &corner, const QVector3D &dim);
|
||||
|
||||
/**
|
||||
* @brief For a given pixel coordinate and camera transformation matrix compute a line containing all points corresponding to this pixel
|
||||
*
|
||||
* The returned pair contains a point and a direction vector describing the line.
|
||||
*/
|
||||
LAY_PLUGIN_PUBLIC std::pair<QVector3D, QVector3D>
|
||||
camera_normal (const QMatrix4x4 &camera_trans, double x, double y);
|
||||
|
||||
/**
|
||||
* @brief Normalizes a scene transformation
|
||||
*
|
||||
* Scene transformations consist of a scaling and displacement. Both are
|
||||
* interchangeable to some extent under the presence of a perspective
|
||||
* transformation (further away makes the scene smaller). This normalization
|
||||
* tries to find a displacement which has "ztarget" target value for z. Without normalization
|
||||
* the scene tends to "move away" with respect to z.
|
||||
*/
|
||||
LAY_PLUGIN_PUBLIC void
|
||||
normalize_scene_trans (const QMatrix4x4 &cam_trans, QVector3D &displacement, double &scale, double ztarget = 0.0);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,150 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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
|
||||
|
||||
*/
|
||||
|
||||
#ifndef HDR_layD25ViewWidget
|
||||
#define HDR_layD25ViewWidget
|
||||
|
||||
#include "dbPolygon.h"
|
||||
|
||||
#include "layD25MemChunks.h"
|
||||
#include "layD25Camera.h"
|
||||
|
||||
#include <QOpenGLWidget>
|
||||
#include <QOpenGLVertexArrayObject>
|
||||
#include <QOpenGLBuffer>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QMatrix4x4>
|
||||
#include <QPoint>
|
||||
#include <QVector3D>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace db
|
||||
{
|
||||
class Layout;
|
||||
class Cell;
|
||||
}
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
class LayoutView;
|
||||
class D25ViewWidget;
|
||||
|
||||
class D25InteractionMode
|
||||
{
|
||||
public:
|
||||
D25InteractionMode (D25ViewWidget *widget);
|
||||
virtual ~D25InteractionMode ();
|
||||
|
||||
D25ViewWidget *view () { return mp_view; }
|
||||
virtual void mouse_move (QMouseEvent *event) = 0;
|
||||
|
||||
private:
|
||||
D25ViewWidget *mp_view;
|
||||
};
|
||||
|
||||
class D25ViewWidget
|
||||
: public QOpenGLWidget,
|
||||
private QOpenGLFunctions,
|
||||
public D25Camera
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
D25ViewWidget (QWidget *parent);
|
||||
~D25ViewWidget ();
|
||||
|
||||
void keyPressEvent (QKeyEvent *event);
|
||||
void keyReleaseEvent (QKeyEvent *event);
|
||||
void wheelEvent (QWheelEvent *event);
|
||||
void mousePressEvent (QMouseEvent *event);
|
||||
void mouseReleaseEvent (QMouseEvent *event);
|
||||
void mouseMoveEvent (QMouseEvent *event);
|
||||
|
||||
bool attach_view(lay::LayoutView *view);
|
||||
|
||||
QVector3D hit_point_with_scene(const QVector3D &line_dir);
|
||||
void refresh ();
|
||||
void reset ();
|
||||
|
||||
QVector3D displacement () const { return m_displacement; }
|
||||
|
||||
void set_displacement (const QVector3D &d)
|
||||
{
|
||||
m_displacement = d;
|
||||
refresh ();
|
||||
}
|
||||
|
||||
double scale_factor () const { return m_scale_factor; }
|
||||
|
||||
void set_scale_factor (double f)
|
||||
{
|
||||
m_scale_factor = f;
|
||||
refresh ();
|
||||
}
|
||||
|
||||
signals:
|
||||
void scale_factor_changed (double f);
|
||||
|
||||
protected:
|
||||
virtual void camera_changed ();
|
||||
virtual double aspect_ratio () const;
|
||||
|
||||
public slots:
|
||||
void fit ();
|
||||
|
||||
private:
|
||||
typedef lay::mem_chunks<GLfloat, 1024 * 18> chunks_type;
|
||||
|
||||
std::auto_ptr<D25InteractionMode> mp_mode;
|
||||
QOpenGLShaderProgram *m_shapes_program, *m_gridplane_program;
|
||||
double m_scale_factor;
|
||||
QVector3D m_displacement;
|
||||
lay::LayoutView *mp_view;
|
||||
db::DBox m_bbox;
|
||||
double m_zmin, m_zmax;
|
||||
|
||||
std::list<chunks_type> m_vertex_chunks;
|
||||
|
||||
struct LayerInfo {
|
||||
const chunks_type *vertex_chunk;
|
||||
GLfloat color [4];
|
||||
};
|
||||
|
||||
std::list<LayerInfo> m_layers;
|
||||
|
||||
void initializeGL ();
|
||||
void paintGL ();
|
||||
void resizeGL (int w, int h);
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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 "layXORToolDialog.h"
|
||||
#include "layDispatcher.h"
|
||||
|
||||
#include "layPlugin.h"
|
||||
|
||||
namespace lay
|
||||
{
|
||||
|
||||
class XORPlugin
|
||||
: public lay::Plugin
|
||||
{
|
||||
public:
|
||||
XORPlugin (Plugin *parent, lay::LayoutView *view)
|
||||
: lay::Plugin (parent), mp_view (view)
|
||||
{
|
||||
mp_dialog = new lay::XORToolDialog (0);
|
||||
}
|
||||
|
||||
~XORPlugin ()
|
||||
{
|
||||
delete mp_dialog;
|
||||
mp_dialog = 0;
|
||||
}
|
||||
|
||||
void menu_activated (const std::string &symbol)
|
||||
{
|
||||
if (symbol == "lay::xor_tool") {
|
||||
|
||||
if (mp_dialog->exec_dialog (mp_view)) {
|
||||
|
||||
// ... implementation is in layXORToolDialog.cc ...
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
lay::LayoutView *mp_view;
|
||||
lay::XORToolDialog *mp_dialog;
|
||||
};
|
||||
|
||||
class XORPluginDeclaration
|
||||
: public lay::PluginDeclaration
|
||||
{
|
||||
public:
|
||||
XORPluginDeclaration ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual void get_options (std::vector < std::pair<std::string, std::string> > &options) const
|
||||
{
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_xor_input_mode, "all"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_xor_output_mode, "rdb"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_xor_nworkers, "1"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_xor_layer_offset, ""));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_xor_axorb, "true"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_xor_anotb, "false"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_xor_bnota, "false"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_xor_summarize, "false"));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_xor_tolerances, ""));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_xor_tiling, ""));
|
||||
options.push_back (std::pair<std::string, std::string> (cfg_xor_region_mode, "all"));
|
||||
}
|
||||
|
||||
virtual lay::ConfigPage *config_page (QWidget * /*parent*/, std::string & /*title*/) const
|
||||
{
|
||||
// .. nothing yet ..
|
||||
return 0;
|
||||
}
|
||||
|
||||
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::xor_tool", "xor_tool:edit", "tools_menu.post_verification_group", tl::to_string (QObject::tr ("XOR Tool"))));
|
||||
}
|
||||
|
||||
virtual bool configure (const std::string & /*name*/, const std::string & /*value*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void config_finalize ()
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
lay::Plugin *create_plugin (db::Manager *, lay::Dispatcher *root, lay::LayoutView *view) const
|
||||
{
|
||||
return new XORPlugin (root, view);
|
||||
}
|
||||
};
|
||||
|
||||
static tl::RegisteredClass<lay::PluginDeclaration> config_decl (new lay::XORPluginDeclaration (), 3000, "lay::XORPlugin");
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
TARGET = d25_ui
|
||||
DESTDIR = $$OUT_PWD/../../../../lay_plugins
|
||||
|
||||
include($$PWD/../../../lay_plugin.pri)
|
||||
|
||||
INCLUDEPATH += $$RDB_INC $$ANT_INC
|
||||
DEPENDPATH += $$RDB_INC $$ANT_INC
|
||||
LIBS += -L$$DESTDIR/.. -lklayout_rdb -lklayout_ant
|
||||
|
||||
HEADERS = \
|
||||
layD25View.h \
|
||||
layD25ViewWidget.h \
|
||||
layD25MemChunks.h \
|
||||
layD25ViewUtils.h \
|
||||
layD25Camera.h
|
||||
|
||||
SOURCES = \
|
||||
layD25View.cc \
|
||||
layD25ViewWidget.cc \
|
||||
layD25Plugin.cc \
|
||||
layD25MemChunks.cc \
|
||||
layD25ViewUtils.cc \
|
||||
layD25Camera.cc
|
||||
|
||||
FORMS = \
|
||||
D25View.ui \
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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 "layD25Camera.h"
|
||||
#include "tlUnitTest.h"
|
||||
|
||||
static std::string v2s (const QVector4D &v)
|
||||
{
|
||||
return tl::to_string (v.x ()) + "," + tl::to_string (v.y ()) + "," + tl::to_string (v.z ());
|
||||
}
|
||||
|
||||
static std::string v2s (const QVector3D &v)
|
||||
{
|
||||
return tl::to_string (v.x ()) + "," + tl::to_string (v.y ()) + "," + tl::to_string (v.z ());
|
||||
}
|
||||
|
||||
static std::string v2s_2d (const QVector3D &v)
|
||||
{
|
||||
return tl::to_string (v.x ()) + "," + tl::to_string (v.y ());
|
||||
}
|
||||
|
||||
TEST(1_Transformations)
|
||||
{
|
||||
lay::D25Camera cam;
|
||||
|
||||
cam.set_cam_azimuth (45.0);
|
||||
EXPECT_EQ (cam.cam_azimuth (), 45.0);
|
||||
cam.set_cam_elevation (22.0);
|
||||
EXPECT_EQ (cam.cam_elevation (), 22.0);
|
||||
|
||||
cam.camera_reset ();
|
||||
EXPECT_EQ (cam.cam_azimuth (), 0.0);
|
||||
EXPECT_EQ (cam.cam_elevation (), 0.0);
|
||||
|
||||
EXPECT_EQ (v2s (cam.cam_trans ().map (QVector4D (1, 0, 0, 1))), "1,0,0");
|
||||
EXPECT_EQ (v2s (cam.cam_trans ().map (QVector4D (0, 1, 0, 1))), "0,1,0");
|
||||
EXPECT_EQ (v2s (cam.cam_trans ().map (QVector4D (0, 0, 1, 1))), "0,0,1");
|
||||
EXPECT_EQ (v2s (cam.cam_direction ()), "0,0,-1");
|
||||
EXPECT_EQ (v2s (cam.cam_position ()), "0,0,4");
|
||||
|
||||
// looking up from the bottom, x axis stays the same (azimuth = 0)
|
||||
cam.set_cam_elevation (90.0);
|
||||
|
||||
EXPECT_EQ (v2s (cam.cam_trans ().map (QVector4D (1, 0, 0, 1))), "1,0,0");
|
||||
EXPECT_EQ (v2s (cam.cam_trans ().map (QVector4D (0, 1, 0, 1))), "0,0,-1");
|
||||
EXPECT_EQ (v2s (cam.cam_trans ().map (QVector4D (0, 0, 1, 1))), "0,1,0");
|
||||
|
||||
EXPECT_EQ (v2s (cam.cam_direction ()), "0,1,0");
|
||||
EXPECT_EQ (v2s (cam.cam_position ()), "0,-4,0");
|
||||
|
||||
// looking down from the top, x axis stays the same (azimuth = 0)
|
||||
cam.set_cam_elevation (-90.0);
|
||||
|
||||
EXPECT_EQ (v2s (cam.cam_trans ().map (QVector4D (1, 0, 0, 1))), "1,0,0");
|
||||
EXPECT_EQ (v2s (cam.cam_trans ().map (QVector4D (0, 1, 0, 1))), "0,0,1");
|
||||
EXPECT_EQ (v2s (cam.cam_trans ().map (QVector4D (0, 0, 1, 1))), "0,-1,0");
|
||||
|
||||
EXPECT_EQ (v2s (cam.cam_direction ()), "0,-1,0");
|
||||
EXPECT_EQ (v2s (cam.cam_position ()), "0,4,0");
|
||||
|
||||
// looking from the left, y axis stays the same (elevation = 0)
|
||||
cam.set_cam_elevation (0.0);
|
||||
cam.set_cam_azimuth (90.0);
|
||||
|
||||
EXPECT_EQ (v2s (cam.cam_trans ().map (QVector4D (1, 0, 0, 1))), "0,0,-1");
|
||||
EXPECT_EQ (v2s (cam.cam_trans ().map (QVector4D (0, 1, 0, 1))), "0,1,0");
|
||||
EXPECT_EQ (v2s (cam.cam_trans ().map (QVector4D (0, 0, 1, 1))), "1,0,0");
|
||||
|
||||
EXPECT_EQ (v2s (cam.cam_direction ()), "1,0,0");
|
||||
EXPECT_EQ (v2s (cam.cam_position ()), "-4,0,0");
|
||||
|
||||
// looking from the right, y axis stays the same (elevation = 0)
|
||||
cam.set_cam_elevation (0.0);
|
||||
cam.set_cam_azimuth (-90.0);
|
||||
|
||||
EXPECT_EQ (v2s (cam.cam_trans ().map (QVector4D (1, 0, 0, 1))), "0,0,1");
|
||||
EXPECT_EQ (v2s (cam.cam_trans ().map (QVector4D (0, 1, 0, 1))), "0,1,0");
|
||||
EXPECT_EQ (v2s (cam.cam_trans ().map (QVector4D (0, 0, 1, 1))), "-1,0,0");
|
||||
|
||||
EXPECT_EQ (v2s (cam.cam_direction ()), "-1,0,0");
|
||||
EXPECT_EQ (v2s (cam.cam_position ()), "4,0,0");
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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 "layD25MemChunks.h"
|
||||
#include "tlUnitTest.h"
|
||||
|
||||
TEST(1_Basic)
|
||||
{
|
||||
lay::mem_chunks<int, 2> ch;
|
||||
EXPECT_EQ (ch.begin () == ch.end (), true);
|
||||
|
||||
ch.add (1);
|
||||
EXPECT_EQ (ch.begin () == ch.end (), false);
|
||||
EXPECT_EQ (ch.begin ()->size (), size_t (1));
|
||||
EXPECT_EQ (ch.begin ()->front () [0], 1);
|
||||
|
||||
ch.add (17);
|
||||
EXPECT_EQ (ch.begin () == ch.end (), false);
|
||||
EXPECT_EQ (ch.begin ()->size (), size_t (2));
|
||||
EXPECT_EQ (ch.begin ()->front () [0], 1);
|
||||
EXPECT_EQ (ch.begin ()->front () [1], 17);
|
||||
|
||||
lay::mem_chunks<int, 2>::iterator c = ch.begin ();
|
||||
EXPECT_EQ (c == ch.end (), false);
|
||||
++c;
|
||||
EXPECT_EQ (c == ch.end (), true);
|
||||
|
||||
ch.add (42);
|
||||
c = ch.begin ();
|
||||
EXPECT_EQ (c == ch.end (), false);
|
||||
EXPECT_EQ (c->size (), size_t (2));
|
||||
EXPECT_EQ (c->front () [0], 1);
|
||||
EXPECT_EQ (c->front () [1], 17);
|
||||
++c;
|
||||
EXPECT_EQ (c == ch.end (), false);
|
||||
EXPECT_EQ (c->size (), size_t (1));
|
||||
EXPECT_EQ (c->front () [0], 42);
|
||||
++c;
|
||||
EXPECT_EQ (c == ch.end (), true);
|
||||
|
||||
ch.clear ();
|
||||
EXPECT_EQ (ch.begin () == ch.end (), true);
|
||||
}
|
||||
|
||||
TEST(2_Copy)
|
||||
{
|
||||
lay::mem_chunks<int, 2> ch1;
|
||||
ch1.add (1);
|
||||
ch1.add (17);
|
||||
ch1.add (42);
|
||||
|
||||
lay::mem_chunks<int, 2> ch (ch1);
|
||||
|
||||
lay::mem_chunks<int, 2>::iterator c = ch.begin ();
|
||||
|
||||
EXPECT_EQ (c == ch.end (), false);
|
||||
EXPECT_EQ (c->size (), size_t (2));
|
||||
EXPECT_EQ (c->front () [0], 1);
|
||||
EXPECT_EQ (c->front () [1], 17);
|
||||
++c;
|
||||
EXPECT_EQ (c == ch.end (), false);
|
||||
EXPECT_EQ (c->size (), size_t (1));
|
||||
EXPECT_EQ (c->front () [0], 42);
|
||||
++c;
|
||||
EXPECT_EQ (c == ch.end (), true);
|
||||
|
||||
ch1.clear ();
|
||||
ch = ch1;
|
||||
EXPECT_EQ (ch.begin () == ch.end (), true);
|
||||
}
|
||||
|
|
@ -0,0 +1,240 @@
|
|||
|
||||
/*
|
||||
|
||||
KLayout Layout Viewer
|
||||
Copyright (C) 2006-2020 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 "layD25ViewUtils.h"
|
||||
#include "tlUnitTest.h"
|
||||
|
||||
static std::string v2s (const QVector3D &v)
|
||||
{
|
||||
return tl::to_string (v.x ()) + "," + tl::to_string (v.y ()) + "," + tl::to_string (v.z ());
|
||||
}
|
||||
|
||||
static std::string v2s_2d (const QVector3D &v)
|
||||
{
|
||||
return tl::to_string (v.x ()) + "," + tl::to_string (v.y ());
|
||||
}
|
||||
|
||||
TEST(1_CutPoint)
|
||||
{
|
||||
std::pair<bool, QVector3D> r;
|
||||
|
||||
r = lay::cutpoint_line_with_plane (QVector3D (0, 0, 0), QVector3D (0, 0, 1), QVector3D (0, 0, 0), QVector3D (1, 0, 0));
|
||||
EXPECT_EQ (r.first, false);
|
||||
|
||||
r = lay::cutpoint_line_with_plane (QVector3D (1, 2, 3), QVector3D (0, 0, 2), QVector3D (4, 5, 6), QVector3D (0, 0, 1));
|
||||
EXPECT_EQ (r.first, true);
|
||||
EXPECT_EQ (v2s (r.second), "1,2,6");
|
||||
|
||||
r = lay::cutpoint_line_with_plane (QVector3D (1, 2, 3), QVector3D (0, 0, -1), QVector3D (4, 5, 6), QVector3D (1, 1, 1));
|
||||
EXPECT_EQ (r.first, true);
|
||||
EXPECT_EQ (v2s (r.second), "1,2,12");
|
||||
}
|
||||
|
||||
TEST(2_Face)
|
||||
{
|
||||
std::pair<bool, QVector3D> r;
|
||||
|
||||
r = lay::cutpoint_line_with_face (QVector3D (0, 0, 0), QVector3D (0, 0, 1), QVector3D (0, 0, 0), QVector3D (0, 1, 0), QVector3D (0, 0, 1));
|
||||
EXPECT_EQ (r.first, false);
|
||||
|
||||
r = lay::cutpoint_line_with_face (QVector3D (1, 2, 3), QVector3D (0, 0, 2), QVector3D (4, 5, 6), QVector3D (0, 1, 0), QVector3D (1, 0, 0));
|
||||
EXPECT_EQ (r.first, false);
|
||||
|
||||
r = lay::cutpoint_line_with_face (QVector3D (4, 5, 3), QVector3D (0, 0, 3), QVector3D (4, 5, 6), QVector3D (0, 1, 0), QVector3D (1, 0, 0));
|
||||
EXPECT_EQ (r.first, true);
|
||||
EXPECT_EQ (v2s (r.second), "4,5,6");
|
||||
|
||||
r = lay::cutpoint_line_with_face (QVector3D (4, 7, 3), QVector3D (0, 0, 1), QVector3D (4, 5, 6), QVector3D (0, 1, 0), QVector3D (1, 0, 0));
|
||||
EXPECT_EQ (r.first, false);
|
||||
|
||||
r = lay::cutpoint_line_with_face (QVector3D (4, 6, 3), QVector3D (0, 0, 2), QVector3D (4, 5, 6), QVector3D (0, 1, 0), QVector3D (1, 0, 0));
|
||||
EXPECT_EQ (r.first, true);
|
||||
EXPECT_EQ (v2s (r.second), "4,6,6");
|
||||
|
||||
r = lay::cutpoint_line_with_face (QVector3D (5, 6, 3), QVector3D (0, 0, -1), QVector3D (4, 5, 6), QVector3D (0, 1, 0), QVector3D (1, 0, 0));
|
||||
EXPECT_EQ (r.first, true);
|
||||
EXPECT_EQ (v2s (r.second), "5,6,6");
|
||||
|
||||
r = lay::cutpoint_line_with_face (QVector3D (6, 6, 3), QVector3D (0, 0, 1), QVector3D (4, 5, 6), QVector3D (0, 1, 0), QVector3D (1, 0, 0));
|
||||
EXPECT_EQ (r.first, false);
|
||||
}
|
||||
|
||||
TEST(3_HitWithCuboid)
|
||||
{
|
||||
std::pair<bool, QVector3D> r;
|
||||
|
||||
r = lay::hit_point_with_cuboid (QVector3D (0, 0, 0), QVector3D (0, 0, 1), QVector3D (-1, -1, 3), QVector3D (2, 2, 2));
|
||||
EXPECT_EQ (r.first, true);
|
||||
EXPECT_EQ (v2s (r.second), "0,0,3");
|
||||
|
||||
r = lay::hit_point_with_cuboid (QVector3D (1, 1, 4), QVector3D (0, 0, 1), QVector3D (-1, -1, 3), QVector3D (2, 2, 2));
|
||||
EXPECT_EQ (r.first, true);
|
||||
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, 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);
|
||||
EXPECT_EQ (v2s (r.second), "5,-6,3");
|
||||
|
||||
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,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, 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)
|
||||
{
|
||||
QMatrix4x4 matrix;
|
||||
matrix.perspective (60.0f, 1.5, 0.1f, 100.0f);
|
||||
|
||||
std::pair<QVector3D, QVector3D> ray;
|
||||
QVector3D p;
|
||||
|
||||
ray = lay::camera_normal (matrix, 0.0, 0.0);
|
||||
EXPECT_EQ (v2s (ray.second.normalized ()), "0,0,-1");
|
||||
|
||||
ray = lay::camera_normal (matrix, 1.0, 0.0);
|
||||
EXPECT_EQ (v2s (ray.second), "0.654654,0,-0.755929");
|
||||
|
||||
p = matrix.map (ray.first);
|
||||
EXPECT_EQ (v2s_2d (p), "1,0");
|
||||
|
||||
p = matrix.map (ray.first + ray.second);
|
||||
EXPECT_EQ (v2s_2d (p), "1,0");
|
||||
|
||||
p = matrix.map (ray.first + ray.second * 1000.0);
|
||||
EXPECT_EQ (v2s_2d (p), "1,0");
|
||||
|
||||
ray = lay::camera_normal (matrix, 0.0, -1.0);
|
||||
EXPECT_EQ (v2s (ray.second), "0,-0.5,-0.866025");
|
||||
|
||||
p = matrix.map (ray.first);
|
||||
EXPECT_EQ (v2s_2d (p), "0,-1");
|
||||
|
||||
p = matrix.map (ray.first + ray.second);
|
||||
EXPECT_EQ (v2s_2d (p), "0,-1");
|
||||
|
||||
p = matrix.map (ray.first + ray.second * 1000.0);
|
||||
EXPECT_EQ (v2s_2d (p), "0,-1");
|
||||
}
|
||||
|
||||
TEST(5_CameraNormal)
|
||||
{
|
||||
QMatrix4x4 matrix;
|
||||
QVector3D p;
|
||||
|
||||
matrix.perspective (60.0f, 1.5, 0.1f, 100.0f);
|
||||
matrix.rotate (22.0, 1.0, 0.0, 0.0);
|
||||
matrix.rotate (-15.0, 0.0, 1.0, 0.0);
|
||||
matrix.translate (QVector3D (0.0, 0.0, 4.0));
|
||||
|
||||
std::pair<QVector3D, QVector3D> ray;
|
||||
|
||||
ray = lay::camera_normal (matrix, 0.0, 1.0);
|
||||
EXPECT_EQ (v2s (ray.second), "-0.2563,0.139173,-0.956526");
|
||||
|
||||
p = matrix.map (ray.first);
|
||||
EXPECT_EQ (v2s_2d (p), "0,1");
|
||||
|
||||
p = matrix.map (ray.first + ray.second);
|
||||
EXPECT_EQ (v2s_2d (p), "0,1");
|
||||
|
||||
p = matrix.map (ray.first + ray.second * 1000.0);
|
||||
EXPECT_EQ (v2s_2d (p), "0,1");
|
||||
}
|
||||
|
||||
TEST(6_NormalizeSceneTrans)
|
||||
{
|
||||
QMatrix4x4 cam;
|
||||
cam.perspective (60.0f, 1.5, 0.1f, 100.0f);
|
||||
cam.rotate (22.0, 1.0, 0.0, 0.0);
|
||||
cam.rotate (-15.0, 0.0, 1.0, 0.0);
|
||||
cam.translate (QVector3D (0.0, 0.0, 4.0));
|
||||
|
||||
double scale = 0.1;
|
||||
QVector3D displacement (-5.0, 2.0, 20.0);
|
||||
|
||||
QMatrix4x4 scene1;
|
||||
scene1.scale (scale);
|
||||
scene1.translate (displacement);
|
||||
|
||||
QVector3D v1 = (cam * scene1).map (QVector3D (1.0, -1.0, 2.0));
|
||||
v1.setZ (0);
|
||||
QVector3D v2 = (cam * scene1).map (QVector3D (0.0, 0.0, 5.0));
|
||||
v2.setZ (0);
|
||||
QVector3D v3 = (cam * scene1).map (QVector3D (-1.0, 0.0, 1.0));
|
||||
v3.setZ (0);
|
||||
|
||||
lay::normalize_scene_trans (cam, displacement, scale);
|
||||
|
||||
QMatrix4x4 scene2;
|
||||
scene2.scale (scale);
|
||||
scene2.translate (displacement);
|
||||
|
||||
EXPECT_EQ (tl::sprintf ("%.4f", scale), "0.0667");
|
||||
|
||||
QVector3D u1 = (cam * scene2).map (QVector3D (1.0, -1.0, 2.0));
|
||||
u1.setZ (0);
|
||||
QVector3D u2 = (cam * scene2).map (QVector3D (0.0, 0.0, 5.0));
|
||||
u2.setZ (0);
|
||||
QVector3D u3 = (cam * scene2).map (QVector3D (-1.0, 0.0, 1.0));
|
||||
u3.setZ (0);
|
||||
|
||||
EXPECT_EQ ((u1 - v1).length () < 1e-4, true);
|
||||
EXPECT_EQ ((u2 - v2).length () < 1e-4, true);
|
||||
EXPECT_EQ ((u3 - v3).length () < 1e-4, true);
|
||||
|
||||
lay::normalize_scene_trans (cam, displacement, scale, 10.0);
|
||||
|
||||
QMatrix4x4 scene3;
|
||||
scene3.scale (scale);
|
||||
scene3.translate (displacement);
|
||||
|
||||
EXPECT_EQ (tl::sprintf ("%.4f", scale), "0.0800");
|
||||
EXPECT_EQ (tl::to_string (displacement.z ()), "10");
|
||||
|
||||
QVector3D uu1 = (cam * scene2).map (QVector3D (1.0, -1.0, 2.0));
|
||||
uu1.setZ (0);
|
||||
QVector3D uu2 = (cam * scene2).map (QVector3D (0.0, 0.0, 5.0));
|
||||
uu2.setZ (0);
|
||||
QVector3D uu3 = (cam * scene2).map (QVector3D (-1.0, 0.0, 1.0));
|
||||
uu3.setZ (0);
|
||||
|
||||
EXPECT_EQ ((uu1 - v1).length () < 1e-4, true);
|
||||
EXPECT_EQ ((uu2 - v2).length () < 1e-4, true);
|
||||
EXPECT_EQ ((uu3 - v3).length () < 1e-4, true);
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
DESTDIR_UT = $$OUT_PWD/../../../..
|
||||
|
||||
TARGET = view_25d_tests
|
||||
|
||||
include($$PWD/../../../../lib_ut.pri)
|
||||
|
||||
SOURCES = \
|
||||
layD25MemChunksTests.cc \
|
||||
layD25ViewUtilsTests.cc \
|
||||
layD25CameraTests.cc
|
||||
|
||||
INCLUDEPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../lay_plugin $$PWD/../../../common
|
||||
DEPENDPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../lay_plugin $$PWD/../../../common
|
||||
|
||||
LIBS += -L$$DESTDIR_UT -lklayout_db -lklayout_tl -lklayout_gsi
|
||||
|
||||
PLUGINPATH = $$OUT_PWD/../../../../lay_plugins
|
||||
QMAKE_RPATHDIR += $$PLUGINPATH
|
||||
|
||||
LIBS += -L$$PLUGINPATH -ld25_ui
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
TEMPLATE = subdirs
|
||||
|
||||
equals(HAVE_QT5, "1") {
|
||||
SUBDIRS = lay_plugin unit_tests
|
||||
}
|
||||
Loading…
Reference in New Issue