177 lines
8.3 KiB
C++
Executable file
177 lines
8.3 KiB
C++
Executable file
#include "horizontalslicetocontourlinemapper.h"
|
|
#include <iostream>
|
|
|
|
|
|
HorizontalSliceToContourLineMapper::HorizontalSliceToContourLineMapper(){
|
|
std::cout << "CONTOUR MAPPER CONSTRUCTOR CALLED - creating " << this << std::endl;
|
|
}
|
|
|
|
HorizontalSliceToContourLineMapper::~HorizontalSliceToContourLineMapper() {
|
|
std::cout << "CONTOUR MAPPER DESTRUCTOR CALLED - deleting " << this << std::endl;
|
|
//delete[] isolist;
|
|
}
|
|
|
|
void HorizontalSliceToContourLineMapper::getSlice(float *source, int x, int y, int z, int current_z) {
|
|
// Sets up the variables
|
|
slice = source;
|
|
xs = x;
|
|
ys = y;
|
|
zs = z;
|
|
iz = current_z;
|
|
}
|
|
|
|
void HorizontalSliceToContourLineMapper::newZ(float* newsource, int z) {
|
|
// updates the mapper pointer and sets a new z-slice
|
|
slice = newsource;
|
|
iz = z;
|
|
}
|
|
|
|
void HorizontalSliceToContourLineMapper::setIso(float* isos, int nums) {
|
|
|
|
isolist = new float[nums];
|
|
for (int i=0; i<nums; i++) {
|
|
isolist[i] = isos[i];
|
|
}
|
|
numIsos = nums;
|
|
}
|
|
|
|
int HorizontalSliceToContourLineMapper::marchingSquaresNum(float isoline, float v0, float v1,float v2,float v3) {
|
|
// The idea is to check which vertices lie above the isoline-value. Each vertex is equal to 2^n
|
|
// We do this because we can describe each of the 15 cases uniquely using a 4-bit binary number
|
|
char result = 0;
|
|
if (isoline<v0) {
|
|
result +=1;
|
|
} if (isoline<v1) {
|
|
result +=2;
|
|
} if (isoline<v2) {
|
|
result +=4;
|
|
} if (isoline<v3) {
|
|
result +=8;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
QVector<QVector3D> HorizontalSliceToContourLineMapper::mapSliceToContourLineSegments() {
|
|
QVector<QVector3D> vectors; // We store all of our points in a dynamic array as Vector3Ds
|
|
QVector3D vector1; // Vector 1 and 2 will then be connected as a line (using GL_LINES)
|
|
QVector3D vector2;
|
|
int squareCase = 0; // Initially I used char here, but I swapped it with int, because debugging was hell
|
|
float v0, v1, v2, v3, iso; // Initializing values we'll soon be needing
|
|
float z_value = float(iz)/(zs-1);
|
|
float x_value, y_value;
|
|
|
|
for (int i = 0; i < numIsos; i++) {
|
|
// We loop through all the isolines
|
|
//std::cout << "iso: " << isolist[i]; //we check what is in the isolist; a leftover from the debug times
|
|
for (int y=0; y< ys-1; y++) {
|
|
// Here we loop through all x and y values except for the last one, because we actually loop
|
|
// through squares with vertices x, x+1, y and y+1.
|
|
for (int x=0; x< xs-1; x++) {
|
|
// Watch out! The notation has been taken from the lecture
|
|
v3 = slice[3*((y+1)*xs+x)]; //top left
|
|
v2 = slice[3*((y+1)*xs+x+1)]; //top right
|
|
v1 = slice[3*(y*xs+x+1)]; //botom right
|
|
v0 = slice[3*(y*xs+x)]; //bottom left
|
|
iso = isolist[i];
|
|
squareCase = marchingSquaresNum(iso, v0, v1, v2, v3);
|
|
// Viet found the amazing way of reducing the number of cases (before that I used switch x3)
|
|
// We use if-instructions because Switch doesn't allow for the or operation
|
|
// Lookuptable is nonetheless very mechanical
|
|
if (squareCase==1 || squareCase==14) {
|
|
|
|
|
|
x_value = float(x)/(xs-1);
|
|
y_value = float(y)/(ys-1)+(iso-v0)/((ys-1)*(v3-v0));
|
|
vector1 = QVector3D(x_value,y_value,z_value);
|
|
|
|
x_value = float(x)/(xs-1)+(iso-v0)/((xs-1)*(v1-v0));
|
|
y_value = float(y)/(ys-1);
|
|
vector2 = QVector3D(x_value, y_value,z_value);
|
|
|
|
|
|
} else if (squareCase==2 || squareCase==13) {
|
|
|
|
x_value = float(x+1)/(xs-1);
|
|
y_value = float(y)/(ys-1)+(iso-v1)/((ys-1)*(v2-v1));
|
|
vector1 = QVector3D(x_value,y_value,z_value);
|
|
|
|
x_value = float(x)/(xs-1)+(iso-v0)/((xs-1)*(v1-v0));
|
|
y_value = float(y)/(ys-1);
|
|
vector2 = QVector3D(x_value, y_value,z_value);
|
|
|
|
|
|
} else if (squareCase==3 || squareCase==12) {
|
|
x_value = float(x)/(xs-1);
|
|
y_value = float(y)/(ys-1)+(iso-v0)/((ys-1)*(v3-v0));
|
|
vector1 = QVector3D(x_value,y_value,z_value);
|
|
|
|
x_value = float(x+1)/(xs-1);
|
|
y_value = float(y)/(ys-1)+(iso-v1)/((ys-1)*(v2-v1));
|
|
vector2 = QVector3D(x_value,y_value,z_value);
|
|
|
|
} else if (squareCase==4 || squareCase==11) {
|
|
|
|
x_value = float(x+1)/(xs-1);
|
|
y_value = float(y)/(ys-1)+(iso-v1)/((ys-1)*(v2-v1));
|
|
vector1 = QVector3D(x_value, y_value, z_value);
|
|
|
|
x_value = float(x)/(xs-1)+(iso-v3)/((xs-1)*(v2-v3));
|
|
y_value = float(y+1)/(ys-1);
|
|
vector2 = QVector3D(x_value,y_value,z_value);
|
|
|
|
} else if (squareCase==5) {
|
|
//Special case requires checking is the centre is positive
|
|
std::cout << 0.25*(v0+v1+v2+v3) << std::endl;
|
|
if (0.25*(v0+v1+v2+v3)>iso) {
|
|
std::cout << "Gi funkcias!" << std::endl;
|
|
vector1 = QVector3D(float(x+1)/(xs-1),float(y)/(ys-1)+(iso-v1)/((ys-1)*(v2-v1)),z_value);
|
|
vector2 = QVector3D(float(x)/(xs-1)+(iso-v3)/((xs-1)*(v2-v3)),float(y+1)/(ys-1),z_value);
|
|
vectors << vector1 << vector2;
|
|
vector1 = QVector3D(float(x)/(xs-1),float(y)/(ys-1)+(iso-v0)/((ys-1)*(v3-v0)),z_value);
|
|
vector2 = QVector3D(float(x)/(xs-1)+(iso-v0)/((xs-1)*(v1-v0)),float(y)/(ys-1),z_value);
|
|
|
|
} else {
|
|
vector1 = QVector3D(float(x)/(xs-1)+(iso-v3)/((xs-1)*(v2-v3)),float(y+1)/(ys-1),z_value);
|
|
vector2 = QVector3D(float(x)/(xs-1),float(y)/(ys-1)+(iso-v0)/((ys-1)*(v3-v0)),z_value);
|
|
vectors << vector1 << vector2;
|
|
vector1 = QVector3D(float(x+1)/(xs-1),float(y)/(ys-1)+(iso-v3)/((ys-1)*(v2-v3)),z_value);
|
|
vector2 = QVector3D(float(x)/(xs-1)+(iso-v0)/((xs-1)*(v1-v0)),float(y)/(ys-1),z_value);
|
|
|
|
}
|
|
} else if (squareCase==10) {
|
|
//Special case requires checking is the centre is positive
|
|
std::cout << 0.25*(v0+v1+v2+v3) << std::endl;
|
|
if (0.25*(v0+v1+v2+v3)>iso) {
|
|
vector1 = QVector3D(float(x)/(xs-1)+(iso-v3)/((xs-1)*(v2-v3)),float(y+1)/(ys-1),z_value);
|
|
vector2 = QVector3D(float(x)/(xs-1),float(y)/(ys-1)+(iso-v0)/((ys-1)*(v3-v0)),z_value);
|
|
vectors << vector1 << vector2;
|
|
vector1 = QVector3D(float(x+1)/(xs-1),float(y)/(ys-1)+(iso-v3)/((ys-1)*(v2-v3)),z_value);
|
|
vector2 = QVector3D(float(x)/(xs-1)+(iso-v0)/((xs-1)*(v1-v0)),float(y)/(ys-1),z_value);
|
|
|
|
} else {
|
|
std::cout << "Gi funkcias!" << std::endl;
|
|
vector1 = QVector3D(float(x+1)/(xs-1),float(y)/(ys-1)+(iso-v1)/((ys-1)*(v2-v1)),z_value);
|
|
vector2 = QVector3D(float(x)/(xs-1)+(iso-v3)/((xs-1)*(v2-v3)),float(y+1)/(ys-1),z_value);
|
|
vectors << vector1 << vector2;
|
|
vector1 = QVector3D(float(x)/(xs-1),float(y)/(ys-1)+(iso-v0)/((ys-1)*(v3-v0)),z_value);
|
|
vector2 = QVector3D(float(x)/(xs-1)+(iso-v0)/((xs-1)*(v1-v0)),float(y)/(ys-1),z_value);
|
|
}
|
|
|
|
} else if (squareCase==6 || squareCase==9) {
|
|
|
|
vector1 = QVector3D(float(x)/(xs-1)+(iso-v0)/((xs-1)*(v1-v0)),float(y)/(ys-1),z_value);
|
|
vector2 = QVector3D(float(x)/(xs-1)+(iso-v3)/((xs-1)*(v2-v3)),float(y+1)/(ys-1),z_value);
|
|
|
|
} else if (squareCase==7 || squareCase==8) {
|
|
vector1 = QVector3D(float(x)/(xs-1)+(iso-v3)/((xs-1)*(v2-v3)),float(y+1)/(ys-1),z_value);
|
|
vector2 = QVector3D(float(x)/(xs-1),float(y)/(ys-1)+(iso-v0)/((ys-1)*(v3-v0)),z_value);
|
|
} else {
|
|
// cases 0 and 15 are the ones where we draw no lines and they belong here
|
|
continue;
|
|
}
|
|
vectors << vector1 << vector2;
|
|
}
|
|
}
|
|
}
|
|
return vectors;
|
|
}
|