BRL-CAD
sh_stxt.c
Go to the documentation of this file.
1 /* S H _ S T X T . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1986-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 liboptical/sh_stxt.c
21  *
22  * Routines to implement solid (i.e., 3-D) texture maps.
23  *
24  * XXX Solid texturing is still preliminary.
25  *
26  */
27 
28 #include "common.h"
29 
30 #include <stddef.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <math.h>
34 
35 #include "vmath.h"
36 #include "raytrace.h"
37 #include "optical.h"
38 
39 
40 HIDDEN int stxt_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip);
41 HIDDEN int brick_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp);
42 HIDDEN int mbound_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp);
43 HIDDEN int rbound_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp);
44 HIDDEN void stxt_print(register struct region *rp, void *dp);
45 HIDDEN void stxt_free(void *cp);
46 
47 /* local sp_hook function */
48 HIDDEN void stxt_transp_hook(const struct bu_structparse *, const char *, void *, const char *, void *);
49 
50 #define STX_NAME_LEN 128
51 struct stxt_specific {
52  int stx_transp[3]; /* RGB for transparency */
53  char stx_file[STX_NAME_LEN]; /* Filename */
54  uint32_t stx_magic;
55  int stx_w; /* Width of texture in pixels */
56  int stx_fw; /* File width of texture in pixels */
57  int stx_n; /* Number of scanlines */
58  int stx_d; /* Depth of texture (Num pix files)*/
59  vect_t stx_min;
60  vect_t stx_max;
61  char *stx_pixels; /* Pixel holding area */
62  int trans_valid; /* boolean: has stx_transp been set? */
63 };
64 #define STXT_MAGIC 0xfeedbaad
65 #define SOL_NULL ((struct stxt_specific *)0)
66 #define SOL_O(m) bu_offsetof(struct stxt_specific, m)
67 
69  {"%d", 1, "transp", SOL_O(stx_transp), stxt_transp_hook, NULL, NULL },
70  {"%s", STX_NAME_LEN, "file", SOL_O(stx_file), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
71  {"%d", 1, "w", SOL_O(stx_w), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
72  {"%d", 1, "n", SOL_O(stx_n), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
73  {"%d", 1, "d", SOL_O(stx_d), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
74  {"%d", 1, "fw", SOL_O(stx_fw), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
75  {"%d", 1, "trans_valid", SOL_O(trans_valid), BU_STRUCTPARSE_FUNC_NULL, NULL, NULL },
76  {"", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL }
77 };
78 
79 
80 struct mfuncs stxt_mfuncs[] = {
81  {MF_MAGIC, "brick", 0, MFI_HIT, 0, stxt_setup, brick_render, stxt_print, stxt_free },
82  {MF_MAGIC, "mbound", 0, MFI_HIT, 0, stxt_setup, mbound_render, stxt_print, stxt_free },
83  {MF_MAGIC, "rbound", 0, MFI_HIT, 0, stxt_setup, rbound_render, stxt_print, stxt_free },
84  {0, (char *)0, 0, 0, 0, 0, 0, 0, 0 }
85 };
86 
87 
88 /*
89  * Hooked function, called by bu_structparse.
90  */
91 HIDDEN void
92 stxt_transp_hook(const struct bu_structparse *ptab,
93  const char *name,
94  void *cp,
95  const char *UNUSED(value),
96  void *UNUSED(data))
97 {
98  register struct stxt_specific *stp =
99  (struct stxt_specific *)cp;
100 
101  if (BU_STR_EQUAL(name, stxt_parse[0].sp_name) && ptab == stxt_parse) {
102  stp->trans_valid = 1;
103  } else {
104  bu_log("file:%s, line:%d stxt_transp_hook name:(%s) instead of (%s)\n",
105  __FILE__, __LINE__, name, stxt_parse[0].sp_name);
106  }
107 }
108 
109 
110 /*
111  * Load the texture into memory.
112  * Returns 0 on failure, 1 on success.
113  */
114 HIDDEN int
115 stxt_read(register struct stxt_specific *stp)
116 {
117  char *linebuf;
118  register FILE *fp;
119  register int i;
120  char name[256];
121  int frame, ln;
122  int rd, rdd;
123 
124  /*** MEMORY HOG ***/
125  stp->stx_pixels = (char *)bu_malloc(
126  stp->stx_w * stp->stx_n * stp->stx_d * 3,
127  stp->stx_file);
128 
129  ln = 0;
130  rdd = 0;
131  rd = 0;
132 
133  /* LOOP: through list of basename.n files */
134  for (frame = 0; frame <= stp->stx_d-1; frame++) {
135 
136  snprintf(name, 256, "%s.%d", stp->stx_file, frame);
137 
138  if ((fp = fopen(name, "rb")) == NULL) {
139  bu_log("stxt_read(%s): can't open\n", name);
140  stp->stx_file[0] = '\0';
141  return 0;
142  }
143  linebuf = (char *)bu_malloc(stp->stx_fw*3, "texture file line");
144 
145  for (i = 0; i < stp->stx_n; i++) {
146  if ((rd = (int)fread(linebuf, 1, stp->stx_fw*3, fp)) != stp->stx_fw*3) {
147  bu_log("stxt_read: read error on %s\n", name);
148  stp->stx_file[0] = '\0';
149  (void)fclose(fp);
150  bu_free(linebuf, "file line, error");
151  return 0;
152  }
153  memcpy(stp->stx_pixels + ln*stp->stx_w*3, linebuf, stp->stx_w*3);
154  ln++;
155  rdd += rd;
156  }
157  (void)fclose(fp);
158  bu_free(linebuf, "texture file line");
159  }
160  return 1; /* OK */
161 }
162 
163 
164 HIDDEN int
165 stxt_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *UNUSED(mfp), struct rt_i *UNUSED(rtip))
166 /* New since 4.4 release */
167 {
168  register struct stxt_specific *stp;
169 
170  BU_GET(stp, struct stxt_specific);
171  *dpp = stp;
172 
173  /** Set up defaults **/
174  stp->stx_magic = STXT_MAGIC;
175  stp->stx_file[0] = '\0';
176  stp->stx_w = stp->stx_fw = stp->stx_n = stp->stx_d = -1;
177 
178  if (rt_bound_tree(rp->reg_treetop, stp->stx_min, stp->stx_max) < 0)
179  return -1;
180 
181  /** Get input values **/
182  if (bu_struct_parse(matparm, stxt_parse, (char *)stp, NULL) < 0) {
183  BU_PUT(stp, struct stxt_specific);
184  return -1;
185  }
186  /*** DEFAULT SIZE OF STXT FILES ***/
187  if (stp->stx_w < 0) stp->stx_w = 512;
188  if (stp->stx_n < 0) stp->stx_n = stp->stx_w;
189 
190  /** Defaults to an orthogonal projection?? **/
191  if (stp->stx_d < 0) stp->stx_d = 1;
192 
193  if (stp->stx_fw < 0) stp->stx_fw = stp->stx_w;
194  stp->stx_pixels = (char *)0;
195  if (stp->trans_valid)
196  rp->reg_transmit = 1;
197 
198  /** Read in texture file/s **/
199  return stxt_read(stp);
200 }
201 
202 
203 HIDDEN void
204 stxt_free(void *cp)
205 {
206  register struct stxt_specific *stp =
207  (struct stxt_specific *)cp;
208 
209  if (stp->stx_magic != STXT_MAGIC) bu_log("stxt_free(): bad magic\n");
210 
211  if (stp->stx_pixels)
212  bu_free(stp->stx_pixels, "solid texture pixel array");
213  BU_PUT(cp, struct stxt_specific);
214 }
215 
216 
217 HIDDEN void
218 stxt_print(register struct region *rp, void *dp)
219 {
220  bu_struct_print(rp->reg_name, stxt_parse, (char *)dp);
221 }
222 
223 
224 HIDDEN int
225 brick_render(struct application *UNUSED(ap), const struct partition *UNUSED(pp), struct shadework *swp, void *dp)
226 {
227  register struct stxt_specific *stp =
228  (struct stxt_specific *)dp;
229  vect_t lx, ly, lz; /* local coordinate axis */
230  fastf_t f;
231  double iptr;
232  fastf_t sx, sy, sz;
233  int tx, ty, tz;
234  register long r, g, b;
235  int u1, u2, u3;
236  register unsigned char *cp;
237 
238  if (stp->stx_magic != STXT_MAGIC) bu_log("brick_render(): bad magic\n");
239 
240  /*
241  * If no texture file present, or if
242  * texture isn't and can't be read, give debug colors
243  */
244  if (stp->stx_file[0] == '\0' ||
245  (stp->stx_pixels == (char *)0 && stxt_read(stp) == 0)) {
246  VSET(swp->sw_color, 1, 0, 1);
247  return 1;
248  }
249 
250  /** Local Coordinate Axis **/
251  VSET(lx, 1, 0, 0);
252  VSET(ly, 0, 1, 0);
253  VSET(lz, 0, 0, 1);
254 
255  f = VDOT(swp->sw_hit.hit_point, lx) / (float)stp->stx_w;
256  if (f < 0) f = -f;
257  f = modf(f, &iptr);
258  sx=f;
259 /********************************
260  * if (f < 0.5)
261  * sx = 2 * f;
262  * else
263  * sx = 2 * (1 - f);
264  *********************************/
265 
266  f = VDOT(swp->sw_hit.hit_point, ly) / (float)stp->stx_n;
267  if (f < 0) f = -f;
268  f = modf(f, &iptr);
269  sy=f;
270 /*********************************
271  * if (f < 0.5)
272  * sy = 2 * f;
273  * else
274  * sy = 2 * (1 - f);
275  **********************************/
276 
277  f = VDOT(swp->sw_hit.hit_point, lz) / (float)stp->stx_d;
278  if (f < 0) f = -f;
279  f = modf(f, &iptr);
280  sz=f;
281 /*********************************
282  * if (f < 0.5)
283  * sz = 2 * f;
284  * else
285  * sz = 2 * (1 - f);
286  **********************************/
287 
288 /*bu_log("sx = %f\tsy = %f\tsz = %f\n", sx, sy, sz);*/
289 
290  /* Index into TEXTURE SPACE */
291  tx = sx * (stp->stx_w-1);
292  ty = sy * (stp->stx_n-1);
293  tz = sz * (stp->stx_d-1);
294 
295  u1 = (int)tz * stp->stx_n * stp->stx_w * 3.0;
296  u2 = (int)ty * stp->stx_w * 3.0;
297  u3 = (int)tx * 3.0;
298 
299  cp = (unsigned char *)(stp->stx_pixels + u1 + u2 + u3);
300 
301  r = *cp++;
302  g = *cp++;
303  b = *cp++;
304 
305  VSET(swp->sw_color,
306  (r+0.5) / 255.0,
307  (g+0.5) / 255.0,
308  (b+0.5) / 255.0);
309 
310  return 1;
311 }
312 
313 
314 /*
315  * Use region RPP to bound solid texture (rbound).
316  */
317 HIDDEN int
318 rbound_render(struct application *UNUSED(ap), const struct partition *UNUSED(pp), struct shadework *swp, void *dp)
319 {
320  register struct stxt_specific *stp =
321  (struct stxt_specific *)dp;
322  fastf_t sx, sy, sz;
323  int tx, ty, tz;
324  register long r, g, b;
325 
326  int u1, u2, u3;
327  register unsigned char *cp;
328 
329  if (stp->stx_magic != STXT_MAGIC) bu_log("rbound_render(): bad magic\n");
330 
331  /*
332  * If no texture file present, or if
333  * texture isn't and can't be read, give debug colors
334  */
335  if (stp->stx_file[0] == '\0' ||
336  (stp->stx_pixels == (char *)0 && stxt_read(stp) == 0)) {
337  VSET(swp->sw_color, 1, 0, 1);
338  return 1;
339  }
340 
341  /* NORMALIZE x, y, z to [0..1) */
342 #if 1
343  /* XXX hack hack, permute axes, for vertical letters. -M */
344  sz = (swp->sw_hit.hit_point[0] - stp->stx_min[0]) /
345  (stp->stx_max[0] - stp->stx_min[0] + 1.0);
346  sx = (swp->sw_hit.hit_point[1] - stp->stx_min[1]) /
347  (stp->stx_max[1] - stp->stx_min[1] + 1.0);
348  sy = (swp->sw_hit.hit_point[2] - stp->stx_min[2]) /
349  (stp->stx_max[2] - stp->stx_min[2] + 1.0);
350 #else
351  sx = (swp->sw_hit.hit_point[0] - stp->stx_min[0]) /
352  (stp->stx_max[0] - stp->stx_min[0] + 1.0);
353  sy = (swp->sw_hit.hit_point[1] - stp->stx_min[1]) /
354  (stp->stx_max[1] - stp->stx_min[1] + 1.0);
355  sz = (swp->sw_hit.hit_point[2] - stp->stx_min[2]) /
356  (stp->stx_max[2] - stp->stx_min[2] + 1.0);
357 #endif
358 
359  /* Index into TEXTURE SPACE */
360  tx = sx * (stp->stx_w-1);
361  ty = sy * (stp->stx_n-1);
362  tz = sz * (stp->stx_d-1);
363 
364  u1 = (int)tz * stp->stx_n * stp->stx_w * 3.0;
365  u2 = (int)ty * stp->stx_w * 3.0;
366  u3 = (int)tx * 3.0;
367 
368  cp = (unsigned char *)(stp->stx_pixels + u1 + u2 + u3);
369 
370  r = *cp++;
371  g = *cp++;
372  b = *cp++;
373 
374  VSET(swp->sw_color,
375  (r+0.5) / 255.0,
376  (g+0.5) / 255.0,
377  (b+0.5) / 255.0);
378 
379  return 1;
380 }
381 
382 
383 /*
384  * Use model RPP as solid texture bounds. (mbound).
385  */
386 HIDDEN int
387 mbound_render(struct application *ap, const struct partition *UNUSED(pp), struct shadework *swp, void *dp)
388 {
389  register struct stxt_specific *stp =
390  (struct stxt_specific *)dp;
391  fastf_t sx, sy, sz;
392  int tx, ty, tz;
393  register long r, g, b;
394  int u1, u2, u3;
395  register unsigned char *cp;
396 
397  if (stp->stx_magic != STXT_MAGIC) bu_log("mbound_render(): bad magic\n");
398 
399  /*
400  * If no texture file present, or if
401  * texture isn't and can't be read, give debug colors
402  */
403  if (stp->stx_file[0] == '\0' ||
404  (stp->stx_pixels == (char *)0 && stxt_read(stp) == 0)) {
405  VSET(swp->sw_color, 1, 0, 1);
406  return 1;
407  }
408 
409  /* NORMALIZE x, y, z to [0..1) */
410  sx = (swp->sw_hit.hit_point[0] - ap->a_rt_i->mdl_min[0]) /
411  (ap->a_rt_i->mdl_max[0] - ap->a_rt_i->mdl_min[0] + 1.0);
412  sy = (swp->sw_hit.hit_point[1] - ap->a_rt_i->mdl_min[1]) /
413  (ap->a_rt_i->mdl_max[1] - ap->a_rt_i->mdl_min[1] + 1.0);
414  sz = (swp->sw_hit.hit_point[2] - ap->a_rt_i->mdl_min[2]) /
415  (ap->a_rt_i->mdl_max[2] - ap->a_rt_i->mdl_min[2] + 1.0);
416 
417  /* Index into TEXTURE SPACE */
418  tx = sx * (stp->stx_w-1);
419  ty = sy * (stp->stx_n-1);
420  tz = sz * (stp->stx_d-1);
421 
422  u1 = (int)tz * stp->stx_n * stp->stx_w * 3;
423  u2 = (int)ty * stp->stx_w * 3;
424  u3 = (int)tx * 3;
425 
426  cp = (unsigned char *)(stp->stx_pixels + u1 + u2 + u3);
427 
428  r = *cp++;
429  g = *cp++;
430  b = *cp++;
431 
432  VSET(swp->sw_color,
433  (r+0.5) / 255.0,
434  (g+0.5) / 255.0,
435  (b+0.5) / 255.0);
436 
437  return 1;
438 }
439 
440 
441 /*
442  * Local Variables:
443  * mode: C
444  * tab-width: 8
445  * indent-tabs-mode: t
446  * c-file-style: "stroustrup"
447  * End:
448  * ex: shiftwidth=4 tabstop=8
449  */
struct mfuncs * mfuncs[16]
Definition: sh_stack.c:51
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
HIDDEN int rbound_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
Definition: sh_stxt.c:318
point_t mdl_min
min corner of model bounding RPP
Definition: raytrace.h:1769
#define MF_MAGIC
Definition: magic.h:205
struct mfuncs stxt_mfuncs[]
Definition: sh_stxt.c:80
vect_t stx_min
Definition: sh_stxt.c:59
Definition: clone.c:90
int rt_bound_tree(const union tree *tp, vect_t tree_min, vect_t tree_max)
#define VSET(a, b, c, d)
Definition: color.c:53
char * stx_pixels
Definition: sh_stxt.c:61
HIDDEN int brick_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
Definition: sh_stxt.c:225
Header file for the BRL-CAD common definitions.
const char * reg_name
Identifying string.
Definition: raytrace.h:539
#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
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
if(share_geom)
Definition: nmg_mod.c:3829
COMPLEX data[64]
Definition: fftest.c:34
struct rt_i * a_rt_i
this librt instance
Definition: raytrace.h:1588
#define SOL_O(m)
Definition: sh_stxt.c:66
char stx_file[STX_NAME_LEN]
Definition: sh_stxt.c:53
#define BU_GET(_ptr, _type)
Definition: malloc.h:201
int reg_transmit
flag: material transmits light
Definition: raytrace.h:549
vect_t stx_max
Definition: sh_stxt.c:60
int stx_fw
Definition: sh_stxt.c:56
#define UNUSED(parameter)
Definition: common.h:239
#define BU_PUT(_ptr, _type)
Definition: malloc.h:215
HIDDEN void stxt_transp_hook(const struct bu_structparse *, const char *, void *, const char *, void *)
Definition: sh_stxt.c:92
#define BU_STRUCTPARSE_FUNC_NULL
Definition: parse.h:153
HIDDEN void stxt_free(void *cp)
Definition: sh_stxt.c:204
uint32_t stx_magic
Definition: sh_stxt.c:54
#define STXT_MAGIC
Definition: sh_stxt.c:64
struct bu_structparse stxt_parse[]
Definition: sh_stxt.c:68
#define STX_NAME_LEN
Definition: sh_stxt.c:50
HIDDEN int mbound_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
Definition: sh_stxt.c:387
int trans_valid
Definition: sh_stxt.c:62
point_t mdl_max
max corner of model bounding RPP
Definition: raytrace.h:1770
int bu_struct_parse(const struct bu_vls *in_vls, const struct bu_structparse *desc, const char *base, void *data)
Definition: parse.c:878
union tree * reg_treetop
Pointer to boolean tree.
Definition: raytrace.h:540
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
HIDDEN void stxt_print(register struct region *rp, void *dp)
Definition: sh_stxt.c:218
HIDDEN int stxt_read(register struct stxt_specific *stp)
Definition: sh_stxt.c:115
Definition: vls.h:56
double fastf_t
Definition: defines.h:300
Header file for the BRL-CAD Optical Library, LIBOPTICAL.
int stx_transp[3]
Definition: sh_stxt.c:52
HIDDEN int stxt_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip)
Definition: sh_stxt.c:165
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126