<commit_before>#include <ctype.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "dbg.h"

#include "stl.h"

void stl_free(stl_object *obj) {
		if(obj == NULL) return;
		if(obj->facets) free(obj->facets);
		free(obj);
}

stl_object *stl_alloc(char *header, uint32_t n_facets) {
		stl_object *obj = (stl_object*)calloc(1, sizeof(stl_object));
		check_mem(obj);

		if(header != NULL) {
				memcpy(obj->header, header, sizeof(obj->header));
		}

		obj->facet_count = n_facets;
		if(n_facets > 0) {
				obj->facets = (stl_facet*)calloc(n_facets, sizeof(stl_facet));
				check_mem(obj->facets);
		}

		return obj;
error:
		exit(-1);
}

void v3_cross(float3 *result, float3 v1, float3 v2, int normalize) {
		float3 v1_x_v2 = {
				v1[1]*v2[2] - v1[2]*v2[1],
				v1[2]*v2[0] - v1[0]*v2[2],
				v1[0]*v2[1] - v1[1]*v2[0]
		};
		if(normalize) {
				float mag = sqrt(v1_x_v2[0]*v1_x_v2[0] + v1_x_v2[1]*v1_x_v2[1] + v1_x_v2[2]*v1_x_v2[2]);
				v1_x_v2[0] /= mag;
				v1_x_v2[1] /= mag;
				v1_x_v2[2] /= mag;
		}
		memcpy(result, &v1_x_v2, sizeof(float3));
}

void stl_facet_update_normal(stl_facet *facet) {
		float3 *fvs = facet->vertices;
		float3 v1 = {fvs[0][0] - fvs[1][0], fvs[0][1] - fvs[1][1], fvs[0][2] - fvs[1][2]};
		float3 v2 = {fvs[0][0] - fvs[2][0], fvs[0][1] - fvs[2][1], fvs[0][2] - fvs[2][2]};
		v3_cross(&facet->normal, v1, v2, 1);
}

stl_facet *stl_read_facet(int fd) {
		int rc = -1;
		stl_facet *facet = (stl_facet*)calloc(1, sizeof(stl_facet));
		check_mem(facet);

		rc = read(fd, &facet->normal, sizeof(facet->normal));
		check(rc == sizeof(facet->normal), "Failed to read normal. Read %d expected %zu", rc, sizeof(facet->normal));
		rc = read(fd, &facet->vertices, sizeof(facet->vertices));
		check(rc == sizeof(facet->vertices), "Failed to read triangle vertecies. Read %d expected %zu", rc, sizeof(facet->vertices));
		rc = read(fd, &facet->attr, sizeof(facet->attr));
		check(rc == sizeof(facet->attr), "Failed to read attr bytes. Read %d expect %zu", rc, sizeof(facet->attr));

		return facet;
error:
		exit(-1);
}

/*
 * Allocate, read, and return a anull terminated string from `fd'.
 * Return NULL in caes of error
 */
char* read_line(int fd, int downcase) {
		int rc = -1;
		char *buffer = NULL;
		size_t size = 1024;
		int cur = 0;
		check_mem((buffer = calloc(size, 1)));

		while((cur < size) && ((rc = read(fd, buffer + cur++, 1)) != -1)) {
				int last = cur - 1;
				check(rc != -1, "read_line(%d) failed", fd);
				if(downcase) buffer[last] = tolower(buffer[last]);
				if(buffer[last] == '\n') break;
				if(rc == 0) break;
		}
		check(cur < size, "BUG: Line exceeds allocated length of %zd in read_line(%d)", size, fd);

		if((strlen(buffer) == 0) && (rc == 0)) goto eof;

		return buffer;

eof: /* "Deallocate and return NULL." Different label than error for clarity */
error:
		if(buffer != NULL) free(buffer);
		return NULL;
}

stl_object *stl_read_text_object(int fd) {
		stl_object *obj = NULL;
		char *line = read_line(fd, 0);
		check(line != NULL, "Failed to read STL/ASCII header.");
		check((obj = stl_alloc(NULL, 0)), "Failed to allocated new STL object.");
		snprintf(obj->header, sizeof(obj->header), "[STL/ASCII]: '%s'", line);
		log_info("Header: [%s]", obj->header);
		free(line);

		size_t lines = 0;
		while((line = read_line(fd, 1))) {
				lines++;
				log_info("Line: [%s]", line);
				free(line);
		}

		return obj;
error:
		return NULL;
}

