1 /***********************************************************************/
2 /* Open Visualization Data Explorer                                    */
3 /* (C) Copyright IBM Corp. 1989,1999                                   */
4 /* ALL RIGHTS RESERVED                                                 */
5 /* This code licensed under the                                        */
6 /*    "IBM PUBLIC LICENSE - Open Visualization Data Explorer"          */
7 /***********************************************************************/
8 /*
9  * $Header: /src/master/dx/src/exec/dxmods/rotate.c,v 1.3 1999/05/10 15:45:30 gda Exp $
10  */
11 
12 #include <dxconfig.h>
13 
14 
15 #include <dx/dx.h>
16 #include <ctype.h>
17 
18 static int getdim(Object dimo, int *dim);
19 static int getmatrix(int dim, float deg, Matrix *m);
20 
21 /* should the default rotation be 90? */
22 #define DEF_AXIS  1
23 #define DEF_DEG   0.0
24 
25 #define MAXINPUTS 45  /* obj + 2 inputs w/defaults + 2 w/o + 20 repeat pairs */
26 
27 int
m_Rotate(Object * in,Object * out)28 m_Rotate(Object *in, Object *out)
29 {
30     float deg = DEF_DEG;
31     int i, dim = DEF_AXIS;
32     int seen_null = 0;
33     int say_warn = 0;
34     Object xformed = NULL;
35     Matrix m;
36 
37     out[0] = NULL;
38 
39     if (!in[0]) {
40 	DXSetError(ERROR_BAD_PARAMETER, "#10000", "input");
41 	return ERROR;
42     }
43 
44     i = 1;
45 
46     /* handle the first 2 parameters because they have default values.
47      */
48     if (!in[1] || !in[2]) {
49 
50         if (in[1] && !getdim(in[1], &dim))
51 	    return ERROR;
52 
53 	if (in[2] && !DXExtractFloat(in[2], &deg)) {
54 	    DXSetError(ERROR_BAD_PARAMETER, "#10080", "rotation");
55             return ERROR;
56 	}
57 
58 	if (!getmatrix(dim, deg, &m))
59 	    return ERROR;
60 
61 	xformed = (Object)DXNewXform(in[0], m);
62 	if (!xformed)
63 	    return ERROR;
64 
65         /* start at 3rd parm */
66         i = 3;
67     }
68 
69 
70     /* parse rest of parms in pairs: axis letter, number of degrees
71      *  if either of the first two parms was null, this loop starts at 3.
72      *  otherwise it starts at 1.
73      */
74     for ( ; i<MAXINPUTS; i+=2) {
75 
76         /* allow a pair of nulls, but if one is non-null, make sure it
77          *  has a matching parameter.
78          */
79         if (!in[i] && in[i+1]) {
80 	    DXSetError(ERROR_BAD_PARAMETER, "#10000", "axis");
81 	    goto error;
82 	}
83 
84         if (in[i] && !in[i+1]) {
85             DXSetError(ERROR_BAD_PARAMETER, "#10000", "rotation");
86 	    goto error;
87 	}
88 
89 	if (!in[i] && !in[i+1]) {
90 	    seen_null = 1;
91 	    continue;
92 	}
93 
94         if (seen_null) {
95             say_warn = 1;
96 	    seen_null = 0;
97 	}
98 
99 	/* get axis and number of degrees of rotation.
100 	 */
101 	if (!getdim(in[i], &dim))
102 	    goto error;
103 
104         if (!DXExtractFloat(in[i+1], &deg)) {
105             DXSetError(ERROR_BAD_PARAMETER, "#10080", "rotation");
106 	    goto error;
107 	}
108 
109 	/* turn axis & degrees into a transformation matrix
110 	 */
111 	if (!getmatrix(dim, deg, &m))
112 	    goto error;
113 
114 	/* the following shuffling is done so that if there is an
115 	 *  error, we can delete the partially rotated object.
116 	 *  out[0] get zeroed so that if there is an error in a
117 	 *  subsequent set of rotations, we can just call DXErrorReturn.
118 	 */
119 	out[0] = (Object)DXNewXform((xformed ? xformed : in[0]), m);
120 
121 	if (!out[0])
122 	    goto error;
123 
124 	xformed = out[0];
125 	out[0] = NULL;
126 
127     }
128 
129     if (say_warn)
130         DXWarning("skipping null objects in rotation list");
131 
132     out[0] = xformed;
133     return(out[0] ? OK : ERROR);
134 
135   error:
136     DXDelete(xformed);
137     out[0] = NULL;
138     return ERROR;
139 
140 }
141 
getdim(Object dimo,int * dim)142 static int getdim(Object dimo, int *dim)
143 {
144     char *ax;
145 
146     /* if string given, convert to integer */
147     if (DXExtractString(dimo, &ax)) {
148 
149 	if (ax[1] != '\0')
150 	    goto error;
151 
152 	switch(ax[0]) {
153 	  case 'x':
154 	  case 'X': *dim = 0; break;
155 	  case 'y':
156 	  case 'Y': *dim = 1; break;
157 	  case 'z':
158 	  case 'Z': *dim = 2; break;
159 	  default:
160 	    goto error;
161 
162 	}
163 
164     } else if (DXExtractInteger(dimo, dim)) {
165 
166 	if (*dim < 0 || *dim > 3)
167 	    goto error;
168 
169     } else
170 	goto error;
171 
172 
173     return OK;
174 
175   error:
176     DXErrorReturn(ERROR_BAD_PARAMETER, "axis must be X, Y, Z or 0, 1, 2");
177 
178 }
179 
180 
getmatrix(int dim,float deg,Matrix * m)181 static int getmatrix(int dim, float deg, Matrix *m)
182 {
183     /* set rotation matrix */
184     switch (dim) {
185       case 0:
186 	*m = DXRotateX(deg * DEG);
187 	break;
188       case 1:
189 	*m = DXRotateY(deg * DEG);
190 	break;
191       case 2:
192 	*m = DXRotateZ(deg * DEG);
193 	break;
194       default:
195 	DXSetError(ERROR_BAD_PARAMETER, "axis must be X, Y, Z or 0, 1, 2");
196 	return ERROR;
197     }
198 
199     return OK;
200 }
201