mirror of https://github.com/KLayout/klayout.git
WIP.
This commit is contained in:
parent
56d406aaad
commit
7077bac647
|
|
@ -0,0 +1,164 @@
|
|||
|
||||
/*
|
||||
|
||||
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 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 {
|
||||
return cutpoint_line_with_plane (line, line_dir, corner, QVector3D::crossProduct (u, v));
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
if (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 (dist < -epsilon) {
|
||||
// ignore all cutpoints behind us
|
||||
} else 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 ()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
|
||||
/*
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
|
||||
#include "layD25ViewWidget.h"
|
||||
#include "layD25ViewUtils.h"
|
||||
#include "layLayoutView.h"
|
||||
|
||||
#include "dbRecursiveShapeIterator.h"
|
||||
|
|
@ -50,7 +51,9 @@ D25ViewWidget::D25ViewWidget (QWidget *parent)
|
|||
format.setSamples (4); // more -> widget extends beyond boundary!
|
||||
setFormat (format);
|
||||
|
||||
m_cam_position = QVector3D (0.0, 0.0, 3.0); // @@@
|
||||
m_cam_position = QVector3D (0.0, 0.0, 4.0); // @@@
|
||||
m_scale_factor = 1.0;
|
||||
m_focus_dist = 0.0;
|
||||
}
|
||||
|
||||
D25ViewWidget::~D25ViewWidget ()
|
||||
|
|
@ -194,19 +197,36 @@ static QVector3D cam_direction (double azimuth, double elevation)
|
|||
void
|
||||
D25ViewWidget::wheelEvent (QWheelEvent *event)
|
||||
{
|
||||
double cal = 0.6;
|
||||
double px = (event->pos ().x () - width () / 2) * 2.0 / width ();
|
||||
double py = -(event->pos ().y () - height () / 2) * 2.0 / height ();
|
||||
|
||||
int dx = event->pos ().x () - width () / 2;
|
||||
int dy = -(event->pos ().y () - height () / 2);
|
||||
double f = exp (event->angleDelta ().y () * (1.0 / (90 * 8)));
|
||||
|
||||
double da = atan (dx * cal * 2.0 / height ()) * 180 / M_PI;
|
||||
double de = atan (dy * cal * 2.0 / height ()) * 180 / M_PI;
|
||||
// compute vector of line of sight
|
||||
std::pair<QVector3D, QVector3D> ray = camera_normal (m_cam_trans, px, py);
|
||||
|
||||
m_cam_position += (event->angleDelta ().y () * (1.0 / (45 * 8))) * cam_direction (m_cam_azimuth + da, m_cam_elevation + de);
|
||||
// by definition the ray goes through the camera position
|
||||
std::pair<bool, QVector3D> hp = hit_point_with_scene (m_cam_position, ray.second);
|
||||
|
||||
QVector3D pm = m_cam_trans.map(hp.second);
|
||||
printf("@@@ mouse=%g,%g back=%g,%g\n", px, py, pm.x(), pm.y());
|
||||
printf("@@@ before: hp=%g,%g,%g d=%g,%g,%g s=%g\n", hp.second.x(), hp.second.y(), hp.second.z(), m_displacement.x(), m_displacement.y(), m_displacement.z(), m_scale_factor); fflush(stdout);
|
||||
|
||||
m_displacement = hp.second * (1.0 - f) + m_displacement * f;
|
||||
m_scale_factor *= f;
|
||||
|
||||
update_cam_trans ();
|
||||
}
|
||||
|
||||
std::pair<bool, QVector3D>
|
||||
D25ViewWidget::hit_point_with_scene (const QVector3D &line, const QVector3D &line_dir)
|
||||
{
|
||||
QVector3D corner = QVector3D (m_bbox.left (), m_zmin, -(m_bbox.bottom () + m_bbox.height ())) * m_scale_factor + m_displacement;
|
||||
QVector3D dim = QVector3D (m_bbox.width (), m_zmax - m_zmin, m_bbox.height ()) * m_scale_factor;
|
||||
|
||||
return lay::hit_point_with_cuboid (line, line_dir, corner, dim);
|
||||
}
|
||||
|
||||
void
|
||||
D25ViewWidget::mousePressEvent (QMouseEvent *event)
|
||||
{
|
||||
|
|
@ -221,6 +241,19 @@ D25ViewWidget::mousePressEvent (QMouseEvent *event)
|
|||
m_start_cam_position = m_cam_position;
|
||||
m_start_cam_azimuth = m_cam_azimuth;
|
||||
m_start_cam_elevation = m_cam_elevation;
|
||||
m_start_displacement = m_displacement;
|
||||
|
||||
m_focus_dist = 2.0;
|
||||
|
||||
if (m_dragging || m_rotating) {
|
||||
|
||||
QVector3D cd = cam_direction (m_start_cam_azimuth, m_start_cam_elevation);
|
||||
std::pair<bool, QVector3D> hp = hit_point_with_scene (m_cam_position, cd);
|
||||
if (hp.first) {
|
||||
m_focus_dist = std::max (m_focus_dist, double ((m_cam_position - hp.second).length ()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -232,12 +265,10 @@ D25ViewWidget::mouseReleaseEvent (QMouseEvent * /*event*/)
|
|||
void
|
||||
D25ViewWidget::mouseMoveEvent (QMouseEvent *event)
|
||||
{
|
||||
double focus_dist = 4.0; // 4 times focal length
|
||||
|
||||
if (m_dragging) {
|
||||
|
||||
// for the chosen perspective transformation:
|
||||
double cal = 0.6 * focus_dist;
|
||||
double cal = 0.6 * m_focus_dist;
|
||||
|
||||
QPoint d = event->pos () - m_start_pos;
|
||||
double f = cal * 2.0 / double (height ());
|
||||
|
|
@ -249,13 +280,14 @@ D25ViewWidget::mouseMoveEvent (QMouseEvent *event)
|
|||
QVector3D yv (-re * xv.z (), cos (m_start_cam_elevation * M_PI / 180.0), re * xv.x ());
|
||||
QVector3D drag = xv * dx + yv * dy;
|
||||
|
||||
// "-drag" because we're not dragging the camera, we're dragging the scene
|
||||
m_cam_position = m_start_cam_position - drag;
|
||||
m_displacement = m_start_displacement + drag;
|
||||
|
||||
update_cam_trans ();
|
||||
|
||||
} else if (m_rotating) {
|
||||
|
||||
double focus_dist = 4.0; // @@@
|
||||
|
||||
QPoint d = event->pos () - m_start_pos;
|
||||
|
||||
double ax = atan (d.x () / (0.5 * height ())) * 180 / M_PI;
|
||||
|
|
@ -274,9 +306,12 @@ D25ViewWidget::mouseMoveEvent (QMouseEvent *event)
|
|||
void
|
||||
D25ViewWidget::update_cam_trans ()
|
||||
{
|
||||
printf("@@@ e=%g a=%g x,y,z=%g,%g,%g\n", m_cam_elevation, m_cam_azimuth, m_cam_position.x(), m_cam_position.y(), m_cam_position.z()); fflush(stdout);
|
||||
printf("@@@ e=%g a=%g x,y,z=%g,%g,%g d=%g,%g,%g s=%g f=%g\n", m_cam_elevation, m_cam_azimuth, m_cam_position.x(), m_cam_position.y(), m_cam_position.z(), m_displacement.x(), m_displacement.y(), m_displacement.z(), m_scale_factor, m_focus_dist); fflush(stdout);
|
||||
QMatrix4x4 t;
|
||||
|
||||
// finally add perspective
|
||||
t.perspective (60.0f, float (width ()) / float (height ()), 0.1f, 100.0f);
|
||||
|
||||
// third: elevation
|
||||
t.rotate (-m_cam_elevation, 1.0, 0.0, 0.0);
|
||||
|
||||
|
|
@ -312,6 +347,10 @@ D25ViewWidget::prepare_view ()
|
|||
{
|
||||
double z = 0.0, dz = 0.2; // @@@
|
||||
|
||||
m_bbox = db::DBox ();
|
||||
bool zset = false;
|
||||
m_zmin = m_zmax = 0.0;
|
||||
|
||||
for (lay::LayerPropertiesConstIterator lp = mp_view->begin_layers (); ! lp.at_end (); ++lp) {
|
||||
|
||||
if (! lp->has_children () && lp->visible (true) && lp->cellview_index () >= 0 && lp->cellview_index () < int (mp_view->cellviews ())) {
|
||||
|
|
@ -322,9 +361,9 @@ D25ViewWidget::prepare_view ()
|
|||
|
||||
LayerInfo info;
|
||||
// @@@ use alpha?
|
||||
info.color[0] = (color & 0xff) / 255.0f;
|
||||
info.color[0] = ((color >> 16) & 0xff) / 255.0f;
|
||||
info.color[1] = ((color >> 8) & 0xff) / 255.0f;
|
||||
info.color[2] = ((color >> 16) & 0xff) / 255.0f;
|
||||
info.color[2] = (color & 0xff) / 255.0f;
|
||||
info.color[3] = 1.0;
|
||||
info.vertex_chunk = &m_vertex_chunks.back ();
|
||||
|
||||
|
|
@ -333,6 +372,17 @@ D25ViewWidget::prepare_view ()
|
|||
const lay::CellView &cv = mp_view->cellview ((unsigned int) lp->cellview_index ());
|
||||
render_layout (m_vertex_chunks.back (), cv->layout (), *cv.cell (), (unsigned int) lp->layer_index (), z, z + dz);
|
||||
|
||||
m_bbox += db::DBox (cv.cell ()->bbox ((unsigned int) lp->layer_index ())) * cv->layout ().dbu ();
|
||||
|
||||
if (! zset) {
|
||||
m_zmin = z;
|
||||
m_zmax = z + dz;
|
||||
zset = true;
|
||||
} else {
|
||||
m_zmin = std::min (z, m_zmin);
|
||||
m_zmax = std::max (z + dz, m_zmax);
|
||||
}
|
||||
|
||||
z += dz; // @@@
|
||||
|
||||
}
|
||||
|
|
@ -513,6 +563,7 @@ D25ViewWidget::render_layout (D25ViewWidget::chunks_type &chunks, const db::Layo
|
|||
void
|
||||
D25ViewWidget::paintGL ()
|
||||
{
|
||||
printf("@@@ width=%d,height=%d\n", width(),height()); // @@@
|
||||
const qreal retinaScale = devicePixelRatio ();
|
||||
glViewport (0, 0, width () * retinaScale, height () * retinaScale);
|
||||
|
||||
|
|
@ -523,12 +574,19 @@ D25ViewWidget::paintGL ()
|
|||
|
||||
m_shapes_program->bind ();
|
||||
|
||||
QMatrix4x4 matrix;
|
||||
matrix.perspective (60.0f, float (width ()) / float (height ()), 0.1f, 100.0f);
|
||||
matrix *= m_cam_trans;
|
||||
QMatrix4x4 scene_trans;
|
||||
|
||||
// provide the displacement and scaling
|
||||
scene_trans.translate (m_displacement);
|
||||
scene_trans.scale (m_scale_factor);
|
||||
// this way we can use y as z coordinate when drawing
|
||||
scene_trans.scale (1.0, 1.0, -1.0);
|
||||
|
||||
m_shapes_program->setUniformValue ("matrix", m_cam_trans * scene_trans);
|
||||
|
||||
// NOTE: z axis of illum points towards the scene because we include the z inversion in the scene transformation matrix
|
||||
m_shapes_program->setUniformValue ("illum", QVector3D (-3.0, -4.0, 2.0).normalized ());
|
||||
|
||||
m_shapes_program->setUniformValue ("matrix", matrix);
|
||||
m_shapes_program->setUniformValue ("illum", QVector3D (-3.0, -4.0, -2.0).normalized ());
|
||||
m_shapes_program->setUniformValue ("ambient", QVector4D (0.5, 0.5, 0.5, 0.5));
|
||||
|
||||
glEnableVertexAttribArray (positions);
|
||||
|
|
@ -552,7 +610,8 @@ D25ViewWidget::paintGL ()
|
|||
|
||||
glEnableVertexAttribArray (positions);
|
||||
|
||||
m_gridplane_program->setUniformValue ("matrix", matrix);
|
||||
// @@@ m_gridplane_program->setUniformValue ("matrix", m_cam_trans * m_scene_trans);
|
||||
m_gridplane_program->setUniformValue ("matrix", QMatrix4x4 ()); // @@@
|
||||
|
||||
// @@@
|
||||
|
||||
|
|
@ -567,6 +626,7 @@ D25ViewWidget::paintGL ()
|
|||
|
||||
glDrawArrays (GL_TRIANGLES, 0, 6);
|
||||
|
||||
#if 0
|
||||
GLfloat gridline_vertices[] = {
|
||||
-1.0, 0.0, -2.0, -1.0, 0.0, 0.0,
|
||||
-0.75, 0.0, -2.0, -0.75, 0.0, 0.0,
|
||||
|
|
@ -587,6 +647,28 @@ D25ViewWidget::paintGL ()
|
|||
1.0, 0.0, -0.25, -1.0, 0.0, -0.25,
|
||||
1.0, 0.0, 0.0, -1.0, 0.0, 0.0
|
||||
};
|
||||
#else
|
||||
GLfloat gridline_vertices[] = {
|
||||
-1.0, -1.0, 0.0, -1.0, 1.0, 0.0,
|
||||
-0.75, -1.0, 0.0, -0.75, 1.0, 0.0,
|
||||
-0.5, -1.0, 0.0, -0.5, 1.0, 0.0,
|
||||
-0.25, -1.0, 0.0, -0.25, 1.0, 0.0,
|
||||
0.0, -1.0, 0.0, 0.0, 1.0, 0.0,
|
||||
0.25, -1.0, 0.0, 0.25, 1.0, 0.0,
|
||||
0.5, -1.0, 0.0, 0.5, 1.0, 0.0,
|
||||
0.75, -1.0, 0.0, 0.75, 1.0, 0.0,
|
||||
1.0, -1.0, 0.0, 1.0, 1.0, 0.0,
|
||||
1.0, -1.0, 0.0, -1.0, -1.0, 0.0,
|
||||
1.0, -0.75, 0.0, -1.0, -0.75, 0.0,
|
||||
1.0, -0.5, 0.0, -1.0, -0.5, 0.0,
|
||||
1.0, -0.25, 0.0, -1.0, -0.25, 0.0,
|
||||
1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
|
||||
1.0, 0.25, 0.0, -1.0, 0.25, 0.0,
|
||||
1.0, 0.5, 0.0, -1.0, 0.5, 0.0,
|
||||
1.0, 0.75, 0.0, -1.0, 0.75, 0.0,
|
||||
1.0, 1.0, 0.0, -1.0, 1.0, 0.0
|
||||
};
|
||||
#endif
|
||||
|
||||
m_shapes_program->setUniformValue ("vertexColor", 1.0, 1.0, 1.0, 0.2f);
|
||||
|
||||
|
|
|
|||
|
|
@ -71,11 +71,17 @@ private:
|
|||
QMatrix4x4 m_cam_trans;
|
||||
bool m_dragging, m_rotating;
|
||||
QVector3D m_cam_position;
|
||||
double m_scale_factor;
|
||||
double m_cam_azimuth, m_cam_elevation;
|
||||
QVector3D m_displacement;
|
||||
double m_focus_dist;
|
||||
QPoint m_start_pos;
|
||||
QVector3D m_start_cam_position;
|
||||
double m_start_cam_azimuth, m_start_cam_elevation;
|
||||
QVector3D m_start_displacement;
|
||||
lay::LayoutView *mp_view;
|
||||
db::DBox m_bbox;
|
||||
double m_zmin, m_zmax;
|
||||
|
||||
std::list<chunks_type> m_vertex_chunks;
|
||||
|
||||
|
|
@ -95,6 +101,7 @@ private:
|
|||
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);
|
||||
std::pair<bool, QVector3D> hit_point_with_scene (const QVector3D &line, const QVector3D &line_dir);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,13 +11,15 @@ LIBS += -L$$DESTDIR/.. -lklayout_rdb -lklayout_ant
|
|||
HEADERS = \
|
||||
layD25View.h \
|
||||
layD25ViewWidget.h \
|
||||
layD25MemChunks.h
|
||||
layD25MemChunks.h \
|
||||
layD25ViewUtils.h
|
||||
|
||||
SOURCES = \
|
||||
layD25View.cc \
|
||||
layD25ViewWidget.cc \
|
||||
layD25Plugin.cc \
|
||||
layD25MemChunks.cc
|
||||
layD25MemChunks.cc \
|
||||
layD25ViewUtils.cc
|
||||
|
||||
FORMS = \
|
||||
D25View.ui \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,168 @@
|
|||
|
||||
/*
|
||||
|
||||
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, false);
|
||||
|
||||
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,5");
|
||||
|
||||
r = lay::hit_point_with_cuboid (QVector3D (5, -6, 6), QVector3D (0, 0, 1), QVector3D (-1, -1, 3), QVector3D (2, 2, 2));
|
||||
EXPECT_EQ (r.first, false);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ include($$PWD/../../../../lib_ut.pri)
|
|||
|
||||
SOURCES = \
|
||||
layD25MemChunksTests.cc \
|
||||
layD25ViewUtilsTests.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
|
||||
|
|
|
|||
Loading…
Reference in New Issue