Root/solidify/solid.c

Source at commit 01d8e411f34d448b83fdb1cbfa4b63b0ac95fe6b created 8 years 8 months ago.
By Werner Almesberger, Use the project name to disambiguate names in POV-Ray output.
1/*
2 * solid.c - Data structure and handling of a solid made of two opposing faces
3 *
4 * Written 2010 by Werner Almesberger
5 * Copyright 2010 by Werner Almesberger
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13
14#include <stdint.h>
15#include <stdlib.h>
16#include <stdio.h>
17
18#include "face.h"
19#include "solid.h"
20
21
22static void height_field(const char *name, const struct face *f,
23    const struct matrix *m)
24{
25    FILE *file;
26    int x, y;
27    int z;
28    uint16_t g;
29    uint8_t v[2];
30
31    file = fopen(name, "w");
32    if (!file) {
33        perror(name);
34        exit(1);
35    }
36    fprintf(file, "P5\n%d %d\n65535\n", f->sx, f->sy);
37    for (y = 0; y != f->sy; y++)
38        for (x = 0; x != f->sx; x++) {
39            z = get(f->a, x+f->a->min_x, y+f->a->min_y);
40            g = z == UNDEF ? 0 :
41                65535*(z-f->a->min_z)/(f->a->max_z-f->a->min_z);
42            v[0] = g >> 8;
43            v[1] = g;
44            fwrite(v, 2, 1, file);
45        }
46    fclose(file);
47}
48
49
50static void sanitize(const char *s, char *res)
51{
52    while (*s) {
53        if ((*s >= 'A' && *s <= 'Z') ||
54            (*s >= 'a' && *s <= 'z') ||
55            (*s >= '0' && *s <= '9') || *s == '_')
56            *res = *s;
57        else
58            *res = '_';
59        res++;
60        s++;
61    }
62    *res = 0;
63}
64
65
66void povray(const char *name, const struct solid *s)
67{
68    struct matrix m;
69    char tmp[1000]; /* @@@ enough */
70
71    m.a[0][0] = m.a[1][1] = 1;
72    m.a[0][1] = m.a[1][0] = 0;
73    m.b[0] = m.b[1] = 0;
74
75    sprintf(tmp, "%s-top.pgm", name);
76    height_field(tmp, s->a, &m);
77    sprintf(tmp, "%s-bot.pgm", name);
78    height_field(tmp, s->b, &m);
79
80    /*
81     * 1/65535 = 0.000015..., so we set the water level a bit lower, e.g.,
82     * to 0.0001
83     */
84    sanitize(name, tmp);
85    printf(
86"#declare Part_%s =\n"
87" intersection {\n"
88" height_field { pgm \"%s-top.pgm\" water_level 0.00001 smooth }\n"
89" height_field { pgm \"%s-bot.pgm\" water_level 0.00001 smooth }\n"
90" }\n", tmp, name, name);
91}
92

Archive Download this file

Branches:
master



interactive