From f514fc7ffe2716675b294a28ad53e991266b8bf7 Mon Sep 17 00:00:00 2001 From: PedroEdiaz Date: Tue, 3 Dec 2024 22:18:48 -0600 Subject: [PATCH] setup examples and clean codebase --- example/basic.c | 92 ++++++++++ example/n-cube.c | 50 ++++++ example/riemman.c | 50 ++++++ include/klein/klein.h | 48 ++++++ include/klein/norm.h | 118 +++++++++++++ include/klein/parm.h | 134 +++++++++++++++ src/data/axis.h | 40 ----- src/klein.c | 34 ++-- src/surface.c | 388 ------------------------------------------ 9 files changed, 516 insertions(+), 438 deletions(-) create mode 100644 example/basic.c create mode 100644 example/n-cube.c create mode 100644 example/riemman.c create mode 100644 include/klein/klein.h create mode 100644 include/klein/norm.h create mode 100644 include/klein/parm.h delete mode 100644 src/data/axis.h delete mode 100644 src/surface.c diff --git a/example/basic.c b/example/basic.c new file mode 100644 index 0000000..0488340 --- /dev/null +++ b/example/basic.c @@ -0,0 +1,92 @@ +#include +#include + +#define KLEIN_IMPLEMENT +#include +#include +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +void cube(float *d_surface, int *coord, unsigned char *grid) +{ + int i; + + for (i = 0; i < 4; i++) + d_surface[i] = (2 * (float)coord[i] / grid[i]) - 1; + + if (4 == 2) + d_surface[2] = 0; +} + +void mobius(float *d_surface, int *coord, unsigned char *grid) +{ + const float width = 0.5; + float u = (2 * M_PI) * ((float)coord[0] / grid[0]); + float v = (2 * width) * ((float)coord[1] / grid[1]) - width; + + d_surface[0] = cos(u) + v * cos(u / 2) * cos(u); + d_surface[1] = sin(u) + v * cos(u / 2) * sin(u); + d_surface[2] = v * sin(u / 2); +} + +void torus(float *d_surface, int *coord, unsigned char *grid) +{ + float u = (2 * M_PI) * ((float)coord[0] / grid[0]); + float v = (2 * M_PI) * ((float)coord[1] / grid[1]); + + d_surface[0] = (1 + 0.5 * cos(v)) * cos(u); + d_surface[1] = (1 + 0.5 * cos(v)) * sin(u); + d_surface[2] = 0.5 * sin(v); +} + +void klein(float *d_surface, int *coord, unsigned char *grid) +{ + float u = (2 * M_PI) * ((float)coord[0] / grid[0]); + float v = (2 * M_PI) * ((float)coord[1] / grid[1]); + + d_surface[0] = (0.5 * cos(v) + 0.5) * cos(u); + d_surface[1] = (0.5 * cos(v) + 0.5) * sin(u); + d_surface[2] = sin(v) * cos(u / 2); + d_surface[3] = sin(v) * sin(u / 2); +} + +int main(void) +{ + unsigned char i = 0; + const char *file_name[] = {"mobius.klein", "torus.klein", "klein.klein"}; + struct parm parametrization[] = {{ + .grid = (unsigned char[]){16, 4}, + .m = 2, + .n = 3, + .f = mobius, + }, + { + .grid = (unsigned char[]){16, 8}, + .m = 2, + .n = 3, + .f = torus, + }, + { + .grid = (unsigned char[]){16, 16}, + .m = 2, + .n = 4, + .f = klein, + }}; + + for (i = 0; i < 3; ++i) + { + struct klein klein; + printf("writing %s\n", file_name[i]); + + klein_parametrize(&klein, parametrization[i]); + klein_normalize(&klein); + klein_export_file(klein, file_name[i]); + + free(klein.vertex); + free(klein.normals); + } + return 0; +} diff --git a/example/n-cube.c b/example/n-cube.c new file mode 100644 index 0000000..74ec02a --- /dev/null +++ b/example/n-cube.c @@ -0,0 +1,50 @@ +#include +#include + +#define KLEIN_IMPLEMENT +#include +#include +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +unsigned char dim = 4; + +void cube(float *d_surface, int *coord, unsigned char *grid) +{ + int i; + + for (i = 0; i < dim; i++) + d_surface[i] = (2 * (float)coord[i] / grid[i]) - 1; + + if (dim == 2) + d_surface[2] = 0; +} + +int main(void) +{ + unsigned char i; + char file_name[0xff]; + struct klein klein; + struct parm parametrization = { + .m = dim, + .n = dim, + .f = cube, + }; + + parametrization.grid = malloc(dim); + + for (i = 0; i < dim; ++i) + parametrization.grid[i] = 1 << i; + + snprintf(file_name, 0xff, "%03d-cube.klein", dim); + printf("writing %s\n", file_name); + + klein_parametrize(&klein, parametrization); + klein_normalize(&klein); + klein_export_file(klein, file_name); + + return 0; +} diff --git a/example/riemman.c b/example/riemman.c new file mode 100644 index 0000000..8af7920 --- /dev/null +++ b/example/riemman.c @@ -0,0 +1,50 @@ +#include +#include +#include + +#define KLEIN_IMPLEMENT +#include +#include +#include + +#ifndef CMPLX +#define CMPLX(a, b) (a + I * b) +#endif + +complex float f(complex float z) { return csqrt(z); } + +void riemman(float *d_surface, int *coords, unsigned char *grid) +{ + complex float eq; + float u = 2 * ((float)coords[0] / grid[0]) - 1; + float v = 2 * ((float)coords[1] / grid[1]) - 1; + + eq = f(CMPLX(u, v)); + + d_surface[0] = u; + d_surface[1] = v; + d_surface[2] = creal(eq); + d_surface[3] = cimag(eq); +} + +int main(void) +{ + const char *file_name = "riemman.klein"; + struct klein klein; + struct parm parametrization = { + .grid = (unsigned char[]){16, 4}, + .m = 2, + .n = 4, + .f = riemman, + }; + + printf("writing %s\n", file_name); + + klein_parametrize(&klein, parametrization); + klein_normalize(&klein); + klein_export_file(klein, file_name); + + free(klein.vertex); + free(klein.normals); + return 0; +} diff --git a/include/klein/klein.h b/include/klein/klein.h new file mode 100644 index 0000000..6265adf --- /dev/null +++ b/include/klein/klein.h @@ -0,0 +1,48 @@ +#ifdef KLEIN_H +#error file included twice +#endif +#define KLEIN_H + +#ifdef KLEIN_IMPLEMENT +#include +#include +#endif + +struct klein +{ + unsigned long vertex_size; + float *vertex, *normals; + unsigned char dim; +}; + +/* + The klein format must have: + 5 bytes with klein. + 1 byte empty for expantions + 1 byte with the dimention of the surface + +*/ + +static inline +int klein_export_file(struct klein klein, const char * filename); + + +#ifdef KLEIN_IMPLEMENT +static inline +int klein_export_file(struct klein klein, const char * filename) +{ + FILE *file = fopen(filename, "wb"); + if (!file) + return 1; + + fwrite("KLEIN", 1, 5, file); + fwrite("\0", 1, 1, file); + fwrite(&klein.dim, 1, 1, file); + fwrite(&klein.vertex_size, 8, 1, file); + fwrite(klein.vertex, 16, klein.vertex_size * klein.dim, file); + fwrite(klein.normals, 16, klein.vertex_size * klein.dim, file); + + fclose(file); + return 0; +} +#endif diff --git a/include/klein/norm.h b/include/klein/norm.h new file mode 100644 index 0000000..bca38f3 --- /dev/null +++ b/include/klein/norm.h @@ -0,0 +1,118 @@ +static inline +void __calculate_normal( float *p1, float *p2, float *p3, float *normal, unsigned char n) +{ unsigned char i; + float alpha; + float *v1, *v2, *v3; + float *u1, *u2, *u3; + + v1 = malloc(n * sizeof(float)); + v2 = malloc(n * sizeof(float)); + v3 = malloc(n * sizeof(float)); + u1 = malloc(n * sizeof(float)); + u2 = malloc(n * sizeof(float)); + u3 = malloc(n * sizeof(float)); + + /* + Calculate a normal vector of a plain using Gram-Schmidt process + */ + { + for (i = 0; i < n; ++i) + { + v1[i] = p2[i] - p1[i]; + v2[i] = p3[i] - p1[i]; + v3[i] = p1[i]; + } + + for (i = 0; i < n; ++i) + { + u1[i] = v1[i]; + } + + { + float proj[n]; + float dot_v2_u1 = 0.0f, dot_u1_u1 = 0.0f; + for (i = 0; i < n; ++i) + { + dot_v2_u1 += v2[i] * u1[i]; + dot_u1_u1 += u1[i] * u1[i]; + } + alpha = dot_v2_u1 / dot_u1_u1; + + for (i = 0; i < n; ++i) + { + proj[i] = u1[i] * alpha; + u2[i] = v2[i] - proj[i]; + } + } + + { + float proj1[n], proj2[n]; + float dot_v3_u1 = 0.0f, dot_u1_u1 = 0.0f; + float dot_v3_u2 = 0.0f, dot_u2_u2 = 0.0f; + + for (i = 0; i < n; ++i) + { + dot_v3_u1 += v3[i] * u1[i]; + dot_u1_u1 += u1[i] * u1[i]; + } + for (i = 0; i < n; ++i) + { + proj1[i] = u1[i] * (dot_v3_u1 / dot_u1_u1); + } + + for (i = 0; i < n; ++i) + { + dot_v3_u2 += v3[i] * u2[i]; + dot_u2_u2 += u2[i] * u2[i]; + } + for (i = 0; i < n; ++i) + { + proj2[i] = u2[i] * (dot_v3_u2 / dot_u2_u2); + u3[i] = v3[i] - proj1[i] - proj2[i]; + } + } + + float magnitude = 0.0f; + for (i = 0; i < n; ++i) + { + magnitude += u3[i] * u3[i]; + } + magnitude = sqrtf(magnitude); + + for (i = 0; i < n; ++i) + { + normal[i] = u3[i] / magnitude; + } + + free(v1); + free(v2); + free(v3); + free(u1); + free(u2); + free(u3); + return; + } +} + +void klein_normalize(struct klein * klein) +{ + unsigned long i; + unsigned char j; + float *norm_vec; + + klein->normals = malloc((klein->dim * klein->vertex_size) * sizeof(float)); + norm_vec = malloc(klein->dim * sizeof(float)); + + for (i = 0; i < klein->vertex_size; i += 3 * klein->dim) + { + __calculate_normal(klein->vertex + i, klein->vertex + i + klein->dim, klein->vertex + i + 2 * klein->dim, norm_vec, klein->dim); + for (j = 0; j < klein->dim; ++j ) + { + (klein->normals + i)[j]=norm_vec[j]; + (klein->normals + i + klein->dim)[j]=norm_vec[j]; + (klein->normals + i + 2*klein->dim)[j]=norm_vec[j]; + } + } + + free(norm_vec); +} diff --git a/include/klein/parm.h b/include/klein/parm.h new file mode 100644 index 0000000..de888b4 --- /dev/null +++ b/include/klein/parm.h @@ -0,0 +1,134 @@ +#ifndef KLEIN_H +#warning Please include klein/klein.h before klein/parm.h +#endif + +#ifdef KLEIN_PARM_H +#error file included twice +#endif +#define KLEIN_PARM_H + + +typedef void (*function_t)(float *, int *, unsigned char *); + +struct parm +{ + unsigned char *grid; + unsigned char m, n; + function_t f; +}; + + +void klein_parametrize( struct klein * klein, struct parm parm ); + +#ifdef KLEIN_IMPLEMENT +#ifdef TEST +#include +#endif + +static inline int __factorial(int n) +{ + if (n == 1) + return 1; + + return n * __factorial(n - 1); +} + +static inline int __face(int n) +{ + if (n == 2) + return 1; + + return (1 << (n - 3)) * __factorial(n) / __factorial(n - 2); +} + +void klein_parametrize( struct klein * klein, struct parm parm) +{ + unsigned int i, j, k, o, p, n; + unsigned long size, q = 0; + int *face; + +#ifdef TEST + assert(__face(2) == 1); + assert(__face(3) == 6); + assert(__face(4) == 24); +#endif + + klein->dim = parm.n; + klein->vertex_size = 0; + { + unsigned char test = 0; + for (o = 0; o < parm.m; o++) + { + for (p = 0; p < o; p++) + { + test += 1; + klein->vertex_size += parm.grid[p] * parm.grid[o] * 6 * __face(parm.m); + } + } + klein->vertex_size /= test; + } + + size = (klein->dim) * (klein->vertex_size); + klein->vertex = malloc(size * sizeof(float)); + + face = malloc(parm.m * sizeof(int)); + + for (o = 0; o < parm.m; o++) + { + for (p = 0; p < o; p++) + { + for (k = 0; k < (1 << (parm.m - 2)); k++) + { + unsigned char skip = 0; + for (n = 0; n < parm.m; n++) + { + if (n == o || n == p) + skip++; + + face[n] = (k & (1 << (n - skip))) ? parm.grid[n] : 0; + } + + for (i = 0; i < parm.grid[p]; i++) + { + for (j = 0; j < parm.grid[o]; j++) + { + face[p] = i; + face[o] = j; + parm.f(&klein->vertex[q], face, parm.grid); + q += parm.n; + + face[p] = i + 1; + face[o] = j; + parm.f(&klein->vertex[q], face, parm.grid); + q += parm.n; + + face[p] = i + 1; + face[o] = j + 1; + parm.f(&klein->vertex[q], face, parm.grid); + q += parm.n; + + face[p] = i; + face[o] = j; + parm.f(&klein->vertex[q], face, parm.grid); + q += parm.n; + + face[p] = i; + face[o] = j + 1; + parm.f(&klein->vertex[q], face, parm.grid); + q += parm.n; + + face[p] = i + 1; + face[o] = j + 1; + parm.f(&klein->vertex[q], face, parm.grid); + q += parm.n; + } + } + } + } + } + +#ifdef TEST + assert(q == size); +#endif +} +#endif diff --git a/src/data/axis.h b/src/data/axis.h deleted file mode 100644 index 3ccddc8..0000000 --- a/src/data/axis.h +++ /dev/null @@ -1,40 +0,0 @@ -#undef A -#undef B -#undef C -#undef D -#undef E -#undef F -#undef G -#undef H - -#define A -2.0,-0.05,-0.05, -#define B -2.0,-0.05, 0.05, -#define C -2.0, 0.05,-0.05, -#define D -2.0, 0.05, 0.05, -#define E 2.0,-0.05,-0.05, -#define F 2.0,-0.05, 0.05, -#define G 2.0, 0.05,-0.05, -#define H 2.0, 0.05, 0.05, - -float d_axis[] = -{ - 3*3*2*6, - - A C E - G E C - - E G F - H F G - - F H B - D B H - - B D A - C A D - - C D G - H G D - - E B A - B E F -}; diff --git a/src/klein.c b/src/klein.c index e13c9c4..8add64b 100644 --- a/src/klein.c +++ b/src/klein.c @@ -2,29 +2,43 @@ #include -int create_surface_klein( unsigned char * path, struct surface * surface ) +/* + KLEIN Format: + 5 bytes with KLEIN + 1 byte empty for scaling + 1 byte with the dimention of the surface + 8 bytes interprated as a long with the number of vertex + n bytes with the vertex data of the surface + n bytes with the normal data of the surface + + where n is the size of the vertex and normal data that could be + calculated as the dimention of the surface time the number of vertes + time the size of a 16 bytes float. +*/ + +int create_surface_klein(unsigned char *path, struct surface *surface) { unsigned long size; char buffer[5]; - FILE * file = fopen(path, "rb" ); - if( !file ) + FILE *file = fopen(path, "rb"); + if (!file) return 1; - fread(buffer, 1, 5, file ); + fread(buffer, 1, 5, file); - if( strncmp(buffer, "KLEIN", 5 ) ) + if (strncmp(buffer, "KLEIN", 5)) return 1; - fread(buffer, 1, 1, file ); + fread(buffer, 1, 1, file); fread(&surface->dim, 1, 1, file); fread(&surface->vertex, 8, 1, file); - + size = surface->dim * surface->vertex; - surface->data=malloc(16*size ); - fread(surface->data, 16,size, file); + surface->data = malloc(16 * size); + fread(surface->data, 16, size, file); - surface->norm=malloc(16*size ); + surface->norm = malloc(16 * size); fread(surface->norm, 16, size, file); return 0; } diff --git a/src/surface.c b/src/surface.c deleted file mode 100644 index 4bf66a7..0000000 --- a/src/surface.c +++ /dev/null @@ -1,388 +0,0 @@ -#include -#include -#include -#include - -#define TEST - -#define CGLM_ALL_UNALIGNED -#include -#include - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -#ifndef CMPLX -#define CMPLX(a, b) (a + I * b) -#endif - -#ifdef TEST -#include -#endif -#include - -typedef void (*function_t)(float *, int *, unsigned char *); - -struct parm -{ - unsigned char *grid; - unsigned char m, n; - function_t f; -}; - -// Función para escribir el archivo .klein -int write_klein_file(const char *filename, unsigned char dim, unsigned long vertex, float *vertices, float *normals) -{ - FILE *file = fopen(filename, "wb"); - if (!file) - { - perror("Error al abrir el archivo"); - exit(EXIT_FAILURE); - } - - // Escribir encabezado - fwrite("KLEIN", 1, 5, file); // Los primeros 5 bytes son "KLEIN" - fputc(0, file); // Byte vacío - fwrite(&dim, 1, 1, file); // Dimensión de la superficie - fwrite(&vertex, sizeof(unsigned long), 1, file); // Número de vértices (8 bytes) - fwrite(vertices, sizeof(float), vertex * dim, file); - fwrite(normals, sizeof(float), vertex * dim, file); - printf("Archivo %s escrito correctamente.\n", filename); - - fclose(file); - return 0; -} - -int factorial(int n) -{ - if (n == 1) - return 1; - - return n * factorial(n - 1); -} - -int faces(int n) -{ - if (n == 2) - return 1; - - return (1 << (n - 3)) * factorial(n) / factorial(n - 2); -} - -void riemman(float *d_surface, int *coords, unsigned char *grid) -{ - complex double eq; - float u = 2 * ((float)coords[0] / grid[0]) - 1; - float v = 2 * ((float)coords[1] / grid[1]) - 1; - - eq = csqrt(CMPLX(u, v)); - - d_surface[0] = u; - d_surface[1] = v; - d_surface[2] = creal(eq); - d_surface[3] = cimag(eq); -} - -void cube(float *d_surface, int *coord, unsigned char *grid) -{ - int i; - - for (i = 0; i < 4; i++) - d_surface[i] = (2 * (float)coord[i] / grid[i]) - 1; - - if (4 == 2) - d_surface[2] = 0; -} - -void mobius(float *d_surface, int *coord, unsigned char *grid) -{ - const float width = 0.5; - float u = (2 * M_PI) * ((float)coord[0] / grid[0]); - float v = (2 * width) * ((float)coord[1] / grid[1]) - width; - - d_surface[0] = cos(u) + v * cos(u / 2) * cos(u); - d_surface[1] = sin(u) + v * cos(u / 2) * sin(u); - d_surface[2] = v * sin(u / 2); -} - -void torus(float *d_surface, int *coord, unsigned char *grid) -{ - float u = (2 * M_PI) * ((float)coord[0] / grid[0]); - float v = (2 * M_PI) * ((float)coord[1] / grid[1]); - - d_surface[0] = (1 + 0.5 * cos(v)) * cos(u); - d_surface[1] = (1 + 0.5 * cos(v)) * sin(u); - d_surface[2] = 0.5 * sin(v); -} - -void klein(float *d_surface, int *coord, unsigned char *grid) -{ - float u = (2 * M_PI) * ((float)coord[0] / grid[0]); - float v = (2 * M_PI) * ((float)coord[1] / grid[1]); - - d_surface[0] = (0.5 * cos(v) + 0.5) * cos(u); - d_surface[1] = (0.5 * cos(v) + 0.5) * sin(u); - d_surface[2] = sin(v) * cos(u / 2); - d_surface[3] = sin(v) * sin(u / 2); -} - -float *generate_data_surface(unsigned char *dim, unsigned long *vertex, struct parm *parm) -{ - unsigned int i, j, k, o, p, n; - unsigned long size, q = 0; - float *d_surface; - int *cara; - - parm->f = cube; - parm->m = 4; - parm->n = 4; - parm->grid = (unsigned char[]){16, 8, 4, 2, 1}; - -#ifdef TEST - assert(faces(2) == 1); - assert(faces(3) == 6); - assert(faces(4) == 24); -#endif - - *dim = parm->n; - *vertex = 0; - - { - unsigned char test = 0; - for (o = 0; o < parm->m; o++) - { - for (p = 0; p < o; p++) - { - test += 1; - *vertex += parm->grid[p] * parm->grid[o] * 6 * faces(parm->n); - } - } - *vertex /= test; - } - - cara = malloc(parm->m * sizeof(int)); - size = (*dim) * (*vertex); - d_surface = malloc(size * sizeof(float)); - - for (o = 0; o < parm->m; o++) - { - for (p = 0; p < o; p++) - { - for (k = 0; k < (1 << (parm->m - 2)); k++) - { - unsigned char skip = 0; - for (n = 0; n < parm->m; n++) - { - if (n == o || n == p) - skip++; - - cara[n] = (k & (1 << (n - skip))) ? parm->grid[n] : 0; - } - - for (i = 0; i < parm->grid[p]; i++) - { - for (j = 0; j < parm->grid[o]; j++) - { - cara[p] = i; - cara[o] = j; - parm->f(&d_surface[q], cara, parm->grid); - q += parm->n; - - cara[p] = i + 1; - cara[o] = j; - parm->f(&d_surface[q], cara, parm->grid); - q += parm->n; - - cara[p] = i + 1; - cara[o] = j + 1; - parm->f(&d_surface[q], cara, parm->grid); - q += parm->n; - - cara[p] = i; - cara[o] = j; - parm->f(&d_surface[q], cara, parm->grid); - q += parm->n; - - cara[p] = i; - cara[o] = j + 1; - parm->f(&d_surface[q], cara, parm->grid); - q += parm->n; - - cara[p] = i + 1; - cara[o] = j + 1; - parm->f(&d_surface[q], cara, parm->grid); - q += parm->n; - } - } - } - } - } - -#ifdef TEST - assert(q == size); -#endif - return d_surface; -} - -static void __calculate_normal( - float *p1, float *p2, float *p3, float *normal, unsigned char n) -{ - unsigned char i; - float alpha; - float *v1, *v2, *v3; - float *u1, *u2, *u3; - - v1 = malloc(n * sizeof(float)); - v2 = malloc(n * sizeof(float)); - v3 = malloc(n * sizeof(float)); - u1 = malloc(n * sizeof(float)); - u2 = malloc(n * sizeof(float)); - u3 = malloc(n * sizeof(float)); - - /* - Calculate a normal vector of a plain using Gram-Schmidt process - */ - { - for (i = 0; i < n; ++i) - { - v1[i] = p2[i] - p1[i]; - v2[i] = p3[i] - p1[i]; - v3[i] = p1[i]; - } - - for (i = 0; i < n; ++i) - { - u1[i] = v1[i]; - } - - { - float proj[n]; - float dot_v2_u1 = 0.0f, dot_u1_u1 = 0.0f; - for (i = 0; i < n; ++i) - { - dot_v2_u1 += v2[i] * u1[i]; - dot_u1_u1 += u1[i] * u1[i]; - } - alpha = dot_v2_u1 / dot_u1_u1; - - for (i = 0; i < n; ++i) - { - proj[i] = u1[i] * alpha; - u2[i] = v2[i] - proj[i]; - } - } - - { - float proj1[n], proj2[n]; - float dot_v3_u1 = 0.0f, dot_u1_u1 = 0.0f; - float dot_v3_u2 = 0.0f, dot_u2_u2 = 0.0f; - - for (i = 0; i < n; ++i) - { - dot_v3_u1 += v3[i] * u1[i]; - dot_u1_u1 += u1[i] * u1[i]; - } - for (i = 0; i < n; ++i) - { - proj1[i] = u1[i] * (dot_v3_u1 / dot_u1_u1); - } - - for (i = 0; i < n; ++i) - { - dot_v3_u2 += v3[i] * u2[i]; - dot_u2_u2 += u2[i] * u2[i]; - } - for (i = 0; i < n; ++i) - { - proj2[i] = u2[i] * (dot_v3_u2 / dot_u2_u2); - u3[i] = v3[i] - proj1[i] - proj2[i]; - } - } - - float magnitude = 0.0f; - for (i = 0; i < n; ++i) - { - magnitude += u3[i] * u3[i]; - } - magnitude = sqrtf(magnitude); - - for (i = 0; i < n; ++i) - { - normal[i] = u3[i] / magnitude; - } - - free(v1); - free(v2); - free(v3); - free(u1); - free(u2); - free(u3); - return; - } -} - -float *generate_normals_surface(float *d, unsigned char m, unsigned long vertex) -{ - float *n; - float *norm_vec; - - n = malloc((m * vertex) * sizeof(float)); - - norm_vec = malloc(m * sizeof(float)); - - for (int i = 0; i < *d; i += 3 * m) - { - - __calculate_normal(d + i, d + i + m, d + i + 2 * m, norm_vec, m); - glm_vec3_copy(norm_vec, n + i); - glm_vec3_copy(norm_vec, n + i + m); - glm_vec3_copy(norm_vec, n + i + 2 * m); - } - - free(norm_vec); - return n; -} -int main() -{ - - struct parm parm_instance; - parm_instance.grid = (unsigned char[]){16, 8, 4, 2, 1}; - parm_instance.m = 4; - parm_instance.n = 4; - parm_instance.f = cube; - unsigned char dim; - unsigned long vertex; - float *vertices, *normals; - - // Generar datos de la superficie - vertices = generate_data_surface(&dim, &vertex, &parm_instance); - - // Verificar datos generados - if (vertices == NULL) { - printf("Error: vertices no generados.\n"); - return 1; - } - - printf("Dim: %u, Vertex: %lu\n", dim, vertex); - - // Generar normales - normals = generate_normals_surface(vertices, dim, vertex); - - // Verificar normales generadas - if (normals == NULL) { - printf("Error: normales no generadas.\n"); - free(vertices); - return 1; - } - - // Escribir el archivo - printf("Escribiendo archivo .klein\n"); - write_klein_file("test.klein", dim, vertex, vertices, normals); - - free(vertices); - free(normals); - - return 0; -} -