ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgflib/xf.c
(Generate patch)

Comparing ray/src/cv/mgflib/xf.c (file contents):
Revision 1.4 by greg, Sat Jun 25 16:33:19 1994 UTC vs.
Revision 1.5 by greg, Wed Jun 29 16:15:25 1994 UTC

# Line 27 | Line 27 | XF_SPEC        *xf_context;                    /* current context */
27  
28   static int      xf_maxarg;              /* # allocated arguments */
29  
30 + static XF_SPEC  *new_xf();
31 + static long     comp_xfid();
32 + static int      put_oname();
33  
34 +
35   int
36   xf_handler(ac, av)              /* handle xf entity */
37   int     ac;
38   char    **av;
39   {
36 #define randshift(x,n)  ((long)(x) << shifttab[(n)&63])
37        static char     shifttab[64] = { 15, 5, 11, 5, 6, 3,
38                                9, 15, 13, 2, 13, 5, 2, 12, 14, 11,
39                                11, 12, 12, 3, 2, 11, 8, 12, 1, 12,
40                                5, 4, 15, 9, 14, 5, 13, 14, 2, 10,
41                                10, 14, 12, 3, 5, 5, 14, 6, 12, 11,
42                                13, 9, 12, 8, 1, 6, 5, 12, 7, 13,
43                                15, 8, 9, 2, 6, 11, 9, 11 };
44        register int    i;
40          register XF_SPEC        *spec;
41 +        register int    n;
42 +        int     rv;
43          XF      thisxf;
44  
45 <        if (ac == 1) {                  /* pop top transform */
45 >        if (ac == 1) {                  /* something with existing transform */
46                  if ((spec = xf_context) == NULL)
47                          return(MG_OK);          /* should be error? */
48 <                while (xf_argc > spec->xav0)
49 <                        free((MEM_PTR)xf_argv[--xf_argc]);
50 <                xf_argv[xf_argc] = NULL;
51 <                xf_context = spec->prev;
52 <                free((MEM_PTR)spec);
53 <                return(MG_OK);
48 >                n = -1;
49 >                if (spec->xarr != NULL) {       /* check for iteration */
50 >                        register struct xf_array        *ap = spec->xarr;
51 >
52 >                        (void)put_oname((struct xf_array *)NULL);
53 >                        n = ap->ndim;
54 >                        while (n--) {
55 >                                if (++ap->aarg[n].i < ap->aarg[n].n)
56 >                                        break;
57 >                                (void)strcpy(ap->aarg[n].arg, "0");
58 >                                ap->aarg[n].i = 0;
59 >                        }
60 >                        if (n >= 0) {
61 >                                if ((rv = mg_fgoto(&ap->spos)) != MG_OK)
62 >                                        return(rv);
63 >                                sprintf(ap->aarg[n].arg, "%d", ap->aarg[n].i);
64 >                                (void)put_oname(ap);
65 >                        } else
66 >                                free((MEM_PTR)ap);
67 >                }
68 >                if (n < 0) {                    /* pop transform */
69 >                        xf_argv[xf_argc=spec->xav0] = NULL;
70 >                        xf_context = spec->prev;
71 >                        free((MEM_PTR)spec);
72 >                        return(MG_OK);
73 >                }
74 >        } else {                        /* else allocate transform */
75 >                if ((spec = new_xf(ac-1, av+1)) == NULL)
76 >                        return(MG_EMEM);
77 >                spec->prev = xf_context;        /* push onto stack */
78 >                xf_context = spec;
79          }
80                                          /* translate new specification */
81 <        if (xf(&thisxf, ac-1, av+1) != ac-1)
81 >        if (xf(&thisxf, spec->xac, &xf_argv[spec->xav0]) != spec->xac)
82                  return(MG_ETYPE);
83 <                                        /* allocate space for new transform */
84 <        spec = (XF_SPEC *)malloc(sizeof(XF_SPEC));
83 >                                        /* compute total transformation */
84 >        if (spec->prev != NULL) {
85 >                multmat4(spec->xf.xfm, spec->prev->xf.xfm, thisxf.xfm);
86 >                spec->xf.sca = spec->prev->xf.sca * thisxf.sca;
87 >        } else
88 >                spec->xf = thisxf;
89 >        spec->xid = comp_xfid(spec->xf.xfm);    /* compute unique ID */
90 >        return(MG_OK);
91 > }
92 >
93 >
94 > static XF_SPEC *
95 > new_xf(ac, av)                  /* allocate new transform structure */
96 > int     ac;
97 > char    **av;
98 > {
99 >        register XF_SPEC        *spec;
100 >        register int    i;
101 >        char    *cp;
102 >        int     n, ndim;
103 >
104 >        ndim = 0;
105 >        n = 0;                          /* compute space req'd by arguments */
106 >        for (i = 0; i < ac; i++)
107 >                if (!strcmp(av[i], "-a")) {
108 >                        ndim++;
109 >                        i++;
110 >                } else
111 >                        n += strlen(av[i]) + 1;
112 >        if (ndim > XF_MAXDIM)
113 >                return(NULL);
114 >        spec = (XF_SPEC *)malloc(sizeof(XF_SPEC) + n);
115          if (spec == NULL)
116 <                return(MG_EMEM);
116 >                return(NULL);
117 >        if (ndim) {
118 >                spec->xarr = (struct xf_array *)malloc(sizeof(struct xf_array));
119 >                if (spec->xarr == NULL)
120 >                        return(NULL);
121 >                mg_fgetpos(&spec->xarr->spos);
122 >                spec->xarr->ndim = 0;           /* incremented below */
123 >        } else
124 >                spec->xarr = NULL;
125          spec->xav0 = xf_argc;
126 <        spec->xac = ac-1;
126 >        spec->xac = ac;
127                                          /* and store new xf arguments */
128 <        if (xf_argc+ac > xf_maxarg) {
128 >        if (xf_argc+ac+1 > xf_maxarg) {
129                  if (!xf_maxarg)
130                          xf_argv = (char **)malloc(
131 <                                        (xf_maxarg=ac)*sizeof(char *));
131 >                                        (xf_maxarg=ac+1)*sizeof(char *));
132                  else
133                          xf_argv = (char **)realloc((MEM_PTR)xf_argv,
134 <                                        (xf_maxarg+=ac)*sizeof(char *));
134 >                                (xf_maxarg=xf_argc+ac+1)*sizeof(char *));
135                  if (xf_argv == NULL)
136 <                        return(MG_EMEM);
136 >                        return(NULL);
137          }
138 <        for (i = 0; i < ac-1; i++) {
139 <                xf_argv[xf_argc] = (char *)malloc(strlen(av[i+1])+1);
140 <                if (xf_argv[xf_argc] == NULL)
141 <                        return(MG_EMEM);
142 <                strcpy(xf_argv[xf_argc++], av[i+1]);
143 <        }
138 >        cp = (char *)(spec + 1);        /* use memory allocated above */
139 >        for (i = 0; i < ac; i++)
140 >                if (!strcmp(av[i], "-a")) {
141 >                        xf_argv[xf_argc++] = "-i";
142 >                        xf_argv[xf_argc++] = strcpy(
143 >                                        spec->xarr->aarg[spec->xarr->ndim].arg,
144 >                                        "0");
145 >                        spec->xarr->aarg[spec->xarr->ndim].i = 0;
146 >                        spec->xarr->aarg[spec->xarr->ndim++].n = atoi(av[++i]);
147 >                } else {
148 >                        xf_argv[xf_argc++] = strcpy(cp, av[i]);
149 >                        cp += strlen(av[i]) + 1;
150 >                }
151          xf_argv[xf_argc] = NULL;
152 <                                        /* compute total transformation */
153 <        if (xf_context != NULL) {
154 <                multmat4(spec->xf.xfm, xf_context->xf.xfm, thisxf.xfm);
155 <                spec->xf.sca = xf_context->xf.sca * thisxf.sca;
89 <        } else
90 <                spec->xf = thisxf;
91 <        spec->xid = 0;                  /* compute unique transform id */
92 <        for (i = 0; i < sizeof(MAT4)/sizeof(unsigned short); i++)
93 <                spec->xid ^= randshift(((unsigned short *)&spec->xf.xfm)[i],i);
152 >        if (spec->xarr != NULL)
153 >                (void)put_oname(spec->xarr);
154 >        return(spec);
155 > }
156  
157 <        spec->prev = xf_context;        /* push new transform onto stack */
158 <        xf_context = spec;
159 <        return(MG_OK);
160 < #undef randshift
157 >
158 > static int
159 > put_oname(ap)                   /* put out name for this instance */
160 > register struct xf_array        *ap;
161 > {
162 >        static char     oname[10*XF_MAXDIM];
163 >        static char     *oav[3] = {mg_ename[MG_E_OBJECT], oname};
164 >        register int    i;
165 >        register char   *cp1, *cp2;
166 >
167 >        if (ap == NULL)
168 >                return(mg_handle(MG_E_OBJECT, 1, oav));
169 >        cp1 = oname;
170 >        *cp1 = 'a';
171 >        for (i = 0; i < ap->ndim; i++) {
172 >                for (cp2 = ap->aarg[i].arg; *cp2; )
173 >                        *++cp1 = *cp2++;
174 >                *++cp1 = '.';
175 >        }
176 >        *cp1 = '\0';
177 >        return(mg_handle(MG_E_OBJECT, 2, oav));
178   }
179  
180  
181 + static long
182 + comp_xfid(xfm)                  /* compute unique ID from matrix */
183 + register MAT4   xfm;
184 + {
185 +        static char     shifttab[64] = { 15, 5, 11, 5, 6, 3,
186 +                                9, 15, 13, 2, 13, 5, 2, 12, 14, 11,
187 +                                11, 12, 12, 3, 2, 11, 8, 12, 1, 12,
188 +                                5, 4, 15, 9, 14, 5, 13, 14, 2, 10,
189 +                                10, 14, 12, 3, 5, 5, 14, 6, 12, 11,
190 +                                13, 9, 12, 8, 1, 6, 5, 12, 7, 13,
191 +                                15, 8, 9, 2, 6, 11, 9, 11 };
192 +        register int    i;
193 +        register long   xid;
194 +
195 +        xid = 0;                        /* compute unique transform id */
196 +        for (i = 0; i < sizeof(MAT4)/sizeof(unsigned short); i++)
197 +                xid ^= (long)(((unsigned short *)xfm)[i]) << shifttab[i&63];
198 +        return(xid);
199 + }
200 +
201 +
202   void
203   xf_clear()                      /* clear transform stack */
204   {
205          register XF_SPEC        *spec;
206  
107        while (xf_argc)
108                free((MEM_PTR)xf_argv[--xf_argc]);
207          if (xf_maxarg) {
208                  free((MEM_PTR)xf_argv);
209                  xf_argv = NULL;
210                  xf_maxarg = 0;
211          }
212 +        xf_argc = 0;
213          while ((spec = xf_context) != NULL) {
214                  xf_context = spec->prev;
215 +                if (spec->xarr != NULL)
216 +                        free((MEM_PTR)spec->xarr);
217                  free((MEM_PTR)spec);
218          }
219   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines