aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gui/fpgaviewwidget.cc131
-rw-r--r--gui/fpgaviewwidget.h28
-rw-r--r--gui/lineshader.cc2
-rw-r--r--gui/quadtree.h111
4 files changed, 135 insertions, 137 deletions
diff --git a/gui/fpgaviewwidget.cc b/gui/fpgaviewwidget.cc
index 7e7b6e4f..ac51467c 100644
--- a/gui/fpgaviewwidget.cc
+++ b/gui/fpgaviewwidget.cc
@@ -31,11 +31,9 @@
NEXTPNR_NAMESPACE_BEGIN
-FPGAViewWidget::FPGAViewWidget(QWidget *parent) :
- QOpenGLWidget(parent), ctx_(nullptr), paintTimer_(this),
- lineShader_(this), zoom_(10.0f),
- rendererArgs_(new FPGAViewWidget::RendererArgs),
- rendererData_(new FPGAViewWidget::RendererData)
+FPGAViewWidget::FPGAViewWidget(QWidget *parent)
+ : QOpenGLWidget(parent), ctx_(nullptr), paintTimer_(this), lineShader_(this), zoom_(10.0f),
+ rendererArgs_(new FPGAViewWidget::RendererArgs), rendererData_(new FPGAViewWidget::RendererData)
{
colors_.background = QColor("#000000");
colors_.grid = QColor("#333");
@@ -126,52 +124,54 @@ float FPGAViewWidget::PickedElement::distance(Context *ctx, float wx, float wy)
// Go over its' GraphicElements, and calculate the distance to them.
std::vector<float> distances;
- std::transform(graphics.begin(), graphics.end(), std::back_inserter(distances), [&](const GraphicElement &ge) -> float {
- switch(ge.type) {
- case GraphicElement::TYPE_BOX:
- {
- // If outside the box, return unit distance to closest border.
- float outside_x = -1, outside_y = -1;
- if (dx < ge.x1 || dx > ge.x2) {
- outside_x = std::min(std::abs(dx - ge.x1), std::abs(dx - ge.x2));
- }
- if (dy < ge.y1 || dy > ge.y2) {
- outside_y = std::min(std::abs(dy - ge.y1), std::abs(dy - ge.y2));
- }
- if (outside_x != -1 && outside_y != -1)
- return std::min(outside_x, outside_y);
-
- // If in box, return 0.
- return 0;
- }
- case GraphicElement::TYPE_LINE:
- case GraphicElement::TYPE_ARROW:
- {
- // Return somewhat primitively calculated distance to segment.
- // TODO(q3k): consider coming up with a better algorithm
- QVector2D w(wx, wy);
- QVector2D a(ge.x1, ge.y1);
- QVector2D b(ge.x2, ge.y2);
- float dw = a.distanceToPoint(w) + b.distanceToPoint(w);
- float dab = a.distanceToPoint(b);
- return std::abs(dw-dab) / dab;
- }
- default:
- // Not close to antyhing.
- return -1;
- }
- });
+ std::transform(graphics.begin(), graphics.end(), std::back_inserter(distances),
+ [&](const GraphicElement &ge) -> float {
+ switch (ge.type) {
+ case GraphicElement::TYPE_BOX: {
+ // If outside the box, return unit distance to closest border.
+ float outside_x = -1, outside_y = -1;
+ if (dx < ge.x1 || dx > ge.x2) {
+ outside_x = std::min(std::abs(dx - ge.x1), std::abs(dx - ge.x2));
+ }
+ if (dy < ge.y1 || dy > ge.y2) {
+ outside_y = std::min(std::abs(dy - ge.y1), std::abs(dy - ge.y2));
+ }
+ if (outside_x != -1 && outside_y != -1)
+ return std::min(outside_x, outside_y);
+
+ // If in box, return 0.
+ return 0;
+ }
+ case GraphicElement::TYPE_LINE:
+ case GraphicElement::TYPE_ARROW: {
+ // Return somewhat primitively calculated distance to segment.
+ // TODO(q3k): consider coming up with a better algorithm
+ QVector2D w(wx, wy);
+ QVector2D a(ge.x1, ge.y1);
+ QVector2D b(ge.x2, ge.y2);
+ float dw = a.distanceToPoint(w) + b.distanceToPoint(w);
+ float dab = a.distanceToPoint(b);
+ return std::abs(dw - dab) / dab;
+ }
+ default:
+ // Not close to antyhing.
+ return -1;
+ }
+ });
// Find smallest non -1 distance.
// Find closest element.
return *std::min_element(distances.begin(), distances.end(), [&](float a, float b) {
- if (a == -1) return false;
- if (b == -1) return true;
+ if (a == -1)
+ return false;
+ if (b == -1)
+ return true;
return a < b;
});
}
-void FPGAViewWidget::renderGraphicElement(RendererData *data, LineShaderData &out, const GraphicElement &el, float x, float y)
+void FPGAViewWidget::renderGraphicElement(RendererData *data, LineShaderData &out, const GraphicElement &el, float x,
+ float y)
{
if (el.type == GraphicElement::TYPE_BOX) {
auto line = PolyLine(true);
@@ -234,15 +234,15 @@ void FPGAViewWidget::populateQuadTree(RendererData *data, const DecalXY &decal,
if (el.type == GraphicElement::TYPE_BOX) {
// Boxes are bounded by themselves.
- data->qt->insert(PickQuadTree::BoundingBox(x+el.x1, y+el.y1, x+el.x2, y+el.y2), element);
+ data->qt->insert(PickQuadTree::BoundingBox(x + el.x1, y + el.y1, x + el.x2, y + el.y2), element);
}
if (el.type == GraphicElement::TYPE_LINE || el.type == GraphicElement::TYPE_ARROW) {
// Lines are bounded by their AABB slightly enlarged.
- float x0 = x+el.x1;
- float y0 = y+el.y1;
- float x1 = x+el.x2;
- float y1 = y+el.y2;
+ float x0 = x + el.x1;
+ float y0 = y + el.y1;
+ float x1 = x + el.x2;
+ float y1 = y + el.y2;
if (x1 < x0)
std::swap(x0, x1);
if (y1 < y0)
@@ -301,7 +301,8 @@ void FPGAViewWidget::paintGL()
// Render Arch graphics.
lineShader_.draw(rendererData_->gfxByStyle[GraphicElement::STYLE_FRAME], colors_.frame, thick11Px, matrix);
lineShader_.draw(rendererData_->gfxByStyle[GraphicElement::STYLE_HIDDEN], colors_.hidden, thick11Px, matrix);
- lineShader_.draw(rendererData_->gfxByStyle[GraphicElement::STYLE_INACTIVE], colors_.inactive, thick11Px, matrix);
+ lineShader_.draw(rendererData_->gfxByStyle[GraphicElement::STYLE_INACTIVE], colors_.inactive, thick11Px,
+ matrix);
lineShader_.draw(rendererData_->gfxByStyle[GraphicElement::STYLE_ACTIVE], colors_.active, thick11Px, matrix);
// Draw highlighted items.
@@ -313,7 +314,7 @@ void FPGAViewWidget::paintGL()
flags = rendererData_->flags;
}
-
+
{
QMutexLocker locker(&rendererArgsLock_);
rendererArgs_->flags.clear();
@@ -410,7 +411,6 @@ void FPGAViewWidget::renderLines(void)
flags = rendererArgs_->flags;
}
-
// Render decals if necessary.
if (decalsChanged) {
auto data = std::unique_ptr<FPGAViewWidget::RendererData>(new FPGAViewWidget::RendererData);
@@ -469,7 +469,7 @@ void FPGAViewWidget::renderLines(void)
for (int i = 0; i < 8; i++)
data->gfxHighlighted[i] = rendererData_->gfxHighlighted[i];
}
-
+
rendererData_ = std::move(data);
}
}
@@ -549,15 +549,16 @@ boost::optional<FPGAViewWidget::PickedElement> FPGAViewWidget::pickElement(float
// Calculate distances to all elements picked.
using ElemDist = std::pair<const PickedElement *, float>;
std::vector<ElemDist> distances;
- std::transform(elems.begin(), elems.end(), std::back_inserter(distances),
- [&](const PickedElement &e) -> ElemDist {
- return std::make_pair(&e, e.distance(ctx_, worldx, worldy));
- });
+ std::transform(elems.begin(), elems.end(), std::back_inserter(distances), [&](const PickedElement &e) -> ElemDist {
+ return std::make_pair(&e, e.distance(ctx_, worldx, worldy));
+ });
// Find closest non -1 element.
- auto closest = std::min_element(distances.begin(), distances.end(), [&](const ElemDist &a, const ElemDist &b){
- if (a.second == -1) return false;
- if (b.second == -1) return true;
+ auto closest = std::min_element(distances.begin(), distances.end(), [&](const ElemDist &a, const ElemDist &b) {
+ if (a.second == -1)
+ return false;
+ if (b.second == -1)
+ return true;
return a.second < b.second;
});
@@ -619,7 +620,6 @@ void FPGAViewWidget::mouseMoveEvent(QMouseEvent *event)
update();
}
-
// Invert the projection matrix to calculate screen/mouse to world/grid
// coordinates.
QVector4D FPGAViewWidget::mouseToWorldCoordinates(int x, int y)
@@ -640,8 +640,8 @@ QVector4D FPGAViewWidget::mouseToWorldCoordinates(int x, int y)
// operation properly.
QVector3D ray = vec.toVector3DAffine();
ray.normalize();
- ray.setX((ray.x()/-ray.z()) * zoom_);
- ray.setY((ray.y()/ray.z()) * zoom_);
+ ray.setX((ray.x() / -ray.z()) * zoom_);
+ ray.setY((ray.y() / ray.z()) * zoom_);
ray.setZ(1.0);
vec = viewMove_.inverted() * QVector4D(ray.x(), ray.y(), ray.z(), 1.0);
@@ -677,7 +677,6 @@ void FPGAViewWidget::zoom(int level)
zoom_ -= level / 100.0;
} else {
zoom_ -= level / 10.0;
-
}
if (zoom_ < zoomNear_)
@@ -708,12 +707,12 @@ void FPGAViewWidget::zoomOutbound()
float h = y1 - y0;
viewMove_.setToIdentity();
- viewMove_.translate(-w/2, -h/2);
+ viewMove_.translate(-w / 2, -h / 2);
// Our FOV is π/2, so distance for camera to see a plane of width H is H/2.
// We add 1 unit to cover half a unit of extra space around.
- float distance_w = w/2 + 1;
- float distance_h = h/2 + 1;
+ float distance_w = w / 2 + 1;
+ float distance_h = h / 2 + 1;
zoom_ = std::max(distance_w, distance_h);
update();
}
diff --git a/gui/fpgaviewwidget.h b/gui/fpgaviewwidget.h
index 067f3b7f..4fefe020 100644
--- a/gui/fpgaviewwidget.h
+++ b/gui/fpgaviewwidget.h
@@ -20,7 +20,6 @@
#ifndef MAPGLWIDGET_H
#define MAPGLWIDGET_H
-#include <boost/optional.hpp>
#include <QMainWindow>
#include <QMutex>
#include <QOpenGLBuffer>
@@ -32,11 +31,12 @@
#include <QThread>
#include <QTimer>
#include <QWaitCondition>
+#include <boost/optional.hpp>
+#include "designwidget.h"
+#include "lineshader.h"
#include "nextpnr.h"
#include "quadtree.h"
-#include "lineshader.h"
-#include "designwidget.h"
NEXTPNR_NAMESPACE_BEGIN
@@ -108,7 +108,6 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
QSize minimumSizeHint() const override;
QSize sizeHint() const override;
-
public Q_SLOTS:
void newContext(Context *ctx);
void onSelectedArchItem(std::vector<DecalXY> decals);
@@ -124,14 +123,16 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
void clickedWire(WireId wire);
private:
- const float zoomNear_ = 0.1f; // do not zoom closer than this
+ const float zoomNear_ = 0.1f; // do not zoom closer than this
const float zoomFar_ = 100.0f; // do not zoom further than this
const float zoomLvl1_ = 1.0f;
const float zoomLvl2_ = 5.0f;
- struct PickedElement {
+ struct PickedElement
+ {
ElementType type;
- union Inner {
+ union Inner
+ {
BelId bel;
WireId wire;
PipId pip;
@@ -202,17 +203,14 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
bool zoomOutbound;
- PassthroughFlags() :
- zoomOutbound(false) {}
- PassthroughFlags &operator=(const PassthroughFlags &other) noexcept {
+ PassthroughFlags() : zoomOutbound(false) {}
+ PassthroughFlags &operator=(const PassthroughFlags &other) noexcept
+ {
zoomOutbound = other.zoomOutbound;
return *this;
}
- void clear()
- {
- zoomOutbound = false;
- }
+ void clear() { zoomOutbound = false; }
};
struct RendererArgs
@@ -253,7 +251,7 @@ class FPGAViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
void renderGraphicElement(RendererData *data, LineShaderData &out, const GraphicElement &el, float x, float y);
void renderDecal(RendererData *data, LineShaderData &out, const DecalXY &decal);
void renderArchDecal(RendererData *data, const DecalXY &decal);
- void populateQuadTree(RendererData *data, const DecalXY &decal, const PickedElement& element);
+ void populateQuadTree(RendererData *data, const DecalXY &decal, const PickedElement &element);
boost::optional<PickedElement> pickElement(float worldx, float worldy);
QVector4D mouseToWorldCoordinates(int x, int y);
QVector4D mouseToWorldDimensions(float x, float y);
diff --git a/gui/lineshader.cc b/gui/lineshader.cc
index 94a7a010..eba96020 100644
--- a/gui/lineshader.cc
+++ b/gui/lineshader.cc
@@ -17,8 +17,8 @@
*
*/
-#include "log.h"
#include "lineshader.h"
+#include "log.h"
NEXTPNR_NAMESPACE_BEGIN
diff --git a/gui/quadtree.h b/gui/quadtree.h
index f803f770..be677747 100644
--- a/gui/quadtree.h
+++ b/gui/quadtree.h
@@ -26,14 +26,16 @@
NEXTPNR_NAMESPACE_BEGIN
// A node of a QuadTree. Internal.
-template <typename CoordinateT, typename ElementT>
-class QuadTreeNode
+template <typename CoordinateT, typename ElementT> class QuadTreeNode
{
public:
- class BoundingBox {
- friend class QuadTreeNode;
+ class BoundingBox
+ {
+ friend class QuadTreeNode;
+
private:
CoordinateT x0_, x1_, y0_, y1_;
+
public:
// Standard constructor for a given (x0,y0), (x1,y1) bounding box
//
@@ -41,11 +43,11 @@ class QuadTreeNode
// @param y0 y coordinate of top-left corner of box
// @param x1 x coordinate of bottom-right corner of box
// @param y1 y coordinate of bottom-right corner of box
- BoundingBox(CoordinateT x0, CoordinateT y0, CoordinateT x1, CoordinateT y1) :
- x0_(x0), x1_(x1), y0_(y0), y1_(y1) {}
+ BoundingBox(CoordinateT x0, CoordinateT y0, CoordinateT x1, CoordinateT y1) : x0_(x0), x1_(x1), y0_(y0), y1_(y1)
+ {
+ }
- BoundingBox(const BoundingBox &other) :
- x0_(other.x0_), x1_(other.x1_), y0_(other.y0_), y1_(other.y1_) {}
+ BoundingBox(const BoundingBox &other) : x0_(other.x0_), x1_(other.x1_), y0_(other.y0_), y1_(other.y1_) {}
// Whether a bounding box contains a given points.
// A point is defined to be in a bounding box when it's not lesser than
@@ -74,14 +76,16 @@ class QuadTreeNode
private:
// A pair of Element and BoundingBox that contains it.
- class BoundElement {
- friend class QuadTreeNode;
+ class BoundElement
+ {
+ friend class QuadTreeNode;
+
private:
BoundingBox bb_;
ElementT elem_;
+
public:
- BoundElement(BoundingBox bb, ElementT elem) :
- bb_(bb), elem_(elem) {}
+ BoundElement(BoundingBox bb, ElementT elem) : bb_(bb), elem_(elem) {}
};
// The bounding box that this node describes.
@@ -103,7 +107,7 @@ class QuadTreeNode
// Depth at which this node is - root is at 0, first level at 1, etc.
int depth_;
- // Checks whether a given bounding box fits within this node - used for
+ // Checks whether a given bounding box fits within this node - used for
// sanity checking on insertion.
// @param b bounding box to check
// @returns whether b fits in this node entirely
@@ -124,7 +128,8 @@ class QuadTreeNode
// Used to describe one of 5 possible places an element can exist:
// - the node itself (THIS)
// - any of the 4 children nodes.
- enum Quadrant {
+ enum Quadrant
+ {
THIS = -1,
NW = 0,
NE = 1,
@@ -175,23 +180,19 @@ class QuadTreeNode
return true;
}
-
public:
// Standard constructor for node.
// @param b BoundingBox this node covers.
// @param depth depth at which this node is in the tree
// @max_elems how many elements should this node contain before it splits
- QuadTreeNode(BoundingBox b, int depth, size_t max_elems = 4) :
- bound_(b), max_elems_(max_elems), depth_(depth)
- {
- }
+ QuadTreeNode(BoundingBox b, int depth, size_t max_elems = 4) : bound_(b), max_elems_(max_elems), depth_(depth) {}
// Disallow copies.
QuadTreeNode(const QuadTreeNode &other) = delete;
QuadTreeNode &operator=(const QuadTreeNode &other) = delete;
// Allow moves.
- QuadTreeNode(QuadTreeNode &&other) :
- bound_(other.bound_), max_elems_(other.max_elems_), children_(std::move(other.children_)),
- splitx_(other.splitx_), splity_(other.splity_), elems_(std::move(other.elems_)), depth_(other.depth_)
+ QuadTreeNode(QuadTreeNode &&other)
+ : bound_(other.bound_), max_elems_(other.max_elems_), children_(std::move(other.children_)),
+ splitx_(other.splitx_), splity_(other.splity_), elems_(std::move(other.elems_)), depth_(other.depth_)
{
other.children_ = nullptr;
}
@@ -221,14 +222,14 @@ class QuadTreeNode
// Do we have children?
if (children_ != nullptr) {
- // Put the element either recursively into a child if it fits
- // entirely or keep it for ourselves if not.
- auto quad = quadrant(k);
- if (quad == THIS) {
- elems_.push_back(BoundElement(k, std::move(v)));
- } else {
- return children_[quad].insert(k, std::move(v));
- }
+ // Put the element either recursively into a child if it fits
+ // entirely or keep it for ourselves if not.
+ auto quad = quadrant(k);
+ if (quad == THIS) {
+ elems_.push_back(BoundElement(k, std::move(v)));
+ } else {
+ return children_[quad].insert(k, std::move(v));
+ }
} else {
// No children and not about to have any.
if (!should_split()) {
@@ -242,10 +243,17 @@ class QuadTreeNode
children_ = decltype(children_)(new QuadTreeNode<CoordinateT, ElementT>[4] {
// Note: not using [NW] = QuadTreeNode because that seems to
// crash g++ 7.3.0.
- /* NW */ QuadTreeNode<CoordinateT, ElementT>(BoundingBox(bound_.x0_, bound_.y0_, splitx_, splity_), depth_+1, max_elems_),
- /* NE */ QuadTreeNode<CoordinateT, ElementT>(BoundingBox(splitx_, bound_.y0_, bound_.x1_, splity_), depth_+1, max_elems_),
- /* SW */ QuadTreeNode<CoordinateT, ElementT>(BoundingBox(bound_.x0_, splity_, splitx_, bound_.y1_), depth_+1, max_elems_),
- /* SE */ QuadTreeNode<CoordinateT, ElementT>(BoundingBox(splitx_, splity_, bound_.x1_, bound_.y1_), depth_+1, max_elems_),
+ /* NW */ QuadTreeNode<CoordinateT, ElementT>(BoundingBox(bound_.x0_, bound_.y0_, splitx_, splity_),
+ depth_ + 1, max_elems_),
+ /* NE */
+ QuadTreeNode<CoordinateT, ElementT>(BoundingBox(splitx_, bound_.y0_, bound_.x1_, splity_),
+ depth_ + 1, max_elems_),
+ /* SW */
+ QuadTreeNode<CoordinateT, ElementT>(BoundingBox(bound_.x0_, splity_, splitx_, bound_.y1_),
+ depth_ + 1, max_elems_),
+ /* SE */
+ QuadTreeNode<CoordinateT, ElementT>(BoundingBox(splitx_, splity_, bound_.x1_, bound_.y1_),
+ depth_ + 1, max_elems_),
});
// Move all elements to where they belong.
auto it = elems_.begin();
@@ -271,20 +279,23 @@ class QuadTreeNode
// Dump a human-readable representation of the tree to stdout.
void dump(int level) const
{
- for (int i = 0; i < level; i++) printf(" ");
+ for (int i = 0; i < level; i++)
+ printf(" ");
printf("loc: % 3d % 3d % 3d % 3d\n", bound_.x0_, bound_.y0_, bound_.x1_, bound_.y1_);
if (elems_.size() != 0) {
- for (int i = 0; i < level; i++) printf(" ");
+ for (int i = 0; i < level; i++)
+ printf(" ");
printf("elems: %zu\n", elems_.size());
}
if (children_ != nullptr) {
- for (int i = 0; i < level; i++) printf(" ");
+ for (int i = 0; i < level; i++)
+ printf(" ");
printf("children:\n");
- children_[NW].dump(level+1);
- children_[NE].dump(level+1);
- children_[SW].dump(level+1);
- children_[SE].dump(level+1);
+ children_[NW].dump(level + 1);
+ children_[NE].dump(level + 1);
+ children_[SW].dump(level + 1);
+ children_[SE].dump(level + 1);
}
}
@@ -331,8 +342,7 @@ class QuadTreeNode
//
// @param CoodinateT scalar type of the coordinate system - int, float, ...
// @param ElementT type of the contained element. Must be movable or copiable.
-template <typename CoordinateT, typename ElementT>
-class QuadTree
+template <typename CoordinateT, typename ElementT> class QuadTree
{
private:
// Root of the tree.
@@ -348,10 +358,7 @@ class QuadTree
//
// @param b Bounding box of the entire tree - all comitted elements must
// fit within in.
- QuadTree(BoundingBox b) :
- root_(b, 0)
- {
- }
+ QuadTree(BoundingBox b) : root_(b, 0) {}
// Inserts a new value at a given bounding box.e
// BoundingBoxes are not deduplicated - if two are pushed with the same
@@ -367,17 +374,11 @@ class QuadTree
}
// Dump a human-readable representation of the tree to stdout.
- void dump() const
- {
- root_.dump(0);
- }
+ void dump() const { root_.dump(0); }
// Return count of BoundingBoxes/Elements contained.
// @returns count of elements contained.
- size_t size() const
- {
- return root_.size();
- }
+ size_t size() const { return root_.size(); }
// Retrieve elements whose bounding boxes cover the given coordinates.
//