mirror of
git://projects.qi-hardware.com/cae-tools.git
synced 2024-12-23 03:59:00 +02:00
143 lines
2.7 KiB
C
143 lines
2.7 KiB
C
/*
|
|
* ptrude.c - Extrusion of a 2D path along a perpendicular 2D path
|
|
*
|
|
* Written 2011 by Werner Almesberger
|
|
* Copyright 2011 by Werner Almesberger
|
|
*
|
|
* 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
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
|
|
#include "path.h"
|
|
#include "extrude.h"
|
|
#include "ptrude.h"
|
|
|
|
|
|
int debug = 0;
|
|
|
|
|
|
static FILE *open_file(const char *name, const char *mode)
|
|
{
|
|
FILE *file;
|
|
|
|
if (!strcmp(name, "-"))
|
|
return strcmp(mode, "r") ? stdout : stdin;
|
|
|
|
file = fopen(name, mode);
|
|
if (!file) {
|
|
perror(name);
|
|
exit(1);
|
|
}
|
|
return file;
|
|
}
|
|
|
|
|
|
static void close_file(FILE *file)
|
|
{
|
|
if (file == stdin || file == stdout)
|
|
return;
|
|
if (fclose(file) == EOF) {
|
|
perror("fclose");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
|
|
static void do_face(void *data, struct point a, struct point b, struct point c)
|
|
{
|
|
FILE *file = data;
|
|
|
|
fprintf(file, "facet normal 0 0 0\n");
|
|
fprintf(file, " outer loop\n");
|
|
fprintf(file, " vertex %f %f %f\n", a.x, a.y, a.z);
|
|
fprintf(file, " vertex %f %f %f\n", b.x, b.y, b.z);
|
|
fprintf(file, " vertex %f %f %f\n", c.x, c.y, c.z);
|
|
fprintf(file, " endloop\nendfacet\n");
|
|
}
|
|
|
|
|
|
static void do_extrude(const struct path *path, const struct path *shape,
|
|
double r, double d)
|
|
{
|
|
FILE *file = stdout;
|
|
|
|
fprintf(file, "solid ptrude\n");
|
|
extrude(path, shape, r, d, do_face, file);
|
|
fprintf(file, "endsolid ptrude\n");
|
|
}
|
|
|
|
|
|
static void usage(const char *name)
|
|
{
|
|
fprintf(stderr,
|
|
"usage: %s shape radius tolerance\n"
|
|
"%6s %s path shape radius tolerance\n",
|
|
name, "", name);
|
|
exit(1);
|
|
}
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
FILE *file;
|
|
struct path *path = NULL;
|
|
const struct path *shape;
|
|
double r, d;
|
|
char *end;
|
|
int c;
|
|
|
|
while ((c = getopt(argc, argv, "d")) != EOF)
|
|
switch (c) {
|
|
case 'd':
|
|
debug = 1;
|
|
break;
|
|
default:
|
|
usage(*argv);
|
|
}
|
|
|
|
switch (argc-optind) {
|
|
case 3:
|
|
break;
|
|
case 4:
|
|
file = open_file(argv[optind], "r");
|
|
path = load_path(file);
|
|
close_file(file);
|
|
break;
|
|
default:
|
|
usage(*argv);
|
|
}
|
|
|
|
file = open_file(argv[argc-3], "r");
|
|
shape = load_path(file);
|
|
close_file(file);
|
|
|
|
r = strtod(argv[argc-2], &end);
|
|
if (*end || r <= 0)
|
|
usage(*argv);
|
|
d = strtod(argv[argc-1], &end);
|
|
if (*end || d <= 0)
|
|
usage (*argv);
|
|
|
|
if (path) {
|
|
/*
|
|
* We split the error budget evenly between path and shape.
|
|
*/
|
|
path_set_length(path);
|
|
shape = round_path(shape, r, sqrt(d));
|
|
do_extrude(path, shape, r, sqrt(d));
|
|
} else {
|
|
shape = round_path(shape, r, d);
|
|
save_path(stdout, shape);
|
|
}
|
|
|
|
return 0;
|
|
}
|