BRL-CAD
sh_stack.c
Go to the documentation of this file.
1 /* S H _ S T A C K . 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_stack.c
21  *
22  * Stack multiple material modules together
23  *
24  */
25 
26 #include "common.h"
27 
28 #include <stddef.h>
29 #include <stdio.h>
30 #include <string.h>
31 
32 #include "vmath.h"
33 #include "raytrace.h"
34 #include "optical.h"
35 
36 
37 HIDDEN int sh_stk_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mf_p, struct rt_i *rtip);
38 HIDDEN int sh_stk_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp);
39 HIDDEN void sh_stk_print(register struct region *rp, void *dp);
40 HIDDEN void sh_stk_free(void *cp);
41 HIDDEN int ext_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mf_p, struct rt_i *rtip);
42 
43 struct mfuncs stk_mfuncs[] = {
45  {MF_MAGIC, "extern", 0, 0, 0, ext_setup, sh_stk_render, sh_stk_print, sh_stk_free},
46  {0, (char *)0, 0, 0, 0, 0, 0, 0, 0}
47 };
48 
49 
50 struct stk_specific {
51  struct mfuncs *mfuncs[16];
52  void *udata[16];
53 };
54 #define STK_NULL ((struct stk_specific *)0)
55 #define STK_O(m) bu_offsetof(struct stk_specific, m)
56 
58  {"", 0, (char *)0, 0, BU_STRUCTPARSE_FUNC_NULL, NULL, NULL }
59 };
60 
61 
62 /*
63  * Returns 0 on failure, 1 on success.
64  */
65 HIDDEN int
66 ext_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mf_p, struct rt_i *rtip)
67 
68 /* parameter string */
69 /* pointer to user data pointer */
70 
71 
72 {
73  struct bu_mapped_file *parameter_file;
74  struct bu_vls parameter_data = BU_VLS_INIT_ZERO;
75  char *filename;
76  int status;
77 
78  RT_CHECK_RTI(rtip);
79  BU_CK_VLS(matparm);
80  RT_CK_REGION(rp);
81 
82  filename = bu_vls_addr(matparm);
83  parameter_file = bu_open_mapped_file(filename, (char *)NULL);
84  if (!parameter_file) {
85  bu_log("cannot open external shader file \"%s\"\n", filename);
86  bu_bomb("ext_setup()\n");
87  }
88 
89  bu_vls_strncpy(&parameter_data, (char *)parameter_file->buf,
90  parameter_file->buflen);
91 
92  if (rdebug&RDEBUG_SHADE) {
93  bu_log("ext_setup(%s): {%s}\n",
94  filename, bu_vls_addr(&parameter_data));
95  }
96 
97  bu_close_mapped_file(parameter_file);
98 
99  status = sh_stk_setup(rp, &parameter_data, dpp, mf_p, rtip);
100 
101  bu_vls_free(&parameter_data);
102 
103  return status;
104 }
105 
106 
107 HIDDEN int
108 sh_stk_dosetup(char *cp, struct region *rp, void **dpp, struct mfuncs **mpp, struct rt_i *rtip)
109 
110 
111 /* udata pointer address */
112 /* mfuncs pointer address */
113 
114 
115 {
116  register struct mfuncs *mfp;
117  register struct mfuncs *mfp_new;
118  struct bu_vls arg = BU_VLS_INIT_ZERO;
119  char matname[32];
120  int ret;
121  int i;
122  struct mfuncs *shaders = MF_NULL;
123 
124  RT_CK_RTI(rtip);
125 
127  bu_log("...starting \"%s\"\n", cp);
128 
129  /* skip leading white space */
130  while (*cp == ' ' || *cp == '\t')
131  cp++;
132 
133  for (i = 0; i < 31 && *cp != '\0'; i++, cp++) {
134  if (*cp == ' ' || *cp == '\t') {
135  matname[i++] = '\0';
136  break;
137  } else
138  matname[i] = *cp;
139  }
140  matname[i] = '\0'; /* ensure null termination */
141 
142 retry:
143  /* get list of available shaders */
144  if (!shaders) {
145  optical_shader_init(&shaders);
146  }
147 
148  for (mfp = shaders; mfp && mfp->mf_name != NULL; mfp = mfp->mf_forw) {
149  if (matname[0] != mfp->mf_name[0] ||
150  !BU_STR_EQUAL(matname, mfp->mf_name))
151  continue;
152  goto found;
153  }
154 
155  /* If we get here, then the shader wasn't found in the list of
156  * compiled-in (or previously loaded) shaders. See if we can
157  * dynamically load it.
158  */
159 
160  bu_log("Shader \"%s\"... ", matname);
161 
162  if ((mfp_new = load_dynamic_shader(matname))) {
163  mlib_add_shader(&shaders, mfp_new);
164  goto retry;
165  }
166 
167  bu_log("stack_setup(%s): material not known\n",
168  matname);
169  ret = -1;
170  goto out;
171 
172 found:
173  *mpp = mfp;
174  *dpp = (char *)0;
175  if (*cp != '\0')
176  bu_vls_strcat(&arg, ++cp);
177  if (rdebug&RDEBUG_MATERIAL)
178  bu_log("calling %s with %s\n", mfp->mf_name, bu_vls_addr(&arg));
179  if (!mfp || !mfp->mf_setup || mfp->mf_setup(rp, &arg, dpp, mfp, rtip) < 0) {
180  /* Setup has failed */
181  bu_vls_free(&arg);
182  ret = -1; /* BAD */
183  goto out;
184  }
185  bu_vls_free(&arg);
186  ret = 0; /* OK */
187 out:
188  if (rdebug&RDEBUG_MATERIAL)
189  bu_log("...finished \"%s\", ret=%d\n", matname, ret);
190  return ret;
191 }
192 
193 
194 /*
195  * Returns 0 on failure, 1 on success.
196  */
197 HIDDEN int
198 sh_stk_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *UNUSED(mf_p), struct rt_i *rtip)
199 
200 /* parameter string */
201 /* pointer to user data pointer */
202 
203 
204 {
205  register struct stk_specific *sp;
206  char *cp, *start;
207  int i;
208  int inputs = 0;
209  struct mfuncs *mfp;
210 
211  BU_CK_VLS(matparm);
212  RT_CK_RTI(rtip);
213 
214  BU_GET(sp, struct stk_specific);
215  *dpp = sp;
216 
217  /*bu_struct_parse(matparm, sh_stk_parse, (char *)sp);*/
218 
220  bu_log("sh_stk_setup called with \"%s\"\n", bu_vls_addr(matparm));
221 
222  i = 0;
223  start = cp = bu_vls_addr(matparm);
224  while (*cp != '\0') {
225  if (*cp == ';') {
226  *cp = '\0';
227  if (i >= 16) {
228  bu_log("sh_stk_setup: max levels exceeded\n");
229  return 0;
230  }
231  /* add one */
232  if (sh_stk_dosetup(start, rp, &sp->udata[i], &sp->mfuncs[i], rtip) == 0) {
233  inputs |= sp->mfuncs[i]->mf_inputs;
234  i++;
235  } else {
236  /* XXX else clear entry? */
237  bu_log("Problem in stack shader setup\n");
238  }
239  start = ++cp;
240  } else {
241  cp++;
242  }
243  }
244  if (start != cp) {
245  if (i >= 16) {
246  bu_log("sh_stk_setup: max levels exceeded\n");
247  return 0;
248  }
249  /* add one */
250  if (sh_stk_dosetup(start, rp, &sp->udata[i], &sp->mfuncs[i], rtip) == 0) {
251  inputs |= sp->mfuncs[i]->mf_inputs;
252  i++;
253  } else {
254  /* XXX else clear entry? */
255  }
256  }
257 
258  /* Request only those input bits needed by subordinate shaders */
259  BU_ALLOC(mfp, struct mfuncs);
260  memcpy((char *)mfp, (char *)rp->reg_mfuncs, sizeof(*mfp));
261  mfp->mf_inputs = inputs;
262  rp->reg_mfuncs = (void *)mfp;
263  return 1;
264 }
265 
266 
267 /*
268  * Evaluate all of the rendering functions in the stack.
269  *
270  * Returns:
271  * 0 stack processing aborted
272  * 1 stack processed to completion
273  */
274 HIDDEN int
275 sh_stk_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
276 {
277  register struct stk_specific *sp =
278  (struct stk_specific *)dp;
279  int i;
280  int ret_status = 0;
281  char tmp[128];
282 
283  if (sp == NULL) {
284  bu_log("sh_stk_render: Null pointer\n");
285  return 0;
286  }
287 
288  for (i = 0; i < 16 && sp->mfuncs[i] != NULL; i++) {
289  if (rdebug&RDEBUG_SHADE) {
290  snprintf(tmp, 128, "before stacked \"%s\" shader", sp->mfuncs[i]->mf_name);
291 
292  pr_shadework(tmp, swp);
293  }
294 
295  /*
296  * Every shader takes the shadework structure as its
297  * input and updates it as the "output".
298  */
299  if (sp && sp->mfuncs[i] && sp->mfuncs[i]->mf_render)
300  ret_status = sp->mfuncs[i]->mf_render(ap, pp, swp, sp->udata[i]);
301  if (ret_status != 1)
302  return 0;
303 
304  }
305  return 1;
306 }
307 
308 
309 HIDDEN void
310 sh_stk_print(register struct region *rp, void *dp)
311 {
312  register struct stk_specific *sp =
313  (struct stk_specific *)dp;
314  int i;
315 
316  if (sp == NULL) {
317  bu_log("sh_stk_print: Null pointer\n");
318  return;
319  }
320 
321  bu_log("~~~~starting stack print\n");
322 
323  for (i = 0; i < 16 && sp->mfuncs[i] != NULL; i++) {
324  bu_log("~~~~stack entry %d:\n", i);
325  if (sp && sp->mfuncs[i] && sp->mfuncs[i]->mf_print) {
326  sp->mfuncs[i]->mf_print(rp, sp->udata[i]);
327  } else {
328  bu_log("WARNING: unexpected NULL print function encountered\n");
329  }
330  }
331 
332  bu_log("~~~~ending stack print\n");
333 }
334 
335 
336 HIDDEN void
337 sh_stk_free(void *cp)
338 {
339  register struct stk_specific *sp =
340  (struct stk_specific *)cp;
341  int i;
342 
343  if (sp == NULL)
344  return;
345 
346  for (i = 0; i < 16 && sp->mfuncs[i] != NULL; i++) {
347  if (sp && sp->mfuncs[i] && sp->mfuncs[i]->mf_free) {
348  sp->mfuncs[i]->mf_free(sp->udata[i]);
349  }
350  }
351 
352  BU_PUT(cp, struct stk_specific);
353 }
354 
355 
356 /*
357  * Local Variables:
358  * mode: C
359  * tab-width: 8
360  * indent-tabs-mode: t
361  * c-file-style: "stroustrup"
362  * End:
363  * ex: shiftwidth=4 tabstop=8
364  */
struct mfuncs * mfuncs[16]
Definition: sh_stack.c:51
char filename[MAXLENGTH]
Definition: human.c:105
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
#define MF_MAGIC
Definition: magic.h:205
#define RT_CK_RTI(_p)
Definition: raytrace.h:1833
void bu_vls_strcat(struct bu_vls *vp, const char *s)
Definition: vls.c:368
void bu_vls_strncpy(struct bu_vls *vp, const char *s, size_t n)
Definition: vls.c:339
HIDDEN int sh_stk_render(struct application *ap, const struct partition *pp, struct shadework *swp, void *dp)
Definition: sh_stack.c:275
Header file for the BRL-CAD common definitions.
HIDDEN void sh_stk_free(void *cp)
Definition: sh_stack.c:337
#define RT_CK_REGION(_p)
Definition: raytrace.h:559
#define HIDDEN
Definition: common.h:86
struct mfuncs * load_dynamic_shader(const char *material)
Definition: material.c:130
void * udata[16]
Definition: sh_stack.c:52
HIDDEN int sh_stk_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mf_p, struct rt_i *rtip)
Definition: sh_stack.c:198
void optical_shader_init(struct mfuncs **headp)
Definition: init.c:61
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
#define BU_CK_VLS(_vp)
Definition: vls.h:69
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
#define RT_CHECK_RTI(_p)
Definition: raytrace.h:1832
#define BU_GET(_ptr, _type)
Definition: malloc.h:201
HIDDEN int sh_stk_dosetup(char *cp, struct region *rp, void **dpp, struct mfuncs **mpp, struct rt_i *rtip)
Definition: sh_stack.c:108
#define UNUSED(parameter)
Definition: common.h:239
#define BU_PUT(_ptr, _type)
Definition: malloc.h:215
goto out
Definition: nmg_mod.c:3846
struct bu_mapped_file * bu_open_mapped_file(const char *name, const char *appl)
Definition: mappedfile.c:56
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
#define BU_STRUCTPARSE_FUNC_NULL
Definition: parse.h:153
void pr_shadework(const char *str, const struct shadework *swp)
Definition: shade.c:52
#define RDEBUG_MATERIAL
Definition: optical.h:127
#define RDEBUG_SHADE
Definition: optical.h:130
void mlib_add_shader(struct mfuncs **headp, struct mfuncs *mfp1)
Definition: material.c:54
void bu_close_mapped_file(struct bu_mapped_file *mp)
Definition: mappedfile.c:339
HIDDEN int ext_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mf_p, struct rt_i *rtip)
Definition: sh_stack.c:66
HIDDEN void sh_stk_print(register struct region *rp, void *dp)
Definition: sh_stack.c:310
struct mfuncs stk_mfuncs[]
Definition: sh_stack.c:43
#define BU_VLS_INIT_ZERO
Definition: vls.h:84
Definition: vls.h:56
void bu_bomb(const char *str) _BU_ATTR_NORETURN
Definition: bomb.c:91
Header file for the BRL-CAD Optical Library, LIBOPTICAL.
void * reg_mfuncs
User appl. funcs for material.
Definition: raytrace.h:547
int rdebug
Definition: init.c:39
struct bu_structparse stk_parse[]
Definition: sh_stack.c:57
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126