From 849c727e6afe3c140d3c50f83bf2714590c97789 Mon Sep 17 00:00:00 2001 From: Martin de La Gorce Date: Sun, 28 Feb 2021 11:26:01 +0000 Subject: [PATCH] formatting cpp code --- C++/DifferentiableRenderer.h | 1423 ++++++++++++++++++---------------- 1 file changed, 751 insertions(+), 672 deletions(-) diff --git a/C++/DifferentiableRenderer.h b/C++/DifferentiableRenderer.h index 4f97366..e580a2c 100644 --- a/C++/DifferentiableRenderer.h +++ b/C++/DifferentiableRenderer.h @@ -40,50 +40,55 @@ using namespace std; -#define SWAP(_a_, _b_, _c_) { _c_ = _a_; _a_ = _b_; _b_ = _c_; } - +#define SWAP(_a_, _b_, _c_) \ + { \ + _c_ = _a_; \ + _a_ = _b_; \ + _b_ = _c_; \ + } void get_edge_xrange_from_ineq(double ineq[12], int width, int y, int &x_begin, int &x_end); -inline void render_part_interpolated(double* image, double* z_buffer, int y_begin, int x_min, int x_max, int y_end, bool strict_edge, double* xy1_to_A, double* xy1_to_Z, double* left_eq, double* right_eq, int width, int height, int sizeA, bool perspective_correct); -inline void render_part_interpolated_B(double* image, double* image_B, double* z_buffer, int x_min, int x_max, int y_begin, int y_end, bool strict_edge,double* xy1_to_A, double* xy1_to_A_B, double* xy1_to_Z, double* left_eq, double* right_eq, int width, int height, int sizeA, bool perspective_correct); -inline void render_part_textured_gouraud(double* image, double* z_buffer, int x_min, int x_max, int y_begin, int y_end, bool strict_edge,double* xy1_to_UV, double* xy1_to_L, double* xy1_to_Z, double* left_eq, double* right_eq, int width, int height, int sizeA, double* Texture, int* Texture_size, bool perspective_correct); -inline void render_part_textured_gouraud_B(double* image, double* image_B, double* z_buffer, int x_min, int x_max, int y_begin, int y_end, bool strict_edge, double* xy1_to_UV, double* xy1_to_UV_B, double* xy1_to_L, double* xy1_to_L_B, double* xy1_to_Z, double* left_eq, double* right_eq, int width, int height, int sizeA, double* Texture, double* Texture_B, int* Texture_size, bool perspective_correct); - -struct Scene { - unsigned int* faces; - unsigned int* faces_uv; - double* depths; - double* uv; - double* ij; - double* shade; - double* colors; - bool* edgeflags; - bool* textured; - bool* shaded; +inline void render_part_interpolated(double *image, double *z_buffer, int y_begin, int x_min, int x_max, int y_end, bool strict_edge, double *xy1_to_A, double *xy1_to_Z, double *left_eq, double *right_eq, int width, int height, int sizeA, bool perspective_correct); +inline void render_part_interpolated_B(double *image, double *image_B, double *z_buffer, int x_min, int x_max, int y_begin, int y_end, bool strict_edge, double *xy1_to_A, double *xy1_to_A_B, double *xy1_to_Z, double *left_eq, double *right_eq, int width, int height, int sizeA, bool perspective_correct); +inline void render_part_textured_gouraud(double *image, double *z_buffer, int x_min, int x_max, int y_begin, int y_end, bool strict_edge, double *xy1_to_UV, double *xy1_to_L, double *xy1_to_Z, double *left_eq, double *right_eq, int width, int height, int sizeA, double *Texture, int *Texture_size, bool perspective_correct); +inline void render_part_textured_gouraud_B(double *image, double *image_B, double *z_buffer, int x_min, int x_max, int y_begin, int y_end, bool strict_edge, double *xy1_to_UV, double *xy1_to_UV_B, double *xy1_to_L, double *xy1_to_L_B, double *xy1_to_Z, double *left_eq, double *right_eq, int width, int height, int sizeA, double *Texture, double *Texture_B, int *Texture_size, bool perspective_correct); + +struct Scene +{ + unsigned int *faces; + unsigned int *faces_uv; + double *depths; + double *uv; + double *ij; + double *shade; + double *colors; + bool *edgeflags; + bool *textured; + bool *shaded; int nb_triangles; int nb_vertices; - bool clockwise; - bool backface_culling; + bool clockwise; + bool backface_culling; int nb_uv; int height; int width; int nb_colors; - double* texture; + double *texture; int texture_height; int texture_width; - double* background_image; - double* background_color; + double *background_image; + double *background_color; // fields to store adjoint - double* uv_b; - double* ij_b; - double* shade_b; - double* colors_b; - double* texture_b; + double *uv_b; + double *ij_b; + double *shade_b; + double *colors_b; + double *texture_b; bool strict_edge; bool perspective_correct; }; -void inv_matrix_3x3(double* S, double* T) +void inv_matrix_3x3(double *S, double *T) { // S= |S[0] S[1] S[2]| // |S[3] S[4] S[5]| @@ -115,16 +120,14 @@ void inv_matrix_3x3(double* S, double* T) //S(i*) //} -void inv_matrix_3x3_B(double* S, double* S_B, double* T, double* T_B) +void inv_matrix_3x3_B(double *S, double *S_B, double *T, double *T_B) { - double Tp[9] = { 0 }; - double Tp_B[9] = { 0 }; + double Tp[9] = {0}; + double Tp_B[9] = {0}; // S= |S[0] S[1] S[2]| // |S[3] S[4] S[5]| // |S[6] S[7] S[8]| - - // mult_matrix(3,3,3,R,T_b,T'); //T_b=-mult_matrix(3,3,3, T',R) @@ -156,10 +159,14 @@ void inv_matrix_3x3_B(double* S, double* S_B, double* T, double* T_B) } // double t = (S[0] * Tp[0] + S[1] * Tp[3] + S[2] * Tp[6]); // double inv_det=1/t - double t_B = inv_det_b * (-inv_det * inv_det);//? + double t_B = inv_det_b * (-inv_det * inv_det); //? - S_B[0] += Tp[0] * t_B; Tp_B[0] += S[0] * t_B; S_B[1] += Tp[3] * t_B; - Tp_B[3] += S[1] * t_B; S_B[2] += Tp[6] * t_B; Tp_B[6] += S[2] * t_B; + S_B[0] += Tp[0] * t_B; + Tp_B[0] += S[0] * t_B; + S_B[1] += Tp[3] * t_B; + Tp_B[3] += S[1] * t_B; + S_B[2] += Tp[6] * t_B; + Tp_B[6] += S[2] * t_B; //Tp[0]=(S[4]*S[8]-S[7]*S[5]); @@ -223,10 +230,9 @@ void inv_matrix_3x3_B(double* S, double* S_B, double* T, double* T_B) S_B[1] += -S[3] * Tp_B[8]; } - -inline void mul_matrix3x3_vect(double R[3], double M[9], double V[3]) +inline void mul_matrix3x3_vect(double R[3], double M[9], double V[3]) { - for (int i = 0; i < 3; i++) //v:vertex , d:dimension + for (int i = 0; i < 3; i++) //v:vertex , d:dimension { R[i] = 0; for (int j = 0; j < 3; j++) @@ -234,19 +240,18 @@ inline void mul_matrix3x3_vect(double R[3], double M[9], double V[3]) } } -inline void mul_matrix3x3_vect_B(double R_B[3], double M_B[9], const double V[3]) +inline void mul_matrix3x3_vect_B(double R_B[3], double M_B[9], const double V[3]) { - for (int i = 0; i < 3; i++) //v:vertex , d:dimension + for (int i = 0; i < 3; i++) //v:vertex , d:dimension { for (int j = 0; j < 3; j++) M_B[3 * i + j] += R_B[i] * V[j]; - } } -inline void mul_matrixNx3_vect(int N, double R[], double M[], double V[3]) +inline void mul_matrixNx3_vect(int N, double R[], double M[], double V[3]) { - for (int i = 0; i < N; i++) //v:vertex , d:dimension + for (int i = 0; i < N; i++) //v:vertex , d:dimension { R[i] = 0; for (int j = 0; j < 3; j++) @@ -254,19 +259,18 @@ inline void mul_matrixNx3_vect(int N, double R[], double M[], double V[3]) } } -inline void mul_matrixNx3_vect_B(int N, double R_B[], double M_B[], const double V[3]) +inline void mul_matrixNx3_vect_B(int N, double R_B[], double M_B[], const double V[3]) { - for (int i = 0; i < N; i++) //v:vertex , d:dimension + for (int i = 0; i < N; i++) //v:vertex , d:dimension { for (int j = 0; j < 3; j++) M_B[3 * i + j] += R_B[i] * V[j]; - } } -inline void mul_vect_matrix3x3(double R[3], double V[3], double M[9]) +inline void mul_vect_matrix3x3(double R[3], double V[3], double M[9]) { - for (int i = 0; i < 3; i++) //v:vertex , d:dimension + for (int i = 0; i < 3; i++) //v:vertex , d:dimension { R[i] = 0; for (int j = 0; j < 3; j++) @@ -274,9 +278,9 @@ inline void mul_vect_matrix3x3(double R[3], double V[3], double M[9]) } } -inline void mul_vect_matrix3x3_B(const double R[3], const double R_B[3], const double V[3], double V_B[3], double M[9], double M_B[9]) +inline void mul_vect_matrix3x3_B(const double R[3], const double R_B[3], const double V[3], double V_B[3], double M[9], double M_B[9]) { - for (int i = 0; i < 3; i++) //v:vertex , d:dimension + for (int i = 0; i < 3; i++) //v:vertex , d:dimension { for (int j = 0; j < 3; j++) @@ -285,54 +289,52 @@ inline void mul_vect_matrix3x3_B(const double R[3], const double R_B[3], const V_B[j] += R_B[i] * M[3 * j + i]; } // R[i]+=M[3*j+i]*V[j]; - } } - -inline void mul_matrix(const int I, const int J, const int K, double* AB, double* A, double* B) +inline void mul_matrix(const int I, const int J, const int K, double *AB, double *A, double *B) // A matrix of size (I,J) // B matrix of size (J,K) // AB=A*B { - for (int i = 0; i < I; i++) //v:vertex , d:dimension + for (int i = 0; i < I; i++) //v:vertex , d:dimension for (int k = 0; k < K; k++) { - double* ptr = &AB[K*i + k]; + double *ptr = &AB[K * i + k]; *ptr = 0; for (int j = 0; j < J; j++) - *ptr += A[i*J + j] * B[j*K + k]; + *ptr += A[i * J + j] * B[j * K + k]; } } -inline void mul_matrix_B(const int I, const int J, const int K, double* AB, double* AB_B, double* A, double* A_B, double* B, double* B_B) +inline void mul_matrix_B(const int I, const int J, const int K, double *AB, double *AB_B, double *A, double *A_B, double *B, double *B_B) // A matrix of size (I,J) // B matrix of size (J,K) // AB=A*B { - for (int i = 0; i < I; i++) //v:vertex , d:dimension + for (int i = 0; i < I; i++) //v:vertex , d:dimension for (int k = 0; k < K; k++) { - double* ptr; - ptr = &AB[K*i + k]; + double *ptr; + ptr = &AB[K * i + k]; *ptr = 0; for (int j = 0; j < J; j++) - *ptr += A[i*J + j] * B[j*K + k]; + *ptr += A[i * J + j] * B[j * K + k]; - ptr = &AB_B[K*i + k]; + ptr = &AB_B[K * i + k]; for (int j = 0; j < J; j++) - //*ptr+=A[i*J+j]*B[j*K+k]; + //*ptr+=A[i*J+j]*B[j*K+k]; { - A_B[i*J + j] += *ptr*B[j*K + k]; - B_B[j*K + k] += *ptr*A[i*J + j]; + A_B[i * J + j] += *ptr * B[j * K + k]; + B_B[j * K + k] += *ptr * A[i * J + j]; } } } -inline void mul_matrix3x3_vect(double R[3],const double** M,const double V[3]) +inline void mul_matrix3x3_vect(double R[3], const double **M, const double V[3]) // M is given one column after antother column { - for (int i = 0; i < 3; i++) //v:vertex , d:dimension + for (int i = 0; i < 3; i++) //v:vertex , d:dimension { R[i] = 0; for (int j = 0; j < 3; j++) @@ -340,20 +342,20 @@ inline void mul_matrix3x3_vect(double R[3],const double** M,const double V[3]) } } -inline void mul_matrix_3x3(double AB[9],const double** A, const double B[3]) +inline void mul_matrix_3x3(double AB[9], const double **A, const double B[3]) // A is given one column after antother column { - for (int i = 0; i < 3; i++) //v:vertex , d:dimension + for (int i = 0; i < 3; i++) //v:vertex , d:dimension for (int j = 0; j < 3; j++) { - double* ptr = &AB[3 * i + j]; + double *ptr = &AB[3 * i + j]; *ptr = 0; for (int k = 0; k < 3; k++) *ptr += A[k][i] * B[3 * k + j]; } } -inline double dot_prod(const double V1[3],const double V2[3]) +inline double dot_prod(const double V1[3], const double V2[3]) { double R = 0; for (int i = 0; i < 3; i++) @@ -368,11 +370,11 @@ inline void dot_prod_B(const double R_B, double V1_B[3], const double V2[3]) } inline void Edge_equ3(double e[3], const double v1[2], const double v2[2], bool clockwise) -{ +{ // compute edges equations of type ax+by+c = 0 - + if (clockwise) - { + { e[0] = (v1[1] - v2[1]); e[1] = (v2[0] - v1[0]); } @@ -381,57 +383,69 @@ inline void Edge_equ3(double e[3], const double v1[2], const double v2[2], bool e[0] = (v2[1] - v1[1]); e[1] = (v1[0] - v2[0]); } - - e[2] = - 0.5 * ( e[0] * (v1[0] + v2[0]) + e[1] * (v1[1] + v2[1])); + e[2] = -0.5 * (e[0] * (v1[0] + v2[0]) + e[1] * (v1[1] + v2[1])); } -double signedArea(double ij[3][2],bool clockwise) +double signedArea(double ij[3][2], bool clockwise) { double ux = ij[1][0] - ij[0][0]; double uy = ij[1][1] - ij[0][1]; double vx = ij[2][0] - ij[0][0]; - double vy = ij[2][1] - ij[0][1]; - return 0.5*(ux * vy - vx * uy)*(clockwise?1:-1); + double vy = ij[2][1] - ij[0][1]; + return 0.5 * (ux * vy - vx * uy) * (clockwise ? 1 : -1); } inline void sort3(const double v[3], double sv[3], short int i[3]) -{// v : tree unsorted values +{ // v : tree unsorted values // sv : the three values in v but sorted // c : indices of sorted values double tmp1; short int tmp2; - for (int k = 0; k < 3; k++) sv[k] = v[k]; - for (int k = 0; k < 3; k++) i[k] = k; - if (sv[0] > sv[1]) { SWAP(sv[0], sv[1], tmp1); SWAP(i[0], i[1], tmp2);} - if (sv[0] > sv[2]) { SWAP(sv[0], sv[2], tmp1); SWAP(i[0], i[2], tmp2);} - if (sv[1] > sv[2]) { SWAP(sv[1], sv[2], tmp1); SWAP(i[1], i[2], tmp2);} + for (int k = 0; k < 3; k++) + sv[k] = v[k]; + for (int k = 0; k < 3; k++) + i[k] = k; + if (sv[0] > sv[1]) + { + SWAP(sv[0], sv[1], tmp1); + SWAP(i[0], i[1], tmp2); + } + if (sv[0] > sv[2]) + { + SWAP(sv[0], sv[2], tmp1); + SWAP(i[0], i[2], tmp2); + } + if (sv[1] > sv[2]) + { + SWAP(sv[1], sv[2], tmp1); + SWAP(i[1], i[2], tmp2); + } } inline void elementwise_inverse_vec3(const double input[3], double ouput[3]) -{ +{ for (int i = 0; i < 3; i++) - ouput[i] = 1/input[i]; + ouput[i] = 1 / input[i]; } inline void elementwise_prod_vec3(const double input1[3], const double input2[3], double ouput[3]) -{ +{ for (int i = 0; i < 3; i++) ouput[i] = input1[i] * input2[i]; } - short int floor_div(double a, double b, int x_min, int x_max) { // robust implementation of min ( x_max, max (x_min, floor(a / b))) short int x; - + if (abs(b) * SHRT_MAX > abs(a) + abs(b)) - { - x = (short int) floor(a / b); + { + x = (short int)floor(a / b); if (x < x_min) { x = x_min; @@ -470,7 +484,7 @@ short int ceil_div(double a, double b, int x_min, int x_max) short int x; if (abs(b) * SHRT_MAX > abs(a) + abs(b)) - { + { x = (short int)ceil(a / b); if (x < x_min) { @@ -501,13 +515,14 @@ short int ceil_div(double a, double b, int x_min, int x_max) } } return x; -} +} -template void bilinear_sample(T* A, T I[], int* I_size, double p[2], int sizeA) +template +void bilinear_sample(T *A, T I[], int *I_size, double p[2], int sizeA) { - + // compute integer part and fractional part - + int fp[2]; double e[2]; @@ -523,15 +538,16 @@ template void bilinear_sample(T* A, T I[], int* I_size, double p[2], i { if (fp[k] < 0) { - fp[k] = 0; e[k] = 0; + fp[k] = 0; + e[k] = 0; } if (fp[k] > I_size[k] - 2) { fp[k] = I_size[k] - 2; e[k] = 1; } - } - // bilinear interpolation + } + // bilinear interpolation int indx00 = sizeA * (fp[0] + I_size[0] * fp[1]); int indx10 = sizeA * (fp[0] + 1 + I_size[0] * fp[1]); @@ -539,18 +555,19 @@ template void bilinear_sample(T* A, T I[], int* I_size, double p[2], i int indx11 = sizeA * (fp[0] + 1 + I_size[0] * (fp[1] + 1)); for (int k = 0; k < sizeA; k++) - A[k] = ((1 - e[0])*I[indx00 + k] + e[0] * I[indx10 + k])*(1 - e[1]) + ((1 - e[0])*I[indx01 + k] + e[0] * I[indx11 + k])*e[1]; + A[k] = ((1 - e[0]) * I[indx00 + k] + e[0] * I[indx10 + k]) * (1 - e[1]) + ((1 - e[0]) * I[indx01 + k] + e[0] * I[indx11 + k]) * e[1]; } -template void bilinear_sample_B(T* A, T* A_B, T I[], T I_B[], int* I_size, double p[2], double p_B[2], int sizeA) +template +void bilinear_sample_B(T *A, T *A_B, T I[], T I_B[], int *I_size, double p[2], double p_B[2], int sizeA) { // compute integer part and fractional part int fp[2]; double e[2]; - double e_B[2] = { 0 }; - int out[2] = { 0 }; + double e_B[2] = {0}; + int out[2] = {0}; for (int k = 0; k < 2; k++) { @@ -564,29 +581,32 @@ template void bilinear_sample_B(T* A, T* A_B, T I[], T I_B[], int* I_s { if (fp[k] < 0) { - out[k] = true; fp[k] = 0; e[k] = 0; + out[k] = true; + fp[k] = 0; + e[k] = 0; } if (fp[k] > I_size[k] - 2) { - out[k] = true; fp[k] = I_size[k] - 2; + out[k] = true; + fp[k] = I_size[k] - 2; e[k] = 1; } } - // bilinear interpolation + // bilinear interpolation int indx00 = sizeA * (fp[0] + I_size[0] * fp[1]); int indx10 = sizeA * (fp[0] + 1 + I_size[0] * fp[1]); int indx01 = sizeA * (fp[0] + I_size[0] * (fp[1] + 1)); int indx11 = sizeA * (fp[0] + 1 + I_size[0] * (fp[1] + 1)); - //for(int k=0;k void bilinear_sample_B(T* A, T* A_B, T I[], T I_B[], int* I_s e_B[0] += t1_B * (I[indx10 + k] - I[indx00 + k]); e_B[0] += t2_B * (I[indx11 + k] - I[indx01 + k]); - I_B[indx00 + k] = (1 - e[0])*(1 - e[1]) * A_B[k]; + I_B[indx00 + k] = (1 - e[0]) * (1 - e[1]) * A_B[k]; I_B[indx10 + k] = e[0] * (1 - e[1]) * A_B[k]; - I_B[indx01 + k] = (1 - e[0]) *e[1] * A_B[k]; + I_B[indx01 + k] = (1 - e[0]) * e[1] * A_B[k]; I_B[indx11 + k] = e[0] * e[1] * A_B[k]; } for (int k = 0; k < 2; k++) @@ -609,7 +629,7 @@ template void bilinear_sample_B(T* A, T* A_B, T I[], T I_B[], int* I_s } } -void get_triangle_stencil_equations(double Vxy[][2], double bary_to_xy1[9], double xy1_to_bary[9], double edge_eq[][3], bool strict_edge, int &x_min, int &x_max, int* y_begin, int* y_end, int* left_edge_id, int* right_edge_id) +void get_triangle_stencil_equations(double Vxy[][2], double bary_to_xy1[9], double xy1_to_bary[9], double edge_eq[][3], bool strict_edge, int &x_min, int &x_max, int *y_begin, int *y_end, int *left_edge_id, int *right_edge_id) { // create a matrix that map barycentric coordinates to homogeneous image coordinates @@ -621,7 +641,7 @@ void get_triangle_stencil_equations(double Vxy[][2], double bary_to_xy1[9], dou // the affine transformation mapping from homogeneous image coordinates into triangle // coordinates writes : - for (int v = 0; v < 3; v++) //v:vertex , d:dimension + for (int v = 0; v < 3; v++) //v:vertex , d:dimension for (int d = 0; d < 2; d++) bary_to_xy1[3 * d + v] = Vxy[v][d]; for (int v = 0; v < 3; v++) @@ -630,24 +650,26 @@ void get_triangle_stencil_equations(double Vxy[][2], double bary_to_xy1[9], dou inv_matrix_3x3(bary_to_xy1, xy1_to_bary); // compute edges equations of type x=ay+b - - bool clockwise = signedArea(Vxy, true)>0; + + bool clockwise = signedArea(Vxy, true) > 0; Edge_equ3(edge_eq[0], Vxy[0], Vxy[1], clockwise); Edge_equ3(edge_eq[1], Vxy[1], Vxy[2], clockwise); Edge_equ3(edge_eq[2], Vxy[2], Vxy[0], clockwise); - // sort vertices w.r.t y direction - double x_unsorted[3]; - double y_unsorted[3]; - short int x_order[3]; - short int y_order[3]; - double x_sorted[3]; - double y_sorted[3]; + // sort vertices w.r.t y direction + double x_unsorted[3]; + double y_unsorted[3]; + short int x_order[3]; + short int y_order[3]; + double x_sorted[3]; + double y_sorted[3]; - for (int k = 0; k < 3; k++) x_unsorted[k] = Vxy[k][0]; + for (int k = 0; k < 3; k++) + x_unsorted[k] = Vxy[k][0]; sort3(x_unsorted, x_sorted, x_order); - for (int k = 0; k < 3; k++) y_unsorted[k] = Vxy[k][1]; + for (int k = 0; k < 3; k++) + y_unsorted[k] = Vxy[k][1]; sort3(y_unsorted, y_sorted, y_order); // computing x bounds @@ -661,21 +683,20 @@ void get_triangle_stencil_equations(double Vxy[][2], double bary_to_xy1[9], dou } x_max = (short)floor(x_sorted[2]); - + // limit upper part if (strict_edge) { - + y_begin[0] = (short)floor(y_sorted[0]) + 1; } else { - + y_begin[0] = (short)ceil(y_sorted[0]); } - + y_end[0] = (short)floor(y_sorted[1]); - // limit lower part if (strict_edge) @@ -683,7 +704,7 @@ void get_triangle_stencil_equations(double Vxy[][2], double bary_to_xy1[9], dou y_begin[1] = (short)floor(y_sorted[1]) + 1; } else - { + { y_begin[1] = (short)ceil(y_sorted[1]); } y_end[1] = (short)floor(y_sorted[2]); @@ -694,38 +715,41 @@ void get_triangle_stencil_equations(double Vxy[][2], double bary_to_xy1[9], dou id = y_order[0]; if (edge_eq[(id) % 3][0] > 0) { - right_edge_id[0] = (id + 2) % 3; left_edge_id[0] = (id) % 3; + right_edge_id[0] = (id + 2) % 3; + left_edge_id[0] = (id) % 3; } else { - right_edge_id[0] = (id) % 3; left_edge_id[0] = (id + 2) % 3; + right_edge_id[0] = (id) % 3; + left_edge_id[0] = (id + 2) % 3; } - - + id = y_order[2]; if (edge_eq[(id) % 3][0] < 0) { - right_edge_id[1] = (id) % 3; left_edge_id[1] = (id + 2) % 3; + right_edge_id[1] = (id) % 3; + left_edge_id[1] = (id + 2) % 3; } else { - right_edge_id[1] = (id + 2) % 3; left_edge_id[1] = (id) % 3; + right_edge_id[1] = (id + 2) % 3; + left_edge_id[1] = (id) % 3; } - } -template void rasterize_triangle_interpolated(double Vxy[][2], double Zvertex[3], T* Avertex[], double z_buffer[], T image[], int height, int width, int sizeA, bool strict_edge, bool perspective_correct) +template +void rasterize_triangle_interpolated(double Vxy[][2], double Zvertex[3], T *Avertex[], double z_buffer[], T image[], int height, int width, int sizeA, bool strict_edge, bool perspective_correct) { - int y_begin[2], y_end[2]; - - double edge_eq[3][3]; - double bary_to_xy1[9]; - double xy1_to_bary[9]; - double* xy1_to_A; - double xy1_to_Z[3]; - int left_edge_id[2], right_edge_id[2]; + int y_begin[2], y_end[2]; + + double edge_eq[3][3]; + double bary_to_xy1[9]; + double xy1_to_bary[9]; + double *xy1_to_A; + double xy1_to_Z[3]; + int left_edge_id[2], right_edge_id[2]; int x_min, x_max; - + // compute triangle borders equations //double Vxy[][2],double bary_to_xy1[9],double xy1_to_bary[9],double* edge_eq[3],y_begin,y_end,left_edge_id,right_edge_id) @@ -733,17 +757,18 @@ template void rasterize_triangle_interpolated(double Vxy[][2], double // create matrices that map image coordinates to attributes A and depth z xy1_to_A = new double[3 * sizeA]; - + if (perspective_correct) { - double inv_Zvertex[3]; + double inv_Zvertex[3]; elementwise_inverse_vec3(Zvertex, inv_Zvertex); for (short int i = 0; i < sizeA; i++) for (short int j = 0; j < 3; j++) { xy1_to_A[3 * i + j] = 0; - for (short int k = 0; k < 3; k++) xy1_to_A[3 * i + j] += (Avertex[k][i] * inv_Zvertex[k]) * xy1_to_bary[k * 3 + j]; + for (short int k = 0; k < 3; k++) + xy1_to_A[3 * i + j] += (Avertex[k][i] * inv_Zvertex[k]) * xy1_to_bary[k * 3 + j]; } mul_vect_matrix3x3(xy1_to_Z, inv_Zvertex, xy1_to_bary); @@ -754,34 +779,36 @@ template void rasterize_triangle_interpolated(double Vxy[][2], double for (short int j = 0; j < 3; j++) { xy1_to_A[3 * i + j] = 0; - for (short int k = 0; k < 3; k++) xy1_to_A[3 * i + j] += Avertex[k][i] * xy1_to_bary[k * 3 + j]; + for (short int k = 0; k < 3; k++) + xy1_to_A[3 * i + j] += Avertex[k][i] * xy1_to_bary[k * 3 + j]; } mul_vect_matrix3x3(xy1_to_Z, Zvertex, xy1_to_bary); } for (int k = 0; k < 2; k++) { - render_part_interpolated(image, z_buffer, x_min, x_max, y_begin[k], y_end[k], strict_edge, xy1_to_A, xy1_to_Z, edge_eq[left_edge_id[k]], edge_eq[right_edge_id[k]], width, height, sizeA , perspective_correct); + render_part_interpolated(image, z_buffer, x_min, x_max, y_begin[k], y_end[k], strict_edge, xy1_to_A, xy1_to_Z, edge_eq[left_edge_id[k]], edge_eq[right_edge_id[k]], width, height, sizeA, perspective_correct); } delete[] xy1_to_A; } -template void rasterize_triangle_interpolated_B(double Vxy[][2], double Vxy_B[][2], double Zvertex[3], T* Avertex[], T* Avertex_B[], double z_buffer[], T image[], T image_B[], int height, int width, int sizeA, bool strict_edge, bool perspective_correct) +template +void rasterize_triangle_interpolated_B(double Vxy[][2], double Vxy_B[][2], double Zvertex[3], T *Avertex[], T *Avertex_B[], double z_buffer[], T image[], T image_B[], int height, int width, int sizeA, bool strict_edge, bool perspective_correct) { - int y_begin[2], y_end[2]; - double edge_eq[3][3]; - double bary_to_xy1[9]; - double xy1_to_bary[9]; - double* xy1_to_A; - double xy1_to_Z[3]; - int left_edge_id[2], right_edge_id[2]; - int x_min, x_max; + int y_begin[2], y_end[2]; + double edge_eq[3][3]; + double bary_to_xy1[9]; + double xy1_to_bary[9]; + double *xy1_to_A; + double xy1_to_Z[3]; + int left_edge_id[2], right_edge_id[2]; + int x_min, x_max; if (perspective_correct) { - throw "backward gradient propagation not supported yet with perspective_correct=True"; + throw "backward gradient propagation not supported yet with perspective_correct=True"; } - + // compute triangle borders equations //double Vxy[][2],double bary_to_xy1[9],double xy1_to_bary[9],double* edge_eq[3],y_begin,y_end,left_edge_id,right_edge_id) @@ -794,19 +821,20 @@ template void rasterize_triangle_interpolated_B(double Vxy[][2], doubl for (short int j = 0; j < 3; j++) { xy1_to_A[3 * i + j] = 0; - for (short int k = 0; k < 3; k++) xy1_to_A[3 * i + j] += Avertex[k][i] * xy1_to_bary[k * 3 + j]; + for (short int k = 0; k < 3; k++) + xy1_to_A[3 * i + j] += Avertex[k][i] * xy1_to_bary[k * 3 + j]; } mul_vect_matrix3x3(xy1_to_Z, Zvertex, xy1_to_bary); double *xy1_to_A_B; xy1_to_A_B = new double[3 * sizeA]; - for (short int i = 0; i < 3 * sizeA; i++) xy1_to_A_B[i] = 0; - - for (int k = 0; k < 2; k++) - render_part_interpolated_B(image, image_B, z_buffer, x_min, x_max , y_begin[k], y_end[k], strict_edge, xy1_to_A, xy1_to_A_B, xy1_to_Z, edge_eq[left_edge_id[k]], edge_eq[right_edge_id[k]], width, height, sizeA, perspective_correct); + for (short int i = 0; i < 3 * sizeA; i++) + xy1_to_A_B[i] = 0; + for (int k = 0; k < 2; k++) + render_part_interpolated_B(image, image_B, z_buffer, x_min, x_max, y_begin[k], y_end[k], strict_edge, xy1_to_A, xy1_to_A_B, xy1_to_Z, edge_eq[left_edge_id[k]], edge_eq[right_edge_id[k]], width, height, sizeA, perspective_correct); - double xy1_to_bary_B[9] = { 0 }; + double xy1_to_bary_B[9] = {0}; //for(short int i=0;i<9;i++) xy1_to_bary_B[i]=0 for (short int i = 0; i < sizeA; i++) @@ -814,17 +842,17 @@ template void rasterize_triangle_interpolated_B(double Vxy[][2], doubl { for (short int k = 0; k < 3; k++) - //xy1_to_A[3*i+j]+=Avertex[k][i]*xy1_to_bary[k*3+j]; + //xy1_to_A[3*i+j]+=Avertex[k][i]*xy1_to_bary[k*3+j]; { Avertex_B[k][i] += xy1_to_A_B[3 * i + j] * xy1_to_bary[k * 3 + j]; xy1_to_bary_B[k * 3 + j] += Avertex[k][i] * xy1_to_A_B[3 * i + j]; } } - double bary_to_xy1_B[9] = { 0 }; + double bary_to_xy1_B[9] = {0}; inv_matrix_3x3_B(bary_to_xy1, bary_to_xy1_B, xy1_to_bary, xy1_to_bary_B); - for (int v = 0; v < 3; v++) //v:vertex , d:dimension + for (int v = 0; v < 3; v++) //v:vertex , d:dimension for (int d = 0; d < 2; d++) Vxy_B[v][d] += bary_to_xy1_B[3 * d + v]; @@ -832,19 +860,16 @@ template void rasterize_triangle_interpolated_B(double Vxy[][2], doubl delete[] xy1_to_A_B; } -inline void get_xrange(int width, const double* left_eq, const double* right_eq, short int y, bool strict_edge, short int x_min,short int x_max, short int &x_begin, short int &x_end) +inline void get_xrange(int width, const double *left_eq, const double *right_eq, short int y, bool strict_edge, short int x_min, short int x_max, short int &x_begin, short int &x_end) { - // compute beginning and ending of the rasterized line - + // compute beginning and ending of the rasterized line short int temp_x; double numerator; - - - if (x_min<0) - { + if (x_min < 0) + { x_min = 0; } if (x_max > width - 1) @@ -859,31 +884,32 @@ inline void get_xrange(int width, const double* left_eq, const double* right_eq, if (strict_edge) { - // pixels falling exactly on an edge shared by two triangle will be drawn only once + // pixels falling exactly on an edge shared by two triangle will be drawn only once // when rasterizing the the triangle on the left of the edge. - temp_x = 1 + floor_div(numerator , left_eq[0], x_min-1, x_max); + temp_x = 1 + floor_div(numerator, left_eq[0], x_min - 1, x_max); } else { // pixels falling exactly on an edge shared by two triangle will be drawn twice - temp_x = ceil_div(numerator , left_eq[0], x_min-1, x_max); + temp_x = ceil_div(numerator, left_eq[0], x_min - 1, x_max); } - if (temp_x > x_begin) x_begin = temp_x; - + if (temp_x > x_begin) + x_begin = temp_x; + numerator = -(right_eq[1] * y + right_eq[2]); - temp_x = floor_div(numerator , right_eq[0], x_min-1, x_max); - if (temp_x < x_end) + temp_x = floor_div(numerator, right_eq[0], x_min - 1, x_max); + if (temp_x < x_end) { x_end = temp_x; } } -inline void render_part_interpolated(double* image, double* z_buffer, int x_min, int x_max, int y_begin, int y_end, bool strict_edge, double* xy1_to_A, double* xy1_to_Z, double* left_eq, double* right_eq, int width, int height, int sizeA, bool perspective_correct) +inline void render_part_interpolated(double *image, double *z_buffer, int x_min, int x_max, int y_begin, int y_end, bool strict_edge, double *xy1_to_A, double *xy1_to_Z, double *left_eq, double *right_eq, int width, int height, int sizeA, bool perspective_correct) { double t[3]; double *A0y; double Z0y; - short int x_begin, x_end; + short int x_begin, x_end; double Z; A0y = new double[sizeA]; @@ -897,34 +923,37 @@ inline void render_part_interpolated(double* image, double* z_buffer, int x_min, } for (short int y = y_begin; y <= y_end; y++) { - // Line rasterization setup for interpolated values + // Line rasterization setup for interpolated values - t[0] = 0; t[1] = y; t[2] = 1; + t[0] = 0; + t[1] = y; + t[2] = 1; mul_matrixNx3_vect(sizeA, A0y, xy1_to_A, t); Z0y = dot_prod(xy1_to_Z, t); - // compute beginning and ending of the rasterized line + // compute beginning and ending of the rasterized line - get_xrange(width, left_eq, right_eq, y, strict_edge, x_min, x_max, x_begin,x_end); + get_xrange(width, left_eq, right_eq, y, strict_edge, x_min, x_max, x_begin, x_end); //rasterize line int indx = y * width + x_begin; if (perspective_correct) for (short int x = x_begin; x <= x_end; x++) - { + { double inv_Z = Z0y + xy1_to_Z[0] * x; - Z = 1/(inv_Z); + Z = 1 / (inv_Z); if (Z < z_buffer[indx]) { z_buffer[indx] = Z; for (short int k = 0; k < sizeA; k++) - image[sizeA*indx + k] = (A0y[k] + xy1_to_A[3 * k] * x) * Z; + image[sizeA * indx + k] = (A0y[k] + xy1_to_A[3 * k] * x) * Z; } indx++; } - else{ + else + { for (short int x = x_begin; x <= x_end; x++) { Z = Z0y + xy1_to_Z[0] * x; @@ -932,17 +961,16 @@ inline void render_part_interpolated(double* image, double* z_buffer, int x_min, { z_buffer[indx] = Z; for (short int k = 0; k < sizeA; k++) - image[sizeA*indx + k] = A0y[k] + xy1_to_A[3 * k] * x; + image[sizeA * indx + k] = A0y[k] + xy1_to_A[3 * k] * x; } indx++; } } - } - delete[]A0y; + delete[] A0y; } -inline void render_part_interpolated_B(double* image, double* image_B, double* z_buffer,int x_min, int x_max, int y_begin, int y_end, bool strict_edge, double* xy1_to_A, double* xy1_to_A_B, double* xy1_to_Z, double* left_eq, double* right_eq, int width, int height, int sizeA, bool perspective_correct) +inline void render_part_interpolated_B(double *image, double *image_B, double *z_buffer, int x_min, int x_max, int y_begin, int y_end, bool strict_edge, double *xy1_to_A, double *xy1_to_A_B, double *xy1_to_Z, double *left_eq, double *right_eq, int width, int height, int sizeA, bool perspective_correct) { double t[3]; //double *A0y; @@ -953,9 +981,8 @@ inline void render_part_interpolated_B(double* image, double* image_B, double* z if (perspective_correct) { - throw "backward gradient propagation not supported yet with perspective_correct=True"; + throw "backward gradient propagation not supported yet with perspective_correct=True"; } - //A0y =new double[sizeA]; A0y_B = new double[sizeA]; @@ -971,19 +998,21 @@ inline void render_part_interpolated_B(double* image, double* image_B, double* z for (short int y = y_begin; y <= y_end; y++) { - // Line rasterization setup for interpolated values - - t[0] = 0; t[1] = y; t[2] = 1; + // Line rasterization setup for interpolated values + t[0] = 0; + t[1] = y; + t[2] = 1; //mul_matrix3x3_vect(A0y,xy1_to_A,t); - for (short int k = 0; k < sizeA; k++) A0y_B[k] = 0; - + for (short int k = 0; k < sizeA; k++) + A0y_B[k] = 0; + Z0y = dot_prod(xy1_to_Z, t); - // compute beginning and ending of the rasterized line + // compute beginning and ending of the rasterized line - get_xrange(width, left_eq, right_eq, y, strict_edge, x_min, x_max, x_begin,x_end); + get_xrange(width, left_eq, right_eq, y, strict_edge, x_min, x_max, x_begin, x_end); //rasterize line @@ -992,37 +1021,37 @@ inline void render_part_interpolated_B(double* image, double* image_B, double* z { Z = Z0y + xy1_to_Z[0] * x; if (Z == z_buffer[indx]) - { //z_buffer[indx]=Z; + { //z_buffer[indx]=Z; for (short int k = 0; k < sizeA; k++) { //image[sizeA*indx+k]=A0y[k]+xy1_to_A[3*k]*x; - A0y_B[k] += image_B[sizeA*indx + k]; - xy1_to_A_B[3 * k] += image_B[sizeA*indx + k] * x; - image_B[sizeA*indx + k] = 0;// should not be necessary + A0y_B[k] += image_B[sizeA * indx + k]; + xy1_to_A_B[3 * k] += image_B[sizeA * indx + k] * x; + image_B[sizeA * indx + k] = 0; // should not be necessary } } indx++; } mul_matrixNx3_vect_B(sizeA, A0y_B, xy1_to_A_B, t); - } - delete[]A0y_B; + delete[] A0y_B; } -template void rasterize_triangle_textured_gouraud(double Vxy[][2], double Zvertex[3], double UVvertex[][2], double ShadeVertex[], double z_buffer[], T image[], int height, int width, int sizeA, T* Texture, int* Texture_size, bool strict_edge, bool perspective_correct) +template +void rasterize_triangle_textured_gouraud(double Vxy[][2], double Zvertex[3], double UVvertex[][2], double ShadeVertex[], double z_buffer[], T image[], int height, int width, int sizeA, T *Texture, int *Texture_size, bool strict_edge, bool perspective_correct) { - int y_begin[2], y_end[2]; - - double edge_eq[3][3]; - double bary_to_xy1[9]; - double xy1_to_bary[9]; - double xy1_to_UV[6]; - double xy1_to_L[3]; - double xy1_to_Z[3]; - int left_edge_id[2], right_edge_id[2]; - int x_min, x_max; - + int y_begin[2], y_end[2]; + + double edge_eq[3][3]; + double bary_to_xy1[9]; + double xy1_to_bary[9]; + double xy1_to_UV[6]; + double xy1_to_L[3]; + double xy1_to_Z[3]; + int left_edge_id[2], right_edge_id[2]; + int x_min, x_max; + // compute triangle borders equations get_triangle_stencil_equations(Vxy, bary_to_xy1, xy1_to_bary, edge_eq, strict_edge, x_min, x_max, y_begin, y_end, left_edge_id, right_edge_id); @@ -1040,7 +1069,8 @@ template void rasterize_triangle_textured_gouraud(double Vxy[][2], dou for (short int j = 0; j < 3; j++) { xy1_to_UV[3 * i + j] = 0; - for (short int k = 0; k < 3; k++) xy1_to_UV[3 * i + j] += (UVvertex[k][i] * inv_Zvertex[k]) * xy1_to_bary[k * 3 + j]; + for (short int k = 0; k < 3; k++) + xy1_to_UV[3 * i + j] += (UVvertex[k][i] * inv_Zvertex[k]) * xy1_to_bary[k * 3 + j]; } } else @@ -1051,39 +1081,39 @@ template void rasterize_triangle_textured_gouraud(double Vxy[][2], dou for (short int j = 0; j < 3; j++) { xy1_to_UV[3 * i + j] = 0; - for (short int k = 0; k < 3; k++) xy1_to_UV[3 * i + j] += UVvertex[k][i] * xy1_to_bary[k * 3 + j]; + for (short int k = 0; k < 3; k++) + xy1_to_UV[3 * i + j] += UVvertex[k][i] * xy1_to_bary[k * 3 + j]; } } - - for (int k = 0; k < 2; k++) render_part_textured_gouraud(image, z_buffer, x_min, x_max, y_begin[k], y_end[k], strict_edge, xy1_to_UV, xy1_to_L, xy1_to_Z, edge_eq[left_edge_id[k]], edge_eq[right_edge_id[k]], width, height, sizeA, Texture, Texture_size, perspective_correct); } -template void rasterize_triangle_textured_gouraud_B(double Vxy[][2], double Vxy_B[][2], double Zvertex[3], double UVvertex[][2], double UVvertex_B[][2], double ShadeVertex[], double ShadeVertex_B[], double z_buffer[], T image[], T image_B[], int height, int width, int sizeA, T* Texture, T* Texture_B, int* Texture_size, bool strict_edge, bool perspective_correct) +template +void rasterize_triangle_textured_gouraud_B(double Vxy[][2], double Vxy_B[][2], double Zvertex[3], double UVvertex[][2], double UVvertex_B[][2], double ShadeVertex[], double ShadeVertex_B[], double z_buffer[], T image[], T image_B[], int height, int width, int sizeA, T *Texture, T *Texture_B, int *Texture_size, bool strict_edge, bool perspective_correct) { - int y_begin[2], y_end[2]; - double edge_eq[3][3]; - double bary_to_xy1[9]; - double bary_to_xy1_B[9] = { 0 }; - double xy1_to_bary[9]; - double xy1_to_bary_B[9] = { 0 }; - double xy1_to_UV[6]; - double xy1_to_L[3]; - double xy1_to_Z[3]; - double xy1_to_UV_B[6] = { 0 }; - double xy1_to_L_B[3] = { 0 }; - double xy1_to_Z_B[3] = { 0 }; - int x_min, x_max; - - int left_edge_id[2], right_edge_id[2]; - + int y_begin[2], y_end[2]; + double edge_eq[3][3]; + double bary_to_xy1[9]; + double bary_to_xy1_B[9] = {0}; + double xy1_to_bary[9]; + double xy1_to_bary_B[9] = {0}; + double xy1_to_UV[6]; + double xy1_to_L[3]; + double xy1_to_Z[3]; + double xy1_to_UV_B[6] = {0}; + double xy1_to_L_B[3] = {0}; + double xy1_to_Z_B[3] = {0}; + int x_min, x_max; + + int left_edge_id[2], right_edge_id[2]; + if (perspective_correct) { - throw "backward gradient propagation not supported yet with perspective_correct=True"; + throw "backward gradient propagation not supported yet with perspective_correct=True"; } - + // compute triangle borders equations get_triangle_stencil_equations(Vxy, bary_to_xy1, xy1_to_bary, edge_eq, strict_edge, x_min, x_max, y_begin, y_end, left_edge_id, right_edge_id); @@ -1097,17 +1127,18 @@ template void rasterize_triangle_textured_gouraud_B(double Vxy[][2], d for (short int j = 0; j < 3; j++) { xy1_to_UV[3 * i + j] = 0; - for (short int k = 0; k < 3; k++) xy1_to_UV[3 * i + j] += UVvertex[k][i] * xy1_to_bary[k * 3 + j]; + for (short int k = 0; k < 3; k++) + xy1_to_UV[3 * i + j] += UVvertex[k][i] * xy1_to_bary[k * 3 + j]; } for (int k = 0; k < 2; k++) - render_part_textured_gouraud_B(image, image_B, z_buffer, x_min, x_max, y_begin[k], y_end[k], strict_edge, xy1_to_UV, xy1_to_UV_B, xy1_to_L, xy1_to_L_B, xy1_to_Z, edge_eq[left_edge_id[k]], edge_eq[right_edge_id[k]], width, height, sizeA, Texture, Texture_B, Texture_size, perspective_correct); + render_part_textured_gouraud_B(image, image_B, z_buffer, x_min, x_max, y_begin[k], y_end[k], strict_edge, xy1_to_UV, xy1_to_UV_B, xy1_to_L, xy1_to_L_B, xy1_to_Z, edge_eq[left_edge_id[k]], edge_eq[right_edge_id[k]], width, height, sizeA, Texture, Texture_B, Texture_size, perspective_correct); for (short int i = 0; i < 2; i++) for (short int j = 0; j < 3; j++) { for (short int k = 0; k < 3; k++) - { //xy1_to_UV[3*i+j]+=UVvertex[k][i]*xy1_to_bary[k*3+j]; + { //xy1_to_UV[3*i+j]+=UVvertex[k][i]*xy1_to_bary[k*3+j]; UVvertex_B[k][i] += xy1_to_UV_B[3 * i + j] * xy1_to_bary[k * 3 + j]; xy1_to_bary_B[k * 3 + j] += xy1_to_UV_B[3 * i + j] * UVvertex[k][i]; } @@ -1119,12 +1150,12 @@ template void rasterize_triangle_textured_gouraud_B(double Vxy[][2], d inv_matrix_3x3_B(bary_to_xy1, bary_to_xy1_B, xy1_to_bary, xy1_to_bary_B); - for (int v = 0; v < 3; v++) //v:vertex , d:dimension + for (int v = 0; v < 3; v++) //v:vertex , d:dimension for (int d = 0; d < 2; d++) Vxy_B[v][d] += bary_to_xy1_B[3 * d + v]; } -inline void render_part_textured_gouraud(double* image, double* z_buffer, int x_min, int x_max, int y_begin, int y_end, bool strict_edge, double* xy1_to_UV, double* xy1_to_L, double* xy1_to_Z, double* left_eq, double* right_eq, int width, int height, int sizeA, double* Texture, int* Texture_size, bool perspective_correct) +inline void render_part_textured_gouraud(double *image, double *z_buffer, int x_min, int x_max, int y_begin, int y_end, bool strict_edge, double *xy1_to_UV, double *xy1_to_L, double *xy1_to_Z, double *left_eq, double *right_eq, int width, int height, int sizeA, double *Texture, int *Texture_size, bool perspective_correct) { double t[3]; double L0y; @@ -1137,33 +1168,36 @@ inline void render_part_textured_gouraud(double* image, double* z_buffer, int x A = new double[sizeA]; if (y_begin < 0) - { + { y_begin = 0; } if (y_end > height - 1) { y_end = height - 1; } - + for (short int y = y_begin; y <= y_end; y++) { - - // Line rasterization setup for interpolated values - t[0] = 0; t[1] = y; t[2] = 1; + // Line rasterization setup for interpolated values + + t[0] = 0; + t[1] = y; + t[2] = 1; for (short int i = 0; i < 2; i++) { UV0y[i] = 0; - for (short int k = 0; k < 3; k++) UV0y[i] += xy1_to_UV[k + 3 * i] * t[k]; + for (short int k = 0; k < 3; k++) + UV0y[i] += xy1_to_UV[k + 3 * i] * t[k]; } L0y = dot_prod(xy1_to_L, t); Z0y = dot_prod(xy1_to_Z, t); - // compute beginning and ending of the rasterized line + // compute beginning and ending of the rasterized line - get_xrange(width, left_eq, right_eq, y, strict_edge, x_min, x_max, x_begin,x_end); + get_xrange(width, left_eq, right_eq, y, strict_edge, x_min, x_max, x_begin, x_end); // line rasterization @@ -1173,7 +1207,7 @@ inline void render_part_textured_gouraud(double* image, double* z_buffer, int x for (short int x = x_begin; x <= x_end; x++) { double inv_Z = Z0y + xy1_to_Z[0] * x; - Z = 1/inv_Z; + Z = 1 / inv_Z; if (Z < z_buffer[indx]) { double L; @@ -1188,17 +1222,16 @@ inline void render_part_textured_gouraud(double* image, double* z_buffer, int x bilinear_sample(A, Texture, Texture_size, UV, sizeA); for (int k = 0; k < sizeA; k++) - image[sizeA*indx + k] = A[k] * L; + image[sizeA * indx + k] = A[k] * L; } indx++; } - } else - { + { for (short int x = x_begin; x <= x_end; x++) { - + Z = Z0y + xy1_to_Z[0] * x; if (Z < z_buffer[indx]) { @@ -1214,16 +1247,16 @@ inline void render_part_textured_gouraud(double* image, double* z_buffer, int x bilinear_sample(A, Texture, Texture_size, UV, sizeA); for (int k = 0; k < sizeA; k++) - image[sizeA*indx + k] = A[k] * L; + image[sizeA * indx + k] = A[k] * L; } indx++; } } } - delete[]A; + delete[] A; } -inline void render_part_textured_gouraud_B(double* image, double* image_B, double* z_buffer, int x_min, int x_max, int y_begin, int y_end, bool strict_edge, double* xy1_to_UV, double* xy1_to_UV_B, double* xy1_to_L, double* xy1_to_L_B, double* xy1_to_Z, double* left_eq, double* right_eq, int width, int height, int sizeA, double* Texture, double* Texture_B, int* Texture_size, bool perspective_correct) +inline void render_part_textured_gouraud_B(double *image, double *image_B, double *z_buffer, int x_min, int x_max, int y_begin, int y_end, bool strict_edge, double *xy1_to_UV, double *xy1_to_UV_B, double *xy1_to_L, double *xy1_to_L_B, double *xy1_to_Z, double *left_eq, double *right_eq, int width, int height, int sizeA, double *Texture, double *Texture_B, int *Texture_size, bool perspective_correct) { double t[3]; double L0y; @@ -1238,10 +1271,9 @@ inline void render_part_textured_gouraud_B(double* image, double* image_B, doub A = new double[sizeA]; A_B = new double[sizeA]; - if (perspective_correct) { - throw "backward gradient propagation not supported yet with perspective_correct=True"; + throw "backward gradient propagation not supported yet with perspective_correct=True"; } if (y_begin < 0) @@ -1249,20 +1281,23 @@ inline void render_part_textured_gouraud_B(double* image, double* image_B, doub y_begin = 0; } if (y_end > height - 1) - { + { y_end = height - 1; } for (short int y = y_begin; y <= y_end; y++) { - // Line rasterization setup for interpolated values - t[0] = 0; t[1] = y; t[2] = 1; + // Line rasterization setup for interpolated values + t[0] = 0; + t[1] = y; + t[2] = 1; for (short int i = 0; i < 2; i++) { UV0y[i] = 0; - for (short int k = 0; k < 3; k++) UV0y[i] += xy1_to_UV[k + 3 * i] * t[k]; + for (short int k = 0; k < 3; k++) + UV0y[i] += xy1_to_UV[k + 3 * i] * t[k]; } for (short int i = 0; i < 2; i++) UV0y_B[i] = 0; @@ -1271,9 +1306,9 @@ inline void render_part_textured_gouraud_B(double* image, double* image_B, doub double L0y_B = 0; Z0y = dot_prod(xy1_to_Z, t); - // compute beginning and ending of the rasterized line + // compute beginning and ending of the rasterized line - get_xrange(width, left_eq, right_eq, y, strict_edge, x_min, x_max, x_begin,x_end); + get_xrange(width, left_eq, right_eq, y, strict_edge, x_min, x_max, x_begin, x_end); // line rasterization @@ -1286,23 +1321,24 @@ inline void render_part_textured_gouraud_B(double* image, double* image_B, doub double L; double UV[2]; - //z_buffer[indx]=Z; + //z_buffer[indx]=Z; L = L0y + xy1_to_L[0] * x; double L_B = 0; for (int k = 0; k < 2; k++) UV[k] = UV0y[k] + xy1_to_UV[3 * k] * x; - double UV_B[2] = { 0 }; + double UV_B[2] = {0}; bilinear_sample(A, Texture, Texture_size, UV, sizeA); - for (int k = 0; k < sizeA; k++) A_B[k] = 0; + for (int k = 0; k < sizeA; k++) + A_B[k] = 0; //for(int k=0;k0 -> inside the paralellogram + // setup border inequalities e*[i,j,1]>0 -> inside the paralellogram for (short int k = 0; k < 2; k++) for (short int j = 0; j < 3; j++) @@ -1419,12 +1458,12 @@ void get_edge_stencil_equations(double Vxy[][2], int height, int width, double s } } -void get_edge_stencil_equations_B(double Vxy[][2], double Vxy_B[][2], double sigma, double xy1_to_bary_B[6], double xy1_to_transp_B[3],bool clockwise) +void get_edge_stencil_equations_B(double Vxy[][2], double Vxy_B[][2], double sigma, double xy1_to_bary_B[6], double xy1_to_transp_B[3], bool clockwise) { - double edge_to_xy1[9]; - double xy1_to_edge[9]; - double n[2]; - double nt[2]; + double edge_to_xy1[9]; + double xy1_to_edge[9]; + double n[2]; + double nt[2]; if (clockwise) { nt[0] = Vxy[0][1] - Vxy[1][1]; @@ -1432,14 +1471,14 @@ void get_edge_stencil_equations_B(double Vxy[][2], double Vxy_B[][2], double sig } else { - nt[0] = Vxy[1][1] - Vxy[0][1]; - nt[1] = Vxy[0][0] - Vxy[1][0]; + nt[0] = Vxy[1][1] - Vxy[0][1]; + nt[1] = Vxy[0][0] - Vxy[1][0]; } double inv_norm = 1 / sqrt(nt[0] * nt[0] + nt[1] * nt[1]); n[0] = nt[0] * inv_norm; n[1] = nt[1] * inv_norm; - for (int v = 0; v < 2; v++) //v:vertex , d:dimension + for (int v = 0; v < 2; v++) //v:vertex , d:dimension for (int d = 0; d < 2; d++) edge_to_xy1[3 * d + v] = Vxy[v][d]; for (int d = 0; d < 2; d++) @@ -1448,22 +1487,28 @@ void get_edge_stencil_equations_B(double Vxy[][2], double Vxy_B[][2], double sig edge_to_xy1[3 * 2 + v] = 1; edge_to_xy1[3 * 2 + 2] = 0; - double edge_to_xy1_B[9] = { 0 }; - double xy1_to_edge_B[9] = { 0 }; + double edge_to_xy1_B[9] = {0}; + double xy1_to_edge_B[9] = {0}; - for (int k = 0; k < 3; k++) { xy1_to_edge_B[6 + k] += xy1_to_transp_B[k] * (1 / sigma); } - for (int k = 0; k < 6; k++) { xy1_to_edge_B[k] += xy1_to_bary_B[k]; } + for (int k = 0; k < 3; k++) + { + xy1_to_edge_B[6 + k] += xy1_to_transp_B[k] * (1 / sigma); + } + for (int k = 0; k < 6; k++) + { + xy1_to_edge_B[k] += xy1_to_bary_B[k]; + } inv_matrix_3x3_B(edge_to_xy1, edge_to_xy1_B, xy1_to_edge, xy1_to_edge_B); - - for (int v = 0; v < 2; v++) //v:vertex , d:dimension + + for (int v = 0; v < 2; v++) //v:vertex , d:dimension for (int d = 0; d < 2; d++) Vxy_B[v][d] += edge_to_xy1_B[3 * d + v]; - double n_B[3] = { 0 }; + double n_B[3] = {0}; for (int d = 0; d < 2; d++) n_B[d] += edge_to_xy1_B[3 * d + 2]; - - double nt_B[2] = { 0 }; + + double nt_B[2] = {0}; double inv_norm_B = 0; for (int k = 0; k < 2; k++) @@ -1471,9 +1516,9 @@ void get_edge_stencil_equations_B(double Vxy[][2], double Vxy_B[][2], double sig nt_B[k] += n_B[k] * inv_norm; inv_norm_B += n_B[k] * nt[k]; } - double nor_B = -inv_norm_B * (inv_norm*inv_norm); - double nor_s_B = nor_B * 0.5*inv_norm; - + double nor_B = -inv_norm_B * (inv_norm * inv_norm); + double nor_s_B = nor_B * 0.5 * inv_norm; + nt_B[0] += 2 * nt[0] * nor_s_B; nt_B[1] += 2 * nt[1] * nor_s_B; if (clockwise) @@ -1492,18 +1537,18 @@ void get_edge_stencil_equations_B(double Vxy[][2], double Vxy_B[][2], double sig } } - -template void rasterize_edge_interpolated(double Vxy[][2], Te image[], Te *Avertex[], double z_buffer[], double Zvertex[], int height, int width, int sizeA, double sigma,bool clockwise, bool perspective_correct) +template +void rasterize_edge_interpolated(double Vxy[][2], Te image[], Te *Avertex[], double z_buffer[], double Zvertex[], int height, int width, int sizeA, double sigma, bool clockwise, bool perspective_correct) { - double xy1_to_bary[6]; - double xy1_to_transp[3]; - double ineq[12]; - int y_begin, y_end; - double xy1_to_Z[3]; + double xy1_to_bary[6]; + double xy1_to_transp[3]; + double ineq[12]; + int y_begin, y_end; + double xy1_to_Z[3]; double *xy1_to_A; double *A0y = new double[sizeA]; - - get_edge_stencil_equations(Vxy, height, width, sigma, xy1_to_bary, xy1_to_transp, ineq, y_begin, y_end,clockwise); + + get_edge_stencil_equations(Vxy, height, width, sigma, xy1_to_bary, xy1_to_transp, ineq, y_begin, y_end, clockwise); double B_inc[2]; for (short int k = 0; k < 2; k++) @@ -1513,7 +1558,7 @@ template void rasterize_edge_interpolated(double Vxy[][2], Te image[] if (perspective_correct) { - double inv_Zvertex[3]; + double inv_Zvertex[3]; elementwise_inverse_vec3(Zvertex, inv_Zvertex); mul_matrix(1, 2, 3, xy1_to_Z, inv_Zvertex, xy1_to_bary); @@ -1522,7 +1567,8 @@ template void rasterize_edge_interpolated(double Vxy[][2], Te image[] for (short int j = 0; j < 3; j++) { xy1_to_A[3 * i + j] = 0; - for (short int k = 0; k < 2; k++) xy1_to_A[3 * i + j] += (Avertex[k][i] * inv_Zvertex[k]) * xy1_to_bary[k * 3 + j]; + for (short int k = 0; k < 2; k++) + xy1_to_A[3 * i + j] += (Avertex[k][i] * inv_Zvertex[k]) * xy1_to_bary[k * 3 + j]; } } else @@ -1533,16 +1579,19 @@ template void rasterize_edge_interpolated(double Vxy[][2], Te image[] for (short int j = 0; j < 3; j++) { xy1_to_A[3 * i + j] = 0; - for (short int k = 0; k < 2; k++) xy1_to_A[3 * i + j] += Avertex[k][i] * xy1_to_bary[k * 3 + j]; + for (short int k = 0; k < 2; k++) + xy1_to_A[3 * i + j] += Avertex[k][i] * xy1_to_bary[k * 3 + j]; } } for (short int y = y_begin; y <= y_end; y++) - { // Line rasterization setup for interpolated values + { // Line rasterization setup for interpolated values double t[3]; double T0y, Z0y; - t[0] = 0; t[1] = y; t[2] = 1; + t[0] = 0; + t[1] = y; + t[2] = 1; mul_matrixNx3_vect(sizeA, A0y, xy1_to_A, t); T0y = dot_prod(xy1_to_transp, t); Z0y = dot_prod(xy1_to_Z, t); @@ -1575,7 +1624,7 @@ template void rasterize_edge_interpolated(double Vxy[][2], Te image[] } } else - { + { for (short int x = x_begin; x <= x_end; x++) { double Z = Z0y + xy1_to_Z[0] * x; @@ -1587,36 +1636,37 @@ template void rasterize_edge_interpolated(double Vxy[][2], Te image[] { image[sizeA * indx + k] *= T; double A = (A0y[k] + xy1_to_A[3 * k] * x); - image[sizeA * indx + k] += (1 - T)* A; + image[sizeA * indx + k] += (1 - T) * A; } } indx++; } } } - delete[]A0y; - delete[]xy1_to_A; + delete[] A0y; + delete[] xy1_to_A; } -template void rasterize_edge_interpolated_B(double Vxy[][2], double Vxy_B[][2], Te image[], Te image_B[], Te *Avertex[], Te *Avertex_B[], double z_buffer[], double Zvertex[], int height, int width, int sizeA, double sigma,bool clockwise, bool perspective_correct) +template +void rasterize_edge_interpolated_B(double Vxy[][2], double Vxy_B[][2], Te image[], Te image_B[], Te *Avertex[], Te *Avertex_B[], double z_buffer[], double Zvertex[], int height, int width, int sizeA, double sigma, bool clockwise, bool perspective_correct) { - double xy1_to_bary[6]; - double xy1_to_bary_B[6] = { 0 }; - double xy1_to_transp[3]; - double xy1_to_transp_B[3] = { 0 }; - double ineq[12]; - int y_begin, y_end; - double xy1_to_Z[3]; + double xy1_to_bary[6]; + double xy1_to_bary_B[6] = {0}; + double xy1_to_transp[3]; + double xy1_to_transp_B[3] = {0}; + double ineq[12]; + int y_begin, y_end; + double xy1_to_Z[3]; double *xy1_to_A; double *A0y = new double[sizeA]; double *A0y_B = new double[sizeA]; - + if (perspective_correct) { - throw "backward gradient propagation not supported yet with perspective_correct=True"; + throw "backward gradient propagation not supported yet with perspective_correct=True"; } - get_edge_stencil_equations(Vxy, height, width, sigma, xy1_to_bary, xy1_to_transp, ineq, y_begin, y_end,clockwise); + get_edge_stencil_equations(Vxy, height, width, sigma, xy1_to_bary, xy1_to_transp, ineq, y_begin, y_end, clockwise); //double B_inc[2]; //for(short int k=0;k<2;k++) @@ -1630,7 +1680,8 @@ template void rasterize_edge_interpolated_B(double Vxy[][2], double V xy1_to_A = new double[3 * sizeA]; double *xy1_to_A_B; xy1_to_A_B = new double[3 * sizeA]; - for (short int i = 0; i < 3 * sizeA; i++) xy1_to_A_B[i] = 0; + for (short int i = 0; i < 3 * sizeA; i++) + xy1_to_A_B[i] = 0; for (short int i = 0; i < sizeA; i++) for (short int j = 0; j < 3; j++) @@ -1641,13 +1692,16 @@ template void rasterize_edge_interpolated_B(double Vxy[][2], double V } for (short int y = y_begin; y <= y_end; y++) - { // Line rasterization setup for interpolated values + { // Line rasterization setup for interpolated values double t[3]; double T0y, Z0y; - t[0] = 0; t[1] = y; t[2] = 1; + t[0] = 0; + t[1] = y; + t[2] = 1; mul_matrixNx3_vect(sizeA, A0y, xy1_to_A, t); - for (short int k = 0; k < sizeA; k++) A0y_B[k] = 0; + for (short int k = 0; k < sizeA; k++) + A0y_B[k] = 0; T0y = dot_prod(xy1_to_transp, t); double T0y_B = 0; @@ -1675,24 +1729,22 @@ template void rasterize_edge_interpolated_B(double Vxy[][2], double V //image[sizeA*indx+k]*= T; //image[sizeA*indx+k]+= (1-T)*A; - T_B += -image_B[sizeA*indx + k] * A; - double A_B = (1 - T)*image_B[sizeA*indx + k]; + T_B += -image_B[sizeA * indx + k] * A; + double A_B = (1 - T) * image_B[sizeA * indx + k]; // restoring the color before edge drawned - image[sizeA*indx + k] = (image[sizeA*indx + k] - (1 - T)*A) / T; + image[sizeA * indx + k] = (image[sizeA * indx + k] - (1 - T) * A) / T; - T_B += image_B[sizeA*indx + k] * image[sizeA*indx + k]; + T_B += image_B[sizeA * indx + k] * image[sizeA * indx + k]; - image_B[sizeA*indx + k] *= T; + image_B[sizeA * indx + k] *= T; A0y_B[k] += A_B; xy1_to_A_B[3 * k] += x * A_B; - } T0y_B += T_B; T_inc_B += x * T_B; - } indx++; } @@ -1706,7 +1758,7 @@ template void rasterize_edge_interpolated_B(double Vxy[][2], double V for (short int j = 0; j < 3; j++) { for (short int k = 0; k < 2; k++) - //xy1_to_A[3*i+j]+=Avertex[k][i]*xy1_to_bary[k*3+j]; + //xy1_to_A[3*i+j]+=Avertex[k][i]*xy1_to_bary[k*3+j]; { Avertex_B[k][i] += xy1_to_A_B[3 * i + j] * xy1_to_bary[k * 3 + j]; xy1_to_bary_B[k * 3 + j] += Avertex[k][i] * xy1_to_A_B[3 * i + j]; @@ -1717,29 +1769,30 @@ template void rasterize_edge_interpolated_B(double Vxy[][2], double V // xy1_to_bary_B [3*k]+=B_inc_B[k]; xy1_to_transp_B[0] += T_inc_B; - get_edge_stencil_equations_B(Vxy, Vxy_B, sigma, xy1_to_bary_B, xy1_to_transp_B,clockwise); + get_edge_stencil_equations_B(Vxy, Vxy_B, sigma, xy1_to_bary_B, xy1_to_transp_B, clockwise); - delete[]A0y; - delete[]A0y_B; - delete[]xy1_to_A; - delete[]xy1_to_A_B; + delete[] A0y; + delete[] A0y_B; + delete[] xy1_to_A; + delete[] xy1_to_A_B; } -template void rasterize_edge_textured_gouraud(double Vxy[][2], double Zvertex[2], double UVvertex[][2], double ShadeVertex[2], double z_buffer[], Te image[], int height, int width, int sizeA, Te* Texture, int* Texture_size, double sigma,bool clockwise, bool perspective_correct) +template +void rasterize_edge_textured_gouraud(double Vxy[][2], double Zvertex[2], double UVvertex[][2], double ShadeVertex[2], double z_buffer[], Te image[], int height, int width, int sizeA, Te *Texture, int *Texture_size, double sigma, bool clockwise, bool perspective_correct) { - double xy1_to_bary[6]; - double xy1_to_transp[3]; - double ineq[12]; - int y_begin, y_end; - double xy1_to_Z[3]; - double xy1_to_UV[6]; - double xy1_to_L[3]; - double *A; - double UV0y[2]; - + double xy1_to_bary[6]; + double xy1_to_transp[3]; + double ineq[12]; + int y_begin, y_end; + double xy1_to_Z[3]; + double xy1_to_UV[6]; + double xy1_to_L[3]; + double *A; + double UV0y[2]; + A = new double[sizeA]; - - get_edge_stencil_equations(Vxy, height, width, sigma, xy1_to_bary, xy1_to_transp, ineq, y_begin, y_end,clockwise); + + get_edge_stencil_equations(Vxy, height, width, sigma, xy1_to_bary, xy1_to_transp, ineq, y_begin, y_end, clockwise); double B_inc[2]; for (short int k = 0; k < 2; k++) @@ -1748,22 +1801,23 @@ template void rasterize_edge_textured_gouraud(double Vxy[][2], double double T_inc = xy1_to_transp[0]; if (perspective_correct) { - double inv_Zvertex[3]; - double ShadeVertex_div_z[3]; + double inv_Zvertex[3]; + double ShadeVertex_div_z[3]; elementwise_inverse_vec3(Zvertex, inv_Zvertex); elementwise_prod_vec3(inv_Zvertex, ShadeVertex, ShadeVertex_div_z); mul_matrix(1, 2, 3, xy1_to_Z, inv_Zvertex, xy1_to_bary); mul_matrix(1, 2, 3, xy1_to_L, ShadeVertex_div_z, xy1_to_bary); - - for (int i = 0; i < 2; i++) { + + for (int i = 0; i < 2; i++) + { for (int j = 0; j < 3; j++) { xy1_to_UV[3 * i + j] = 0; - for (int k = 0; k < 2; k++) xy1_to_UV[3 * i + j] += UVvertex[k][i] * inv_Zvertex[k] * xy1_to_bary[k * 3 + j]; + for (int k = 0; k < 2; k++) + xy1_to_UV[3 * i + j] += UVvertex[k][i] * inv_Zvertex[k] * xy1_to_bary[k * 3 + j]; } } - } else { @@ -1774,42 +1828,46 @@ template void rasterize_edge_textured_gouraud(double Vxy[][2], double for (short int j = 0; j < 3; j++) { xy1_to_UV[3 * i + j] = 0; - for (short int k = 0; k < 2; k++) xy1_to_UV[3 * i + j] += UVvertex[k][i] * xy1_to_bary[k * 3 + j]; + for (short int k = 0; k < 2; k++) + xy1_to_UV[3 * i + j] += UVvertex[k][i] * xy1_to_bary[k * 3 + j]; } } for (short int y = y_begin; y <= y_end; y++) - { // Line rasterization setup for interpolated values + { // Line rasterization setup for interpolated values double t[3]; double T0y, Z0y, L0y; - t[0] = 0; t[1] = y; t[2] = 1; + t[0] = 0; + t[1] = y; + t[2] = 1; T0y = dot_prod(xy1_to_transp, t); Z0y = dot_prod(xy1_to_Z, t); L0y = dot_prod(xy1_to_L, t); - + for (short int i = 0; i < 2; i++) { UV0y[i] = 0; - for (short int k = 0; k < 3; k++) UV0y[i] += xy1_to_UV[k + 3 * i] * t[k]; + for (short int k = 0; k < 3; k++) + UV0y[i] += xy1_to_UV[k + 3 * i] * t[k]; } // get x range of the line int x_begin, x_end; get_edge_xrange_from_ineq(ineq, width, y, x_begin, x_end); - + //rasterize line int indx = y * width + x_begin; for (short int x = x_begin; x <= x_end; x++) - { + { double Z; if (perspective_correct) { double inv_Z = Z0y + xy1_to_Z[0] * x; - Z = 1 / inv_Z; + Z = 1 / inv_Z; } else { @@ -1817,62 +1875,64 @@ template void rasterize_edge_textured_gouraud(double Vxy[][2], double } if (Z < z_buffer[indx]) { - double L = L0y + xy1_to_L[0] * x;; + double L = L0y + xy1_to_L[0] * x; + ; double T = T0y + T_inc * x; - double UV[2]; + double UV[2]; for (int k = 0; k < 2; k++) { UV[k] = UV0y[k] + xy1_to_UV[3 * k] * x; } if (perspective_correct) { - L *= Z; - for (int k = 0; k < 2; k++) - { - UV[k] *= Z; - } + L *= Z; + for (int k = 0; k < 2; k++) + { + UV[k] *= Z; + } } bilinear_sample(A, Texture, Texture_size, UV, sizeA); for (short int k = 0; k < sizeA; k++) { - image[sizeA*indx + k] *= T; - image[sizeA*indx + k] += (1 - T)*A[k] * L; + image[sizeA * indx + k] *= T; + image[sizeA * indx + k] += (1 - T) * A[k] * L; } } indx++; } } - delete[]A; + delete[] A; } -template void rasterize_edge_textured_gouraud_B(double Vxy[][2], double Vxy_B[][2], double Zvertex[2], double UVvertex[][2], double UVvertex_B[][2], double ShadeVertex[2], double ShadeVertex_B[2], double z_buffer[], Te image[], Te image_B[], int height, int width, int sizeA, Te* Texture, Te* Texture_B, int* Texture_size, double sigma,bool clockwise, bool perspective_correct) +template +void rasterize_edge_textured_gouraud_B(double Vxy[][2], double Vxy_B[][2], double Zvertex[2], double UVvertex[][2], double UVvertex_B[][2], double ShadeVertex[2], double ShadeVertex_B[2], double z_buffer[], Te image[], Te image_B[], int height, int width, int sizeA, Te *Texture, Te *Texture_B, int *Texture_size, double sigma, bool clockwise, bool perspective_correct) { - double xy1_to_bary[6]; - double xy1_to_transp[3]; - double ineq[12]; - int y_begin, y_end; - double xy1_to_Z[3]; - double xy1_to_UV[6]; - double xy1_to_UV_B[6]; - double xy1_to_L[3]; - - double *A; - double *A_B; - double UV0y[2]; + double xy1_to_bary[6]; + double xy1_to_transp[3]; + double ineq[12]; + int y_begin, y_end; + double xy1_to_Z[3]; + double xy1_to_UV[6]; + double xy1_to_UV_B[6]; + double xy1_to_L[3]; + + double *A; + double *A_B; + double UV0y[2]; if (perspective_correct) { - throw "backward gradient propagation not supported yet with perspective_correct=True"; + throw "backward gradient propagation not supported yet with perspective_correct=True"; } A = new double[sizeA]; A_B = new double[sizeA]; - get_edge_stencil_equations(Vxy, height, width, sigma, xy1_to_bary, xy1_to_transp, ineq, y_begin, y_end,clockwise); + get_edge_stencil_equations(Vxy, height, width, sigma, xy1_to_bary, xy1_to_transp, ineq, y_begin, y_end, clockwise); - double xy1_to_bary_B[6] = { 0 }; - double xy1_to_transp_B[3] = { 0 }; + double xy1_to_bary_B[6] = {0}; + double xy1_to_transp_B[3] = {0}; //double B_inc[2]; //for(short int k=0;k<2;k++) @@ -1883,42 +1943,45 @@ template void rasterize_edge_textured_gouraud_B(double Vxy[][2], doub mul_matrix(1, 2, 3, xy1_to_Z, Zvertex, xy1_to_bary); mul_matrix(1, 2, 3, xy1_to_L, ShadeVertex, xy1_to_bary); - double xy1_to_L_B[3] = { 0 }; + double xy1_to_L_B[3] = {0}; for (short int i = 0; i < 2; i++) for (short int j = 0; j < 3; j++) { xy1_to_UV[3 * i + j] = 0; xy1_to_UV_B[3 * i + j] = 0; - for (short int k = 0; k < 2; k++) xy1_to_UV[3 * i + j] += UVvertex[k][i] * xy1_to_bary[k * 3 + j]; + for (short int k = 0; k < 2; k++) + xy1_to_UV[3 * i + j] += UVvertex[k][i] * xy1_to_bary[k * 3 + j]; } - for (short int y = y_begin; y <= y_end; y++) - { // Line rasterization setup for interpolated values + { // Line rasterization setup for interpolated values double t[3]; double T0y, Z0y, L0y; - t[0] = 0; t[1] = y; t[2] = 1; + t[0] = 0; + t[1] = y; + t[2] = 1; T0y = dot_prod(xy1_to_transp, t); Z0y = dot_prod(xy1_to_Z, t); L0y = dot_prod(xy1_to_L, t); double L0y_B = 0; double T0y_B = 0; - + for (short int i = 0; i < 2; i++) { UV0y[i] = 0; - for (short int k = 0; k < 3; k++) UV0y[i] += xy1_to_UV[k + 3 * i] * t[k]; + for (short int k = 0; k < 3; k++) + UV0y[i] += xy1_to_UV[k + 3 * i] * t[k]; } - double UV0y_B[2] = { 0 }; + double UV0y_B[2] = {0}; // get x range of the line int x_begin, x_end; get_edge_xrange_from_ineq(ineq, width, y, x_begin, x_end); - + //rasterize line int indx = y * width + x_begin; @@ -1933,26 +1996,27 @@ template void rasterize_edge_textured_gouraud_B(double Vxy[][2], doub double T = T0y + T_inc * x; double T_B = 0; - double UV[2]; + double UV[2]; for (int k = 0; k < 2; k++) UV[k] = UV0y[k] + xy1_to_UV[3 * k] * x; bilinear_sample(A, Texture, Texture_size, UV, sizeA); - for (short int k = 0; k < sizeA; k++) A_B[k] = 0; + for (short int k = 0; k < sizeA; k++) + A_B[k] = 0; for (short int k = 0; k < sizeA; k++) { //image[sizeA*indx+k]*= T; //image[sizeA*indx+k]+= (1-T)*A[k]*L; - T_B += -image_B[sizeA*indx + k] * A[k] * L; - A_B[k] += L * (1 - T)*image_B[sizeA*indx + k]; - L_B += image_B[sizeA*indx + k] * (1 - T)*A[k]; - image[sizeA*indx + k] = (image[sizeA*indx + k] - (1 - T)*A[k] * L) / T; - T_B += image_B[sizeA*indx + k] * image[sizeA*indx + k]; - image_B[sizeA*indx + k] *= T; + T_B += -image_B[sizeA * indx + k] * A[k] * L; + A_B[k] += L * (1 - T) * image_B[sizeA * indx + k]; + L_B += image_B[sizeA * indx + k] * (1 - T) * A[k]; + image[sizeA * indx + k] = (image[sizeA * indx + k] - (1 - T) * A[k] * L) / T; + T_B += image_B[sizeA * indx + k] * image[sizeA * indx + k]; + image_B[sizeA * indx + k] *= T; } - double UV_B[2] = { 0 }; + double UV_B[2] = {0}; bilinear_sample_B(A, A_B, Texture, Texture_B, Texture_size, UV, UV_B, sizeA); for (int k = 0; k < 2; k++) @@ -1965,7 +2029,6 @@ template void rasterize_edge_textured_gouraud_B(double Vxy[][2], doub xy1_to_L_B[0] += x * L_B; T0y_B += T_B; T_inc_B += x * T_B; - } indx++; } @@ -1973,16 +2036,16 @@ template void rasterize_edge_textured_gouraud_B(double Vxy[][2], doub for (int k = 0; k < 3; k++) xy1_to_transp_B[k] += T0y_B * t[k]; for (short int i = 0; i < 2; i++) - for (short int k = 0; k < 3; k++) xy1_to_UV_B[k + 3 * i] += UV0y_B[i] * t[k]; + for (short int k = 0; k < 3; k++) + xy1_to_UV_B[k + 3 * i] += UV0y_B[i] * t[k]; dot_prod_B(L0y_B, xy1_to_L_B, t); } - for (short int i = 0; i < 2; i++) for (short int j = 0; j < 3; j++) { for (short int k = 0; k < 2; k++) - //xy1_to_UV[3*i+j]+=UVvertex[k][i]*xy1_to_bary[k*3+j]; + //xy1_to_UV[3*i+j]+=UVvertex[k][i]*xy1_to_bary[k*3+j]; { UVvertex_B[k][i] += xy1_to_UV_B[3 * i + j] * xy1_to_bary[k * 3 + j]; xy1_to_bary_B[k * 3 + j] += xy1_to_UV_B[3 * i + j] * UVvertex[k][i]; @@ -1995,27 +2058,28 @@ template void rasterize_edge_textured_gouraud_B(double Vxy[][2], doub get_edge_stencil_equations_B(Vxy, Vxy_B, sigma, xy1_to_bary_B, xy1_to_transp_B, clockwise); - delete[]A; - delete[]A_B; + delete[] A; + delete[] A_B; } -template void rasterize_edge_textured_gouraud_error(double Vxy[][2], double Zvertex[2], double UVvertex[][2], double ShadeVertex[2], double z_buffer[], T image[], double* err_buffer, int height, int width, int sizeA, T* Texture, int* Texture_size, double sigma,bool clockwise, bool perspective_correct) +template +void rasterize_edge_textured_gouraud_error(double Vxy[][2], double Zvertex[2], double UVvertex[][2], double ShadeVertex[2], double z_buffer[], T image[], double *err_buffer, int height, int width, int sizeA, T *Texture, int *Texture_size, double sigma, bool clockwise, bool perspective_correct) { - double xy1_to_bary[6]; - double xy1_to_transp[3]; - double ineq[12]; - int y_begin, y_end; - double xy1_to_Z[3]; - double xy1_to_UV[6]; - double xy1_to_L[3]; - double *A; - double UV0y[2]; - + double xy1_to_bary[6]; + double xy1_to_transp[3]; + double ineq[12]; + int y_begin, y_end; + double xy1_to_Z[3]; + double xy1_to_UV[6]; + double xy1_to_L[3]; + double *A; + double UV0y[2]; + A = new double[sizeA]; - - get_edge_stencil_equations(Vxy, height, width, sigma, xy1_to_bary, xy1_to_transp, ineq, y_begin, y_end,clockwise); - + + get_edge_stencil_equations(Vxy, height, width, sigma, xy1_to_bary, xy1_to_transp, ineq, y_begin, y_end, clockwise); + double B_inc[2]; for (int k = 0; k < 2; k++) B_inc[k] = xy1_to_bary[3 * k]; @@ -2024,18 +2088,20 @@ template void rasterize_edge_textured_gouraud_error(double Vxy[][2], d if (perspective_correct) { - double inv_Zvertex[3]; - double ShadeVertex_div_z[3]; + double inv_Zvertex[3]; + double ShadeVertex_div_z[3]; elementwise_inverse_vec3(Zvertex, inv_Zvertex); elementwise_prod_vec3(inv_Zvertex, ShadeVertex, ShadeVertex_div_z); mul_matrix(1, 2, 3, xy1_to_Z, inv_Zvertex, xy1_to_bary); mul_matrix(1, 2, 3, xy1_to_L, ShadeVertex_div_z, xy1_to_bary); - - for (int i = 0; i < 2; i++) { + + for (int i = 0; i < 2; i++) + { for (int j = 0; j < 3; j++) { xy1_to_UV[3 * i + j] = 0; - for (int k = 0; k < 2; k++) xy1_to_UV[3 * i + j] += UVvertex[k][i] * inv_Zvertex[k] * xy1_to_bary[k * 3 + j]; + for (int k = 0; k < 2; k++) + xy1_to_UV[3 * i + j] += UVvertex[k][i] * inv_Zvertex[k] * xy1_to_bary[k * 3 + j]; } } } @@ -2044,31 +2110,36 @@ template void rasterize_edge_textured_gouraud_error(double Vxy[][2], d mul_matrix(1, 2, 3, xy1_to_Z, Zvertex, xy1_to_bary); mul_matrix(1, 2, 3, xy1_to_L, ShadeVertex, xy1_to_bary); - for (int i = 0; i < 2; i++) { + for (int i = 0; i < 2; i++) + { for (int j = 0; j < 3; j++) { xy1_to_UV[3 * i + j] = 0; - for (int k = 0; k < 2; k++) xy1_to_UV[3 * i + j] += UVvertex[k][i] * xy1_to_bary[k * 3 + j]; + for (int k = 0; k < 2; k++) + xy1_to_UV[3 * i + j] += UVvertex[k][i] * xy1_to_bary[k * 3 + j]; } } } for (int y = y_begin; y <= y_end; y++) { - // Line rasterization setup for interpolated values + // Line rasterization setup for interpolated values double t[3]; double T0y, Z0y, L0y; - t[0] = 0; t[1] = y; t[2] = 1; + t[0] = 0; + t[1] = y; + t[2] = 1; T0y = dot_prod(xy1_to_transp, t); Z0y = dot_prod(xy1_to_Z, t); L0y = dot_prod(xy1_to_L, t); - + for (int i = 0; i < 2; i++) { UV0y[i] = 0; - for (int k = 0; k < 3; k++) UV0y[i] += xy1_to_UV[k + 3 * i] * t[k]; + for (int k = 0; k < 3; k++) + UV0y[i] += xy1_to_UV[k + 3 * i] * t[k]; } // get x range of the line @@ -2082,28 +2153,28 @@ template void rasterize_edge_textured_gouraud_error(double Vxy[][2], d for (int x = x_begin; x <= x_end; x++) { double Z; - + if (perspective_correct) { double inv_Z = Z0y + xy1_to_Z[0] * x; - Z = 1/inv_Z; + Z = 1 / inv_Z; } else { - Z = Z0y + xy1_to_Z[0] * x; - } + Z = Z0y + xy1_to_Z[0] * x; + } if (Z < z_buffer[indx]) { double L = L0y + xy1_to_L[0] * x; double Tr = T0y + T_inc * x; - double UV[2]; + double UV[2]; for (int k = 0; k < 2; k++) UV[k] = UV0y[k] + xy1_to_UV[3 * k] * x; - + if (perspective_correct) { - L *= Z; + L *= Z; for (int k = 0; k < 2; k++) UV[k] *= Z; } @@ -2112,46 +2183,46 @@ template void rasterize_edge_textured_gouraud_error(double Vxy[][2], d double Err = 0; for (int k = 0; k < sizeA; k++) { - double diff = A[k] * L - image[sizeA*indx + k]; + double diff = A[k] * L - image[sizeA * indx + k]; Err += diff * diff; } err_buffer[indx] *= Tr; - err_buffer[indx] += (1 - Tr)*Err; - + err_buffer[indx] += (1 - Tr) * Err; } indx++; } } - delete[]A; + delete[] A; } -template void rasterize_edge_textured_gouraud_error_B(double Vxy[][2], double Vxy_B[][2], double Zvertex[2], double UVvertex[][2], double UVvertex_B[][2], double ShadeVertex[2], double ShadeVertex_B[2], double z_buffer[], T image[], double err_buffer[], double err_buffer_B[], int height, int width, int sizeA, T* Texture, T* Texture_B, int* Texture_size, double sigma, bool clockwise, bool perspective_correct) +template +void rasterize_edge_textured_gouraud_error_B(double Vxy[][2], double Vxy_B[][2], double Zvertex[2], double UVvertex[][2], double UVvertex_B[][2], double ShadeVertex[2], double ShadeVertex_B[2], double z_buffer[], T image[], double err_buffer[], double err_buffer_B[], int height, int width, int sizeA, T *Texture, T *Texture_B, int *Texture_size, double sigma, bool clockwise, bool perspective_correct) { - double xy1_to_bary[6]; - double xy1_to_transp[3]; - double ineq[12]; - int y_begin, y_end; - double xy1_to_Z[3]; - double xy1_to_UV[6]; - double xy1_to_UV_B[6]; - double xy1_to_L[3]; - - double *A; - double *A_B; - double UV0y[2]; + double xy1_to_bary[6]; + double xy1_to_transp[3]; + double ineq[12]; + int y_begin, y_end; + double xy1_to_Z[3]; + double xy1_to_UV[6]; + double xy1_to_UV_B[6]; + double xy1_to_L[3]; + + double *A; + double *A_B; + double UV0y[2]; if (perspective_correct) { - throw "backward gradient propagation not supported yet with perspective_correct=True"; + throw "backward gradient propagation not supported yet with perspective_correct=True"; } - + A = new double[sizeA]; A_B = new double[sizeA]; - get_edge_stencil_equations(Vxy, height, width, sigma, xy1_to_bary, xy1_to_transp, ineq, y_begin, y_end,clockwise); + get_edge_stencil_equations(Vxy, height, width, sigma, xy1_to_bary, xy1_to_transp, ineq, y_begin, y_end, clockwise); - double xy1_to_bary_B[6] = { 0 }; - double xy1_to_transp_B[3] = { 0 }; + double xy1_to_bary_B[6] = {0}; + double xy1_to_transp_B[3] = {0}; //double B_inc[2]; //for(int k=0;k<2;k++) @@ -2162,43 +2233,47 @@ template void rasterize_edge_textured_gouraud_error_B(double Vxy[][2], mul_matrix(1, 2, 3, xy1_to_Z, Zvertex, xy1_to_bary); mul_matrix(1, 2, 3, xy1_to_L, ShadeVertex, xy1_to_bary); - double xy1_to_L_B[3] = { 0 }; + double xy1_to_L_B[3] = {0}; - for (int i = 0; i < 2; i++) { + for (int i = 0; i < 2; i++) + { for (int j = 0; j < 3; j++) { xy1_to_UV[3 * i + j] = 0; xy1_to_UV_B[3 * i + j] = 0; - for (int k = 0; k < 2; k++) xy1_to_UV[3 * i + j] += UVvertex[k][i] * xy1_to_bary[k * 3 + j]; + for (int k = 0; k < 2; k++) + xy1_to_UV[3 * i + j] += UVvertex[k][i] * xy1_to_bary[k * 3 + j]; } } - + for (int y = y_begin; y <= y_end; y++) - { // Line rasterization setup for interpolated values + { // Line rasterization setup for interpolated values double t[3]; double T0y, Z0y, L0y; - t[0] = 0; t[1] = y; t[2] = 1; + t[0] = 0; + t[1] = y; + t[2] = 1; T0y = dot_prod(xy1_to_transp, t); Z0y = dot_prod(xy1_to_Z, t); L0y = dot_prod(xy1_to_L, t); double L0y_B = 0; double T0y_B = 0; - for (int i = 0; i < 2; i++) { UV0y[i] = 0; - for (int k = 0; k < 3; k++) UV0y[i] += xy1_to_UV[k + 3 * i] * t[k]; + for (int k = 0; k < 3; k++) + UV0y[i] += xy1_to_UV[k + 3 * i] * t[k]; } - double UV0y_B[2] = { 0 }; + double UV0y_B[2] = {0}; // get x range of the line int x_begin, x_end; get_edge_xrange_from_ineq(ineq, width, y, x_begin, x_end); - + //rasterize line int indx = y * width + x_begin; @@ -2212,16 +2287,17 @@ template void rasterize_edge_textured_gouraud_error_B(double Vxy[][2], double Tr = T0y + T_inc * x; double Tr_B = 0; - double UV[2]; + double UV[2]; for (int k = 0; k < 2; k++) UV[k] = UV0y[k] + xy1_to_UV[3 * k] * x; bilinear_sample(A, Texture, Texture_size, UV, sizeA); - for (int k = 0; k < sizeA; k++) A_B[k] = 0; + for (int k = 0; k < sizeA; k++) + A_B[k] = 0; double Err = 0; for (int k = 0; k < sizeA; k++) { - double diff = A[k] * L - image[sizeA*indx + k]; + double diff = A[k] * L - image[sizeA * indx + k]; Err += diff * diff; } @@ -2229,22 +2305,22 @@ template void rasterize_edge_textured_gouraud_error_B(double Vxy[][2], // err_buffer[indx]*= Tr; // err_buffer[indx]+= (1-Tr)*Err; Tr_B += -Err * err_buffer_B[indx]; - Err_B += (1 - Tr)*err_buffer_B[indx]; - err_buffer[indx] -= (1 - Tr)*Err; + Err_B += (1 - Tr) * err_buffer_B[indx]; + err_buffer[indx] -= (1 - Tr) * Err; err_buffer[indx] /= Tr; Tr_B += err_buffer_B[indx] * err_buffer[indx]; err_buffer_B[indx] *= Tr; for (int k = 0; k < sizeA; k++) { - double diff = A[k] * L - image[sizeA*indx + k]; + double diff = A[k] * L - image[sizeA * indx + k]; //Err+=diff*diff; - double diff_B = 2 * diff*Err_B; + double diff_B = 2 * diff * Err_B; A_B[k] += diff_B * L; L_B += diff_B * A[k]; } - double UV_B[2] = { 0 }; + double UV_B[2] = {0}; bilinear_sample_B(A, A_B, Texture, Texture_B, Texture_size, UV, UV_B, sizeA); for (int k = 0; k < 2; k++) @@ -2257,22 +2333,23 @@ template void rasterize_edge_textured_gouraud_error_B(double Vxy[][2], xy1_to_L_B[0] += x * L_B; T0y_B += Tr_B; T_inc_B += x * Tr_B; - } indx++; } for (int k = 0; k < 3; k++) xy1_to_transp_B[k] += T0y_B * t[k]; for (int i = 0; i < 2; i++) - for (int k = 0; k < 3; k++) xy1_to_UV_B[k + 3 * i] += UV0y_B[i] * t[k]; + for (int k = 0; k < 3; k++) + xy1_to_UV_B[k + 3 * i] += UV0y_B[i] * t[k]; dot_prod_B(L0y_B, xy1_to_L_B, t); } - - for (int i = 0; i < 2; i++) { + + for (int i = 0; i < 2; i++) + { for (int j = 0; j < 3; j++) { for (int k = 0; k < 2; k++) - //xy1_to_UV[3*i+j]+=UVvertex[k][i]*xy1_to_bary[k*3+j]; + //xy1_to_UV[3*i+j]+=UVvertex[k][i]*xy1_to_bary[k*3+j]; { UVvertex_B[k][i] += xy1_to_UV_B[3 * i + j] * xy1_to_bary[k * 3 + j]; xy1_to_bary_B[k * 3 + j] += xy1_to_UV_B[3 * i + j] * UVvertex[k][i]; @@ -2283,26 +2360,26 @@ template void rasterize_edge_textured_gouraud_error_B(double Vxy[][2], xy1_to_transp_B[0] += T_inc_B; - get_edge_stencil_equations_B(Vxy, Vxy_B, sigma, xy1_to_bary_B, xy1_to_transp_B,clockwise); + get_edge_stencil_equations_B(Vxy, Vxy_B, sigma, xy1_to_bary_B, xy1_to_transp_B, clockwise); - delete[]A; - delete[]A_B; + delete[] A; + delete[] A_B; } - -template void rasterize_edge_interpolated_error(double Vxy[][2], double Zvertex[2], T *Avertex[], double z_buffer[], T image[], double* err_buffer, int height, int width, int sizeA, double sigma,bool clockwise, bool perspective_correct) +template +void rasterize_edge_interpolated_error(double Vxy[][2], double Zvertex[2], T *Avertex[], double z_buffer[], T image[], double *err_buffer, int height, int width, int sizeA, double sigma, bool clockwise, bool perspective_correct) { - double xy1_to_bary[6]; - double xy1_to_transp[3]; - double ineq[12]; - int y_begin, y_end; - double xy1_to_Z[3]; + double xy1_to_bary[6]; + double xy1_to_transp[3]; + double ineq[12]; + int y_begin, y_end; + double xy1_to_Z[3]; double *xy1_to_A = new double[3 * sizeA]; double *A0y = new double[sizeA]; - get_edge_stencil_equations(Vxy, height, width, sigma, xy1_to_bary, xy1_to_transp, ineq, y_begin, y_end,clockwise); - + get_edge_stencil_equations(Vxy, height, width, sigma, xy1_to_bary, xy1_to_transp, ineq, y_begin, y_end, clockwise); + double B_inc[2]; for (int k = 0; k < 2; k++) B_inc[k] = xy1_to_bary[3 * k]; @@ -2311,54 +2388,59 @@ template void rasterize_edge_interpolated_error(double Vxy[][2], doubl if (perspective_correct) { - double inv_Zvertex[3]; + double inv_Zvertex[3]; elementwise_inverse_vec3(Zvertex, inv_Zvertex); mul_matrix(1, 2, 3, xy1_to_Z, inv_Zvertex, xy1_to_bary); - for (int i = 0; i < sizeA; i++) { + for (int i = 0; i < sizeA; i++) + { for (int j = 0; j < 3; j++) { xy1_to_A[3 * i + j] = 0; - for (int k = 0; k < 2; k++) xy1_to_A[3 * i + j] += Avertex[k][i] * inv_Zvertex[k] * xy1_to_bary[k * 3 + j]; + for (int k = 0; k < 2; k++) + xy1_to_A[3 * i + j] += Avertex[k][i] * inv_Zvertex[k] * xy1_to_bary[k * 3 + j]; } - } + } } else { mul_matrix(1, 2, 3, xy1_to_Z, Zvertex, xy1_to_bary); - for (int i = 0; i < sizeA; i++) { + for (int i = 0; i < sizeA; i++) + { for (int j = 0; j < 3; j++) { xy1_to_A[3 * i + j] = 0; - for (int k = 0; k < 2; k++) xy1_to_A[3 * i + j] += Avertex[k][i] * xy1_to_bary[k * 3 + j]; + for (int k = 0; k < 2; k++) + xy1_to_A[3 * i + j] += Avertex[k][i] * xy1_to_bary[k * 3 + j]; } } } for (int y = y_begin; y <= y_end; y++) - { // Line rasterization setup for interpolated values + { // Line rasterization setup for interpolated values double t[3]; double T0y, Z0y; - t[0] = 0; t[1] = y; t[2] = 1; + t[0] = 0; + t[1] = y; + t[2] = 1; mul_matrixNx3_vect(sizeA, A0y, xy1_to_A, t); T0y = dot_prod(xy1_to_transp, t); Z0y = dot_prod(xy1_to_Z, t); - + // get x range of the line int x_begin, x_end; get_edge_xrange_from_ineq(ineq, width, y, x_begin, x_end); - //rasterize line int indx = y * width + x_begin; for (int x = x_begin; x <= x_end; x++) { - double Z; - + double Z; + if (perspective_correct) { double inv_Z = Z0y + xy1_to_Z[0] * x; @@ -2374,51 +2456,50 @@ template void rasterize_edge_interpolated_error(double Vxy[][2], doubl double Tr = T0y + T_inc * x; double Err = 0; for (int k = 0; k < sizeA; k++) - { + { double A = (A0y[k] + xy1_to_A[3 * k] * x); if (perspective_correct) { A *= Z; } - double diff = A - image[sizeA*indx + k]; + double diff = A - image[sizeA * indx + k]; Err += diff * diff; } err_buffer[indx] *= Tr; - err_buffer[indx] += (1 - Tr)*Err; - + err_buffer[indx] += (1 - Tr) * Err; } indx++; } } - delete[]A0y; - delete[]xy1_to_A; + delete[] A0y; + delete[] xy1_to_A; } -template void rasterize_edge_interpolated_error_B(double Vxy[][2], double Vxy_B[][2], double Zvertex[2], T *Avertex[], T *Avertex_B[], double z_buffer[], T image[], double err_buffer[], double err_buffer_B[], int height, int width, int sizeA, double sigma, bool clockwise, bool perspective_correct) +template +void rasterize_edge_interpolated_error_B(double Vxy[][2], double Vxy_B[][2], double Zvertex[2], T *Avertex[], T *Avertex_B[], double z_buffer[], T image[], double err_buffer[], double err_buffer_B[], int height, int width, int sizeA, double sigma, bool clockwise, bool perspective_correct) { - double xy1_to_bary[6]; - double xy1_to_transp[3]; - double ineq[12]; - int y_begin, y_end; - double xy1_to_Z[3]; + double xy1_to_bary[6]; + double xy1_to_transp[3]; + double ineq[12]; + int y_begin, y_end; + double xy1_to_Z[3]; double *A0y = new double[sizeA]; double *A0y_B = new double[sizeA]; - double * xy1_to_A = new double[3 * sizeA]; - double * xy1_to_A_B = new double[3 * sizeA]; + double *xy1_to_A = new double[3 * sizeA]; + double *xy1_to_A_B = new double[3 * sizeA]; if (perspective_correct) { - throw "backward gradient propagation not supported yet with perspective_correct=True"; + throw "backward gradient propagation not supported yet with perspective_correct=True"; } - get_edge_stencil_equations(Vxy, height, width, sigma, xy1_to_bary, xy1_to_transp, ineq, y_begin, y_end, clockwise); - double xy1_to_bary_B[6] = { 0 }; - double xy1_to_transp_B[3] = { 0 }; + double xy1_to_bary_B[6] = {0}; + double xy1_to_transp_B[3] = {0}; //double B_inc[2]; //for(int k=0;k<2;k++) @@ -2429,27 +2510,32 @@ template void rasterize_edge_interpolated_error_B(double Vxy[][2], dou mul_matrix(1, 2, 3, xy1_to_Z, Zvertex, xy1_to_bary); - for (short int i = 0; i < 3 * sizeA; i++) xy1_to_A_B[i] = 0; + for (short int i = 0; i < 3 * sizeA; i++) + xy1_to_A_B[i] = 0; - for (int i = 0; i < sizeA; i++) { + for (int i = 0; i < sizeA; i++) + { for (int j = 0; j < 3; j++) { xy1_to_A[3 * i + j] = 0; - for (int k = 0; k < 2; k++) xy1_to_A[3 * i + j] += Avertex[k][i] * xy1_to_bary[k * 3 + j]; + for (int k = 0; k < 2; k++) + xy1_to_A[3 * i + j] += Avertex[k][i] * xy1_to_bary[k * 3 + j]; } } - for (short int y = y_begin; y <= y_end; y++) { - // Line rasterization setup for interpolated values + // Line rasterization setup for interpolated values double t[3]; double T0y, Z0y; - t[0] = 0; t[1] = y; t[2] = 1; + t[0] = 0; + t[1] = y; + t[2] = 1; mul_matrixNx3_vect(sizeA, A0y, xy1_to_A, t); - for (short int k = 0; k < sizeA; k++) A0y_B[k] = 0; + for (short int k = 0; k < sizeA; k++) + A0y_B[k] = 0; T0y = dot_prod(xy1_to_transp, t); Z0y = dot_prod(xy1_to_Z, t); double T0y_B = 0; @@ -2458,7 +2544,7 @@ template void rasterize_edge_interpolated_error_B(double Vxy[][2], dou int x_begin, x_end; get_edge_xrange_from_ineq(ineq, width, y, x_begin, x_end); - + //rasterize line int indx = y * width + x_begin; @@ -2470,12 +2556,12 @@ template void rasterize_edge_interpolated_error_B(double Vxy[][2], dou double Tr = T0y + T_inc * x; double Tr_B = 0; - + double Err = 0; for (int k = 0; k < sizeA; k++) { double A = A0y[k] + xy1_to_A[3 * k] * x; - double diff = A - image[sizeA*indx + k]; + double diff = A - image[sizeA * indx + k]; Err += diff * diff; } @@ -2483,8 +2569,8 @@ template void rasterize_edge_interpolated_error_B(double Vxy[][2], dou // err_buffer[indx]*= Tr; // err_buffer[indx]+= (1-Tr)*Err; Tr_B += -Err * err_buffer_B[indx]; - Err_B += (1 - Tr)*err_buffer_B[indx]; - err_buffer[indx] -= (1 - Tr)*Err; + Err_B += (1 - Tr) * err_buffer_B[indx]; + err_buffer[indx] -= (1 - Tr) * Err; err_buffer[indx] /= Tr; Tr_B += err_buffer_B[indx] * err_buffer[indx]; err_buffer_B[indx] *= Tr; @@ -2492,31 +2578,28 @@ template void rasterize_edge_interpolated_error_B(double Vxy[][2], dou for (int k = 0; k < sizeA; k++) { double A = A0y[k] + xy1_to_A[3 * k] * x; - double diff = A - image[sizeA*indx + k]; + double diff = A - image[sizeA * indx + k]; //Err+=diff*diff; - double diff_B = 2 * diff*Err_B; + double diff_B = 2 * diff * Err_B; double A_B = diff_B; A0y_B[k] += A_B; xy1_to_A_B[3 * k] += x * A_B; } - T0y_B += Tr_B; T_inc_B += x * Tr_B; - } indx++; } for (int k = 0; k < 3; k++) xy1_to_transp_B[k] += T0y_B * t[k]; - } for (short int i = 0; i < sizeA; i++) for (short int j = 0; j < 3; j++) { for (short int k = 0; k < 2; k++) - //xy1_to_A[3*i+j]+=Avertex[k][i]*xy1_to_bary[k*3+j]; + //xy1_to_A[3*i+j]+=Avertex[k][i]*xy1_to_bary[k*3+j]; { Avertex_B[k][i] += xy1_to_A_B[3 * i + j] * xy1_to_bary[k * 3 + j]; xy1_to_bary_B[k * 3 + j] += Avertex[k][i] * xy1_to_A_B[3 * i + j]; @@ -2525,51 +2608,58 @@ template void rasterize_edge_interpolated_error_B(double Vxy[][2], dou xy1_to_transp_B[0] += T_inc_B; - get_edge_stencil_equations_B(Vxy, Vxy_B, sigma, xy1_to_bary_B, xy1_to_transp_B,clockwise); + get_edge_stencil_equations_B(Vxy, Vxy_B, sigma, xy1_to_bary_B, xy1_to_transp_B, clockwise); - delete[]A0y; - delete[]A0y_B; - delete[]xy1_to_A; - delete[]xy1_to_A_B; + delete[] A0y; + delete[] A0y_B; + delete[] xy1_to_A; + delete[] xy1_to_A_B; } void get_edge_xrange_from_ineq(double ineq[12], int width, int y, int &x_begin, int &x_end) { - // compute beginning and ending of the rasterized line while doing edge antialiasing + // compute beginning and ending of the rasterized line while doing edge antialiasing x_begin = 0; x_end = width - 1; double numerator; - + for (short int k = 0; k < 4; k++) { numerator = -(ineq[3 * k + 1] * y + ineq[3 * k + 2]); if (ineq[3 * k] < 0) { - short int temp_x = floor_div(numerator , ineq[3 * k], x_begin-1,x_end+1); - if (temp_x < x_end) { x_end = temp_x; } + short int temp_x = floor_div(numerator, ineq[3 * k], x_begin - 1, x_end + 1); + if (temp_x < x_end) + { + x_end = temp_x; + } } else { - short int temp_x = 1 + floor_div(numerator , ineq[3 * k],x_begin-1,x_end+1); - if (temp_x > x_begin) { x_begin = temp_x; } + short int temp_x = 1 + floor_div(numerator, ineq[3 * k], x_begin - 1, x_end + 1); + if (temp_x > x_begin) + { + x_begin = temp_x; + } } } } -struct sortdata { +struct sortdata +{ double value; size_t index; }; -struct sortcompare { - bool operator()(sortdata const &left, sortdata const &right) { +struct sortcompare +{ + bool operator()(sortdata const &left, sortdata const &right) + { return left.value > right.value; } }; - - void checkSceneValid(Scene scene, bool has_derivatives) { if (scene.faces == NULL) @@ -2623,9 +2713,9 @@ void checkSceneValid(Scene scene, bool has_derivatives) } } -void renderScene(Scene scene, double* image, double* z_buffer, double sigma, bool antialiaseError = 0, double* obs = NULL, double* err_buffer = NULL) +void renderScene(Scene scene, double *image, double *z_buffer, double sigma, bool antialiaseError = 0, double *obs = NULL, double *err_buffer = NULL) { - + checkSceneValid(scene, false); // first pass : render triangle without edge antialiasing @@ -2636,63 +2726,63 @@ void renderScene(Scene scene, double* image, double* z_buffer, double sigma, boo if (scene.background_image != NULL) { - memcpy(image, scene.background_image, scene.height*scene.width*scene.nb_colors * sizeof(double)); + memcpy(image, scene.background_image, scene.height * scene.width * scene.nb_colors * sizeof(double)); } else - { - for (int i =0; i::infinity()); + fill(z_buffer, z_buffer + scene.height * scene.width, numeric_limits::infinity()); vector sum_depth; sum_depth.resize(scene.nb_triangles); vector signedAreaV; signedAreaV.resize(scene.nb_triangles); - + for (int k = 0; k < scene.nb_triangles; k++) { sum_depth[k].value = 0; sum_depth[k].index = k; - - bool all_verticesInFront=true; - unsigned int * face = &scene.faces[k * 3]; + + bool all_verticesInFront = true; + unsigned int *face = &scene.faces[k * 3]; for (int i = 0; i < 3; i++) { - if (scene.depths[face[i]]<0) + if (scene.depths[face[i]] < 0) { - all_verticesInFront=false; + all_verticesInFront = false; } sum_depth[k].value += scene.depths[face[i]]; } if (all_verticesInFront) - { + { double ij[3][2]; for (int i = 0; i < 3; i++) for (int j = 0; j < 2; j++) ij[i][j] = scene.ij[face[i] * 2 + j]; - signedAreaV[k] = signedArea(ij,scene.clockwise); + signedAreaV[k] = signedArea(ij, scene.clockwise); } else { - signedAreaV[k]=0; + signedAreaV[k] = 0; } } sort(sum_depth.begin(), sum_depth.end(), sortcompare()); for (int k = 0; k < scene.nb_triangles; k++) - if ((signedAreaV[k] > 0)||(!scene.backface_culling)) + if ((signedAreaV[k] > 0) || (!scene.backface_culling)) { - unsigned int * face = &scene.faces[k * 3]; + unsigned int *face = &scene.faces[k * 3]; double ij[3][2]; for (int i = 0; i < 3; i++) for (int j = 0; j < 2; j++) @@ -2704,7 +2794,7 @@ void renderScene(Scene scene, double* image, double* z_buffer, double sigma, boo if ((scene.textured[k] && scene.shaded[k])) { - unsigned int * face_uv = &scene.faces_uv[k * 3]; + unsigned int *face_uv = &scene.faces_uv[k * 3]; double shade[3]; for (int i = 0; i < 3; i++) shade[i] = scene.shade[face[i]]; @@ -2714,29 +2804,29 @@ void renderScene(Scene scene, double* image, double* z_buffer, double sigma, boo { uv[i][j] = scene.uv[face_uv[i] * 2 + j]; } - + rasterize_triangle_textured_gouraud(ij, depths, uv, shade, z_buffer, image, scene.height, scene.width, scene.nb_colors, scene.texture, Texture_size, scene.strict_edge, scene.perspective_correct); } if (!scene.textured[k]) { - double* colors[3]; + double *colors[3]; for (int i = 0; i < 3; i++) colors[i] = scene.colors + face[i] * scene.nb_colors; rasterize_triangle_interpolated(ij, depths, colors, z_buffer, image, scene.height, scene.width, scene.nb_colors, scene.strict_edge, scene.perspective_correct); } } - int list_sub[3][2] = { 1,0,2,1,0,2 }; + int list_sub[3][2] = {1, 0, 2, 1, 0, 2}; if (antialiaseError) { - for (int k = 0; k < scene.width*scene.height; k++) + for (int k = 0; k < scene.width * scene.height; k++) { double s = 0; double d; for (int i = 0; i < scene.nb_colors; i++) { - d = (image[scene.nb_colors*k + i] - obs[scene.nb_colors*k + i]); + d = (image[scene.nb_colors * k + i] - obs[scene.nb_colors * k + i]); s += d * d; } err_buffer[k] = s; @@ -2747,8 +2837,8 @@ void renderScene(Scene scene, double* image, double* z_buffer, double sigma, boo { for (int it = 0; it < scene.nb_triangles; it++) { - size_t k = sum_depth[it].index;// we render the silhouette edges from the furthest from the camera to the nearest as we don't use z_buffer for discontinuity edge overdraw - unsigned int * face = &scene.faces[k * 3]; + size_t k = sum_depth[it].index; // we render the silhouette edges from the furthest from the camera to the nearest as we don't use z_buffer for discontinuity edge overdraw + unsigned int *face = &scene.faces[k * 3]; //k=order[i]; if (signedAreaV[k] > 0) @@ -2760,7 +2850,7 @@ void renderScene(Scene scene, double* image, double* z_buffer, double sigma, boo if (scene.edgeflags[n + k * 3]) { double ij[2][2]; - int* sub; + int *sub; sub = list_sub[n]; for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) @@ -2774,7 +2864,7 @@ void renderScene(Scene scene, double* image, double* z_buffer, double sigma, boo if ((scene.textured[k]) && (scene.shaded[k])) { - unsigned int * face_uv = &scene.faces_uv[k * 3]; + unsigned int *face_uv = &scene.faces_uv[k * 3]; double uv[2][2]; for (int i = 0; i < 2; i++) @@ -2784,23 +2874,21 @@ void renderScene(Scene scene, double* image, double* z_buffer, double sigma, boo for (int i = 0; i < 2; i++) shade[i] = scene.shade[face[sub[i]]]; if (antialiaseError) - rasterize_edge_textured_gouraud_error(ij, depths, uv, shade, z_buffer, obs, err_buffer, scene.height, scene.width, scene.nb_colors, scene.texture, Texture_size, sigma, scene.clockwise, scene.perspective_correct); + rasterize_edge_textured_gouraud_error(ij, depths, uv, shade, z_buffer, obs, err_buffer, scene.height, scene.width, scene.nb_colors, scene.texture, Texture_size, sigma, scene.clockwise, scene.perspective_correct); else - rasterize_edge_textured_gouraud(ij, depths, uv, shade, z_buffer, image, scene.height, scene.width, scene.nb_colors, scene.texture, Texture_size, sigma, scene.clockwise, scene.perspective_correct); - + rasterize_edge_textured_gouraud(ij, depths, uv, shade, z_buffer, image, scene.height, scene.width, scene.nb_colors, scene.texture, Texture_size, sigma, scene.clockwise, scene.perspective_correct); } else { - double* colors[2]; + double *colors[2]; for (int i = 0; i < 2; i++) { colors[i] = scene.colors + face[sub[i]] * scene.nb_colors; } if (antialiaseError) - rasterize_edge_interpolated_error(ij, depths, colors, z_buffer, obs, err_buffer, scene.height, scene.width, scene.nb_colors, sigma, scene.clockwise, scene.perspective_correct); + rasterize_edge_interpolated_error(ij, depths, colors, z_buffer, obs, err_buffer, scene.height, scene.width, scene.nb_colors, sigma, scene.clockwise, scene.perspective_correct); else - rasterize_edge_interpolated(ij, image, colors, z_buffer, depths, scene.height, scene.width, scene.nb_colors, sigma, scene.clockwise, scene.perspective_correct); - + rasterize_edge_interpolated(ij, image, colors, z_buffer, depths, scene.height, scene.width, scene.nb_colors, sigma, scene.clockwise, scene.perspective_correct); } } } @@ -2809,11 +2897,11 @@ void renderScene(Scene scene, double* image, double* z_buffer, double sigma, boo } } -void renderScene_B(Scene scene, double* image, double* z_buffer, double* image_b, double sigma, bool antialiaseError = 0, double* obs = NULL, double* err_buffer = NULL, double* err_buffer_b = NULL) +void renderScene_B(Scene scene, double *image, double *z_buffer, double *image_b, double sigma, bool antialiaseError = 0, double *obs = NULL, double *err_buffer = NULL, double *err_buffer_b = NULL) { // first pass : render triangle without edge antialiasing - + int Texture_size[2]; Texture_size[1] = scene.texture_height; @@ -2821,55 +2909,55 @@ void renderScene_B(Scene scene, double* image, double* z_buffer, double* image_b checkSceneValid(scene, true); - int list_sub[3][2] = { 1,0,2,1,0,2 }; + int list_sub[3][2] = {1, 0, 2, 1, 0, 2}; vector sum_depth; sum_depth.resize(scene.nb_triangles); vector signedAreaV; signedAreaV.resize(scene.nb_triangles); - + if (!scene.backface_culling) { - throw "You have to use backface_culling true if you ant to compute gradients"; + throw "You have to use backface_culling true if you ant to compute gradients"; } for (int k = 0; k < scene.nb_triangles; k++) { sum_depth[k].value = 0; sum_depth[k].index = k; - - bool all_verticesInFront=true; - unsigned int * face = &scene.faces[k * 3]; + + bool all_verticesInFront = true; + unsigned int *face = &scene.faces[k * 3]; for (int i = 0; i < 3; i++) { - if (scene.depths[face[i]]<0) + if (scene.depths[face[i]] < 0) { - all_verticesInFront=false; + all_verticesInFront = false; } sum_depth[k].value += scene.depths[face[i]]; } if (all_verticesInFront) - { + { double ij[3][2]; for (int i = 0; i < 3; i++) for (int j = 0; j < 2; j++) ij[i][j] = scene.ij[face[i] * 2 + j]; - signedAreaV[k] = signedArea(ij,scene.clockwise); + signedAreaV[k] = signedArea(ij, scene.clockwise); } else { - signedAreaV[k]=0; + signedAreaV[k] = 0; } } - + sort(sum_depth.begin(), sum_depth.end(), sortcompare()); if (sigma > 0) for (int it = scene.nb_triangles - 1; it >= 0; it--) { size_t k = sum_depth[it].index; - unsigned int * face = &scene.faces[k * 3]; + unsigned int *face = &scene.faces[k * 3]; if (signedAreaV[k] > 0) for (int n = 2; n >= 0; n--) @@ -2877,7 +2965,7 @@ void renderScene_B(Scene scene, double* image, double* z_buffer, double* image_b if (scene.edgeflags[n + k * 3]) { double ij[2][2]; - int* sub; + int *sub; sub = list_sub[n]; for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) @@ -2896,7 +2984,7 @@ void renderScene_B(Scene scene, double* image, double* z_buffer, double* image_b if ((scene.textured[k]) && (scene.shaded[k])) { - unsigned int * face_uv = &scene.faces_uv[k * 3]; + unsigned int *face_uv = &scene.faces_uv[k * 3]; double uv[2][2]; double uv_b[2][2]; for (int i = 0; i < 2; i++) @@ -2932,12 +3020,11 @@ void renderScene_B(Scene scene, double* image, double* z_buffer, double* image_b { scene.shade_b[face[sub[i]]] = shade_b[i]; } - } else { - double * colors[2]; - double * colors_b[2]; + double *colors[2]; + double *colors_b[2]; for (int i = 0; i < 2; i++) { @@ -2961,16 +3048,16 @@ void renderScene_B(Scene scene, double* image, double* z_buffer, double* image_b if (antialiaseError) { - image_b = new double[scene.width*scene.height*scene.nb_colors]; - for (int k = 0; k < scene.width*scene.height; k++) + image_b = new double[scene.width * scene.height * scene.nb_colors]; + for (int k = 0; k < scene.width * scene.height; k++) for (int i = 0; i < scene.nb_colors; i++) - image_b[scene.nb_colors*k + i] = -2 * (obs[scene.nb_colors*k + i] - image[scene.nb_colors*k + i])*err_buffer_b[k]; + image_b[scene.nb_colors * k + i] = -2 * (obs[scene.nb_colors * k + i] - image[scene.nb_colors * k + i]) * err_buffer_b[k]; } for (int k = scene.nb_triangles - 1; k >= 0; k--) if (signedAreaV[k] > 0) { - unsigned int * face = &scene.faces[k * 3]; + unsigned int *face = &scene.faces[k * 3]; double ij[3][2]; double ij_b[3][2]; for (int i = 0; i < 3; i++) @@ -2989,7 +3076,7 @@ void renderScene_B(Scene scene, double* image, double* z_buffer, double* image_b if (scene.textured[k] && scene.shaded[k]) { - unsigned int * face_uv = &scene.faces_uv[k * 3]; + unsigned int *face_uv = &scene.faces_uv[k * 3]; double uv[3][2]; double uv_b[3][2]; double shade[3]; @@ -3016,12 +3103,11 @@ void renderScene_B(Scene scene, double* image, double* z_buffer, double* image_b } for (int i = 0; i < 3; i++) scene.shade_b[face[i]] = shade_b[i]; - } if (!scene.textured[k]) { - double* colors[3]; - double* colors_b[3]; + double *colors[3]; + double *colors_b[3]; for (int i = 0; i < 3; i++) { @@ -3042,10 +3128,3 @@ void renderScene_B(Scene scene, double* image, double* z_buffer, double* image_b delete[] image_b; } } - - - - - - -