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 #include <dxconfig.h>
10
11
12 #include <string.h>
13 #include <dx/dx.h>
14
15 #define MAXOBJECTS 42 /* must match mdf-c generated dx.mdf file */
16
17 static Error checkdim(Object, int *);
18
19 int
m_CollectMultiGrid(Object * in,Object * out)20 m_CollectMultiGrid(Object *in, Object *out)
21 {
22 int i;
23 int seen_null = 0;
24 int say_warn = 0;
25 Class class;
26 int prev_d = -1;
27 char *cp;
28
29 out[0] = NULL;
30
31 /* for each pair of inputs, if they are both null, skip them and
32 * continue. if one is non-null, return an error. if both are
33 * good, add them to the group. look for repeated names.
34 */
35 for (i = 0; i<MAXOBJECTS; i += 2) {
36
37 /* skip null pairs */
38 if (!in[i] && !in[i+1]) {
39 seen_null = 1;
40 continue;
41 }
42
43 /* check for mismatched pairs of object/names.
44 * make it ok to leave off the name, but require the object
45 * if a name is given.
46 */
47
48 if (!in[i] && in[i+1]) {
49 DXSetError(ERROR_BAD_PARAMETER, "#11065", i/2);
50 goto error;
51 }
52
53
54 /* warn if you see valid pairs after null pairs, but it's not
55 * an error.
56 */
57 if (seen_null) {
58 say_warn = 1;
59 seen_null = 0;
60 }
61
62 /* first non-null object you see, create output group.
63 */
64 if (!out[0]) {
65 out[0] = (Object)DXNewMultiGrid();
66 if (!out[0])
67 return ERROR;
68 }
69
70 if (!in[i+1])
71 cp = NULL;
72 else {
73 if (!DXExtractString(in[i+1], &cp)) {
74 DXSetError(ERROR_BAD_PARAMETER, "#11080", i/2);
75 goto error;
76 }
77 }
78
79 /* check name to see if duplicate */
80 if (cp && DXGetMember((Group)out[0], cp) != NULL) {
81 DXSetError(ERROR_BAD_PARAMETER, "#11085", i/2, cp);
82 goto error;
83 }
84
85 /* check member to see if it's field or partitioned field */
86 class = DXGetObjectClass(in[i]);
87 if (class != CLASS_FIELD && class != CLASS_COMPOSITEFIELD) {
88 if (!cp)
89 DXSetError(ERROR_BAD_PARAMETER, "#11087", i/2);
90 else
91 DXSetError(ERROR_BAD_PARAMETER, "#11088", i/2, cp);
92 goto error;
93 }
94 /* now check the connections to see if they are the same
95 * dimensionality (like cubes & tets, or quads & tris, or lines)
96 */
97 if (checkdim(in[i], &prev_d) == ERROR)
98 goto error;
99
100 /* make it part of the new composite field */
101 if (!DXSetMember((Group)out[0], cp, in[i]))
102 goto error;
103
104 }
105
106 /* this used to complain about no parms (at least 1 member was
107 * required), but it's been changed to allow a user to create
108 * an empty multigrid.
109 */
110 if (!out[0]) {
111 out[0] = (Object)DXNewMultiGrid();
112 /* DXWarning("#4014", "multigrid"); -* empty group */
113 }
114
115 if (say_warn)
116 ; /* DXWarning("#4010"); -* skipping null objects */
117
118 return OK;
119
120 error:
121 DXDelete(out[0]);
122 out[0] = NULL;
123 return ERROR;
124 }
125
126
checkdim(Object in,int * prev_d)127 static Error checkdim(Object in, int *prev_d)
128 {
129 int i = 0;
130 int this_d;
131 Object newo;
132 Array conn;
133 char *cp;
134
135
136 /* if not field, must be partitioned field (already checked it
137 * it is one or the other back in the calling routine).
138 * if partitioned, get a non-empty member to test.
139 */
140 if (DXGetObjectClass(in) != CLASS_FIELD) {
141 /* loop until we get a non-empty field member. if all members
142 * are empty, it can't be the wrong dimensionality - return ok
143 */
144 for (i=0; ; i++) {
145 newo = DXGetEnumeratedMember((Group)in, i, NULL);
146 if (!newo)
147 return OK;
148
149 if (DXGetObjectClass(newo) != CLASS_FIELD) {
150 DXSetError(ERROR_DATA_INVALID,
151 "composite field members must be fields");
152 return ERROR;
153 }
154
155 if (!DXEmptyField((Field)newo)) {
156 in = newo;
157 break;
158 }
159 }
160 }
161
162
163 conn = (Array)DXGetComponentValue((Field)in, "connections");
164
165 /* points */
166 if (!conn)
167 this_d = 0;
168 else {
169
170 if (!DXGetStringAttribute((Object)conn, "element type", &cp) || !cp) {
171 DXSetError(ERROR_DATA_INVALID,
172 "#10255", "connections", "element type");
173 return ERROR;
174 }
175
176
177 if (!strcmp(cp, "points"))
178 this_d = 0;
179 else if (!strcmp(cp, "lines"))
180 this_d = 1;
181 else if (!strcmp(cp, "quads"))
182 this_d = 2;
183 else if (!strcmp(cp, "triangles"))
184 this_d = 2;
185 else if (!strcmp(cp, "cubes"))
186 this_d = 3;
187 else if (!strcmp(cp, "tetrahedra"))
188 this_d = 3;
189 else if (!strncmp(cp, "cubes", 5)) {
190 if(sscanf(cp, "cubes%dD", &this_d) != 1) {
191 this_d = -1; /* unknown type */
192 }
193 }
194
195 else
196 this_d = -1; /* unknown type */
197 }
198
199 if (*prev_d == -1) /* no connections seen yet */
200 *prev_d = this_d;
201
202 if (*prev_d != this_d) {
203 DXSetError(ERROR_DATA_INVALID, "#10420");
204 return ERROR;
205 }
206
207 return OK;
208 }
209