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