stl_object *stl_read_object(int fd) {
		int rc = -1;
		char header[80] = {0};
		uint32_t n_tris = 0;
		stl_object *obj = NULL;

		// Read the header
		rc = read(fd, header, sizeof(header));
		check(rc == sizeof(header), "Unable to read STL header. Got %d bytes.", rc);

		// Triangle count
		rc = read(fd, &n_tris, sizeof(n_tris));
		check(rc == sizeof(n_tris), "Failed to read facet count.");
		check(n_tris > 0, "Facet count cannot be zero.");
<commit_msg>Making and destroying facet lists<commit_after>#include <ctype.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "dbg.h"

#include "stl.h"

void stl_free(stl_object *obj) {
		if(obj == NULL) return;
		if(obj->facets) free(obj->facets);
		free(obj);
}

stl_object *stl_alloc(char *header, uint32_t n_facets) {
		stl_object *obj = (stl_object*)calloc(1, sizeof(stl_object));
		check_mem(obj);

		if(header != NULL) {
				memcpy(obj->header, header, sizeof(obj->header));
		}

		obj->facet_count = n_facets;
		if(n_facets > 0) {
				obj->facets = (stl_facet*)calloc(n_facets, sizeof(stl_facet));
				check_mem(obj->facets);
		}

		return obj;
error:
		exit(-1);
}

void v3_cross(float3 *result, float3 v1, float3 v2, int normalize) {
		float3 v1_x_v2 = {
				v1[1]*v2[2] - v1[2]*v2[1],
				v1[2]*v2[0] - v1[0]*v2[2],
				v1[0]*v2[1] - v1[1]*v2[0]
		};
		if(normalize) {
				float mag = sqrt(v1_x_v2[0]*v1_x_v2[0] + v1_x_v2[1]*v1_x_v2[1] + v1_x_v2[2]*v1_x_v2[2]);
				v1_x_v2[0] /= mag;
				v1_x_v2[1] /= mag;
				v1_x_v2[2] /= mag;
		}
		memcpy(result, &v1_x_v2, sizeof(float3));
}

void stl_facet_update_normal(stl_facet *facet) {
		float3 *fvs = facet->vertices;
		float3 v1 = {fvs[0][0] - fvs[1][0], fvs[0][1] - fvs[1][1], fvs[0][2] - fvs[1][2]};
		float3 v2 = {fvs[0][0] - fvs[2][0], fvs[0][1] - fvs[2][1], fvs[0][2] - fvs[2][2]};
		v3_cross(&facet->normal, v1, v2, 1);
}

stl_facet *stl_read_facet(int fd) {
		int rc = -1;
		stl_facet *facet = (stl_facet*)calloc(1, sizeof(stl_facet));
		check_mem(facet);

		rc = read(fd, &facet->normal, sizeof(facet->normal));
		check(rc == sizeof(facet->normal), "Failed to read normal. Read %d expected %zu", rc, sizeof(facet->normal));
		rc = read(fd, &facet->vertices, sizeof(facet->vertices));
		check(rc == sizeof(facet->vertices), "Failed to read triangle vertecies. Read %d expected %zu", rc, sizeof(facet->vertices));
		rc = read(fd, &facet->attr, sizeof(facet->attr));
		check(rc == sizeof(facet->attr), "Failed to read attr bytes. Read %d expect %zu", rc, sizeof(facet->attr));

		return facet;
error:
		exit(-1);
}

/*
 * Allocate, read, and return a anull terminated string from `fd'.
 * Return NULL in caes of error
 */
char* read_line(int fd, int downcase) {
		int rc = -1;
		char *buffer = NULL;
		size_t size = 1024;
		int cur = 0;
		check_mem((buffer = calloc(size, 1)));

		while((cur < size) && ((rc = read(fd, buffer + cur++, 1)) != -1)) {
				int last = cur - 1;
				check(rc != -1, "read_line(%d) failed", fd);
				if(downcase) buffer[last] = tolower(buffer[last]);
				if(buffer[last] == '\n') break;
				if(rc == 0) break;
		}
		check(cur < size, "BUG: Line exceeds allocated length of %zd in read_line(%d)", size, fd);

		if((strlen(buffer) == 0) && (rc == 0)) goto eof;

		return buffer;

eof: /* "Deallocate and return NULL." Different label than error for clarity */
error:
		if(buffer != NULL) free(buffer);
		return NULL;
}

stl_object *stl_read_text_object(int fd) {
		stl_object *obj = NULL;
		char *line = read_line(fd, 0);
		klist_t(stl_facet) *facets = kl_init(stl_facet);

		check(line != NULL, "Failed to read STL/ASCII header.");
		check((obj = stl_alloc(NULL, 0)), "Failed to allocated new STL object.");
		snprintf(obj->header, sizeof(obj->header), "[STL/ASCII]: '%s'", line);
		log_info("Header: [%s]", obj->header);
		free(line);

		size_t lines = 0;
		while((line = read_line(fd, 1))) {
				lines++;
				log_info("Line: [%s]", line);
				free(line);
		}

		kl_destroy(stl_facet, facets);
		return obj;
error:
		kl_destroy(stl_facet, facets);
		return NULL;
}

stl_object *stl_read_object(int fd) {
		int rc = -1;
		char header[80] = {0};
		uint32_t n_tris = 0;
		stl_object *obj = NULL;

		// Read the header
		rc = read(fd, header, sizeof(header));
		check(rc == sizeof(header), "Unable to read STL header. Got %d bytes.", rc);

		// Triangle count
		rc = read(fd, &n_tris, sizeof(n_tris));
		check(rc == sizeof(n_tris), "Failed to read facet count.");
		check(n_tris > 0, "Facet count cannot be zero.");

{'fraction_non_alphanumeric': 0.19315310763011623, 'fraction_numerical': 0.032844871147043965, 'mean_word_length': 3.9729899497487438, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1810049', 'n_tokens_mistral': 3702, 'n_tokens_neox': 3361, 'n_words': 767}