mirror of
git://projects.qi-hardware.com/cae-tools.git
synced 2024-12-22 23:51:08 +02:00
ptrude/: added (overly, this far) simple extruder
This commit is contained in:
parent
3dcd5cc9aa
commit
c202eda676
@ -13,7 +13,7 @@
|
|||||||
SHELL = /bin/bash
|
SHELL = /bin/bash
|
||||||
|
|
||||||
MAIN = ptrude
|
MAIN = ptrude
|
||||||
OBJS = $(MAIN).o path.o
|
OBJS = $(MAIN).o path.o extrude.o
|
||||||
|
|
||||||
CFLAGS = -Wall -g -Wshadow -Wmissing-prototypes \
|
CFLAGS = -Wall -g -Wshadow -Wmissing-prototypes \
|
||||||
-Wmissing-declarations -Wno-format-zero-length
|
-Wmissing-declarations -Wno-format-zero-length
|
||||||
|
123
ptrude/extrude.c
Normal file
123
ptrude/extrude.c
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* extrude.c - Perform the extrusion
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Known bugs:
|
||||||
|
*
|
||||||
|
* - negative x coordinates in shape produce overlapping faces
|
||||||
|
* - the rounding is only accurate for x = 0. For x > 0, we need to add
|
||||||
|
* more points. Tricky.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "path.h"
|
||||||
|
#include "extrude.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define alloc_tn(t, n) ((t *) malloc(sizeof(t)*(n)))
|
||||||
|
|
||||||
|
|
||||||
|
static void slice(double x, double y, double nx, double ny,
|
||||||
|
const struct path *shape, struct point *p)
|
||||||
|
{
|
||||||
|
const struct vertex *v;
|
||||||
|
|
||||||
|
for (v = shape->vertices; v; v = v->next) {
|
||||||
|
p->x = x+nx*v->x;
|
||||||
|
p->y = y+ny*v->x;
|
||||||
|
p->z = v->y;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void mesh(const struct point *a, const struct point *b, int n,
|
||||||
|
void (*face)(void *data, struct point a, struct point b, struct point c),
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i != n-1; i++) {
|
||||||
|
face(data, a[i], b[i], a[i+1]);
|
||||||
|
face(data, a[i+1], b[i], b[i+1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void extrude(const struct path *path, const struct path *shape,
|
||||||
|
void (*face)(void *data, struct point a, struct point b, struct point c),
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
const struct vertex *v; /* current vertex (for iteration) */
|
||||||
|
const struct vertex *a, *b, *c; /* previous, current, next vertex */
|
||||||
|
struct point *prev, *this; /* previous and current slice */
|
||||||
|
double nx, ny; /* 2D normals */
|
||||||
|
double f; /* factor for normalization */
|
||||||
|
double tx, ty; /* temporary 2D normals */
|
||||||
|
int n = 0; /* number of vertices in shape */
|
||||||
|
|
||||||
|
if (!path->vertices || !path->vertices->next || !shape->vertices)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (v = shape->vertices; v; v = v->next)
|
||||||
|
n++;
|
||||||
|
|
||||||
|
prev = alloc_tn(struct point, n);
|
||||||
|
this = alloc_tn(struct point, n);
|
||||||
|
|
||||||
|
a = path->vertices;
|
||||||
|
b = a->next;
|
||||||
|
nx = b->y-a->y;
|
||||||
|
ny = a->x-b->x;
|
||||||
|
f = hypot(nx, ny);
|
||||||
|
slice(a->x, a->y, nx/f, ny/f, shape, prev);
|
||||||
|
|
||||||
|
for (v = path->vertices->next; v->next; v = v->next) {
|
||||||
|
b = v;
|
||||||
|
c = v->next;
|
||||||
|
|
||||||
|
tx = b->y-a->y;
|
||||||
|
ty = a->x-b->x;
|
||||||
|
f = hypot(tx, ty);
|
||||||
|
nx = tx/f;
|
||||||
|
ny = ty/f;
|
||||||
|
|
||||||
|
tx = c->y-b->y;
|
||||||
|
ty = b->x-c->x;
|
||||||
|
f = hypot(tx, ty);
|
||||||
|
nx += tx/f;
|
||||||
|
ny += ty/f;
|
||||||
|
|
||||||
|
slice(b->x, b->y, nx/2, ny/2, shape, this);
|
||||||
|
mesh(prev, this, n, face, data);
|
||||||
|
|
||||||
|
memcpy(prev, this, sizeof(*prev)*n);
|
||||||
|
|
||||||
|
a = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
nx = v->y-a->y;
|
||||||
|
ny = a->x-v->x;
|
||||||
|
f = hypot(nx, ny);
|
||||||
|
|
||||||
|
slice(v->x, v->y, nx/f, ny/f, shape, this);
|
||||||
|
mesh(prev, this, n, face, data);
|
||||||
|
|
||||||
|
/* @@@ To do: close shape and close top and bottom */
|
||||||
|
|
||||||
|
free(prev);
|
||||||
|
free(this);
|
||||||
|
}
|
65
ptrude/mesh.fig
Normal file
65
ptrude/mesh.fig
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#FIG 3.2 Produced by xfig version 3.2.5b
|
||||||
|
Landscape
|
||||||
|
Center
|
||||||
|
Metric
|
||||||
|
A4
|
||||||
|
100.00
|
||||||
|
Single
|
||||||
|
-2
|
||||||
|
1200 2
|
||||||
|
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
2925 7200 4050 8325
|
||||||
|
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
2925 5400 4275 7200
|
||||||
|
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
2025 4500 4275 5400
|
||||||
|
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
3420 4500 6930 4050
|
||||||
|
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
6075 3150 8325 2025
|
||||||
|
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
4275 5400 6975 5850
|
||||||
|
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
6975 5850 8100 4950
|
||||||
|
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
4275 7200 6750 6975
|
||||||
|
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
6975 4050 8280 3825
|
||||||
|
2 1 0 3 1 7 50 -1 -1 0.000 0 0 -1 1 0 4
|
||||||
|
1 1 3.00 90.00 120.00
|
||||||
|
2700 8325 2925 7200 2925 5400 2025 4500
|
||||||
|
2 1 0 2 1 7 50 -1 -1 0.000 0 0 7 0 0 4
|
||||||
|
4050 8325 4275 7200 4275 5400 3375 4500
|
||||||
|
2 1 0 2 1 7 50 -1 -1 0.000 0 0 7 0 0 4
|
||||||
|
6750 6975 6975 5850 6975 4050 6075 3150
|
||||||
|
2 1 0 2 1 7 50 -1 -1 0.000 0 0 7 0 0 4
|
||||||
|
8100 4950 8325 3825 8325 2025 7425 1125
|
||||||
|
2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 4
|
||||||
|
2025 4500 3375 4500 6075 3150 7425 1125
|
||||||
|
2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 4
|
||||||
|
2925 5400 4275 5400 6975 4050 8325 2025
|
||||||
|
2 1 0 3 4 7 50 -1 -1 0.000 0 0 -1 1 0 4
|
||||||
|
1 1 3.00 90.00 120.00
|
||||||
|
2925 7200 4275 7200 6975 5850 8325 3825
|
||||||
|
2 1 0 2 4 7 50 -1 -1 0.000 0 0 7 0 0 4
|
||||||
|
2709 8343 4059 8343 6759 6993 8109 4968
|
||||||
|
2 1 0 2 4 7 52 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
3195 6975 3015 7155
|
||||||
|
2 1 0 2 1 7 52 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
2520 7200 2790 7200
|
||||||
|
2 1 0 2 1 7 52 -1 -1 0.000 0 0 -1 0 0 2
|
||||||
|
2250 8505 2565 8370
|
||||||
|
3 2 0 2 0 7 50 -1 -1 0.000 0 1 0 3
|
||||||
|
0 0 2.00 90.00 120.00
|
||||||
|
4680 6705 5580 6075 4545 5805
|
||||||
|
0.000 -1.000 0.000
|
||||||
|
3 2 0 2 0 7 50 -1 -1 0.000 0 1 0 3
|
||||||
|
0 0 2.00 90.00 120.00
|
||||||
|
5265 5265 6570 5445 6705 4545
|
||||||
|
0.000 -1.000 0.000
|
||||||
|
4 2 1 50 -1 18 18 0.0000 4 270 870 2835 6480 Shape\001
|
||||||
|
4 1 4 50 -1 18 18 0.0000 4 210 615 3690 7515 Path\001
|
||||||
|
4 1 4 50 -1 19 15 0.0000 4 240 375 3330 6930 tag\001
|
||||||
|
4 1 1 50 -1 19 15 0.0000 4 240 375 2295 7245 tag\001
|
||||||
|
4 1 1 50 -1 14 15 0.0000 4 135 750 1845 8640 start\001
|
||||||
|
4 1 1 50 -1 18 12 0.0000 4 195 1365 2205 8865 (or unique tag)\001
|
@ -17,6 +17,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
|
#include "extrude.h"
|
||||||
#include "ptrude.h"
|
#include "ptrude.h"
|
||||||
|
|
||||||
|
|
||||||
@ -50,6 +51,29 @@ static void close_file(FILE *file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
FILE *file = stdout;
|
||||||
|
|
||||||
|
fprintf(file, "solid ptrude\n");
|
||||||
|
extrude(path, shape, do_face, file);
|
||||||
|
fprintf(file, "endsolid ptrude\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void usage(const char *name)
|
static void usage(const char *name)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -106,7 +130,7 @@ int main(int argc, char **argv)
|
|||||||
*/
|
*/
|
||||||
path = round_path(path, r, sqrt(d));
|
path = round_path(path, r, sqrt(d));
|
||||||
shape = round_path(shape, r, sqrt(d));
|
shape = round_path(shape, r, sqrt(d));
|
||||||
/* ... now all that's missing is the extrusion :-) */
|
do_extrude(path, shape);
|
||||||
} else {
|
} else {
|
||||||
shape = round_path(shape, r, d);
|
shape = round_path(shape, r, d);
|
||||||
save_path(stdout, shape);
|
save_path(stdout, shape);
|
||||||
|
10
ptrude/tp
Normal file
10
ptrude/tp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# test path
|
||||||
|
-100 0
|
||||||
|
100 0
|
||||||
|
200 100
|
||||||
|
200 200
|
||||||
|
100 300
|
||||||
|
0 300
|
||||||
|
-100 200
|
||||||
|
-100 100
|
||||||
|
0 100
|
Loading…
Reference in New Issue
Block a user