2013-06-23 16:18:38 +00:00
|
|
|
/* ADMesh -- process triangulated solid meshes
|
2014-09-23 12:34:37 +00:00
|
|
|
* Copyright (C) 1995, 1996 Anthony D. Martin <amartin@engr.csulb.edu>
|
|
|
|
* Copyright (C) 2013, 2014 several contributors, see AUTHORS
|
2013-06-23 16:18:38 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
2014-09-23 12:34:37 +00:00
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
2014-09-23 12:34:37 +00:00
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2013-06-23 16:18:38 +00:00
|
|
|
*
|
2014-09-23 12:34:37 +00:00
|
|
|
* Questions, comments, suggestions, etc to
|
|
|
|
* https://github.com/admesh/admesh/issues
|
2013-06-23 16:18:38 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
2014-09-23 12:34:37 +00:00
|
|
|
#include <string.h>
|
2013-06-23 16:18:38 +00:00
|
|
|
#include "stl.h"
|
2014-09-23 12:34:37 +00:00
|
|
|
#include "config.h"
|
2013-06-23 16:18:38 +00:00
|
|
|
|
|
|
|
#if !defined(SEEK_SET)
|
|
|
|
#define SEEK_SET 0
|
|
|
|
#define SEEK_CUR 1
|
|
|
|
#define SEEK_END 2
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void
|
2014-09-23 12:34:37 +00:00
|
|
|
stl_print_edges(stl_file *stl, FILE *file) {
|
2013-06-23 16:18:38 +00:00
|
|
|
int i;
|
|
|
|
int edges_allocated;
|
|
|
|
|
2014-09-23 12:34:37 +00:00
|
|
|
if (stl->error) return;
|
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
edges_allocated = stl->stats.number_of_facets * 3;
|
2014-09-23 12:34:37 +00:00
|
|
|
for(i = 0; i < edges_allocated; i++) {
|
|
|
|
fprintf(file, "%d, %f, %f, %f, %f, %f, %f\n",
|
|
|
|
stl->edge_start[i].facet_number,
|
|
|
|
stl->edge_start[i].p1.x, stl->edge_start[i].p1.y,
|
|
|
|
stl->edge_start[i].p1.z, stl->edge_start[i].p2.x,
|
|
|
|
stl->edge_start[i].p2.y, stl->edge_start[i].p2.z);
|
|
|
|
}
|
2013-06-23 16:18:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2014-09-23 12:34:37 +00:00
|
|
|
stl_stats_out(stl_file *stl, FILE *file, char *input_file) {
|
|
|
|
if (stl->error) return;
|
|
|
|
|
|
|
|
/* this is here for Slic3r, without our config.h
|
|
|
|
it won't use this part of the code anyway */
|
|
|
|
#ifndef VERSION
|
|
|
|
#define VERSION "unknown"
|
|
|
|
#endif
|
2013-06-23 16:18:38 +00:00
|
|
|
fprintf(file, "\n\
|
2014-09-23 12:34:37 +00:00
|
|
|
================= Results produced by ADMesh version " VERSION " ================\n");
|
2013-06-23 16:18:38 +00:00
|
|
|
fprintf(file, "\
|
|
|
|
Input file : %s\n", input_file);
|
2014-09-23 12:34:37 +00:00
|
|
|
if(stl->stats.type == binary) {
|
|
|
|
fprintf(file, "\
|
2013-06-23 16:18:38 +00:00
|
|
|
File type : Binary STL file\n");
|
2014-09-23 12:34:37 +00:00
|
|
|
} else {
|
|
|
|
fprintf(file, "\
|
2013-06-23 16:18:38 +00:00
|
|
|
File type : ASCII STL file\n");
|
2014-09-23 12:34:37 +00:00
|
|
|
}
|
2013-06-23 16:18:38 +00:00
|
|
|
fprintf(file, "\
|
|
|
|
Header : %s\n", stl->stats.header);
|
|
|
|
fprintf(file, "============== Size ==============\n");
|
2014-09-23 12:34:37 +00:00
|
|
|
fprintf(file, "Min X = % f, Max X = % f\n",
|
|
|
|
stl->stats.min.x, stl->stats.max.x);
|
|
|
|
fprintf(file, "Min Y = % f, Max Y = % f\n",
|
|
|
|
stl->stats.min.y, stl->stats.max.y);
|
|
|
|
fprintf(file, "Min Z = % f, Max Z = % f\n",
|
|
|
|
stl->stats.min.z, stl->stats.max.z);
|
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
fprintf(file, "\
|
|
|
|
========= Facet Status ========== Original ============ Final ====\n");
|
|
|
|
fprintf(file, "\
|
2014-09-23 12:34:37 +00:00
|
|
|
Number of facets : %5d %5d\n",
|
|
|
|
stl->stats.original_num_facets, stl->stats.number_of_facets);
|
2013-06-23 16:18:38 +00:00
|
|
|
fprintf(file, "\
|
2014-09-23 12:34:37 +00:00
|
|
|
Facets with 1 disconnected edge : %5d %5d\n",
|
|
|
|
stl->stats.facets_w_1_bad_edge, stl->stats.connected_facets_2_edge -
|
|
|
|
stl->stats.connected_facets_3_edge);
|
2013-06-23 16:18:38 +00:00
|
|
|
fprintf(file, "\
|
2014-09-23 12:34:37 +00:00
|
|
|
Facets with 2 disconnected edges : %5d %5d\n",
|
|
|
|
stl->stats.facets_w_2_bad_edge, stl->stats.connected_facets_1_edge -
|
|
|
|
stl->stats.connected_facets_2_edge);
|
2013-06-23 16:18:38 +00:00
|
|
|
fprintf(file, "\
|
2014-09-23 12:34:37 +00:00
|
|
|
Facets with 3 disconnected edges : %5d %5d\n",
|
|
|
|
stl->stats.facets_w_3_bad_edge, stl->stats.number_of_facets -
|
|
|
|
stl->stats.connected_facets_1_edge);
|
2013-06-23 16:18:38 +00:00
|
|
|
fprintf(file, "\
|
2014-09-23 12:34:37 +00:00
|
|
|
Total disconnected facets : %5d %5d\n",
|
|
|
|
stl->stats.facets_w_1_bad_edge + stl->stats.facets_w_2_bad_edge +
|
|
|
|
stl->stats.facets_w_3_bad_edge, stl->stats.number_of_facets -
|
|
|
|
stl->stats.connected_facets_3_edge);
|
|
|
|
|
|
|
|
fprintf(file,
|
|
|
|
"=== Processing Statistics === ===== Other Statistics =====\n");
|
2013-06-23 16:18:38 +00:00
|
|
|
fprintf(file, "\
|
|
|
|
Number of parts : %5d Volume : % f\n",
|
2014-09-23 12:34:37 +00:00
|
|
|
stl->stats.number_of_parts, stl->stats.volume);
|
2013-06-23 16:18:38 +00:00
|
|
|
fprintf(file, "\
|
|
|
|
Degenerate facets : %5d\n", stl->stats.degenerate_facets);
|
|
|
|
fprintf(file, "\
|
|
|
|
Edges fixed : %5d\n", stl->stats.edges_fixed);
|
|
|
|
fprintf(file, "\
|
|
|
|
Facets removed : %5d\n", stl->stats.facets_removed);
|
|
|
|
fprintf(file, "\
|
|
|
|
Facets added : %5d\n", stl->stats.facets_added);
|
|
|
|
fprintf(file, "\
|
|
|
|
Facets reversed : %5d\n", stl->stats.facets_reversed);
|
|
|
|
fprintf(file, "\
|
|
|
|
Backwards edges : %5d\n", stl->stats.backwards_edges);
|
|
|
|
fprintf(file, "\
|
|
|
|
Normals fixed : %5d\n", stl->stats.normals_fixed);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-09-23 12:34:37 +00:00
|
|
|
stl_write_ascii(stl_file *stl, const char *file, const char *label) {
|
2013-06-23 16:18:38 +00:00
|
|
|
int i;
|
|
|
|
FILE *fp;
|
|
|
|
char *error_msg;
|
2014-09-23 12:34:37 +00:00
|
|
|
|
|
|
|
if (stl->error) return;
|
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
/* Open the file */
|
|
|
|
fp = fopen(file, "w");
|
2014-09-23 12:34:37 +00:00
|
|
|
if(fp == NULL) {
|
|
|
|
error_msg = (char*)
|
|
|
|
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
|
|
|
sprintf(error_msg, "stl_write_ascii: Couldn't open %s for writing",
|
|
|
|
file);
|
|
|
|
perror(error_msg);
|
|
|
|
free(error_msg);
|
|
|
|
stl->error = 1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
fprintf(fp, "solid %s\n", label);
|
2014-09-23 12:34:37 +00:00
|
|
|
|
|
|
|
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
|
|
|
fprintf(fp, " facet normal % .8E % .8E % .8E\n",
|
|
|
|
stl->facet_start[i].normal.x, stl->facet_start[i].normal.y,
|
|
|
|
stl->facet_start[i].normal.z);
|
|
|
|
fprintf(fp, " outer loop\n");
|
|
|
|
fprintf(fp, " vertex % .8E % .8E % .8E\n",
|
|
|
|
stl->facet_start[i].vertex[0].x, stl->facet_start[i].vertex[0].y,
|
|
|
|
stl->facet_start[i].vertex[0].z);
|
|
|
|
fprintf(fp, " vertex % .8E % .8E % .8E\n",
|
|
|
|
stl->facet_start[i].vertex[1].x, stl->facet_start[i].vertex[1].y,
|
|
|
|
stl->facet_start[i].vertex[1].z);
|
|
|
|
fprintf(fp, " vertex % .8E % .8E % .8E\n",
|
|
|
|
stl->facet_start[i].vertex[2].x, stl->facet_start[i].vertex[2].y,
|
|
|
|
stl->facet_start[i].vertex[2].z);
|
|
|
|
fprintf(fp, " endloop\n");
|
|
|
|
fprintf(fp, " endfacet\n");
|
|
|
|
}
|
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
fprintf(fp, "endsolid %s\n", label);
|
2014-09-23 12:34:37 +00:00
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
fclose(fp);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-09-23 12:34:37 +00:00
|
|
|
stl_print_neighbors(stl_file *stl, char *file) {
|
2013-06-23 16:18:38 +00:00
|
|
|
int i;
|
|
|
|
FILE *fp;
|
|
|
|
char *error_msg;
|
|
|
|
|
2014-09-23 12:34:37 +00:00
|
|
|
if (stl->error) return;
|
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
/* Open the file */
|
|
|
|
fp = fopen(file, "w");
|
2014-09-23 12:34:37 +00:00
|
|
|
if(fp == NULL) {
|
|
|
|
error_msg = (char*)
|
|
|
|
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
|
|
|
sprintf(error_msg, "stl_print_neighbors: Couldn't open %s for writing",
|
|
|
|
file);
|
|
|
|
perror(error_msg);
|
|
|
|
free(error_msg);
|
|
|
|
stl->error = 1;
|
|
|
|
return;
|
|
|
|
}
|
2013-06-23 16:18:38 +00:00
|
|
|
|
2014-09-23 12:34:37 +00:00
|
|
|
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
|
|
|
fprintf(fp, "%d, %d,%d, %d,%d, %d,%d\n",
|
|
|
|
i,
|
|
|
|
stl->neighbors_start[i].neighbor[0],
|
|
|
|
(int)stl->neighbors_start[i].which_vertex_not[0],
|
|
|
|
stl->neighbors_start[i].neighbor[1],
|
|
|
|
(int)stl->neighbors_start[i].which_vertex_not[1],
|
|
|
|
stl->neighbors_start[i].neighbor[2],
|
|
|
|
(int)stl->neighbors_start[i].which_vertex_not[2]);
|
|
|
|
}
|
|
|
|
fclose(fp);
|
2013-06-23 16:18:38 +00:00
|
|
|
}
|
|
|
|
|
2014-09-23 12:34:37 +00:00
|
|
|
void
|
|
|
|
stl_put_little_int(FILE *fp, int value_in) {
|
2013-06-23 16:18:38 +00:00
|
|
|
int new_value;
|
2014-09-23 12:34:37 +00:00
|
|
|
union {
|
|
|
|
int int_value;
|
|
|
|
char char_value[4];
|
|
|
|
} value;
|
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
value.int_value = value_in;
|
2014-09-23 12:34:37 +00:00
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
new_value = value.char_value[0] & 0xFF;
|
|
|
|
new_value |= (value.char_value[1] & 0xFF) << 0x08;
|
|
|
|
new_value |= (value.char_value[2] & 0xFF) << 0x10;
|
|
|
|
new_value |= (value.char_value[3] & 0xFF) << 0x18;
|
|
|
|
fwrite(&new_value, sizeof(int), 1, fp);
|
|
|
|
}
|
|
|
|
|
2014-09-23 12:34:37 +00:00
|
|
|
void
|
|
|
|
stl_put_little_float(FILE *fp, float value_in) {
|
2013-06-23 16:18:38 +00:00
|
|
|
int new_value;
|
2014-09-23 12:34:37 +00:00
|
|
|
union {
|
|
|
|
float float_value;
|
|
|
|
char char_value[4];
|
|
|
|
} value;
|
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
value.float_value = value_in;
|
2014-09-23 12:34:37 +00:00
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
new_value = value.char_value[0] & 0xFF;
|
|
|
|
new_value |= (value.char_value[1] & 0xFF) << 0x08;
|
|
|
|
new_value |= (value.char_value[2] & 0xFF) << 0x10;
|
|
|
|
new_value |= (value.char_value[3] & 0xFF) << 0x18;
|
|
|
|
fwrite(&new_value, sizeof(int), 1, fp);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-09-23 12:34:37 +00:00
|
|
|
stl_write_binary_block(stl_file *stl, FILE *fp)
|
2013-06-23 16:18:38 +00:00
|
|
|
{
|
2014-09-23 12:34:37 +00:00
|
|
|
int i;
|
2013-06-23 16:18:38 +00:00
|
|
|
for(i = 0; i < stl->stats.number_of_facets; i++)
|
|
|
|
{
|
|
|
|
stl_put_little_float(fp, stl->facet_start[i].normal.x);
|
|
|
|
stl_put_little_float(fp, stl->facet_start[i].normal.y);
|
|
|
|
stl_put_little_float(fp, stl->facet_start[i].normal.z);
|
|
|
|
stl_put_little_float(fp, stl->facet_start[i].vertex[0].x);
|
|
|
|
stl_put_little_float(fp, stl->facet_start[i].vertex[0].y);
|
|
|
|
stl_put_little_float(fp, stl->facet_start[i].vertex[0].z);
|
|
|
|
stl_put_little_float(fp, stl->facet_start[i].vertex[1].x);
|
|
|
|
stl_put_little_float(fp, stl->facet_start[i].vertex[1].y);
|
|
|
|
stl_put_little_float(fp, stl->facet_start[i].vertex[1].z);
|
|
|
|
stl_put_little_float(fp, stl->facet_start[i].vertex[2].x);
|
|
|
|
stl_put_little_float(fp, stl->facet_start[i].vertex[2].y);
|
|
|
|
stl_put_little_float(fp, stl->facet_start[i].vertex[2].z);
|
|
|
|
fputc(stl->facet_start[i].extra[0], fp);
|
|
|
|
fputc(stl->facet_start[i].extra[1], fp);
|
|
|
|
}
|
2014-09-23 12:34:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
stl_write_binary(stl_file *stl, const char *file, const char *label) {
|
|
|
|
FILE *fp;
|
|
|
|
int i;
|
|
|
|
char *error_msg;
|
|
|
|
|
|
|
|
if (stl->error) return;
|
|
|
|
|
|
|
|
/* Open the file */
|
2015-06-20 12:16:23 +00:00
|
|
|
fp = fopen(file, "wb");
|
2014-09-23 12:34:37 +00:00
|
|
|
if(fp == NULL) {
|
|
|
|
error_msg = (char*)
|
|
|
|
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
|
|
|
sprintf(error_msg, "stl_write_binary: Couldn't open %s for writing",
|
|
|
|
file);
|
|
|
|
perror(error_msg);
|
|
|
|
free(error_msg);
|
|
|
|
stl->error = 1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
fprintf(fp, "%s", label);
|
|
|
|
for(i = strlen(label); i < LABEL_SIZE; i++) putc(0, fp);
|
|
|
|
|
|
|
|
fseek(fp, LABEL_SIZE, SEEK_SET);
|
|
|
|
|
|
|
|
stl_put_little_int(fp, stl->stats.number_of_facets);
|
|
|
|
|
|
|
|
stl_write_binary_block(stl, fp);
|
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
fclose(fp);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-09-23 12:34:37 +00:00
|
|
|
stl_write_vertex(stl_file *stl, int facet, int vertex) {
|
|
|
|
if (stl->error) return;
|
2013-06-23 16:18:38 +00:00
|
|
|
printf(" vertex %d/%d % .8E % .8E % .8E\n", vertex, facet,
|
2014-09-23 12:34:37 +00:00
|
|
|
stl->facet_start[facet].vertex[vertex].x,
|
|
|
|
stl->facet_start[facet].vertex[vertex].y,
|
|
|
|
stl->facet_start[facet].vertex[vertex].z);
|
2013-06-23 16:18:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-09-23 12:34:37 +00:00
|
|
|
stl_write_facet(stl_file *stl, char *label, int facet) {
|
|
|
|
if (stl->error) return;
|
2013-06-23 16:18:38 +00:00
|
|
|
printf("facet (%d)/ %s\n", facet, label);
|
|
|
|
stl_write_vertex(stl, facet, 0);
|
|
|
|
stl_write_vertex(stl, facet, 1);
|
|
|
|
stl_write_vertex(stl, facet, 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-09-23 12:34:37 +00:00
|
|
|
stl_write_edge(stl_file *stl, char *label, stl_hash_edge edge) {
|
|
|
|
if (stl->error) return;
|
2013-06-23 16:18:38 +00:00
|
|
|
printf("edge (%d)/(%d) %s\n", edge.facet_number, edge.which_edge, label);
|
2014-09-23 12:34:37 +00:00
|
|
|
if(edge.which_edge < 3) {
|
|
|
|
stl_write_vertex(stl, edge.facet_number, edge.which_edge % 3);
|
|
|
|
stl_write_vertex(stl, edge.facet_number, (edge.which_edge + 1) % 3);
|
|
|
|
} else {
|
|
|
|
stl_write_vertex(stl, edge.facet_number, (edge.which_edge + 1) % 3);
|
|
|
|
stl_write_vertex(stl, edge.facet_number, edge.which_edge % 3);
|
|
|
|
}
|
2013-06-23 16:18:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-09-23 12:34:37 +00:00
|
|
|
stl_write_neighbor(stl_file *stl, int facet) {
|
|
|
|
if (stl->error) return;
|
2013-06-23 16:18:38 +00:00
|
|
|
printf("Neighbors %d: %d, %d, %d ; %d, %d, %d\n", facet,
|
2014-09-23 12:34:37 +00:00
|
|
|
stl->neighbors_start[facet].neighbor[0],
|
|
|
|
stl->neighbors_start[facet].neighbor[1],
|
|
|
|
stl->neighbors_start[facet].neighbor[2],
|
|
|
|
stl->neighbors_start[facet].which_vertex_not[0],
|
|
|
|
stl->neighbors_start[facet].which_vertex_not[1],
|
|
|
|
stl->neighbors_start[facet].which_vertex_not[2]);
|
2013-06-23 16:18:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-09-23 12:34:37 +00:00
|
|
|
stl_write_quad_object(stl_file *stl, char *file) {
|
2013-06-23 16:18:38 +00:00
|
|
|
FILE *fp;
|
|
|
|
int i;
|
|
|
|
int j;
|
|
|
|
char *error_msg;
|
|
|
|
stl_vertex connect_color;
|
|
|
|
stl_vertex uncon_1_color;
|
|
|
|
stl_vertex uncon_2_color;
|
|
|
|
stl_vertex uncon_3_color;
|
|
|
|
stl_vertex color;
|
2014-09-23 12:34:37 +00:00
|
|
|
|
|
|
|
if (stl->error) return;
|
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
/* Open the file */
|
|
|
|
fp = fopen(file, "w");
|
2014-09-23 12:34:37 +00:00
|
|
|
if(fp == NULL) {
|
|
|
|
error_msg = (char*)
|
|
|
|
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
|
|
|
sprintf(error_msg, "stl_write_quad_object: Couldn't open %s for writing",
|
|
|
|
file);
|
|
|
|
perror(error_msg);
|
|
|
|
free(error_msg);
|
|
|
|
stl->error = 1;
|
|
|
|
return;
|
|
|
|
}
|
2013-06-23 16:18:38 +00:00
|
|
|
|
|
|
|
connect_color.x = 0.0;
|
|
|
|
connect_color.y = 0.0;
|
|
|
|
connect_color.z = 1.0;
|
|
|
|
uncon_1_color.x = 0.0;
|
|
|
|
uncon_1_color.y = 1.0;
|
|
|
|
uncon_1_color.z = 0.0;
|
|
|
|
uncon_2_color.x = 1.0;
|
|
|
|
uncon_2_color.y = 1.0;
|
|
|
|
uncon_2_color.z = 1.0;
|
|
|
|
uncon_3_color.x = 1.0;
|
|
|
|
uncon_3_color.y = 0.0;
|
|
|
|
uncon_3_color.z = 0.0;
|
|
|
|
|
|
|
|
fprintf(fp, "CQUAD\n");
|
2014-09-23 12:34:37 +00:00
|
|
|
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
|
|
|
j = ((stl->neighbors_start[i].neighbor[0] == -1) +
|
|
|
|
(stl->neighbors_start[i].neighbor[1] == -1) +
|
|
|
|
(stl->neighbors_start[i].neighbor[2] == -1));
|
|
|
|
if(j == 0) {
|
|
|
|
color = connect_color;
|
|
|
|
} else if(j == 1) {
|
|
|
|
color = uncon_1_color;
|
|
|
|
} else if(j == 2) {
|
|
|
|
color = uncon_2_color;
|
|
|
|
} else {
|
|
|
|
color = uncon_3_color;
|
2013-06-23 16:18:38 +00:00
|
|
|
}
|
2014-09-23 12:34:37 +00:00
|
|
|
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n",
|
|
|
|
stl->facet_start[i].vertex[0].x,
|
|
|
|
stl->facet_start[i].vertex[0].y,
|
|
|
|
stl->facet_start[i].vertex[0].z, color.x, color.y, color.z);
|
|
|
|
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n",
|
|
|
|
stl->facet_start[i].vertex[1].x,
|
|
|
|
stl->facet_start[i].vertex[1].y,
|
|
|
|
stl->facet_start[i].vertex[1].z, color.x, color.y, color.z);
|
|
|
|
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n",
|
|
|
|
stl->facet_start[i].vertex[2].x,
|
|
|
|
stl->facet_start[i].vertex[2].y,
|
|
|
|
stl->facet_start[i].vertex[2].z, color.x, color.y, color.z);
|
|
|
|
fprintf(fp, "%f %f %f %1.1f %1.1f %1.1f 1\n",
|
|
|
|
stl->facet_start[i].vertex[2].x,
|
|
|
|
stl->facet_start[i].vertex[2].y,
|
|
|
|
stl->facet_start[i].vertex[2].z, color.x, color.y, color.z);
|
|
|
|
}
|
2013-06-23 16:18:38 +00:00
|
|
|
fclose(fp);
|
|
|
|
}
|
2014-09-23 12:34:37 +00:00
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
void
|
2014-09-23 12:34:37 +00:00
|
|
|
stl_write_dxf(stl_file *stl, char *file, char *label) {
|
2013-06-23 16:18:38 +00:00
|
|
|
int i;
|
|
|
|
FILE *fp;
|
|
|
|
char *error_msg;
|
2014-09-23 12:34:37 +00:00
|
|
|
|
|
|
|
if (stl->error) return;
|
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
/* Open the file */
|
|
|
|
fp = fopen(file, "w");
|
2014-09-23 12:34:37 +00:00
|
|
|
if(fp == NULL) {
|
|
|
|
error_msg = (char*)
|
|
|
|
malloc(81 + strlen(file)); /* Allow 80 chars+file size for message */
|
|
|
|
sprintf(error_msg, "stl_write_ascii: Couldn't open %s for writing",
|
|
|
|
file);
|
|
|
|
perror(error_msg);
|
|
|
|
free(error_msg);
|
|
|
|
stl->error = 1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
fprintf(fp, "999\n%s\n", label);
|
|
|
|
fprintf(fp, "0\nSECTION\n2\nHEADER\n0\nENDSEC\n");
|
|
|
|
fprintf(fp, "0\nSECTION\n2\nTABLES\n0\nTABLE\n2\nLAYER\n70\n1\n\
|
|
|
|
0\nLAYER\n2\n0\n70\n0\n62\n7\n6\nCONTINUOUS\n0\nENDTAB\n0\nENDSEC\n");
|
|
|
|
fprintf(fp, "0\nSECTION\n2\nBLOCKS\n0\nENDSEC\n");
|
2014-09-23 12:34:37 +00:00
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
fprintf(fp, "0\nSECTION\n2\nENTITIES\n");
|
|
|
|
|
2014-09-23 12:34:37 +00:00
|
|
|
for(i = 0; i < stl->stats.number_of_facets; i++) {
|
|
|
|
fprintf(fp, "0\n3DFACE\n8\n0\n");
|
|
|
|
fprintf(fp, "10\n%f\n20\n%f\n30\n%f\n",
|
|
|
|
stl->facet_start[i].vertex[0].x, stl->facet_start[i].vertex[0].y,
|
|
|
|
stl->facet_start[i].vertex[0].z);
|
|
|
|
fprintf(fp, "11\n%f\n21\n%f\n31\n%f\n",
|
|
|
|
stl->facet_start[i].vertex[1].x, stl->facet_start[i].vertex[1].y,
|
|
|
|
stl->facet_start[i].vertex[1].z);
|
|
|
|
fprintf(fp, "12\n%f\n22\n%f\n32\n%f\n",
|
|
|
|
stl->facet_start[i].vertex[2].x, stl->facet_start[i].vertex[2].y,
|
|
|
|
stl->facet_start[i].vertex[2].z);
|
|
|
|
fprintf(fp, "13\n%f\n23\n%f\n33\n%f\n",
|
|
|
|
stl->facet_start[i].vertex[2].x, stl->facet_start[i].vertex[2].y,
|
|
|
|
stl->facet_start[i].vertex[2].z);
|
|
|
|
}
|
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
fprintf(fp, "0\nENDSEC\n0\nEOF\n");
|
2014-09-23 12:34:37 +00:00
|
|
|
|
2013-06-23 16:18:38 +00:00
|
|
|
fclose(fp);
|
|
|
|
}
|
2014-09-23 12:34:37 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
stl_clear_error(stl_file *stl) {
|
|
|
|
stl->error = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
stl_exit_on_error(stl_file *stl) {
|
|
|
|
if (!stl->error) return;
|
|
|
|
stl->error = 0;
|
|
|
|
stl_close(stl);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
stl_get_error(stl_file *stl) {
|
|
|
|
return stl->error;
|
|
|
|
}
|