Commit 8353717f authored by CHEVALIER Arthur's avatar CHEVALIER Arthur Committed by Mathieu Faverge

fix(quadtree): Dropping quadtree structure so changed filename and classname

feat(zooming): Added selector visual hint
parent c09078e2
......@@ -42,7 +42,7 @@ set (MATRIXVISUALIZER_hdrs
Windows/MatrixWindow.hpp
Windows/MatrixGLWidget.hpp
Common/QuadTree.hpp
Common/Zooming.hpp
)
set (MATRIXVISUALIZER_srcs
......@@ -57,7 +57,7 @@ set (MATRIXVISUALIZER_srcs
Windows/MatrixWindow.cpp
Windows/MatrixGLWidget.cpp
Common/QuadTree.cpp
Common/Zooming.cpp
)
set (MATRIXVISUALIZER_forms_tmp
......
#include "QuadTree.hpp"
#include "../Helper.hpp"
bool QuadTreeRecur(symbol_matrix_t* matrix, Node* actual, int cutsRemaining, int startColumn, int endColumn, int startRow, int endRow);
QuadTree::QuadTree(Node* root, symbol_matrix_t* matrix)
: m_root(root)
, m_matrix(matrix)
{
// Fill correct colors
move(0.f, 1.f, 0.f, 1.f);
}
void destroyRecur(Node* actual)
{
int i;
if (actual == nullptr)
return;
for (i = 0; i < actual->m_nbChildren; ++i)
destroyRecur(actual->m_children[i]);
delete actual;
}
QuadTree::~QuadTree()
{
// Destroy quadtree
destroyRecur(m_root);
symbol_matrix_deinit(m_matrix);
delete m_matrix;
}
GLfloat QuadTree::getColor(int x, int y)
{
return m_colors[x][y];
}
#include <iostream>
void QuadTree::move(float xStart, float xEnd, float yStart, float yEnd)
{
int i, j;
std::cerr << "Moving from " << xStart << "," << yStart << " to " << xEnd << "," << yEnd << std::endl;
int startCblk = xStart * m_matrix->m_cblknbr;
int endCbkl = startCblk + (xEnd - xStart) * m_matrix->m_cblknbr;
int diffCblk = endCbkl - startCblk;
int startRow = yStart * m_matrix->m_rowsnbr;
int endRow = startRow + (yEnd - yStart) * m_matrix->m_rowsnbr;
int diffRow = endRow - startRow;
symbol_cblk_t* cblks = m_matrix->m_cblktab;
symbol_blok_t* bloks = m_matrix->m_bloktab;
for (i = 0; i < DEFAULT_LEVEL_POWER_2; ++i)
{
for (j = 0; j < DEFAULT_LEVEL_POWER_2; ++j)
{
m_colors[i][j] = 0.f;
}
}
float xCoeff = (float)DEFAULT_LEVEL_POWER_2 / (float)diffCblk;
float yCoeff = (float)DEFAULT_LEVEL_POWER_2 / (float)diffRow;
std::cerr << "xCoeff: " << xCoeff << ", " << "yCoeff: " << yCoeff << std::endl;
for (i = startCblk; i < endCbkl; ++i)
{
int firstBlokNum = cblks[i].m_bloknum;
int nextBlokNum = (i + 1 != m_matrix->m_cblknbr ? cblks[i + 1].m_bloknum : m_matrix->m_cblknbr);
int x = ((float)i - startCblk) * xCoeff;
for (j = firstBlokNum; j < nextBlokNum; ++j)
{
symbol_blok_t* blok = &(bloks[j]);
if (blok->m_frownum > startRow && blok->m_frownum <= endRow)
{
int y = ((float)blok->m_frownum - startRow) * yCoeff;
m_colors[x][y] = 1.0f;
}
}
}
}
size_t GetMemoryLoadRecur(Node* actual)
{
int i;
size_t size = sizeof(Node);
for (i = 0; i < actual->m_nbChildren; ++i)
{
size += GetMemoryLoadRecur(actual->m_children[i]);
}
return size;
}
size_t GetMemoryLoad(Node* root)
{
size_t result = GetMemoryLoadRecur(root);
return result;
}
QuadTree* QuadTree::constructFromSymbolMatrix(symbol_matrix_t* matrix)
{
Node* root = new Node;
// Construct quad tree
Helper::log(LogStatus::MESSAGE, "Starting building QuadTree");
root->m_id = 1;
QuadTreeRecur(matrix, root, QuadTree::DEFAULT_LEVEL, 0, matrix->m_cblknbr, 0, matrix->m_rowsnbr);
Helper::log(LogStatus::MESSAGE, "End building QuadTree");
size_t memory_load = GetMemoryLoad(root) + sizeof(QuadTree);
Helper::log(LogStatus::MESSAGE, "QuadTree takes %.2lf %s of memory !",
MEMORY_WRITE(memory_load), MEMORY_UNIT_WRITE(memory_load));
return new QuadTree(root, matrix);
}
bool QuadTreeRecur(symbol_matrix_t* matrix, Node* actual, int cutsRemaining, int startColumn, int endColumn, int startRow, int endRow)
{
int midCblk = (endColumn - startColumn) / 2;
int midRow = (endRow - startRow) / 2;
actual->m_startCblk = startColumn;
actual->m_endCblk = endColumn;
actual->m_startRow = startRow;
actual->m_endRow = endRow;
if (cutsRemaining == 0)
{
symbol_cblk_t* cblks = matrix->m_cblktab;
symbol_blok_t* bloks = matrix->m_bloktab;
int i, j;
for (i = startColumn; i <= endColumn; ++i)
{
int firstBlokNum = cblks[i].m_bloknum;
int nextBlokNum = (i + 1 != matrix->m_cblknbr ? cblks[i + 1].m_bloknum : matrix->m_cblknbr);
for (j = firstBlokNum; j < nextBlokNum; ++j)
{
symbol_blok_t* blok = &(bloks[j]);
if (blok->m_frownum >= startRow && blok->m_frownum <= endRow)
{
if (!(blok->m_flags & BLOK_FLAG_IN_TREE))
{
blok->m_localization = actual->m_id;
blok->m_flags |= BLOK_FLAG_IN_TREE;
}
}
}
}
return true;
}
else
{
int nbValidNode = 0;
Node* first = new Node;
first->m_id = actual->m_id << 2;
if (!QuadTreeRecur(matrix, first, cutsRemaining - 1, startColumn, startColumn + midCblk, startRow, startRow + midRow))
{
delete first;
first = nullptr;
}
else
nbValidNode++;
Node* second = new Node;
second->m_id = (actual->m_id << 2) | 1;
if (!QuadTreeRecur(matrix, second, cutsRemaining - 1, startColumn, startColumn + midCblk, startRow, startRow + midRow))
{
delete second;
second = nullptr;
}
else
nbValidNode++;
Node* third = new Node;
third->m_id = (actual->m_id << 2) | 2;
if (!QuadTreeRecur(matrix, third, cutsRemaining - 1, startColumn, startColumn + midCblk, startRow, startRow + midRow))
{
delete third;
third = nullptr;
}
else
nbValidNode++;
Node* fourth = new Node;
fourth->m_id = (actual->m_id << 2) | 3;
if (!QuadTreeRecur(matrix, fourth, cutsRemaining - 1, startColumn, startColumn + midCblk, startRow, startRow + midRow))
{
delete fourth;
fourth = nullptr;
}
else
nbValidNode++;
if (nbValidNode > 0)
{
actual->m_nbChildren = nbValidNode;
actual->m_children = (Node**)malloc(nbValidNode * sizeof(Node*));
Node** tmp = actual->m_children;
if (first != nullptr)
{
*tmp = first;
tmp++;
}
if (second != nullptr)
{
*tmp = second;
tmp++;
}
if (third != nullptr)
{
*tmp = third;
tmp++;
}
if (fourth != nullptr)
{
*tmp = fourth;
tmp++;
}
}
return nbValidNode > 0;
}
}
\ No newline at end of file
#include "Zooming.hpp"
#include "../Helper.hpp"
Zooming::Zooming(symbol_matrix_t* matrix)
: m_matrix(matrix)
{
// Fill correct colors
move(0.f, 1.f, 0.f, 1.f);
}
Zooming::~Zooming()
{
// Destroy quadtree
symbol_matrix_deinit(m_matrix);
delete m_matrix;
}
GLfloat Zooming::getColor(int x, int y)
{
return m_colors[x][y];
}
void Zooming::move(double xStart, double xEnd, double yStart, double yEnd)
{
int i, j, m, n;
int startCol = xStart * m_matrix->m_colsnbr;
int endCol = xEnd * m_matrix->m_colsnbr;
int diffCols = endCol - startCol;
// Find first cblk
int startCblk = 0;
int endCblk = 0;
for (i = 0; i < m_matrix->m_cblknbr; ++i)
{
symbol_cblk_t* cblk = &(m_matrix->m_cblktab[i]);
if (cblk->m_fcolumn <= startCol && cblk->m_lcolnum >= startCol)
startCblk = i;
if (cblk->m_fcolumn <= endCol && cblk->m_lcolnum >= endCol)
endCblk = i;
}
int diffCblk = endCblk - startCblk;
int startRow = yStart * m_matrix->m_rowsnbr;
int endRow = yEnd * m_matrix->m_rowsnbr;
int diffRow = endRow - startRow;
symbol_cblk_t* cblks = m_matrix->m_cblktab;
symbol_blok_t* bloks = m_matrix->m_bloktab;
for (i = 0; i < DEFAULT_LEVEL_POWER_2; ++i)
{
for (j = 0; j < DEFAULT_LEVEL_POWER_2; ++j)
{
m_colors[i][j] = 0.f;
}
}
float xCoeff = (float)DEFAULT_LEVEL_POWER_2 / ((float)diffCols + 1);
float yCoeff = (float)DEFAULT_LEVEL_POWER_2 / ((float)diffRow + 1);
for (i = startCblk; i <= endCblk; ++i)
{
int firstBlokNum = cblks[i].m_bloknum;
int nextBlokNum = (i + 1 != m_matrix->m_cblknbr ? cblks[i + 1].m_bloknum : m_matrix->m_bloknbr);
// Get first block size in col from x to xEnd
symbol_cblk_t* cblk = &(cblks[i]);
int startingCol = (cblk->m_fcolumn < startCol ? startCol : cblk->m_fcolumn);
int endingCol = (cblk->m_lcolnum > endCol ? endCol + 1 : cblk->m_lcolnum);
int x = (startingCol - startCol) * xCoeff;
int xEnd = (endingCol - startCol) * xCoeff;
for (j = firstBlokNum; j < nextBlokNum; ++j)
{
symbol_blok_t* blok = &(bloks[j]);
if (blok->m_frownum >= startRow && blok->m_frownum <= endRow)
{
// Get first block size in row from y to yEnd
int startingRow = (blok->m_frownum < startRow ? startRow : blok->m_frownum);
int endingRow = (blok->m_lrownum > endRow ? endRow + 1 : blok->m_lrownum);
int y = (startingRow - startRow) * yCoeff;
int yEnd = (endingRow - startRow) * yCoeff;
m = x;
do
{
n = y;
do
{
m_colors[m][n] = 1.0f;
n++;
} while (n < yEnd);
m++;
} while (m < xEnd);
}
}
}
}
\ No newline at end of file
......@@ -5,38 +5,21 @@
#include "../Formats/SymbolMatrix.hpp"
typedef struct Node
{
uint32_t m_id;
int32_t m_nbChildren;
// Position
int32_t m_startCblk;
int32_t m_endCblk;
int32_t m_startRow;
int32_t m_endRow;
struct Node** m_children;
} Node;
class QuadTree
class Zooming
{
public:
static const int DEFAULT_LEVEL = 10;
static const int DEFAULT_LEVEL_POWER_2 = 1024;
public:
QuadTree(Node* root, symbol_matrix_t* matrix);
~QuadTree();
Zooming(symbol_matrix_t* matrix);
~Zooming();
GLfloat getColor(int x, int y);
void move(float xStart, float xEnd, float yStart, float yEnd);
static QuadTree* constructFromSymbolMatrix(symbol_matrix_t* matrix);
void move(double xStart, double xEnd, double yStart, double yEnd);
private:
Node* m_root;
symbol_matrix_t* m_matrix;
GLfloat m_colors[DEFAULT_LEVEL_POWER_2][DEFAULT_LEVEL_POWER_2];
......
......@@ -6,7 +6,7 @@
typedef struct symbol_cblk_s
{
int32_t m_fcolumn; // First column index
int32_t m_lcolnum; // Last column index (inclusive)
int32_t m_lcolnum; // Last column index (exclusive)
int32_t m_bloknum; // First blok in column
int32_t m_flags; // Flags
} symbol_cblk_t;
......@@ -17,7 +17,7 @@ typedef struct symbol_cblk_s
typedef struct symbol_blok_s
{
int32_t m_frownum; // First row index
int32_t m_lrownum; // Last row index
int32_t m_lrownum; // Last row index (exclusive)
int32_t m_lcblknm; // Local column blok
int32_t m_fcblknm; // Facing column blok
......@@ -52,7 +52,7 @@ typedef struct symbol_matrix_s
int32_t m_cblknbr;
int32_t m_bloknbr;
int32_t m_nodenbr;
int32_t m_colsnbr;
int32_t m_rowsnbr;
symbol_cblk_t* m_cblktab;
......
......@@ -10,20 +10,21 @@ int pastix_read_symbol(FILE* stream, symbol_matrix_t* matrix)
int32_t versval;
int32_t cblknum;
int32_t bloknum;
int32_t nodenbr;
int32_t result = 0;
result += pastix_read_int(stream, &versval);
result += pastix_read_int(stream, &matrix->m_cblknbr);
result += pastix_read_int(stream, &matrix->m_bloknbr);
result += pastix_read_int(stream, &matrix->m_nodenbr);
result += pastix_read_int(stream, &nodenbr);
result += pastix_read_int(stream, &matrix->m_baseval);
if ((result != 5) ||
(versval < 0) ||
(versval > 1) ||
(matrix->m_bloknbr < matrix->m_cblknbr) ||
(matrix->m_nodenbr < matrix->m_cblknbr))
(nodenbr < matrix->m_cblknbr))
{
Helper::log(LogStatus::FATAL, "Loading symbol file, bad header !");
......@@ -41,6 +42,7 @@ int pastix_read_symbol(FILE* stream, symbol_matrix_t* matrix)
}
int32_t cblknbr = matrix->m_cblknbr;
int32_t maxcol = 0;
for (cblknum = 0; cblknum < cblknbr; ++cblknum)
{
result = pastix_read_int(stream, &(matrix->m_cblktab[cblknum].m_fcolumn));
......@@ -55,11 +57,17 @@ int pastix_read_symbol(FILE* stream, symbol_matrix_t* matrix)
return 1;
}
if (matrix->m_cblktab[cblknum].m_lcolnum > maxcol)
maxcol = matrix->m_cblktab[cblknum].m_lcolnum;
matrix->m_cblktab[cblknum].m_flags = 0;
matrix->m_cblktab[cblknum].m_lcolnum++;
}
matrix->m_cblktab[cblknbr].m_fcolumn = matrix->m_cblktab[cblknbr].m_lcolnum = matrix->m_nodenbr + matrix->m_baseval;
matrix->m_cblktab[cblknbr].m_fcolumn = matrix->m_cblktab[cblknbr].m_lcolnum = nodenbr + matrix->m_baseval;
matrix->m_cblktab[cblknbr].m_bloknum = matrix->m_bloknbr + matrix->m_baseval;
matrix->m_colsnbr = maxcol + 1;
int32_t bloknbr = matrix->m_bloknbr;
int32_t maxrow = 0;
for (bloknum = 0; bloknum < bloknbr; ++bloknum)
......@@ -78,6 +86,7 @@ int pastix_read_symbol(FILE* stream, symbol_matrix_t* matrix)
if (matrix->m_bloktab[bloknum].m_lrownum > maxrow)
maxrow = matrix->m_bloktab[bloknum].m_lrownum;
matrix->m_bloktab[bloknum].m_lrownum++;
matrix->m_bloktab[bloknum].m_localization = 0;
matrix->m_bloktab[bloknum].m_flags = 0;
......@@ -105,7 +114,7 @@ int pastix_read_symbol(FILE* stream, symbol_matrix_t* matrix)
" Base value: %10d\n",
versval,
matrix->m_cblknbr, matrix->m_rowsnbr,
matrix->m_bloknbr, matrix->m_nodenbr,
matrix->m_bloknbr, nodenbr,
matrix->m_baseval
);
......
......@@ -14,22 +14,25 @@ static void drawSquare(GLfloat x, GLfloat y, GLfloat dx, GLfloat dy, GLfloat r,
glColor3f(r, g, b);
// Setup square corners
glVertex2f(x, y);
glVertex2f(x, y);
glVertex2f(x + dx, y);
glVertex2f(x + dx, y - dy);
glVertex2f(x, y - dy);
glVertex2f(x + dx, y + dy);
glVertex2f(x, y + dy);
glEnd();
}
static void drawEmpty()
static void drawTemporarySelection(int x, int y, int dx, int dy)
{
glBegin(GL_TRIANGLES);
glColor3f(BACKGROUND_COLOR_R, BACKGROUND_COLOR_G, BACKGROUND_COLOR_B);
glVertex2f(0, QuadTree::DEFAULT_LEVEL_POWER_2);
glVertex2f(QuadTree::DEFAULT_LEVEL_POWER_2, QuadTree::DEFAULT_LEVEL_POWER_2);
glVertex2f(QuadTree::DEFAULT_LEVEL_POWER_2, 0);
glEnd();
glBegin(GL_QUADS);
// Setup color
glColor4f(1.f, 1.f, 1.f, .25f);
// Setup vertex
glVertex2f(x, y);
glVertex2f(x + dx, y);
glVertex2f(x + dx, y + dy);
glVertex2f(x, y + dy);
glEnd();
}
MatrixGLWidget::MatrixGLWidget(QWidget* parent, symbol_matrix_t* matrix, QLabel* label)
......@@ -43,7 +46,7 @@ MatrixGLWidget::MatrixGLWidget(QWidget* parent, symbol_matrix_t* matrix, QLabel*
{
this->setFixedSize(MATRIX_WINDOW_LENGTH, MATRIX_WINDOW_HEIGHT);
m_quadtree = QuadTree::constructFromSymbolMatrix(matrix);
m_zooming = new Zooming(matrix);
#ifdef USE_QT5
connect(&m_updateTimer, &QTimer::timeout, this, &MatrixGLWidget::updateTimer);
......@@ -67,7 +70,7 @@ MatrixGLWidget::MatrixGLWidget(QWidget* parent, symbol_matrix_t* matrix, QLabel*
MatrixGLWidget::~MatrixGLWidget()
{
delete m_quadtree;
delete m_zooming;
}
void MatrixGLWidget::initializeGL()
......@@ -75,11 +78,14 @@ void MatrixGLWidget::initializeGL()
#ifdef USE_QT5
initializeOpenGLFunctions();
#endif
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glClearColor(BACKGROUND_COLOR_R, BACKGROUND_COLOR_G, BACKGROUND_COLOR_B, 1.f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, QuadTree::DEFAULT_LEVEL_POWER_2, QuadTree::DEFAULT_LEVEL_POWER_2, 0, -1, 1);
glOrtho(0, Zooming::DEFAULT_LEVEL_POWER_2, Zooming::DEFAULT_LEVEL_POWER_2, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
......@@ -90,14 +96,14 @@ void MatrixGLWidget::resizeGL(int w, int h)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, QuadTree::DEFAULT_LEVEL_POWER_2, QuadTree::DEFAULT_LEVEL_POWER_2, 0, -1, 1);
glOrtho(0, Zooming::DEFAULT_LEVEL_POWER_2, Zooming::DEFAULT_LEVEL_POWER_2, 0, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();