BRL-CAD
sh_temp.c
Go to the documentation of this file.
1 /* S H _ T E M P . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1999-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 /** @file libmultispectral/sh_temp.c
21  *
22  * Temperature map lookup.
23  * Based upon liboptical/sh_text.c
24  *
25  */
26 
27 #include "common.h"
28 
29 #include <stddef.h>
30 #include <stdio.h>
31 #include <ctype.h>
32 
33 #include "bu/cv.h"
34 #include "vmath.h"
35 #include "raytrace.h"
36 #include "optical.h"
37 
38 
39 extern struct region env_region; /* import from view.c */
40 
41 HIDDEN int temp_setup(register struct region *rp, struct bu_vls *matparm, void **dp, const struct mfuncs *mfp, struct rt_i *rtip);
42 HIDDEN int temp_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp);
43 HIDDEN void temp_print(register struct region *rp, void *dp);
44 HIDDEN void temp_free(void *cp);
45 
46 extern int mlib_zero();
47 extern int mlib_one();
48 extern void mlib_void();
49 
50 struct mfuncs temp_mfuncs[] = {
51  {MF_MAGIC, "temp", 0, MFI_UV, 0, temp_setup, temp_render, temp_print, temp_free },
52  {0, (char *)0, 0, 0, 0, 0, 0, 0, 0 }
53 };
54 
55 
56 #define TXT_NAME_LEN 128
57 struct temp_specific {
58  char t_file[TXT_NAME_LEN]; /* Filename */
59  int t_w; /* Width of texture in pixels */
60  int t_n; /* Number of scanlines */
61  struct bu_mapped_file *mp;
62 };
63 #define TX_NULL ((struct temp_specific *)0)
64 #define TX_O(m) bu_offsetof(struct temp_specific, m)
65 
67  {"%s", TXT_NAME_LEN, "file", TX_O(t_file), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
68  {"%d", 1, "w", TX_O(t_w), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
69  {"%d", 1, "n", TX_O(t_n), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
70  {"%d", 1, "l", TX_O(t_n), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL }, /*compat*/
71  {"", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL }
72 };
73 
74 
75 /*
76  * Given a u, v coordinate within the texture (0 <= u, v <= 1.0),
77  * return a pointer to the relevant pixel.
78  *
79  * Note that .pix files are stored left-to-right, bottom-to-top,
80  * which works out very naturally for the indexing scheme.
81  */
82 HIDDEN int
83 temp_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
84 {
85  register struct temp_specific *tp =
86  (struct temp_specific *)dp;
87  fastf_t xmin, xmax, ymin, ymax;
88  int dx, dy;
89  register fastf_t temp = 0;
90 
91  if (rdebug & RDEBUG_SHADE)
92  bu_log("in temp_render(): du=%g, dv=%g\n", swp->sw_uv.uv_du, swp->sw_uv.uv_dv);
93  /*
94  * If no texture file present, or if
95  * texture isn't and can't be read, give debug colors
96  * Set temp in degK to be the sum of the X&Y screen coordinates.
97  */
98  if (tp->t_file[0] == '\0' || !tp->mp) {
99  swp->sw_temperature = ap->a_x + ap->a_y;
100  if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
101  (void)rr_render(ap, pp, swp);
102  return 1;
103  }
104 
105  /* u is left->right index, v is line number bottom->top */
106  /* Don't filter more than 1/8 of the texture for 1 pixel! */
107  if (swp->sw_uv.uv_du > 0.125) swp->sw_uv.uv_du = 0.125;
108  if (swp->sw_uv.uv_dv > 0.125) swp->sw_uv.uv_dv = 0.125;
109 
110  if (swp->sw_uv.uv_du < 0 || swp->sw_uv.uv_dv < 0) {
111  bu_log("temp_render uv=%g, %g, du dv=%g %g seg=%s\n",
112  swp->sw_uv.uv_u, swp->sw_uv.uv_v, swp->sw_uv.uv_du, swp->sw_uv.uv_dv,
113  pp->pt_inseg->seg_stp->st_name);
114  swp->sw_uv.uv_du = swp->sw_uv.uv_dv = 0;
115  }
116 
117  xmin = swp->sw_uv.uv_u - swp->sw_uv.uv_du;
118  xmax = swp->sw_uv.uv_u + swp->sw_uv.uv_du;
119  ymin = swp->sw_uv.uv_v - swp->sw_uv.uv_dv;
120  ymax = swp->sw_uv.uv_v + swp->sw_uv.uv_dv;
121  if (xmin < 0) xmin = 0;
122  if (ymin < 0) ymin = 0;
123  if (xmax > 1) xmax = 1;
124  if (ymax > 1) ymax = 1;
125 
126  if (rdebug & RDEBUG_SHADE)
127  bu_log("footprint in texture space is (%g %g) <-> (%g %g)\n",
128  xmin * (tp->t_w-1), ymin * (tp->t_n-1),
129  xmax * (tp->t_w-1), ymax * (tp->t_n-1));
130 
131  dx = (int)(xmax * (tp->t_w-1)) - (int)(xmin * (tp->t_w-1));
132  dy = (int)(ymax * (tp->t_n-1)) - (int)(ymin * (tp->t_n-1));
133 
134  if (rdebug & RDEBUG_SHADE)
135  bu_log("\tdx = %d, dy = %d\n", dx, dy);
136  if (dx == 0 && dy == 0) {
137  /* No averaging necessary */
138 
139  register unsigned char *cp;
140  double ttemp;
141 
142  cp = ((unsigned char *)(tp->mp->buf)) +
143  (int)(ymin * (tp->t_n-1)) * tp->t_w * 8 +
144  (int)(xmin * (tp->t_w-1)) * 8;
145  bu_cv_ntohd((unsigned char *)&ttemp, cp, 1);
146  temp += ttemp;
147  } else {
148  /* Calculate weighted average of cells in footprint */
149 
150  fastf_t tot_area=0.0;
151  fastf_t cell_area;
152  int start_line, stop_line, line;
153  int start_col, stop_col, col;
154  fastf_t xstart, xstop, ystart, ystop;
155 
156  xstart = xmin * (tp->t_w-1);
157  xstop = xmax * (tp->t_w-1);
158  ystart = ymin * (tp->t_n-1);
159  ystop = ymax * (tp->t_n-1);
160 
161  start_line = ystart;
162  stop_line = ystop;
163  start_col = xstart;
164  stop_col = xstop;
165 
166  if (rdebug & RDEBUG_SHADE) {
167  bu_log("\thit in texture space = (%g %g)\n", swp->sw_uv.uv_u * (tp->t_w-1), swp->sw_uv.uv_v * (tp->t_n-1));
168  bu_log("\t averaging from (%g %g) to (%g %g)\n", xstart, ystart, xstop, ystop);
169  bu_log("\tcontributions to average:\n");
170  }
171 
172  for (line = start_line; line <= stop_line; line++) {
173  register unsigned char *cp;
174  fastf_t line_factor;
175  fastf_t line_upper, line_lower;
176 
177  line_upper = line + 1.0;
178  if (line_upper > ystop)
179  line_upper = ystop;
180  line_lower = line;
181  if (line_lower < ystart)
182  line_lower = ystart;
183  line_factor = line_upper - line_lower;
184  cp = ((unsigned char *)(tp->mp->buf)) +
185  line * tp->t_w * 8 + (int)(xstart) * 8;
186 
187  for (col = start_col; col <= stop_col; col++) {
188  fastf_t col_upper, col_lower;
189  double ttemp;
190 
191  col_upper = col + 1.0;
192  if (col_upper > xstop)
193  col_upper = xstop;
194  col_lower = col;
195  if (col_lower < xstart)
196  col_lower = xstart;
197  cell_area = line_factor * (col_upper - col_lower);
198  tot_area += cell_area;
199 
200  bu_cv_ntohd((unsigned char *)&ttemp, cp, 1);
201 
202  if (rdebug & RDEBUG_SHADE)
203  bu_log("\t %g weight=%g (from col=%d line=%d)\n",
204  ttemp,
205  cell_area, col, line);
206 
207  temp += ttemp * cell_area;
208  }
209  }
210  temp /= tot_area;
211  }
212 
213  if (rdebug & RDEBUG_SHADE)
214  bu_log(" average temp: %g\n", temp);
215 
216  swp->sw_temperature = temp;
217 
218  if (swp->sw_reflect > 0 || swp->sw_transmit > 0)
219  (void)rr_render(ap, pp, swp);
220  return 1;
221 }
222 
223 
224 HIDDEN int
225 temp_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *UNUSED(rtip))
226 
227 
228 /* New since 4.4 release */
229 {
230  register struct temp_specific *tp;
231  size_t pixelbytes = 8;
232 
233  BU_CK_VLS(matparm);
234  BU_GET(tp, struct temp_specific);
235  *dpp = tp;
236 
237  tp->t_file[0] = '\0';
238  tp->t_w = tp->t_n = -1;
239  if (bu_struct_parse(matparm, temp_parse, (char *)tp, NULL) < 0) {
240  BU_PUT(tp, struct temp_specific);
241  return -1;
242  }
243  if (tp->t_w < 0) tp->t_w = 512;
244  if (tp->t_n < 0) tp->t_n = tp->t_w;
245 
246  if (tp->t_file[0] == '\0') return -1; /* FAIL, no file */
247  if (!(tp->mp = bu_open_mapped_file(tp->t_file, NULL)))
248  return -1; /* FAIL */
249 
250  /* Ensure file is large enough */
251  if (tp->mp->buflen < tp->t_w * tp->t_n * pixelbytes) {
252  bu_log("\ntemp_setup() ERROR %s %s needs %zu bytes, '%s' only has %zu\n",
253  rp->reg_name,
254  mfp->mf_name,
255  tp->t_w * tp->t_n * pixelbytes,
256  tp->mp->name,
257  tp->mp->buflen);
258  return -1; /* FAIL */
259  }
260 
261  return 1; /* OK */
262 }
263 
264 
265 HIDDEN void
266 temp_print(register struct region *rp, void *UNUSED(dp))
267 {
268  bu_struct_print(rp->reg_name, temp_parse, (char *)rp->reg_udata);
269 }
270 
271 
272 HIDDEN void
273 temp_free(void *cp)
274 {
275  struct temp_specific *tp =
276  (struct temp_specific *)cp;
277 
278  if (tp->mp)
280  BU_PUT(cp, struct temp_specific);
281 }
282 
283 
284 /*
285  * Local Variables:
286  * mode: C
287  * tab-width: 8
288  * indent-tabs-mode: t
289  * c-file-style: "stroustrup"
290  * End:
291  * ex: shiftwidth=4 tabstop=8
292  */
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
int mlib_zero()
#define MF_MAGIC
Definition: magic.h:205
struct soltab * seg_stp
pointer back to soltab
Definition: raytrace.h:372
Header file for the BRL-CAD common definitions.
int mlib_one()
const char * reg_name
Identifying string.
Definition: raytrace.h:539
struct region env_region
Definition: init.c:50
#define HIDDEN
Definition: common.h:86
void bu_struct_print(const char *title, const struct bu_structparse *parsetab, const char *base)
Definition: parse.c:1221
HIDDEN int temp_setup(register struct region *rp, struct bu_vls *matparm, void **dp, const struct mfuncs *mfp, struct rt_i *rtip)
Definition: sh_temp.c:225
#define BU_CK_VLS(_vp)
Definition: vls.h:69
#define TX_O(m)
Definition: sh_temp.c:64
struct bu_mapped_file * mp
Definition: sh_temp.c:61
void mlib_void()
int a_x
Screen X of ray, if applicable.
Definition: raytrace.h:1596
#define BU_GET(_ptr, _type)
Definition: malloc.h:201
struct seg * pt_inseg
IN seg ptr (gives stp)
Definition: raytrace.h:576
#define UNUSED(parameter)
Definition: common.h:239
#define BU_PUT(_ptr, _type)
Definition: malloc.h:215
struct bu_mapped_file * bu_open_mapped_file(const char *name, const char *appl)
Definition: mappedfile.c:56
char t_file[TXT_NAME_LEN]
Definition: sh_temp.c:58
#define BU_STRUCTPARSE_FUNC_NULL
Definition: parse.h:153
HIDDEN void temp_free(void *cp)
Definition: sh_temp.c:273
struct bu_structparse temp_parse[]
Definition: sh_temp.c:66
struct mfuncs temp_mfuncs[]
Definition: sh_temp.c:50
void bu_cv_ntohd(unsigned char *out, const unsigned char *in, size_t count)
#define RDEBUG_SHADE
Definition: optical.h:130
int bu_struct_parse(const struct bu_vls *in_vls, const struct bu_structparse *desc, const char *base, void *data)
Definition: parse.c:878
int a_y
Screen Y of ray, if applicable.
Definition: raytrace.h:1597
void bu_close_mapped_file(struct bu_mapped_file *mp)
Definition: mappedfile.c:339
#define TXT_NAME_LEN
Definition: sh_temp.c:56
int rr_render(struct application *app, const struct partition *pp, struct shadework *swp)
void * reg_udata
User appl. data for material.
Definition: raytrace.h:548
Definition: vls.h:56
HIDDEN void temp_print(register struct region *rp, void *dp)
Definition: sh_temp.c:266
double fastf_t
Definition: defines.h:300
Header file for the BRL-CAD Optical Library, LIBOPTICAL.
int rdebug
Definition: init.c:39
HIDDEN int temp_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
Definition: sh_temp.c:83