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.3 by greg, Fri Jun 24 15:32:40 1994 UTC vs.
Revision 1.12 by greg, Wed Nov 29 19:55:45 1995 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines