File: | refine/refineAIM.c |
Warning: | line 1317, column 16 3rd function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * CAPS: Computational Aircraft Prototype Syntheses | |||
3 | * | |||
4 | * refine AIM | |||
5 | * | |||
6 | * * Copyright 2014-2023, Massachusetts Institute of Technology | |||
7 | * Licensed under The GNU Lesser General Public License, version 2.1 | |||
8 | * See http://www.opensource.org/licenses/lgpl-2.1.php | |||
9 | * | |||
10 | */ | |||
11 | ||||
12 | /*!\mainpage Introduction | |||
13 | * | |||
14 | * \section overviewRefine refine AIM Overview | |||
15 | * A module in the Computational Aircraft Prototype Syntheses (CAPS) has been developed to interact with the | |||
16 | * unstructured mesh adaptation software <a href="https://github.com/nasa/refine">refine</a>. | |||
17 | * | |||
18 | * An outline of the AIM's inputs and outputs are provided in \ref aimInputsRefine and \ref aimOutputsRefine, respectively. | |||
19 | * | |||
20 | * The refine AIM can automatically execute ref, with details provided in \ref aimExecuteRefine. | |||
21 | * | |||
22 | */ | |||
23 | ||||
24 | #include <string.h> | |||
25 | #include <math.h> | |||
26 | #include "aimUtil.h" | |||
27 | #include "aimMesh.h" | |||
28 | ||||
29 | #include "meshUtils.h" // Collection of helper functions for meshing | |||
30 | #include "miscUtils.h" // Collection of helper functions for miscellaneous analysis | |||
31 | ||||
32 | #include "libMeshbWriter.h" | |||
33 | #include "libMeshb/sources/libmeshb7.h" | |||
34 | ||||
35 | #define EXPORT_MESHB_VERTEX_ID(1) (1) | |||
36 | #define EXPORT_MESHB_2D_ID(1) (1) | |||
37 | #define EXPORT_MESHB_3D_ID(0) (0) | |||
38 | #define EXPORT_MESHB_VERTEX_3(10000000) (10000000) | |||
39 | #define EXPORT_MESHB_VERTEX_4(200000000) (200000000) | |||
40 | ||||
41 | ||||
42 | #ifdef WIN32 | |||
43 | /* needs Advapi32.lib & Ws2_32.lib */ | |||
44 | #include <Windows.h> | |||
45 | #define strcasecmp stricmp | |||
46 | #define snprintf _snprintf | |||
47 | #define access _access | |||
48 | #define F_OK0 0 | |||
49 | #else | |||
50 | #include <unistd.h> | |||
51 | #endif | |||
52 | ||||
53 | //#define DEBUG | |||
54 | ||||
55 | #define CROSS(a,b,c)a[0] = (b[1]*c[2]) - (b[2]*c[1]); a[1] = (b[2]*c[0]) - (b[0]* c[2]); a[2] = (b[0]*c[1]) - (b[1]*c[0]) a[0] = (b[1]*c[2]) - (b[2]*c[1]);\ | |||
56 | a[1] = (b[2]*c[0]) - (b[0]*c[2]);\ | |||
57 | a[2] = (b[0]*c[1]) - (b[1]*c[0]) | |||
58 | #define DOT(a,b)(a[0]*b[0] + a[1]*b[1] + a[2]*b[2]) (a[0]*b[0] + a[1]*b[1] + a[2]*b[2]) | |||
59 | ||||
60 | enum aimInputs | |||
61 | { | |||
62 | inref = 1, /* index is 1-based */ | |||
63 | inComplexity, | |||
64 | inPasses, | |||
65 | inMesh, | |||
66 | inSurface_Mesh, | |||
67 | inScalarFieldFile, | |||
68 | inHessianFieldFile, | |||
69 | inMetricFieldFile, | |||
70 | NUMINPUT = inMetricFieldFile /* Total number of inputs */ | |||
71 | }; | |||
72 | ||||
73 | enum aimOutputs | |||
74 | { | |||
75 | outMesh = 1, /* index is 1-based */ | |||
76 | outSurface_Mesh, | |||
77 | outxyz, | |||
78 | NUMOUT = outxyz /* Total number of outputs */ | |||
79 | }; | |||
80 | ||||
81 | static char egadsFileName[] = "refine_in.egads"; | |||
82 | static char refine_out[] = "refine_out.meshb"; | |||
83 | static char refInput[] = "refInput.txt"; | |||
84 | static char metricFileName[] = "metric.solb"; | |||
85 | ||||
86 | ||||
87 | typedef struct { | |||
88 | int npts; | |||
89 | double *xyz; | |||
90 | double *t; | |||
91 | int *ivp; // volume node index | |||
92 | } edgeData; | |||
93 | ||||
94 | ||||
95 | typedef struct { | |||
96 | int npts; | |||
97 | double *xyz; | |||
98 | double *uv; | |||
99 | int ntri; | |||
100 | int *tris; | |||
101 | int *ivp; // volume node index | |||
102 | } faceData; | |||
103 | ||||
104 | ||||
105 | typedef struct { | |||
106 | double **rvec; | |||
107 | ego *surfaces; | |||
108 | ego body; | |||
109 | ego *faces; | |||
110 | ego *edges; | |||
111 | ego *nodes; | |||
112 | int nfaces; | |||
113 | int nedges; | |||
114 | int nnodes; | |||
115 | ||||
116 | edgeData *tedges; | |||
117 | faceData *tfaces; | |||
118 | } bodyData; | |||
119 | ||||
120 | ||||
121 | typedef struct { | |||
122 | int ivp; // global index into volume vertexes | |||
123 | int egadsType; // egads type, NODE, EDGE, FACE | |||
124 | int egadsID; // type-index | |||
125 | double param[2]; // parametric coordinates of the vertex | |||
126 | } srfVertex; | |||
127 | ||||
128 | ||||
129 | typedef struct { | |||
130 | // Mesh reference obtained from meshing AIM | |||
131 | aimMeshRef *meshRef; | |||
132 | ||||
133 | meshStruct *surfaceMesh; | |||
134 | ||||
135 | aimMeshRef meshRefOut; | |||
136 | ||||
137 | // Attribute to index map | |||
138 | mapAttrToIndexStruct groupMap; | |||
139 | ||||
140 | int *faceID; | |||
141 | ||||
142 | } aimStorage; | |||
143 | ||||
144 | ||||
145 | static int | |||
146 | readlibMeshb(void *aimInfo, aimStorage *refineInstance, aimMesh *mesh); | |||
147 | static int | |||
148 | writelibMeshb(void *aimInfo, ego tess, const char *filename); | |||
149 | ||||
150 | ||||
151 | static int initiate_bodyData(int numBody, bodyData *bodydata) | |||
152 | { | |||
153 | int i; | |||
154 | ||||
155 | for (i = 0; i < numBody; i++) { | |||
156 | bodydata[i].rvec = NULL((void*)0); | |||
157 | bodydata[i].surfaces = NULL((void*)0); | |||
158 | bodydata[i].faces = NULL((void*)0); | |||
159 | bodydata[i].edges = NULL((void*)0); | |||
160 | bodydata[i].nodes = NULL((void*)0); | |||
161 | bodydata[i].nfaces = 0; | |||
162 | bodydata[i].nedges = 0; | |||
163 | bodydata[i].nnodes = 0; | |||
164 | bodydata[i].tedges = NULL((void*)0); | |||
165 | bodydata[i].tfaces = NULL((void*)0); | |||
166 | } | |||
167 | ||||
168 | return CAPS_SUCCESS0; | |||
169 | } | |||
170 | ||||
171 | static int destroy_bodyData(int numBody, bodyData *bodydata) | |||
172 | { | |||
173 | int i, j; | |||
174 | ||||
175 | if (bodydata == NULL((void*)0)) return CAPS_SUCCESS0; | |||
176 | ||||
177 | for (i = 0; i < numBody; i++) { | |||
178 | for (j = 0; j < bodydata[i].nfaces; j++) { | |||
179 | if (bodydata[i].surfaces != NULL((void*)0)) | |||
180 | if (bodydata[i].surfaces[j+bodydata[i].nfaces] != NULL((void*)0)) | |||
181 | EG_deleteObject(bodydata[i].surfaces[j+bodydata[i].nfaces]); | |||
182 | if (bodydata[i].rvec != NULL((void*)0)) | |||
183 | EG_free(bodydata[i].rvec[j]); | |||
184 | } | |||
185 | EG_free(bodydata[i].nodes); | |||
186 | EG_free(bodydata[i].edges); | |||
187 | EG_free(bodydata[i].faces); | |||
188 | EG_free(bodydata[i].surfaces); | |||
189 | EG_free(bodydata[i].rvec); | |||
190 | ||||
191 | if (bodydata[i].tedges != NULL((void*)0)) { | |||
192 | for (j = 0; j < bodydata[i].nedges; j++) { | |||
193 | EG_free(bodydata[i].tedges[j].xyz); | |||
194 | EG_free(bodydata[i].tedges[j].t); | |||
195 | EG_free(bodydata[i].tedges[j].ivp); | |||
196 | } | |||
197 | EG_free(bodydata[i].tedges); | |||
198 | } | |||
199 | ||||
200 | if (bodydata[i].tfaces != NULL((void*)0)) { | |||
201 | for (j = 0; j < bodydata[i].nfaces; j++) { | |||
202 | EG_free(bodydata[i].tfaces[j].xyz); | |||
203 | EG_free(bodydata[i].tfaces[j].uv); | |||
204 | EG_free(bodydata[i].tfaces[j].tris); | |||
205 | EG_free(bodydata[i].tfaces[j].ivp); | |||
206 | } | |||
207 | EG_free(bodydata[i].tfaces); | |||
208 | } | |||
209 | } | |||
210 | ||||
211 | return CAPS_SUCCESS0; | |||
212 | } | |||
213 | ||||
214 | ||||
215 | static int initiate_aimStorage(aimStorage *refineInstance) | |||
216 | { | |||
217 | ||||
218 | int status = CAPS_SUCCESS0; | |||
219 | ||||
220 | refineInstance->meshRef = NULL((void*)0); | |||
221 | refineInstance->surfaceMesh = NULL((void*)0); | |||
222 | ||||
223 | // Mesh reference passed to solver | |||
224 | status = aim_initMeshRef(&refineInstance->meshRefOut); | |||
225 | if (status != CAPS_SUCCESS0) return status; | |||
226 | ||||
227 | status = initiate_mapAttrToIndexStruct(&refineInstance->groupMap); | |||
228 | if (status != CAPS_SUCCESS0) return status; | |||
229 | ||||
230 | refineInstance->faceID = NULL((void*)0); | |||
231 | ||||
232 | return CAPS_SUCCESS0; | |||
233 | } | |||
234 | ||||
235 | ||||
236 | static int destroy_aimStorage(aimStorage *refineInstance) | |||
237 | { | |||
238 | int status; // Function return status | |||
239 | ||||
240 | refineInstance->meshRef = NULL((void*)0); | |||
241 | refineInstance->surfaceMesh = NULL((void*)0); | |||
242 | ||||
243 | // Free the meshRef | |||
244 | aim_freeMeshRef(&refineInstance->meshRefOut); | |||
245 | ||||
246 | status = destroy_mapAttrToIndexStruct(&refineInstance->groupMap); | |||
247 | if (status != CAPS_SUCCESS0) | |||
248 | printf("Status = %d, refineAIM attributeMap group cleanup!!!\n", status); | |||
249 | ||||
250 | AIM_FREE(refineInstance->faceID){ EG_free(refineInstance->faceID); refineInstance->faceID = ((void*)0); }; | |||
251 | ||||
252 | return status; | |||
253 | } | |||
254 | ||||
255 | ||||
256 | /****************** exposed AIM entry points -- Analysis **********************/ | |||
257 | ||||
258 | /* aimInitialize: Initialization Information for the AIM */ | |||
259 | int | |||
260 | aimInitialize(int inst, /*@unused@*/ const char *unitSys, void *aimInfo, | |||
261 | /*@unused@*/ void **instStore, /*@unused@*/ int *major, | |||
262 | /*@unused@*/ int *minor, int *nIn, int *nOut, | |||
263 | int *nFields, char ***fnames, int **franks, int **fInOut) | |||
264 | { | |||
265 | int i, status = CAPS_SUCCESS0; | |||
266 | aimStorage *refineInstance = NULL((void*)0); | |||
267 | ||||
268 | /* specify the number of analysis inputs defined in aimInputs | |||
269 | * and the number of analysis outputs defined in aimOutputs */ | |||
270 | *nIn = NUMINPUT; | |||
271 | *nOut = NUMOUT; | |||
272 | ||||
273 | /* return if "query" only */ | |||
274 | if (inst == -1) return CAPS_SUCCESS0; | |||
275 | ||||
276 | /* specify the field variables this analysis can generate and consume */ | |||
277 | *nFields = 0; | |||
278 | ||||
279 | /* specify the name of each field variable */ | |||
280 | *fnames = NULL((void*)0); | |||
281 | ||||
282 | /* specify the rank of each field variable */ | |||
283 | *franks = NULL((void*)0); | |||
284 | ||||
285 | /* specify if a field is an input field or output field */ | |||
286 | *fInOut = NULL((void*)0); | |||
287 | ||||
288 | /* setup our AIM specific state */ | |||
289 | AIM_ALLOC(refineInstance, 1, aimStorage, aimInfo, status){ if (refineInstance != ((void*)0)) { status = -4; aim_status (aimInfo, status, "refineAIM.c", 289, __func__, 1, "AIM_ALLOC: %s != NULL" , "refineInstance"); goto cleanup; } size_t memorysize = 1; refineInstance = (aimStorage *) EG_alloc(memorysize*sizeof(aimStorage)); if (refineInstance == ((void*)0)) { status = -4; aim_status(aimInfo , status, "refineAIM.c", 289, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "refineInstance", memorysize, "aimStorage"); goto cleanup; } }; | |||
290 | *instStore = refineInstance; | |||
291 | ||||
292 | status = initiate_aimStorage(refineInstance); | |||
293 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 293, __func__, 0); goto cleanup; }; | |||
294 | ||||
295 | status = CAPS_SUCCESS0; | |||
296 | ||||
297 | cleanup: | |||
298 | if (status != CAPS_SUCCESS0) { | |||
299 | /* release all possibly allocated memory on error */ | |||
300 | if (*fnames != NULL((void*)0)) | |||
301 | for (i = 0; i < *nFields; i++) AIM_FREE((*fnames)[i]){ EG_free((*fnames)[i]); (*fnames)[i] = ((void*)0); }; | |||
302 | AIM_FREE(*franks){ EG_free(*franks); *franks = ((void*)0); }; | |||
303 | AIM_FREE(*fInOut){ EG_free(*fInOut); *fInOut = ((void*)0); }; | |||
304 | AIM_FREE(*fnames){ EG_free(*fnames); *fnames = ((void*)0); }; | |||
305 | AIM_FREE(*instStore){ EG_free(*instStore); *instStore = ((void*)0); }; | |||
306 | *nFields = 0; | |||
307 | } | |||
308 | ||||
309 | return status; | |||
310 | } | |||
311 | ||||
312 | ||||
313 | // ********************** AIM Function Break ***************************** | |||
314 | /* aimInputs: Input Information for the AIM */ | |||
315 | int | |||
316 | aimInputs(/*@unused@*/ void *instStore, /*@unused@*/ void *aimInfo, int index, | |||
317 | char **ainame, capsValue *defval) | |||
318 | { | |||
319 | int status = CAPS_SUCCESS0; | |||
320 | ||||
321 | /*! \page aimInputsRefine AIM Inputs | |||
322 | * The following list outlines the refine inputs along with their default value available | |||
323 | * through the AIM interface. | |||
324 | */ | |||
325 | ||||
326 | /* fill in the required members based on the index */ | |||
327 | if (index == inref) { | |||
328 | *ainame = AIM_NAME(ref)EG_strdup("ref"); | |||
329 | defval->type = String; | |||
330 | defval->lfixed = Fixed; | |||
331 | AIM_STRDUP(defval->vals.string, "ref", aimInfo, status){ if (defval->vals.string != ((void*)0)) { status = -4; aim_status (aimInfo, status, "refineAIM.c", 331, __func__, 1, "AIM_STRDUP: %s != NULL!" , "defval->vals.string"); goto cleanup; } defval->vals. string = EG_strdup("ref"); if (defval->vals.string == ((void *)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c" , 331, __func__, 2, "AIM_STRDUP: %s %s", "defval->vals.string" , "ref"); goto cleanup; } }; | |||
332 | ||||
333 | /*! \page aimInputsRefine | |||
334 | * - <B>ref = "ref"</B> <br> | |||
335 | * refine executable | |||
336 | */ | |||
337 | ||||
338 | } else if (index == inPasses) { | |||
339 | *ainame = AIM_NAME(Passes)EG_strdup("Passes"); | |||
340 | defval->type = Integer; | |||
341 | defval->dim = Scalar; | |||
342 | defval->vals.integer = 30; | |||
343 | ||||
344 | /*! \page aimInputsRefine | |||
345 | * - <B> Passes = 30</B> <br> | |||
346 | * Number of refine internal adaptation iterations | |||
347 | */ | |||
348 | ||||
349 | } else if (index == inMesh) { | |||
350 | *ainame = AIM_NAME(Mesh)EG_strdup("Mesh"); | |||
351 | defval->type = PointerMesh; | |||
352 | defval->nrow = 1; | |||
353 | defval->lfixed = Fixed; | |||
354 | defval->vals.AIMptr = NULL((void*)0); | |||
355 | defval->nullVal = IsNull; | |||
356 | AIM_STRDUP(defval->meshWriter, MESHWRITER, aimInfo, status){ if (defval->meshWriter != ((void*)0)) { status = -4; aim_status (aimInfo, status, "refineAIM.c", 356, __func__, 1, "AIM_STRDUP: %s != NULL!" , "defval->meshWriter"); goto cleanup; } defval->meshWriter = EG_strdup("libMeshbWriter"); if (defval->meshWriter == ( (void*)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c" , 356, __func__, 2, "AIM_STRDUP: %s %s", "defval->meshWriter" , "libMeshbWriter"); goto cleanup; } }; | |||
357 | ||||
358 | /*! \page aimInputsRefine | |||
359 | * - <B>Mesh = NULL</B> <br> | |||
360 | * An Area_Mesh or Volume_Mesh link for mesh adaptation | |||
361 | */ | |||
362 | ||||
363 | } else if (index == inSurface_Mesh) { | |||
364 | *ainame = AIM_NAME(Surface_Mesh)EG_strdup("Surface_Mesh"); | |||
365 | defval->type = Pointer; | |||
366 | defval->dim = Vector; | |||
367 | defval->lfixed = Change; | |||
368 | defval->sfixed = Change; | |||
369 | defval->vals.AIMptr = NULL((void*)0); | |||
370 | defval->nullVal = IsNull; | |||
371 | AIM_STRDUP(defval->units, "meshStruct", aimInfo, status){ if (defval->units != ((void*)0)) { status = -4; aim_status (aimInfo, status, "refineAIM.c", 371, __func__, 1, "AIM_STRDUP: %s != NULL!" , "defval->units"); goto cleanup; } defval->units = EG_strdup ("meshStruct"); if (defval->units == ((void*)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c", 371, __func__ , 2, "AIM_STRDUP: %s %s", "defval->units", "meshStruct"); goto cleanup; } }; | |||
372 | ||||
373 | /*! \page aimInputsRefine | |||
374 | * - <B>Surface_Mesh = NULL</B> <br> | |||
375 | * A Surface_Mesh link for surface mesh adaptation (requires Spectral Energies version of refine). | |||
376 | */ | |||
377 | ||||
378 | } else if (index == inComplexity) { | |||
379 | *ainame = AIM_NAME(Complexity)EG_strdup("Complexity"); | |||
380 | defval->type = Double; | |||
381 | defval->dim = Scalar; | |||
382 | defval->nullVal = IsNull; | |||
383 | ||||
384 | /*! \page aimInputsRefine | |||
385 | * - <B> Complexity = NULL</B> <br> | |||
386 | * Must be specified in combination with a ScalarFieldFile or HessianFieldFile. <br> | |||
387 | * Cannot be specified in combination with MetricFieldFile. <br> | |||
388 | * Complexity is approximately half the target number of vertices. | |||
389 | */ | |||
390 | ||||
391 | } else if (index == inScalarFieldFile) { | |||
392 | *ainame = AIM_NAME(ScalarFieldFile)EG_strdup("ScalarFieldFile"); | |||
393 | defval->type = String; | |||
394 | defval->lfixed = Fixed; | |||
395 | defval->dim = Scalar; | |||
396 | defval->nullVal = IsNull; | |||
397 | ||||
398 | /*! \page aimInputsRefine | |||
399 | * - <B> ScalarFieldFile = NULL</B> <br> | |||
400 | * Scalar field file for constructing the multi-scale metric. <br> | |||
401 | * Only one of ScalarFieldFile, HessianFieldFile, or MetricFieldFile may be specified | |||
402 | */ | |||
403 | ||||
404 | } else if (index == inHessianFieldFile) { | |||
405 | *ainame = AIM_NAME(HessianFieldFile)EG_strdup("HessianFieldFile"); | |||
406 | defval->type = String; | |||
407 | defval->lfixed = Fixed; | |||
408 | defval->dim = Scalar; | |||
409 | defval->nullVal = IsNull; | |||
410 | ||||
411 | /*! \page aimInputsRefine | |||
412 | * - <B> HessianFieldFile = NULL</B> <br> | |||
413 | * Hessian field file for constructing the multi-scale metric. <br> | |||
414 | * Only one of ScalarFieldFile, HessianFieldFile, or MetricFieldFile may be specified | |||
415 | */ | |||
416 | ||||
417 | } else if (index == inMetricFieldFile) { | |||
418 | *ainame = AIM_NAME(MetricFieldFile)EG_strdup("MetricFieldFile"); | |||
419 | defval->type = String; | |||
420 | defval->lfixed = Fixed; | |||
421 | defval->dim = Scalar; | |||
422 | defval->nullVal = IsNull; | |||
423 | ||||
424 | /*! \page aimInputsRefine | |||
425 | * - <B> MetricFieldFile = NULL</B> <br> | |||
426 | * Metric field file. <br> | |||
427 | * Only one of ScalarFieldFile, HessianFieldFile, or MetricFieldFile may be specified | |||
428 | */ | |||
429 | ||||
430 | } else { | |||
431 | status = CAPS_BADINDEX-304; | |||
432 | AIM_STATUS(aimInfo, status, "Unknown input index %d!", index)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 432, __func__, 2, "Unknown input index %d!", index); goto cleanup ; }; | |||
433 | } | |||
434 | ||||
435 | AIM_NOTNULL(*ainame, aimInfo, status){ if (*ainame == ((void*)0)) { status = -307; aim_status(aimInfo , status, "refineAIM.c", 435, __func__, 1, "%s == NULL!", "*ainame" ); goto cleanup; } }; | |||
436 | ||||
437 | cleanup: | |||
438 | return status; | |||
439 | } | |||
440 | ||||
441 | ||||
442 | // ********************** AIM Function Break ***************************** | |||
443 | /* aimUpdateState: The always the first call in the execution sequence */ | |||
444 | int | |||
445 | aimUpdateState(void *instStore, void *aimInfo, capsValue *inputs) | |||
446 | { | |||
447 | int nBody, status = CAPS_SUCCESS0; | |||
448 | const char *intents; | |||
449 | ego *bodies; | |||
450 | ||||
451 | char aimFile[PATH_MAX4096]; | |||
452 | ||||
453 | const char *groupName = NULL((void*)0); | |||
454 | aimStorage *refineInstance; | |||
455 | ||||
456 | int nFaces, iface, cID; | |||
457 | ego *faces=NULL((void*)0); | |||
458 | ||||
459 | refineInstance = (aimStorage *) instStore; | |||
460 | ||||
461 | destroy_aimStorage(refineInstance); | |||
462 | ||||
463 | if (inputs[inMesh-1].nullVal == | |||
464 | inputs[inSurface_Mesh-1].nullVal) { | |||
465 | AIM_ERROR(aimInfo, "Only one of 'Mesh' or 'Surface_Mesh' inputs must be linked"){ aim_message(aimInfo, CERROR, 0 , "refineAIM.c", 465, __func__ , "Only one of 'Mesh' or 'Surface_Mesh' inputs must be linked" ); }; | |||
466 | status = CAPS_BADVALUE-311; | |||
467 | goto cleanup; | |||
468 | } | |||
469 | ||||
470 | if ( aim_isFile(aimInfo, refine_out) == CAPS_SUCCESS0 && | |||
471 | inputs[inScalarFieldFile-1 ].nullVal == IsNull && | |||
472 | inputs[inHessianFieldFile-1].nullVal == IsNull && | |||
473 | inputs[inMetricFieldFile-1 ].nullVal == IsNull ) { | |||
474 | AIM_ERROR(aimInfo, "One of ScalarFieldFile, HessianFieldFile, or MetricFieldFile must be specified"){ aim_message(aimInfo, CERROR, 0 , "refineAIM.c", 474, __func__ , "One of ScalarFieldFile, HessianFieldFile, or MetricFieldFile must be specified" ); }; | |||
475 | status = CAPS_BADVALUE-311; | |||
476 | goto cleanup; | |||
477 | } | |||
478 | ||||
479 | if (( inputs[inScalarFieldFile-1 ].nullVal != IsNull && | |||
480 | (inputs[inHessianFieldFile-1].nullVal != IsNull || | |||
481 | inputs[inMetricFieldFile-1 ].nullVal != IsNull)) || | |||
482 | ( inputs[inHessianFieldFile-1].nullVal != IsNull && | |||
483 | (inputs[inScalarFieldFile-1 ].nullVal != IsNull || | |||
484 | inputs[inMetricFieldFile-1 ].nullVal != IsNull)) || | |||
485 | ( inputs[inMetricFieldFile-1 ].nullVal != IsNull && | |||
486 | (inputs[inHessianFieldFile-1].nullVal != IsNull || | |||
487 | inputs[inScalarFieldFile-1 ].nullVal != IsNull)) ) { | |||
488 | AIM_ERROR(aimInfo, "Only one of ScalarFieldFile, HessianFieldFile, or MetricFieldFile may be specified"){ aim_message(aimInfo, CERROR, 0 , "refineAIM.c", 488, __func__ , "Only one of ScalarFieldFile, HessianFieldFile, or MetricFieldFile may be specified" ); }; | |||
489 | status = CAPS_BADVALUE-311; | |||
490 | goto cleanup; | |||
491 | } | |||
492 | ||||
493 | if (inputs[inComplexity-1].nullVal == IsNull && | |||
494 | inputs[inScalarFieldFile-1].nullVal != IsNull) { | |||
495 | AIM_ANALYSISIN_ERROR(aimInfo, inComplexity, "Complexity must be specified along with ScalarFieldFile"){ aim_message(aimInfo, CERROR, inComplexity, "refineAIM.c", 495 , __func__, "Complexity must be specified along with ScalarFieldFile" ); }; | |||
496 | status = CAPS_BADVALUE-311; | |||
497 | goto cleanup; | |||
498 | } | |||
499 | ||||
500 | if (inputs[inComplexity-1].nullVal == IsNull && | |||
501 | inputs[inHessianFieldFile-1].nullVal != IsNull) { | |||
502 | AIM_ANALYSISIN_ERROR(aimInfo, inComplexity, "Complexity must be specified along with HessianFieldFile"){ aim_message(aimInfo, CERROR, inComplexity, "refineAIM.c", 502 , __func__, "Complexity must be specified along with HessianFieldFile" ); }; | |||
503 | status = CAPS_BADVALUE-311; | |||
504 | goto cleanup; | |||
505 | } | |||
506 | ||||
507 | status = aim_getBodies(aimInfo, &intents, &nBody, &bodies); | |||
508 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 508, __func__, 0); goto cleanup; }; | |||
509 | if (nBody != 1) { | |||
510 | AIM_ERROR(aimInfo, "refine only supports a single body: numBody = %d", nBody){ aim_message(aimInfo, CERROR, 0 , "refineAIM.c", 510, __func__ , "refine only supports a single body: numBody = %d", nBody); }; | |||
511 | status = CAPS_BADVALUE-311; | |||
512 | goto cleanup; | |||
513 | } | |||
514 | ||||
515 | // Get mesh | |||
516 | if (inputs[inMesh-1].nullVal == NotNull) { | |||
517 | refineInstance->meshRef = (aimMeshRef *) inputs[inMesh-1].vals.AIMptr; | |||
518 | ||||
519 | // Get attribute to index mapping | |||
520 | status = create_MeshRefToIndexMap(aimInfo, refineInstance->meshRef, &refineInstance->groupMap); | |||
521 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 521, __func__, 0); goto cleanup; }; | |||
522 | ||||
523 | } else if (inputs[inSurface_Mesh-1].nullVal == NotNull) { | |||
524 | refineInstance->surfaceMesh = (meshStruct *) inputs[inSurface_Mesh-1].vals.AIMptr; | |||
525 | ||||
526 | // Get attribute to index mapping | |||
527 | status = copy_mapAttrToIndexStruct(&refineInstance->surfaceMesh->groupMap, &refineInstance->groupMap); | |||
528 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 528, __func__, 0); goto cleanup; }; | |||
529 | } | |||
530 | ||||
531 | status = aim_file(aimInfo, "refine_out", aimFile); | |||
532 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 532, __func__, 0); goto cleanup; }; | |||
533 | AIM_STRDUP(refineInstance->meshRefOut.fileName, aimFile, aimInfo, status){ if (refineInstance->meshRefOut.fileName != ((void*)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c", 533, __func__, 1, "AIM_STRDUP: %s != NULL!", "refineInstance->meshRefOut.fileName" ); goto cleanup; } refineInstance->meshRefOut.fileName = EG_strdup (aimFile); if (refineInstance->meshRefOut.fileName == ((void *)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c" , 533, __func__, 2, "AIM_STRDUP: %s %s", "refineInstance->meshRefOut.fileName" , aimFile); goto cleanup; } }; | |||
534 | ||||
535 | status = EG_getBodyTopos(bodies[0], NULL((void*)0), FACE23, &nFaces, &faces); | |||
536 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 536, __func__, 0); goto cleanup; }; | |||
537 | ||||
538 | AIM_ALLOC(refineInstance->faceID, nFaces, int, aimInfo, status){ if (refineInstance->faceID != ((void*)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c", 538, __func__, 1, "AIM_ALLOC: %s != NULL", "refineInstance->faceID"); goto cleanup ; } size_t memorysize = nFaces; refineInstance->faceID = ( int *) EG_alloc(memorysize*sizeof(int)); if (refineInstance-> faceID == ((void*)0)) { status = -4; aim_status(aimInfo, status , "refineAIM.c", 538, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "refineInstance->faceID", memorysize, "int"); goto cleanup ; } }; | |||
539 | ||||
540 | for (iface = 0; iface < nFaces; iface++) { | |||
541 | ||||
542 | // Look for component/boundary ID for attribute mapper based on capsGroup | |||
543 | status = retrieve_CAPSGroupAttr(faces[iface], &groupName); | |||
544 | if (status != CAPS_SUCCESS0) { | |||
545 | AIM_ERROR(aimInfo, "No capsGroup attribute found on Face %d, unable to assign a boundary index value",{ aim_message(aimInfo, CERROR, 0 , "refineAIM.c", 546, __func__ , "No capsGroup attribute found on Face %d, unable to assign a boundary index value" , iface+1); } | |||
546 | iface+1){ aim_message(aimInfo, CERROR, 0 , "refineAIM.c", 546, __func__ , "No capsGroup attribute found on Face %d, unable to assign a boundary index value" , iface+1); }; | |||
547 | print_AllAttr( aimInfo, faces[iface] ); | |||
548 | goto cleanup; | |||
549 | } | |||
550 | ||||
551 | /*@-nullpass@*/ | |||
552 | status = get_mapAttrToIndexIndex(&refineInstance->groupMap, groupName, &cID); | |||
553 | AIM_STATUS(aimInfo, status, "Unable to retrieve boundary index from capsGroup: %s",if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 554, __func__, 2, "Unable to retrieve boundary index from capsGroup: %s" , groupName); goto cleanup; } | |||
554 | groupName)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 554, __func__, 2, "Unable to retrieve boundary index from capsGroup: %s" , groupName); goto cleanup; }; | |||
555 | /*@+nullpass@*/ | |||
556 | ||||
557 | refineInstance->faceID[iface] = cID; | |||
558 | } | |||
559 | ||||
560 | cleanup: | |||
561 | AIM_FREE(faces){ EG_free(faces); faces = ((void*)0); }; | |||
562 | return status; | |||
563 | } | |||
564 | ||||
565 | ||||
566 | // ********************** AIM Function Break ***************************** | |||
567 | /* aimPreAnalysis: Parse Inputs, Generate Input File(s) */ | |||
568 | int | |||
569 | aimPreAnalysis(/*@unused@*/ const void *instStore, void *aimInfo, | |||
570 | capsValue *inputs) | |||
571 | { | |||
572 | int i, status = CAPS_SUCCESS0; | |||
573 | ||||
574 | int nBody=0; | |||
575 | const char *intents; | |||
576 | ego *bodies=NULL((void*)0); | |||
577 | ||||
578 | ego *bodyCopy=NULL((void*)0), context=NULL((void*)0), model=NULL((void*)0); | |||
579 | ||||
580 | // Output filename | |||
581 | char refine_in[PATH_MAX4096]; | |||
582 | char aimEgadsFile[PATH_MAX4096]; | |||
583 | char aimFile[PATH_MAX4096]; | |||
584 | char relPath[PATH_MAX4096]; | |||
585 | char command[PATH_MAX4096]; | |||
586 | FILE *fp = NULL((void*)0); | |||
587 | ||||
588 | const aimStorage *refineInstance; | |||
589 | ||||
590 | refineInstance = (const aimStorage *) instStore; | |||
591 | ||||
592 | if (inputs[inScalarFieldFile-1].nullVal == NotNull && | |||
593 | access(inputs[inScalarFieldFile-1].vals.string, F_OK0) == 0 && | |||
594 | aim_isFile(aimInfo, refine_out) == CAPS_SUCCESS0) { | |||
595 | ||||
596 | snprintf(refine_in, PATH_MAX4096, "refine_in%s", MESHEXTENSION".meshb"); | |||
597 | ||||
598 | // copy over refine_out to refine_in | |||
599 | status = aim_file(aimInfo, refine_out, aimFile); | |||
600 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 600, __func__, 0); goto cleanup; }; | |||
601 | status = aim_cpFile(aimInfo, aimFile, refine_in); | |||
602 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 602, __func__, 0); goto cleanup; }; | |||
603 | ||||
604 | // remove refine_out | |||
605 | status = aim_rmFile(aimInfo, refine_out); | |||
606 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 606, __func__, 0); goto cleanup; }; | |||
607 | ||||
608 | // compute multiscale metric field | |||
609 | snprintf(command, PATH_MAX4096, | |||
610 | "%s multiscale %s %s %le %s > multiscaleOut.txt", | |||
611 | inputs[inref-1].vals.string, | |||
612 | refine_in, | |||
613 | inputs[inScalarFieldFile-1].vals.string, | |||
614 | inputs[inComplexity-1].vals.real, | |||
615 | metricFileName ); | |||
616 | ||||
617 | status = aim_system(aimInfo, NULL((void*)0), command); | |||
618 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 618, __func__, 0); goto cleanup; }; | |||
619 | ||||
620 | } else if (inputs[inHessianFieldFile-1].nullVal == NotNull && | |||
621 | access(inputs[inHessianFieldFile-1].vals.string, F_OK0) == 0 && | |||
622 | aim_isFile(aimInfo, refine_out) == CAPS_SUCCESS0) { | |||
623 | ||||
624 | snprintf(refine_in, PATH_MAX4096, "refine_in%s", MESHEXTENSION".meshb"); | |||
625 | ||||
626 | // copy over refine_out to refine_in | |||
627 | status = aim_file(aimInfo, refine_out, aimFile); | |||
628 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 628, __func__, 0); goto cleanup; }; | |||
629 | status = aim_cpFile(aimInfo, aimFile, refine_in); | |||
630 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 630, __func__, 0); goto cleanup; }; | |||
631 | ||||
632 | // remove refine_out | |||
633 | status = aim_rmFile(aimInfo, refine_out); | |||
634 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 634, __func__, 0); goto cleanup; }; | |||
635 | ||||
636 | // compute multiscale metric field | |||
637 | snprintf(command, PATH_MAX4096, | |||
638 | "%s multiscale %s %s %le %s --hessian > multiscaleOut.txt", | |||
639 | inputs[inref-1].vals.string, | |||
640 | refine_in, | |||
641 | inputs[inHessianFieldFile-1].vals.string, | |||
642 | inputs[inComplexity-1].vals.real, | |||
643 | metricFileName ); | |||
644 | ||||
645 | status = aim_system(aimInfo, NULL((void*)0), command); | |||
646 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 646, __func__, 0); goto cleanup; }; | |||
647 | ||||
648 | } else if (inputs[inMetricFieldFile-1].nullVal == NotNull && | |||
649 | access(inputs[inMetricFieldFile-1].vals.string, F_OK0) == 0 && | |||
650 | aim_isFile(aimInfo, refine_out) == CAPS_SUCCESS0) { | |||
651 | ||||
652 | // get the relative path | |||
653 | aim_relPath(aimInfo, inputs[inMetricFieldFile-1].vals.string, metricFileName, relPath); | |||
654 | ||||
655 | if (strncmp(relPath, metricFileName, PATH_MAX4096) != 0) { | |||
656 | // Simply create a link to the file | |||
657 | status = aim_symLink(aimInfo, relPath, metricFileName); | |||
658 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 658, __func__, 0); goto cleanup; }; | |||
659 | } | |||
660 | ||||
661 | } else { | |||
662 | if (refineInstance->meshRef != NULL((void*)0)) { | |||
663 | /* create a symbolic link to the file name*/ | |||
664 | snprintf(refine_in, PATH_MAX4096, "%s%s", refineInstance->meshRef->fileName, MESHEXTENSION".meshb"); | |||
665 | status = aim_symLink(aimInfo, refine_in, refine_out); | |||
666 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 666, __func__, 0); goto cleanup; }; | |||
667 | } else if (refineInstance->surfaceMesh != NULL((void*)0)) { | |||
668 | /* write the libMeshb file */ | |||
669 | status = aim_file(aimInfo, refine_out, refine_in); | |||
670 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 670, __func__, 0); goto cleanup; }; | |||
671 | ||||
672 | status = writelibMeshb(aimInfo, refineInstance->surfaceMesh->egadsTess, refine_in); | |||
673 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 673, __func__, 0); goto cleanup; }; | |||
674 | } else { | |||
675 | AIM_ERROR(aimInfo, "Developer error!"){ aim_message(aimInfo, CERROR, 0 , "refineAIM.c", 675, __func__ , "Developer error!"); }; | |||
676 | status = CAPS_NOTIMPLEMENT-334; | |||
677 | goto cleanup; | |||
678 | } | |||
679 | } | |||
680 | ||||
681 | status = aim_getBodies(aimInfo, &intents, &nBody, &bodies); | |||
682 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 682, __func__, 0); goto cleanup; }; | |||
683 | ||||
684 | AIM_ALLOC(bodyCopy, nBody, ego, aimInfo, status){ if (bodyCopy != ((void*)0)) { status = -4; aim_status(aimInfo , status, "refineAIM.c", 684, __func__, 1, "AIM_ALLOC: %s != NULL" , "bodyCopy"); goto cleanup; } size_t memorysize = nBody; bodyCopy = (ego *) EG_alloc(memorysize*sizeof(ego)); if (bodyCopy == ( (void*)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c" , 684, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "bodyCopy" , memorysize, "ego"); goto cleanup; } }; | |||
685 | for (i = 0; i < nBody; i++) bodyCopy[i] = NULL((void*)0); | |||
686 | ||||
687 | // Get context | |||
688 | status = EG_getContext(bodies[0], &context); | |||
689 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 689, __func__, 0); goto cleanup; }; | |||
690 | ||||
691 | // Make a copy of the bodies | |||
692 | for (i = 0; i < nBody; i++) { | |||
693 | status = EG_copyObject(bodies[i], NULL((void*)0), &bodyCopy[i]); | |||
694 | if (status != EGADS_SUCCESS0) goto cleanup; | |||
695 | } | |||
696 | ||||
697 | // Create a model from the copied bodies | |||
698 | status = EG_makeTopology(context, NULL((void*)0), MODEL26, 0, NULL((void*)0), nBody, bodyCopy, | |||
699 | NULL((void*)0), &model); | |||
700 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 700, __func__, 0); goto cleanup; }; | |||
701 | AIM_NOTNULL(model, aimInfo, status){ if (model == ((void*)0)) { status = -307; aim_status(aimInfo , status, "refineAIM.c", 701, __func__, 1, "%s == NULL!", "model" ); goto cleanup; } }; | |||
702 | ||||
703 | status = aim_file(aimInfo, egadsFileName, aimEgadsFile); | |||
704 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 704, __func__, 0); goto cleanup; }; | |||
705 | ||||
706 | //printf("Writing egads file '%s'....\n", aimEgadsFile); | |||
707 | remove(aimEgadsFile); | |||
708 | status = EG_saveModel(model, aimEgadsFile); | |||
709 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 709, __func__, 0); goto cleanup; }; | |||
710 | ||||
711 | fp = aim_fopen(aimInfo, refInput, "w"); | |||
712 | if (fp == NULL((void*)0)) { | |||
713 | AIM_ERROR(aimInfo, "Cannot open %s", refInput){ aim_message(aimInfo, CERROR, 0 , "refineAIM.c", 713, __func__ , "Cannot open %s", refInput); }; | |||
714 | status = CAPS_IOERR-332; | |||
715 | goto cleanup; | |||
716 | } | |||
717 | ||||
718 | fprintf(fp, | |||
719 | " adapt refine_in.meshb --metric %s --egads %s -s %d -x refine_out.meshb", | |||
720 | metricFileName, | |||
721 | egadsFileName, | |||
722 | inputs[inPasses-1].vals.integer); | |||
723 | ||||
724 | cleanup: | |||
725 | ||||
726 | if (model != NULL((void*)0)) { | |||
727 | EG_deleteObject(model); | |||
728 | } else { | |||
729 | if (bodyCopy != NULL((void*)0)) { | |||
730 | for (i = 0; i < nBody; i++) { | |||
731 | if (bodyCopy[i] != NULL((void*)0)) { | |||
732 | (void) EG_deleteObject(bodyCopy[i]); | |||
733 | } | |||
734 | } | |||
735 | } | |||
736 | } | |||
737 | AIM_FREE(bodyCopy){ EG_free(bodyCopy); bodyCopy = ((void*)0); }; | |||
738 | if (fp != NULL((void*)0)) fclose(fp); | |||
739 | ||||
740 | return status; | |||
741 | } | |||
742 | ||||
743 | ||||
744 | // ********************** AIM Function Break ***************************** | |||
745 | /* aimExecute: runs the Analysis & specifies the AIM does the execution */ | |||
746 | int | |||
747 | aimExecute(/*@unused@*/ const void *instStor, /*@unused@*/ void *aimInfo, | |||
748 | int *state) | |||
749 | { | |||
750 | /*! \page aimExecuteRefine AIM Execution | |||
751 | * | |||
752 | * If auto execution is enabled when creating an refine AIM, | |||
753 | * the AIM will execute refine just-in-time with the command line: | |||
754 | * | |||
755 | * \code{.sh} | |||
756 | * ref $(< refInput.txt) > refOutput.txt | |||
757 | * \endcode | |||
758 | * | |||
759 | * where preAnalysis generated the file "refInput.txt" which contains commandline arguments for ref. | |||
760 | * | |||
761 | * The refine analysis directory is assumed to contain a metric.meshb file. This file will | |||
762 | * be generated automatically with preAnalysis using ScalarFieldFile or HessianFieldFile inputs, or | |||
763 | * can be generated manually via system calls to refine and setting MetricFieldFile. | |||
764 | * | |||
765 | * The analysis can be also be explicitly executed with caps_execute in the C-API | |||
766 | * or via Analysis.runAnalysis in the pyCAPS API. | |||
767 | * | |||
768 | * Calling preAnalysis and postAnalysis is NOT allowed when auto execution is enabled. | |||
769 | * | |||
770 | * Auto execution can also be disabled when creating an refine AIM object. | |||
771 | * In this mode, caps_execute and Analysis.runAnalysis can be used to run the analysis, | |||
772 | * or refine can be executed by calling preAnalysis, system call, and posAnalysis as demonstrated | |||
773 | * below with a pyCAPS example: | |||
774 | * | |||
775 | * \code{.py} | |||
776 | * print ("\n\preAnalysis......") | |||
777 | * refine.preAnalysis() | |||
778 | * | |||
779 | * print ("\n\nRunning......") | |||
780 | * refine.system("ref $(< refInput.txt) > refOutput.txt"); # Run via system call | |||
781 | * | |||
782 | * print ("\n\postAnalysis......") | |||
783 | * refine.postAnalysis() | |||
784 | * \endcode | |||
785 | */ | |||
786 | ||||
787 | int status = CAPS_SUCCESS0; | |||
788 | char command[PATH_MAX4096]; | |||
789 | capsValue *ref; | |||
790 | ||||
791 | *state = 0; | |||
792 | ||||
793 | if (aim_isFile(aimInfo, metricFileName) != CAPS_SUCCESS0) | |||
794 | return CAPS_SUCCESS0; | |||
795 | ||||
796 | status = aim_getValue(aimInfo, inref, ANALYSISIN, &ref); | |||
797 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 797, __func__, 0); goto cleanup; }; | |||
798 | ||||
799 | // execute refine adapt in serial | |||
800 | snprintf(command, PATH_MAX4096, | |||
801 | "%s $(< %s) > refOutput.txt", | |||
802 | ref->vals.string, refInput); | |||
803 | ||||
804 | status = aim_system(aimInfo, NULL((void*)0), command); | |||
805 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 805, __func__, 0); goto cleanup; }; | |||
806 | ||||
807 | cleanup: | |||
808 | return status; | |||
809 | } | |||
810 | ||||
811 | ||||
812 | // ********************** AIM Function Break ***************************** | |||
813 | /* aimPostAnalysis: Perform any processing after the Analysis is run */ | |||
814 | int | |||
815 | aimPostAnalysis(void *instStore, void *aimInfo, | |||
816 | /*@unused@*/ int restart, /*@unused@*/ capsValue *inputs) | |||
817 | { | |||
818 | int status = CAPS_SUCCESS0; | |||
819 | aimMesh mesh; | |||
820 | aimStorage *refineInstance; | |||
821 | ||||
822 | refineInstance = (aimStorage *) instStore; | |||
823 | ||||
824 | /*@-immediatetrans@*/ | |||
825 | mesh.meshData = NULL((void*)0); | |||
826 | mesh.meshRef = &refineInstance->meshRefOut; | |||
827 | /*@+immediatetrans@*/ | |||
828 | ||||
829 | //Only read the surface tessellation | |||
830 | status = readlibMeshb(aimInfo, refineInstance, &mesh); | |||
831 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 831, __func__, 0); goto cleanup; }; | |||
832 | ||||
833 | status = aim_freeMeshData(mesh.meshData); | |||
834 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 834, __func__, 0); goto cleanup; }; | |||
835 | AIM_FREE(mesh.meshData){ EG_free(mesh.meshData); mesh.meshData = ((void*)0); }; | |||
836 | ||||
837 | cleanup: | |||
838 | return status; | |||
839 | } | |||
840 | ||||
841 | ||||
842 | // ********************** AIM Function Break ***************************** | |||
843 | /* aimOutputs: Output Information for the AIM */ | |||
844 | int | |||
845 | aimOutputs(/*@unused@*/ void *instStore, /*@unused@*/ void *aimInfo, | |||
846 | /*@unused@*/ int index, char **aoname, capsValue *form) | |||
847 | { | |||
848 | int status = CAPS_SUCCESS0; | |||
849 | #ifdef DEBUG | |||
850 | printf(" skeletonAIM/aimOutputs instance = %d index = %d!\n", | |||
851 | aim_getInstance(aimInfo), index); | |||
852 | #endif | |||
853 | ||||
854 | /*! \page aimOutputsRefine AIM Outputs | |||
855 | * List of available outputs from the refine AIM | |||
856 | */ | |||
857 | ||||
858 | if (index == outMesh) { | |||
859 | ||||
860 | *aoname = AIM_NAME(Mesh)EG_strdup("Mesh"); | |||
861 | form->type = PointerMesh; | |||
862 | form->dim = Scalar; | |||
863 | form->lfixed = Fixed; | |||
864 | form->sfixed = Fixed; | |||
865 | form->vals.AIMptr = NULL((void*)0); | |||
866 | form->nullVal = IsNull; | |||
867 | ||||
868 | /*! \page aimOutputsRefine | |||
869 | * - <B> Mesh </B> <br> | |||
870 | * The output Area_Mesh or Volume_Mesh for a link | |||
871 | */ | |||
872 | ||||
873 | } else if (index == outSurface_Mesh) { | |||
874 | ||||
875 | *aoname = AIM_NAME(Surface_Mesh)EG_strdup("Surface_Mesh"); | |||
876 | form->type = Pointer; | |||
877 | form->dim = Scalar; | |||
878 | form->lfixed = Fixed; | |||
879 | form->sfixed = Fixed; | |||
880 | form->vals.AIMptr = NULL((void*)0); | |||
881 | form->nullVal = IsNull; | |||
882 | AIM_STRDUP(form->units, "meshStruct", aimInfo, status){ if (form->units != ((void*)0)) { status = -4; aim_status (aimInfo, status, "refineAIM.c", 882, __func__, 1, "AIM_STRDUP: %s != NULL!" , "form->units"); goto cleanup; } form->units = EG_strdup ("meshStruct"); if (form->units == ((void*)0)) { status = - 4; aim_status(aimInfo, status, "refineAIM.c", 882, __func__, 2 , "AIM_STRDUP: %s %s", "form->units", "meshStruct"); goto cleanup ; } }; | |||
883 | ||||
884 | /*! \page aimOutputsRefine | |||
885 | * - <B> Surface_Mesh </B> <br> | |||
886 | * The surface mesh for a link | |||
887 | */ | |||
888 | ||||
889 | } else if (index == outxyz) { | |||
890 | ||||
891 | *aoname = AIM_NAME(xyz)EG_strdup("xyz"); | |||
892 | form->type = Double; | |||
893 | form->dim = Array2D; | |||
894 | ||||
895 | /*! \page aimOutputsRefine | |||
896 | * - <B> xyz </B> <br> | |||
897 | * Grid coordinates. Useful for constructing scalar, hessian, or metric fields | |||
898 | */ | |||
899 | ||||
900 | } else { | |||
901 | status = CAPS_BADINDEX-304; | |||
902 | AIM_STATUS(aimInfo, status, "Unknown output index %d!", index)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 902, __func__, 2, "Unknown output index %d!", index); goto cleanup ; }; | |||
903 | } | |||
904 | ||||
905 | AIM_NOTNULL(*aoname, aimInfo, status){ if (*aoname == ((void*)0)) { status = -307; aim_status(aimInfo , status, "refineAIM.c", 905, __func__, 1, "%s == NULL!", "*aoname" ); goto cleanup; } }; | |||
906 | ||||
907 | cleanup: | |||
908 | return status; | |||
909 | } | |||
910 | ||||
911 | ||||
912 | // ********************** AIM Function Break ***************************** | |||
913 | /* aimCalcOutput: Calculate/Retrieve Output Information */ | |||
914 | int | |||
915 | aimCalcOutput(void *instStore, void *aimInfo, | |||
916 | int index, capsValue *val) | |||
917 | { | |||
918 | int i, j, status = CAPS_SUCCESS0; | |||
919 | aimStorage *refineInstance; | |||
920 | aimMesh mesh; | |||
921 | ||||
922 | refineInstance = (aimStorage *) instStore; | |||
923 | ||||
924 | ||||
925 | if (outMesh == index) { | |||
926 | ||||
927 | status = aim_queryMeshes( aimInfo, outMesh, &refineInstance->meshRefOut ); | |||
928 | if (status > 0) { | |||
929 | /*@-immediatetrans@*/ | |||
930 | mesh.meshData = NULL((void*)0); | |||
931 | mesh.meshRef = &refineInstance->meshRefOut; | |||
932 | /*@+immediatetrans@*/ | |||
933 | ||||
934 | status = readlibMeshb(aimInfo, refineInstance, &mesh); | |||
935 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 935, __func__, 0); goto cleanup; }; | |||
936 | ||||
937 | status = aim_writeMeshes(aimInfo, outMesh, &mesh); | |||
938 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 938, __func__, 0); goto cleanup; }; | |||
939 | ||||
940 | status = aim_freeMeshData(mesh.meshData); | |||
941 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 941, __func__, 0); goto cleanup; }; | |||
942 | AIM_FREE(mesh.meshData){ EG_free(mesh.meshData); mesh.meshData = ((void*)0); }; | |||
943 | } | |||
944 | else | |||
945 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 945, __func__, 0); goto cleanup; }; | |||
946 | ||||
947 | /*@-immediatetrans@*/ | |||
948 | // Return the volume mesh references | |||
949 | val->nrow = 1; | |||
950 | val->vals.AIMptr = &refineInstance->meshRefOut; | |||
951 | /*@+immediatetrans@*/ | |||
952 | ||||
953 | //} else if (index == outSurface_Mesh) { | |||
954 | ||||
955 | } else if (index == outxyz) { | |||
956 | ||||
957 | /*@-immediatetrans@*/ | |||
958 | mesh.meshData = NULL((void*)0); | |||
959 | mesh.meshRef = &refineInstance->meshRefOut; | |||
960 | /*@+immediatetrans@*/ | |||
961 | ||||
962 | status = readlibMeshb(aimInfo, refineInstance, &mesh); | |||
963 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 963, __func__, 0); goto cleanup; }; | |||
964 | ||||
965 | AIM_ALLOC(val->vals.reals, mesh.meshData->dim*mesh.meshData->nVertex, double, aimInfo, status){ if (val->vals.reals != ((void*)0)) { status = -4; aim_status (aimInfo, status, "refineAIM.c", 965, __func__, 1, "AIM_ALLOC: %s != NULL" , "val->vals.reals"); goto cleanup; } size_t memorysize = mesh .meshData->dim*mesh.meshData->nVertex; val->vals.reals = (double *) EG_alloc(memorysize*sizeof(double)); if (val-> vals.reals == ((void*)0)) { status = -4; aim_status(aimInfo, status , "refineAIM.c", 965, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "val->vals.reals", memorysize, "double"); goto cleanup; } }; | |||
966 | val->nrow = mesh.meshData->nVertex; | |||
967 | val->ncol = mesh.meshData->dim; | |||
968 | ||||
969 | for (i = 0; i < mesh.meshData->nVertex; i++) { | |||
970 | for (j = 0; j < mesh.meshData->dim; j++) { | |||
971 | val->vals.reals[mesh.meshData->dim*i+j] = mesh.meshData->verts[i][j]; | |||
972 | } | |||
973 | } | |||
974 | ||||
975 | status = aim_freeMeshData(mesh.meshData); | |||
976 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 976, __func__, 0); goto cleanup; }; | |||
977 | AIM_FREE(mesh.meshData){ EG_free(mesh.meshData); mesh.meshData = ((void*)0); }; | |||
978 | ||||
979 | } else { | |||
980 | ||||
981 | status = CAPS_BADINDEX-304; | |||
982 | AIM_STATUS(aimInfo, status, "Unknown output index %d!", index)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 982, __func__, 2, "Unknown output index %d!", index); goto cleanup ; }; | |||
983 | ||||
984 | } | |||
985 | ||||
986 | cleanup: | |||
987 | return status; | |||
988 | } | |||
989 | ||||
990 | ||||
991 | // ********************** AIM Function Break ***************************** | |||
992 | /* aimCleanup: Free up the AIMs storage */ | |||
993 | void aimCleanup(/*@unused@*/ void *instStore) | |||
994 | { | |||
995 | aimStorage *refineInstance = NULL((void*)0); | |||
996 | ||||
997 | /* clean up any allocated data */ | |||
998 | ||||
999 | refineInstance = (aimStorage *) instStore; | |||
1000 | if (refineInstance == NULL((void*)0)) return; | |||
1001 | ||||
1002 | destroy_aimStorage(refineInstance); | |||
1003 | AIM_FREE(refineInstance){ EG_free(refineInstance); refineInstance = ((void*)0); }; | |||
1004 | } | |||
1005 | ||||
1006 | ||||
1007 | // ********************** AIM Function Break ***************************** | |||
1008 | static void swapd(double *xp, double *yp) | |||
1009 | { | |||
1010 | double temp = *xp; | |||
1011 | *xp = *yp; | |||
1012 | *yp = temp; | |||
1013 | } | |||
1014 | ||||
1015 | static void swapi(int *xp, int *yp) | |||
1016 | { | |||
1017 | int temp = *xp; | |||
1018 | *xp = *yp; | |||
1019 | *yp = temp; | |||
1020 | } | |||
1021 | ||||
1022 | ||||
1023 | // ********************** AIM Function Break ***************************** | |||
1024 | // A function to implement bubble sort | |||
1025 | static void | |||
1026 | bubbleSortEdge(edgeData *tedge) | |||
1027 | { | |||
1028 | ||||
1029 | int i, j; | |||
1030 | for (i = 0; i < tedge->npts-1; i++) | |||
1031 | // Last i elements are already in place | |||
1032 | for (j = 0; j < tedge->npts-i-1; j++) | |||
1033 | if (tedge->t[j] > tedge->t[j+1]) { | |||
1034 | swapd(&tedge->t[j] , &tedge->t[j+1] ); | |||
1035 | swapd(&tedge->xyz[3*j+0], &tedge->xyz[3*(j+1)+0]); | |||
1036 | swapd(&tedge->xyz[3*j+1], &tedge->xyz[3*(j+1)+1]); | |||
1037 | swapd(&tedge->xyz[3*j+2], &tedge->xyz[3*(j+1)+2]); | |||
1038 | swapi(&tedge->ivp[j] , &tedge->ivp[j+1] ); | |||
1039 | } | |||
1040 | } | |||
1041 | ||||
1042 | ||||
1043 | static void | |||
1044 | bubbleSortFace(faceData *tface) | |||
1045 | { | |||
1046 | ||||
1047 | int i, j; | |||
1048 | for (i = 0; i < tface->npts-1; i++) | |||
1049 | // Last i elements are already in place | |||
1050 | for (j = 0; j < tface->npts-i-1; j++) | |||
1051 | if (tface->ivp[j] > tface->ivp[j+1]) { | |||
1052 | swapd(&tface->uv[2*j+0] , &tface->uv[2*(j+1)+0] ); | |||
1053 | swapd(&tface->uv[2*j+1] , &tface->uv[2*(j+1)+1] ); | |||
1054 | swapd(&tface->xyz[3*j+0], &tface->xyz[3*(j+1)+0]); | |||
1055 | swapd(&tface->xyz[3*j+1], &tface->xyz[3*(j+1)+1]); | |||
1056 | swapd(&tface->xyz[3*j+2], &tface->xyz[3*(j+1)+2]); | |||
1057 | swapi(&tface->ivp[j] , &tface->ivp[j+1] ); | |||
1058 | } | |||
1059 | } | |||
1060 | ||||
1061 | ||||
1062 | static int | |||
1063 | faceIndex(const int ivp, faceData *tface) | |||
1064 | { | |||
1065 | int i0 = 0; | |||
1066 | int i1 = tface->npts/2; | |||
1067 | int i2 = tface->npts; | |||
1068 | ||||
1069 | while(tface->ivp[i1] != ivp) { | |||
1070 | if (ivp > tface->ivp[i1]) { | |||
1071 | i0 = i1; | |||
1072 | i1 = (i1 + i2)/2; | |||
1073 | } else { | |||
1074 | i2 = i1; | |||
1075 | i1 = (i0 + i1)/2; | |||
1076 | } | |||
1077 | } | |||
1078 | ||||
1079 | return i1+1; | |||
1080 | } | |||
1081 | ||||
1082 | // ********************** AIM Function Break ***************************** | |||
1083 | static int | |||
1084 | readlibMeshb(void *aimInfo, aimStorage *refineInstance, aimMesh *mesh) | |||
1085 | { | |||
1086 | int status = CAPS_SUCCESS0; | |||
1087 | ||||
1088 | char attrname[128]; | |||
1089 | int nBody=0, nLine=0, nTri=0, nTet=0; | |||
1090 | int i, j, elementIndex, nPoint, igroup, iglobal, nglobal; | |||
| ||||
1091 | int elem[4], ivp, id, npts, ntri, iedge, iface; | |||
1092 | int meshVersion, nEdgeVerts, nFaceVerts, *faceGroups=NULL((void*)0), *edgeGroups=NULL((void*)0), tetGroup; | |||
1093 | int oclass, mtype, *faceVertID=NULL((void*)0), *face_tris; | |||
1094 | double reference, t, uv[2], double_gref; | |||
1095 | double result[18]; | |||
1096 | double *face_uv = NULL((void*)0), *face_xyz = NULL((void*)0); | |||
1097 | double v1[3], v2[3], faceNormal[3], triNormal[3], ndot; | |||
1098 | const int *tris = NULL((void*)0), *tric = NULL((void*)0), *ptype = NULL((void*)0), *pindex = NULL((void*)0); | |||
1099 | const double *pxyz = NULL((void*)0), *puv = NULL((void*)0); | |||
1100 | enum aimMeshElem elementTopo; | |||
1101 | char filename[PATH_MAX4096]; | |||
1102 | int64_t fileID=0; | |||
1103 | aimMeshData *meshData = NULL((void*)0); | |||
1104 | bodyData bodydata; | |||
1105 | const char *intents; | |||
1106 | ego *bodies, body, tess, ref, prev, next; | |||
1107 | ||||
1108 | if (mesh == NULL((void*)0)) return CAPS_NULLOBJ-309; | |||
1109 | if (mesh->meshRef == NULL((void*)0)) return CAPS_NULLOBJ-309; | |||
1110 | if (mesh->meshRef->fileName == NULL((void*)0)) return CAPS_NULLOBJ-309; | |||
1111 | ||||
1112 | status = initiate_bodyData(1, &bodydata); | |||
1113 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1113, __func__, 0); goto cleanup; }; | |||
1114 | ||||
1115 | status = aim_getBodies(aimInfo, &intents, &nBody, &bodies); | |||
1116 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1116, __func__, 0); goto cleanup; }; | |||
1117 | ||||
1118 | body = bodies[0]; | |||
1119 | ||||
1120 | status = EG_getBodyTopos(body, NULL((void*)0), NODE20, &bodydata.nnodes, NULL((void*)0)); | |||
1121 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1121, __func__, 0); goto cleanup; }; | |||
1122 | ||||
1123 | status = EG_getBodyTopos(body, NULL((void*)0), EDGE21, &bodydata.nedges, &bodydata.edges); | |||
1124 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1124, __func__, 0); goto cleanup; }; | |||
1125 | ||||
1126 | status = EG_getBodyTopos(body, NULL((void*)0), FACE23, &bodydata.nfaces, &bodydata.faces); | |||
1127 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1127, __func__, 0); goto cleanup; }; | |||
1128 | ||||
1129 | status = aim_freeMeshData(mesh->meshData); | |||
1130 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1130, __func__, 0); goto cleanup; }; | |||
1131 | AIM_FREE(mesh->meshData){ EG_free(mesh->meshData); mesh->meshData = ((void*)0); }; | |||
1132 | ||||
1133 | AIM_ALLOC(meshData, 1, aimMeshData, aimInfo, status){ if (meshData != ((void*)0)) { status = -4; aim_status(aimInfo , status, "refineAIM.c", 1133, __func__, 1, "AIM_ALLOC: %s != NULL" , "meshData"); goto cleanup; } size_t memorysize = 1; meshData = (aimMeshData *) EG_alloc(memorysize*sizeof(aimMeshData)); if (meshData == ((void*)0)) { status = -4; aim_status(aimInfo, status , "refineAIM.c", 1133, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "meshData", memorysize, "aimMeshData"); goto cleanup; } }; | |||
1134 | status = aim_initMeshData(meshData); | |||
1135 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1135, __func__, 0); goto cleanup; }; | |||
1136 | ||||
1137 | snprintf(filename, PATH_MAX4096, "%s%s", mesh->meshRef->fileName, MESHEXTENSION".meshb"); | |||
1138 | ||||
1139 | fileID = GmfOpenMesh(filename, GmfRead1, &meshVersion, &meshData->dim); | |||
1140 | ||||
1141 | if (fileID == 0) { | |||
1142 | AIM_ERROR(aimInfo, "Cannot open file: %s\n", filename){ aim_message(aimInfo, CERROR, 0 , "refineAIM.c", 1142, __func__ , "Cannot open file: %s\n", filename); }; | |||
1143 | status = CAPS_IOERR-332; | |||
1144 | goto cleanup; | |||
1145 | } | |||
1146 | ||||
1147 | AIM_ALLOC(edgeGroups, bodydata.nedges, int, aimInfo, status){ if (edgeGroups != ((void*)0)) { status = -4; aim_status(aimInfo , status, "refineAIM.c", 1147, __func__, 1, "AIM_ALLOC: %s != NULL" , "edgeGroups"); goto cleanup; } size_t memorysize = bodydata .nedges; edgeGroups = (int *) EG_alloc(memorysize*sizeof(int) ); if (edgeGroups == ((void*)0)) { status = -4; aim_status(aimInfo , status, "refineAIM.c", 1147, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "edgeGroups", memorysize, "int"); goto cleanup; } }; | |||
1148 | AIM_ALLOC(faceGroups, bodydata.nfaces, int, aimInfo, status){ if (faceGroups != ((void*)0)) { status = -4; aim_status(aimInfo , status, "refineAIM.c", 1148, __func__, 1, "AIM_ALLOC: %s != NULL" , "faceGroups"); goto cleanup; } size_t memorysize = bodydata .nfaces; faceGroups = (int *) EG_alloc(memorysize*sizeof(int) ); if (faceGroups == ((void*)0)) { status = -4; aim_status(aimInfo , status, "refineAIM.c", 1148, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "faceGroups", memorysize, "int"); goto cleanup; } }; | |||
1149 | for (i = 0; i < bodydata.nedges; i++) edgeGroups[i] = -1; | |||
1150 | for (i = 0; i < bodydata.nfaces; i++) faceGroups[i] = -1; | |||
1151 | tetGroup = -1; | |||
1152 | ||||
1153 | meshData->nVertex = GmfStatKwd(fileID, GmfVertices); | |||
1154 | AIM_ALLOC(meshData->verts, meshData->nVertex, aimMeshCoords, aimInfo, status){ if (meshData->verts != ((void*)0)) { status = -4; aim_status (aimInfo, status, "refineAIM.c", 1154, __func__, 1, "AIM_ALLOC: %s != NULL" , "meshData->verts"); goto cleanup; } size_t memorysize = meshData ->nVertex; meshData->verts = (aimMeshCoords *) EG_alloc (memorysize*sizeof(aimMeshCoords)); if (meshData->verts == ((void*)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c" , 1154, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "meshData->verts" , memorysize, "aimMeshCoords"); goto cleanup; } }; | |||
1155 | ||||
1156 | status = GmfGotoKwd(fileID, GmfVertices); | |||
1157 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1157, __func__, 0); goto cleanup; }; } | |||
1158 | ||||
1159 | // Real nodal coordinates | |||
1160 | if (meshData->dim == 2) { | |||
1161 | for (i = 0; i < meshData->nVertex; i++) { | |||
1162 | status = GmfGetLin(fileID, GmfVertices, &meshData->verts[i][0], | |||
1163 | &meshData->verts[i][1], &reference); | |||
1164 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1164, __func__, 0); goto cleanup; }; } | |||
1165 | } | |||
1166 | ||||
1167 | // read elements | |||
1168 | ||||
1169 | nLine = GmfStatKwd(fileID, GmfEdges); | |||
1170 | nTri = GmfStatKwd(fileID, GmfTriangles); | |||
1171 | ||||
1172 | meshData->nTotalElems = nLine + nTri; | |||
1173 | ||||
1174 | } else { | |||
1175 | for (i = 0; i < meshData->nVertex; i++) { | |||
1176 | status = GmfGetLin(fileID, GmfVertices, &meshData->verts[i][0], | |||
1177 | &meshData->verts[i][1], | |||
1178 | &meshData->verts[i][2], &reference); | |||
1179 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1179, __func__, 0); goto cleanup; }; } | |||
1180 | } | |||
1181 | ||||
1182 | // read elements | |||
1183 | ||||
1184 | nTri = GmfStatKwd(fileID, GmfTriangles); | |||
1185 | nTet = GmfStatKwd(fileID, GmfTetrahedra); | |||
1186 | ||||
1187 | meshData->nTotalElems = nTri + nTet; | |||
1188 | ||||
1189 | } | |||
1190 | ||||
1191 | ||||
1192 | // allocate the element map that maps back to the original element numbering | |||
1193 | AIM_ALLOC(meshData->elemMap, meshData->nTotalElems, aimMeshIndices, aimInfo, status){ if (meshData->elemMap != ((void*)0)) { status = -4; aim_status (aimInfo, status, "refineAIM.c", 1193, __func__, 1, "AIM_ALLOC: %s != NULL" , "meshData->elemMap"); goto cleanup; } size_t memorysize = meshData->nTotalElems; meshData->elemMap = (aimMeshIndices *) EG_alloc(memorysize*sizeof(aimMeshIndices)); if (meshData ->elemMap == ((void*)0)) { status = -4; aim_status(aimInfo , status, "refineAIM.c", 1193, __func__, 3, "AIM_ALLOC: %s size %zu type %s" , "meshData->elemMap", memorysize, "aimMeshIndices"); goto cleanup; } }; | |||
1194 | ||||
1195 | /* Start of element index */ | |||
1196 | elementIndex = 0; | |||
1197 | ||||
1198 | if (meshData->dim
| |||
1199 | ||||
1200 | // Elements Line | |||
1201 | status = GmfGotoKwd(fileID, GmfEdges); | |||
1202 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1202, __func__, 0); goto cleanup; }; } | |||
1203 | ||||
1204 | nPoint = 2; | |||
1205 | elementTopo = aimLine; | |||
1206 | for (i = 0; i < nLine; i++) { | |||
1207 | ||||
1208 | /* read the element and group */ | |||
1209 | status = GmfGetLin(fileID, GmfEdges, &elem[0], | |||
1210 | &elem[1], &igroup); | |||
1211 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1211, __func__, 0); goto cleanup; }; } | |||
1212 | ||||
1213 | if (igroup <= 0) { | |||
1214 | AIM_ERROR(aimInfo, "Group must be a positive number: %d!", igroup){ aim_message(aimInfo, CERROR, 0 , "refineAIM.c", 1214, __func__ , "Group must be a positive number: %d!", igroup); }; | |||
1215 | status = CAPS_IOERR-332; | |||
1216 | goto cleanup; | |||
1217 | } | |||
1218 | igroup -= 1; // make zero based | |||
1219 | ||||
1220 | /* add the group if necessary */ | |||
1221 | if (edgeGroups[igroup] == -1) { | |||
1222 | status = aim_addMeshElemGroup(aimInfo, NULL((void*)0), igroup, elementTopo, 1, nPoint, meshData); | |||
1223 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1223, __func__, 0); goto cleanup; }; | |||
1224 | edgeGroups[igroup] = meshData->nElemGroup-1; | |||
1225 | } | |||
1226 | igroup = edgeGroups[igroup]; | |||
1227 | ||||
1228 | /* add the element to the group */ | |||
1229 | status = aim_addMeshElem(aimInfo, 1, &meshData->elemGroups[igroup]); | |||
1230 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1230, __func__, 0); goto cleanup; }; | |||
1231 | ||||
1232 | /* set the element connectivity */ | |||
1233 | for (j = 0; j < nPoint; j++) | |||
1234 | meshData->elemGroups[igroup].elements[nPoint*(meshData->elemGroups[igroup].nElems-1) + j] = elem[j]; | |||
1235 | ||||
1236 | meshData->elemMap[elementIndex][0] = igroup; | |||
1237 | meshData->elemMap[elementIndex][1] = meshData->elemGroups[igroup].nElems-1; | |||
1238 | ||||
1239 | elementIndex += 1; | |||
1240 | } | |||
1241 | } | |||
1242 | ||||
1243 | AIM_ALLOC(bodydata.tfaces, bodydata.nfaces, faceData, aimInfo, status){ if (bodydata.tfaces != ((void*)0)) { status = -4; aim_status (aimInfo, status, "refineAIM.c", 1243, __func__, 1, "AIM_ALLOC: %s != NULL" , "bodydata.tfaces"); goto cleanup; } size_t memorysize = bodydata .nfaces; bodydata.tfaces = (faceData *) EG_alloc(memorysize*sizeof (faceData)); if (bodydata.tfaces == ((void*)0)) { status = -4 ; aim_status(aimInfo, status, "refineAIM.c", 1243, __func__, 3 , "AIM_ALLOC: %s size %zu type %s", "bodydata.tfaces", memorysize , "faceData"); goto cleanup; } }; | |||
1244 | for (j = 0; j
| |||
1245 | bodydata.tfaces[j].npts = 0; | |||
1246 | bodydata.tfaces[j].xyz = NULL((void*)0); | |||
1247 | bodydata.tfaces[j].uv = NULL((void*)0); | |||
1248 | bodydata.tfaces[j].ntri = 0; | |||
1249 | bodydata.tfaces[j].tris = NULL((void*)0); | |||
1250 | bodydata.tfaces[j].ivp = NULL((void*)0); | |||
1251 | } | |||
1252 | ||||
1253 | /* Elements triangles */ | |||
1254 | status = GmfGotoKwd(fileID, GmfTriangles); | |||
1255 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1255, __func__, 0); goto cleanup; }; } | |||
1256 | ||||
1257 | nPoint = 3; | |||
1258 | elementTopo = aimTri; | |||
1259 | for (i = 0; i < nTri; i++) { | |||
1260 | ||||
1261 | /* read the element and group */ | |||
1262 | status = GmfGetLin(fileID, GmfTriangles, &elem[0], | |||
1263 | &elem[1], | |||
1264 | &elem[2], &igroup); | |||
1265 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1265, __func__, 0); goto cleanup; }; } | |||
1266 | ||||
1267 | if (igroup <= 0) { | |||
1268 | AIM_ERROR(aimInfo, "Group must be a positive number: %d!", igroup){ aim_message(aimInfo, CERROR, 0 , "refineAIM.c", 1268, __func__ , "Group must be a positive number: %d!", igroup); }; | |||
1269 | status = CAPS_IOERR-332; | |||
1270 | goto cleanup; | |||
1271 | } | |||
1272 | igroup -= 1; // make zero based | |||
1273 | ||||
1274 | ntri = bodydata.tfaces[igroup].ntri; | |||
1275 | AIM_REALL(bodydata.tfaces[igroup].tris, 3*(ntri+1), int, aimInfo, status){ size_t memorysize = 3*(ntri+1); bodydata.tfaces[igroup].tris = (int *) EG_reall(bodydata.tfaces[igroup].tris, memorysize* sizeof(int)); if (bodydata.tfaces[igroup].tris == ((void*)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c", 1275 , __func__, 3, "AIM_REALL: %s size %zu type %s", "bodydata.tfaces[igroup].tris" , memorysize, "int"); goto cleanup; } }; | |||
1276 | bodydata.tfaces[igroup].tris[3*ntri+0] = elem[0]; | |||
1277 | bodydata.tfaces[igroup].tris[3*ntri+1] = elem[1]; | |||
1278 | bodydata.tfaces[igroup].tris[3*ntri+2] = elem[2]; | |||
1279 | bodydata.tfaces[igroup].ntri++; | |||
1280 | ||||
1281 | igroup = refineInstance->faceID[igroup]-1; | |||
1282 | ||||
1283 | /* add the group if necessary */ | |||
1284 | if (faceGroups[igroup] == -1) { | |||
1285 | status = aim_addMeshElemGroup(aimInfo, NULL((void*)0), igroup+1, elementTopo, 1, nPoint, meshData); | |||
1286 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1286, __func__, 0); goto cleanup; }; | |||
1287 | faceGroups[igroup] = meshData->nElemGroup-1; | |||
1288 | } | |||
1289 | igroup = faceGroups[igroup]; | |||
1290 | ||||
1291 | /* add the element to the group */ | |||
1292 | status = aim_addMeshElem(aimInfo, 1, &meshData->elemGroups[igroup]); | |||
1293 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1293, __func__, 0); goto cleanup; }; | |||
1294 | ||||
1295 | /* set the element connectivity */ | |||
1296 | for (j = 0; j < nPoint; j++) | |||
1297 | meshData->elemGroups[igroup].elements[nPoint*(meshData->elemGroups[igroup].nElems-1) + j] = elem[j]; | |||
1298 | ||||
1299 | meshData->elemMap[elementIndex][0] = igroup; | |||
1300 | meshData->elemMap[elementIndex][1] = meshData->elemGroups[igroup].nElems-1; | |||
1301 | ||||
1302 | elementIndex += 1; | |||
1303 | } | |||
1304 | ||||
1305 | // If the surface mesh has been processed, read Tets | |||
1306 | if (mesh->meshRef->maps != NULL((void*)0)) { | |||
1307 | ||||
1308 | // Elements Tetrahedral | |||
1309 | status = GmfGotoKwd(fileID, GmfTetrahedra); | |||
1310 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1310, __func__, 0); goto cleanup; }; } | |||
1311 | ||||
1312 | nPoint = 4; | |||
1313 | elementTopo = aimTet; | |||
1314 | ||||
1315 | /* add the group tetGroup */ | |||
1316 | if (tetGroup == -1) { | |||
1317 | status = aim_addMeshElemGroup(aimInfo, NULL((void*)0), igroup, elementTopo, 1, nPoint, meshData); | |||
| ||||
1318 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1318, __func__, 0); goto cleanup; }; | |||
1319 | tetGroup = meshData->nElemGroup-1; | |||
1320 | } | |||
1321 | igroup = tetGroup; | |||
1322 | ||||
1323 | /* add the element to the group */ | |||
1324 | status = aim_addMeshElem(aimInfo, nTet, &meshData->elemGroups[igroup]); | |||
1325 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1325, __func__, 0); goto cleanup; }; | |||
1326 | ||||
1327 | for (i = 0; i < nTet; i++) { | |||
1328 | ||||
1329 | /* read the element and group */ | |||
1330 | status = GmfGetLin(fileID, GmfTetrahedra, &elem[0], | |||
1331 | &elem[1], | |||
1332 | &elem[2], | |||
1333 | &elem[3], &igroup); | |||
1334 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1334, __func__, 0); goto cleanup; }; } | |||
1335 | ||||
1336 | if (igroup != 0) { | |||
1337 | AIM_ERROR(aimInfo, "Tetrahedra group must be 0: %d!", igroup){ aim_message(aimInfo, CERROR, 0 , "refineAIM.c", 1337, __func__ , "Tetrahedra group must be 0: %d!", igroup); }; | |||
1338 | status = CAPS_IOERR-332; | |||
1339 | goto cleanup; | |||
1340 | } | |||
1341 | ||||
1342 | igroup = tetGroup; | |||
1343 | ||||
1344 | /* set the element connectivity */ | |||
1345 | for (j = 0; j < nPoint; j++) | |||
1346 | meshData->elemGroups[igroup].elements[nPoint*(meshData->elemGroups[igroup].nElems-1) + j] = elem[j]; | |||
1347 | ||||
1348 | meshData->elemMap[elementIndex][0] = igroup; | |||
1349 | meshData->elemMap[elementIndex][1] = meshData->elemGroups[igroup].nElems-1; | |||
1350 | ||||
1351 | elementIndex += 1; | |||
1352 | } | |||
1353 | ||||
1354 | } else { | |||
1355 | // generate tessellation | |||
1356 | ||||
1357 | // read parametric coordinates | |||
1358 | ||||
1359 | AIM_ALLOC(bodydata.tedges, bodydata.nedges, edgeData, aimInfo, status){ if (bodydata.tedges != ((void*)0)) { status = -4; aim_status (aimInfo, status, "refineAIM.c", 1359, __func__, 1, "AIM_ALLOC: %s != NULL" , "bodydata.tedges"); goto cleanup; } size_t memorysize = bodydata .nedges; bodydata.tedges = (edgeData *) EG_alloc(memorysize*sizeof (edgeData)); if (bodydata.tedges == ((void*)0)) { status = -4 ; aim_status(aimInfo, status, "refineAIM.c", 1359, __func__, 3 , "AIM_ALLOC: %s size %zu type %s", "bodydata.tedges", memorysize , "edgeData"); goto cleanup; } }; | |||
1360 | for (j = 0; j < bodydata.nedges; j++) { | |||
1361 | bodydata.tedges[j].npts = 0; | |||
1362 | bodydata.tedges[j].xyz = NULL((void*)0); | |||
1363 | bodydata.tedges[j].t = NULL((void*)0); | |||
1364 | bodydata.tedges[j].ivp = NULL((void*)0); | |||
1365 | } | |||
1366 | ||||
1367 | // Read EDGEs | |||
1368 | nEdgeVerts = GmfStatKwd(fileID, GmfVerticesOnGeometricEdges); | |||
1369 | status = GmfGotoKwd(fileID, GmfVerticesOnGeometricEdges); | |||
1370 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1370, __func__, 0); goto cleanup; }; } | |||
1371 | ||||
1372 | // first count points on each edge | |||
1373 | for (j = 0; j < nEdgeVerts; j++) { | |||
1374 | status = GmfGetLin(fileID, GmfVerticesOnGeometricEdges, | |||
1375 | &ivp, | |||
1376 | &id, | |||
1377 | &t, | |||
1378 | &double_gref); // refine abuse of dist | |||
1379 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1379, __func__, 0); goto cleanup; }; } | |||
1380 | ||||
1381 | if (id <= 0 || id > bodydata.nedges) { | |||
1382 | AIM_ERROR(aimInfo, "Edge ID %d is out of range [1, %d]", id, bodydata.nedges){ aim_message(aimInfo, CERROR, 0 , "refineAIM.c", 1382, __func__ , "Edge ID %d is out of range [1, %d]", id, bodydata.nedges); }; | |||
1383 | status = CAPS_IOERR-332; | |||
1384 | goto cleanup; | |||
1385 | } | |||
1386 | bodydata.tedges[id-1].npts++; | |||
1387 | } | |||
1388 | ||||
1389 | for (j = 0; j < bodydata.nedges; j++) { | |||
1390 | npts = bodydata.tedges[j].npts; | |||
1391 | AIM_ALLOC(bodydata.tedges[j].xyz, 3*npts, double, aimInfo, status){ if (bodydata.tedges[j].xyz != ((void*)0)) { status = -4; aim_status (aimInfo, status, "refineAIM.c", 1391, __func__, 1, "AIM_ALLOC: %s != NULL" , "bodydata.tedges[j].xyz"); goto cleanup; } size_t memorysize = 3*npts; bodydata.tedges[j].xyz = (double *) EG_alloc(memorysize *sizeof(double)); if (bodydata.tedges[j].xyz == ((void*)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c", 1391 , __func__, 3, "AIM_ALLOC: %s size %zu type %s", "bodydata.tedges[j].xyz" , memorysize, "double"); goto cleanup; } }; | |||
1392 | AIM_ALLOC(bodydata.tedges[j].t , npts, double, aimInfo, status){ if (bodydata.tedges[j].t != ((void*)0)) { status = -4; aim_status (aimInfo, status, "refineAIM.c", 1392, __func__, 1, "AIM_ALLOC: %s != NULL" , "bodydata.tedges[j].t"); goto cleanup; } size_t memorysize = npts; bodydata.tedges[j].t = (double *) EG_alloc(memorysize* sizeof(double)); if (bodydata.tedges[j].t == ((void*)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c", 1392, __func__ , 3, "AIM_ALLOC: %s size %zu type %s", "bodydata.tedges[j].t" , memorysize, "double"); goto cleanup; } }; | |||
1393 | AIM_ALLOC(bodydata.tedges[j].ivp, npts, int , aimInfo, status){ if (bodydata.tedges[j].ivp != ((void*)0)) { status = -4; aim_status (aimInfo, status, "refineAIM.c", 1393, __func__, 1, "AIM_ALLOC: %s != NULL" , "bodydata.tedges[j].ivp"); goto cleanup; } size_t memorysize = npts; bodydata.tedges[j].ivp = (int *) EG_alloc(memorysize *sizeof(int)); if (bodydata.tedges[j].ivp == ((void*)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c", 1393, __func__ , 3, "AIM_ALLOC: %s size %zu type %s", "bodydata.tedges[j].ivp" , memorysize, "int"); goto cleanup; } }; | |||
1394 | bodydata.tedges[j].npts = 0; | |||
1395 | } | |||
1396 | ||||
1397 | status = GmfGotoKwd(fileID, GmfVerticesOnGeometricEdges); | |||
1398 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1398, __func__, 0); goto cleanup; }; } | |||
1399 | ||||
1400 | // read the data | |||
1401 | for (j = 0; j < nEdgeVerts; j++) { | |||
1402 | status = GmfGetLin(fileID, GmfVerticesOnGeometricEdges, | |||
1403 | &ivp, | |||
1404 | &id, | |||
1405 | &t, | |||
1406 | &double_gref); // refine abuse of dist | |||
1407 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1407, __func__, 0); goto cleanup; }; } | |||
1408 | ||||
1409 | npts = bodydata.tedges[id-1].npts; | |||
1410 | ||||
1411 | bodydata.tedges[id-1].t[npts] = t; | |||
1412 | ||||
1413 | bodydata.tedges[id-1].xyz[3*npts+0] = meshData->verts[ivp-1][0]; | |||
1414 | bodydata.tedges[id-1].xyz[3*npts+1] = meshData->verts[ivp-1][1]; | |||
1415 | bodydata.tedges[id-1].xyz[3*npts+2] = meshData->verts[ivp-1][2]; | |||
1416 | ||||
1417 | bodydata.tedges[id-1].ivp[npts] = ivp; | |||
1418 | ||||
1419 | bodydata.tedges[id-1].npts++; | |||
1420 | } | |||
1421 | ||||
1422 | for (j = 0; j < bodydata.nedges; j++) { | |||
1423 | bubbleSortEdge(&bodydata.tedges[j]); | |||
1424 | } | |||
1425 | ||||
1426 | ||||
1427 | // Count face points first | |||
1428 | nFaceVerts = GmfStatKwd(fileID, GmfVerticesOnGeometricTriangles); | |||
1429 | status = GmfGotoKwd(fileID, GmfVerticesOnGeometricTriangles); | |||
1430 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1430, __func__, 0); goto cleanup; }; } | |||
1431 | ||||
1432 | for (j = 0; j < nFaceVerts; j++) { | |||
1433 | ||||
1434 | status = GmfGetLin(fileID, GmfVerticesOnGeometricTriangles, | |||
1435 | &ivp, | |||
1436 | &id, | |||
1437 | &uv[0], &uv[1], | |||
1438 | &double_gref); // refine abuse of dist | |||
1439 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1439, __func__, 0); goto cleanup; }; } | |||
1440 | ||||
1441 | if (id <= 0 || id > bodydata.nfaces) { | |||
1442 | AIM_ERROR(aimInfo, "Face ID %d is out of range [1, %d]", id, bodydata.nfaces){ aim_message(aimInfo, CERROR, 0 , "refineAIM.c", 1442, __func__ , "Face ID %d is out of range [1, %d]", id, bodydata.nfaces); }; | |||
1443 | status = CAPS_IOERR-332; | |||
1444 | goto cleanup; | |||
1445 | } | |||
1446 | bodydata.tfaces[id-1].npts++; | |||
1447 | } | |||
1448 | ||||
1449 | for (j = 0; j < bodydata.nfaces; j++) { | |||
1450 | npts = bodydata.tfaces[j].npts; | |||
1451 | AIM_ALLOC(bodydata.tfaces[j].xyz , 3*npts, double, aimInfo, status){ if (bodydata.tfaces[j].xyz != ((void*)0)) { status = -4; aim_status (aimInfo, status, "refineAIM.c", 1451, __func__, 1, "AIM_ALLOC: %s != NULL" , "bodydata.tfaces[j].xyz"); goto cleanup; } size_t memorysize = 3*npts; bodydata.tfaces[j].xyz = (double *) EG_alloc(memorysize *sizeof(double)); if (bodydata.tfaces[j].xyz == ((void*)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c", 1451 , __func__, 3, "AIM_ALLOC: %s size %zu type %s", "bodydata.tfaces[j].xyz" , memorysize, "double"); goto cleanup; } }; | |||
1452 | AIM_ALLOC(bodydata.tfaces[j].uv , 2*npts, double, aimInfo, status){ if (bodydata.tfaces[j].uv != ((void*)0)) { status = -4; aim_status (aimInfo, status, "refineAIM.c", 1452, __func__, 1, "AIM_ALLOC: %s != NULL" , "bodydata.tfaces[j].uv"); goto cleanup; } size_t memorysize = 2*npts; bodydata.tfaces[j].uv = (double *) EG_alloc(memorysize *sizeof(double)); if (bodydata.tfaces[j].uv == ((void*)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c", 1452, __func__ , 3, "AIM_ALLOC: %s size %zu type %s", "bodydata.tfaces[j].uv" , memorysize, "double"); goto cleanup; } }; | |||
1453 | AIM_ALLOC(bodydata.tfaces[j].ivp , npts, int , aimInfo, status){ if (bodydata.tfaces[j].ivp != ((void*)0)) { status = -4; aim_status (aimInfo, status, "refineAIM.c", 1453, __func__, 1, "AIM_ALLOC: %s != NULL" , "bodydata.tfaces[j].ivp"); goto cleanup; } size_t memorysize = npts; bodydata.tfaces[j].ivp = (int *) EG_alloc(memorysize *sizeof(int)); if (bodydata.tfaces[j].ivp == ((void*)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c", 1453, __func__ , 3, "AIM_ALLOC: %s size %zu type %s", "bodydata.tfaces[j].ivp" , memorysize, "int"); goto cleanup; } }; | |||
1454 | bodydata.tfaces[j].npts = 0; | |||
1455 | } | |||
1456 | ||||
1457 | status = GmfGotoKwd(fileID, GmfVerticesOnGeometricTriangles); | |||
1458 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1458, __func__, 0); goto cleanup; }; } | |||
1459 | ||||
1460 | // read the data | |||
1461 | for (j = 0; j < nFaceVerts; j++) { | |||
1462 | status = GmfGetLin(fileID, GmfVerticesOnGeometricTriangles, | |||
1463 | &ivp, | |||
1464 | &id, | |||
1465 | &uv[0], &uv[1], | |||
1466 | &double_gref); // refine abuse of dist | |||
1467 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1467, __func__, 0); goto cleanup; }; } | |||
1468 | ||||
1469 | npts = bodydata.tfaces[id-1].npts; | |||
1470 | ||||
1471 | bodydata.tfaces[id-1].uv[2*npts+0] = uv[0]; | |||
1472 | bodydata.tfaces[id-1].uv[2*npts+1] = uv[1]; | |||
1473 | ||||
1474 | bodydata.tfaces[id-1].xyz[3*npts+0] = meshData->verts[ivp-1][0]; | |||
1475 | bodydata.tfaces[id-1].xyz[3*npts+1] = meshData->verts[ivp-1][1]; | |||
1476 | bodydata.tfaces[id-1].xyz[3*npts+2] = meshData->verts[ivp-1][2]; | |||
1477 | ||||
1478 | bodydata.tfaces[id-1].ivp[npts] = ivp; | |||
1479 | ||||
1480 | bodydata.tfaces[id-1].npts++; | |||
1481 | } | |||
1482 | ||||
1483 | for (j = 0; j < bodydata.nfaces; j++) { | |||
1484 | bubbleSortFace(&bodydata.tfaces[j]); | |||
1485 | // get the face triangulation | |||
1486 | for (i = 0; i < bodydata.tfaces[j].ntri; i++) { | |||
1487 | bodydata.tfaces[j].tris[3*i+0] = faceIndex(bodydata.tfaces[j].tris[3*i+0], &bodydata.tfaces[j]); | |||
1488 | bodydata.tfaces[j].tris[3*i+1] = faceIndex(bodydata.tfaces[j].tris[3*i+1], &bodydata.tfaces[j]); | |||
1489 | bodydata.tfaces[j].tris[3*i+2] = faceIndex(bodydata.tfaces[j].tris[3*i+2], &bodydata.tfaces[j]); | |||
1490 | } | |||
1491 | } | |||
1492 | ||||
1493 | // Allocate surfaceMesh from number of bodies | |||
1494 | AIM_ALLOC(mesh->meshRef->maps, 1, aimMeshTessMap, aimInfo, status){ if (mesh->meshRef->maps != ((void*)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c", 1494, __func__, 1 , "AIM_ALLOC: %s != NULL", "mesh->meshRef->maps"); goto cleanup; } size_t memorysize = 1; mesh->meshRef->maps = (aimMeshTessMap *) EG_alloc(memorysize*sizeof(aimMeshTessMap )); if (mesh->meshRef->maps == ((void*)0)) { status = - 4; aim_status(aimInfo, status, "refineAIM.c", 1494, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "mesh->meshRef->maps" , memorysize, "aimMeshTessMap"); goto cleanup; } }; | |||
1495 | mesh->meshRef->nmap = 1; | |||
1496 | mesh->meshRef->maps[0].tess = NULL((void*)0); | |||
1497 | mesh->meshRef->maps[0].map = NULL((void*)0); | |||
1498 | ||||
1499 | // Build up the body tessellation object | |||
1500 | status = EG_initTessBody(body, &tess); | |||
1501 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1501, __func__, 0); goto cleanup; }; | |||
1502 | AIM_NOTNULL(tess, aimInfo, status){ if (tess == ((void*)0)) { status = -307; aim_status(aimInfo , status, "refineAIM.c", 1502, __func__, 1, "%s == NULL!", "tess" ); goto cleanup; } }; | |||
1503 | ||||
1504 | for ( iedge = 0; iedge < bodydata.nedges; iedge++ ) { | |||
1505 | ||||
1506 | // Check if the edge is degenerate | |||
1507 | if (bodydata.edges[iedge]->mtype == DEGENERATE5) continue; | |||
1508 | ||||
1509 | status = EG_setTessEdge(tess, iedge+1, bodydata.tedges[iedge].npts, | |||
1510 | bodydata.tedges[iedge].xyz, | |||
1511 | bodydata.tedges[iedge].t); | |||
1512 | AIM_STATUS(aimInfo, status, "Failed to set tessellation on Edge %d!", iedge+1)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1512, __func__, 2, "Failed to set tessellation on Edge %d!", iedge+1); goto cleanup; }; | |||
1513 | ||||
1514 | // Add the unique indexing of the edge tessellation | |||
1515 | snprintf(attrname, 128, "edgeVertID_%d",iedge+1); | |||
1516 | status = EG_attributeAdd(tess, attrname, ATTRINT1, | |||
1517 | bodydata.tedges[iedge].npts, | |||
1518 | bodydata.tedges[iedge].ivp, NULL((void*)0), NULL((void*)0)); | |||
1519 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1519, __func__, 0); goto cleanup; }; | |||
1520 | } | |||
1521 | ||||
1522 | for (iface = 0; iface < bodydata.nfaces; iface++) { | |||
1523 | ||||
1524 | ntri = bodydata.tfaces[iface].ntri; | |||
1525 | ||||
1526 | face_tris = bodydata.tfaces[iface].tris; | |||
1527 | face_uv = bodydata.tfaces[iface].uv; | |||
1528 | face_xyz = bodydata.tfaces[iface].xyz; | |||
1529 | ||||
1530 | AIM_NOTNULL(face_tris, aimInfo, status){ if (face_tris == ((void*)0)) { status = -307; aim_status(aimInfo , status, "refineAIM.c", 1530, __func__, 1, "%s == NULL!", "face_tris" ); goto cleanup; } }; | |||
1531 | AIM_NOTNULL(face_uv , aimInfo, status){ if (face_uv == ((void*)0)) { status = -307; aim_status(aimInfo , status, "refineAIM.c", 1531, __func__, 1, "%s == NULL!", "face_uv" ); goto cleanup; } }; | |||
1532 | AIM_NOTNULL(face_xyz , aimInfo, status){ if (face_xyz == ((void*)0)) { status = -307; aim_status(aimInfo , status, "refineAIM.c", 1532, __func__, 1, "%s == NULL!", "face_xyz" ); goto cleanup; } }; | |||
1533 | ||||
1534 | // check the normals of the elements match the geometry normals | |||
1535 | // only need to check one element per face to decide for all | |||
1536 | elem[0] = face_tris[0]-1; | |||
1537 | elem[1] = face_tris[1]-1; | |||
1538 | elem[2] = face_tris[2]-1; | |||
1539 | ||||
1540 | // get the uv centroid | |||
1541 | uv[0] = (face_uv[2*elem[0]+0] + face_uv[2*elem[1]+0] + face_uv[2*elem[2]+0])/3.; | |||
1542 | uv[1] = (face_uv[2*elem[0]+1] + face_uv[2*elem[1]+1] + face_uv[2*elem[2]+1])/3.; | |||
1543 | ||||
1544 | // get the normal of the face | |||
1545 | status = EG_evaluate(bodydata.faces[iface], uv, result); | |||
1546 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1546, __func__, 0); goto cleanup; }; | |||
1547 | ||||
1548 | // use cross dX/du x dX/dv to get geometry normal | |||
1549 | v1[0] = result[3]; v1[1] = result[4]; v1[2] = result[5]; | |||
1550 | v2[0] = result[6]; v2[1] = result[7]; v2[2] = result[8]; | |||
1551 | CROSS(faceNormal, v1, v2)faceNormal[0] = (v1[1]*v2[2]) - (v1[2]*v2[1]); faceNormal[1] = (v1[2]*v2[0]) - (v1[0]*v2[2]); faceNormal[2] = (v1[0]*v2[1]) - (v1[1]*v2[0]); | |||
1552 | ||||
1553 | // get mtype=SFORWARD or mtype=SREVERSE for the face to get topology normal | |||
1554 | status = EG_getInfo(bodydata.faces[iface], &oclass, &mtype, &ref, &prev, &next); | |||
1555 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1555, __func__, 0); goto cleanup; }; | |||
1556 | faceNormal[0] *= mtype; | |||
1557 | faceNormal[1] *= mtype; | |||
1558 | faceNormal[2] *= mtype; | |||
1559 | ||||
1560 | // get the normal of the mesh triangle | |||
1561 | v1[0] = face_xyz[3*elem[1]+0] - face_xyz[3*elem[0]+0]; | |||
1562 | v1[1] = face_xyz[3*elem[1]+1] - face_xyz[3*elem[0]+1]; | |||
1563 | v1[2] = face_xyz[3*elem[1]+2] - face_xyz[3*elem[0]+2]; | |||
1564 | ||||
1565 | v2[0] = face_xyz[3*elem[2]+0] - face_xyz[3*elem[0]+0]; | |||
1566 | v2[1] = face_xyz[3*elem[2]+1] - face_xyz[3*elem[0]+1]; | |||
1567 | v2[2] = face_xyz[3*elem[2]+2] - face_xyz[3*elem[0]+2]; | |||
1568 | ||||
1569 | CROSS(triNormal, v1, v2)triNormal[0] = (v1[1]*v2[2]) - (v1[2]*v2[1]); triNormal[1] = ( v1[2]*v2[0]) - (v1[0]*v2[2]); triNormal[2] = (v1[0]*v2[1]) - ( v1[1]*v2[0]); | |||
1570 | ||||
1571 | // get the dot product between the triangle and face normals | |||
1572 | ndot = DOT(faceNormal,triNormal)(faceNormal[0]*triNormal[0] + faceNormal[1]*triNormal[1] + faceNormal [2]*triNormal[2]); | |||
1573 | ||||
1574 | // if the normals are opposite, swap all triangles | |||
1575 | if (ndot < 0) { | |||
1576 | // swap two vertices to reverse the normal | |||
1577 | for (i = 0; i < ntri; i++) { | |||
1578 | swapi(&face_tris[3*i+0], &face_tris[3*i+2]); | |||
1579 | } | |||
1580 | } | |||
1581 | ||||
1582 | status = EG_setTessFace(tess, | |||
1583 | iface+1, | |||
1584 | bodydata.tfaces[iface].npts, | |||
1585 | face_xyz, | |||
1586 | face_uv, | |||
1587 | ntri, | |||
1588 | face_tris); | |||
1589 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1589, __func__, 0); goto cleanup; }; | |||
1590 | ||||
1591 | ||||
1592 | // The points get reindexed to be consistent with loops in EG_setTessFace | |||
1593 | // This uses the new triangulation to map that index change. | |||
1594 | status = EG_getTessFace(tess, iface+1, &npts, &pxyz, &puv, &ptype, | |||
1595 | &pindex, &ntri, &tris, &tric); | |||
1596 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1596, __func__, 0); goto cleanup; }; | |||
1597 | AIM_NOTNULL(tris, aimInfo, status){ if (tris == ((void*)0)) { status = -307; aim_status(aimInfo , status, "refineAIM.c", 1597, __func__, 1, "%s == NULL!", "tris" ); goto cleanup; } }; | |||
1598 | ||||
1599 | AIM_ALLOC(faceVertID, npts, int, aimInfo, status){ if (faceVertID != ((void*)0)) { status = -4; aim_status(aimInfo , status, "refineAIM.c", 1599, __func__, 1, "AIM_ALLOC: %s != NULL" , "faceVertID"); goto cleanup; } size_t memorysize = npts; faceVertID = (int *) EG_alloc(memorysize*sizeof(int)); if (faceVertID == ((void*)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c" , 1599, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "faceVertID" , memorysize, "int"); goto cleanup; } }; | |||
1600 | ||||
1601 | for (i = 0; i < ntri; i++) { | |||
1602 | for (j = 0; j < 3; j++) { | |||
1603 | faceVertID[tris[3*i+j]-1] = bodydata.tfaces[iface].ivp[face_tris[3*i+j]-1]; | |||
1604 | } | |||
1605 | } | |||
1606 | ||||
1607 | // Add the unique indexing of the tessellation | |||
1608 | snprintf(attrname, 128, "faceVertID_%d",iface+1); | |||
1609 | status = EG_attributeAdd(tess, attrname, ATTRINT1, | |||
1610 | bodydata.tfaces[iface].npts, | |||
1611 | faceVertID, NULL((void*)0), NULL((void*)0)); | |||
1612 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1612, __func__, 0); goto cleanup; }; | |||
1613 | ||||
1614 | // replace the shuffled volume ID's | |||
1615 | AIM_FREE(bodydata.tfaces[iface].ivp){ EG_free(bodydata.tfaces[iface].ivp); bodydata.tfaces[iface] .ivp = ((void*)0); }; | |||
1616 | bodydata.tfaces[iface].ivp = faceVertID; | |||
1617 | faceVertID = NULL((void*)0); | |||
1618 | } | |||
1619 | ||||
1620 | // finalize the tessellation | |||
1621 | status = EG_statusTessBody(tess, &body, &i, &nglobal); | |||
1622 | AIM_STATUS(aimInfo, status, "Tessellation object was not built correctly!!!")if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1622, __func__, 1, "Tessellation object was not built correctly!!!" ); goto cleanup; }; | |||
1623 | ||||
1624 | // Create the map from the tessellation global vertex index to the volume mesh vertex index | |||
1625 | AIM_ALLOC(mesh->meshRef->maps[0].map, nglobal, int, aimInfo, status){ if (mesh->meshRef->maps[0].map != ((void*)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c", 1625, __func__ , 1, "AIM_ALLOC: %s != NULL", "mesh->meshRef->maps[0].map" ); goto cleanup; } size_t memorysize = nglobal; mesh->meshRef ->maps[0].map = (int *) EG_alloc(memorysize*sizeof(int)); if (mesh->meshRef->maps[0].map == ((void*)0)) { status = - 4; aim_status(aimInfo, status, "refineAIM.c", 1625, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "mesh->meshRef->maps[0].map" , memorysize, "int"); goto cleanup; } }; | |||
1626 | ||||
1627 | for (iface = 0; iface < bodydata.nfaces; iface++) { | |||
1628 | status = EG_getTessFace(tess, iface+1, &npts, &pxyz, &puv, &ptype, | |||
1629 | &pindex, &ntri, &tris, &tric); | |||
1630 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1630, __func__, 0); goto cleanup; }; | |||
1631 | ||||
1632 | /* construct global vertex indices */ | |||
1633 | for (i = 0; i < npts; i++) { | |||
1634 | status = EG_localToGlobal(tess, iface+1, i+1, &iglobal); | |||
1635 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1635, __func__, 0); goto cleanup; }; | |||
1636 | mesh->meshRef->maps[0].map[iglobal-1] = bodydata.tfaces[iface].ivp[i]; | |||
1637 | } | |||
1638 | } | |||
1639 | ||||
1640 | // save the tessellation with caps | |||
1641 | status = aim_newTess(aimInfo, tess); | |||
1642 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1642, __func__, 0); goto cleanup; }; | |||
1643 | ||||
1644 | /*@-kepttrans@*/ | |||
1645 | // reference the surface mesh object | |||
1646 | mesh->meshRef->maps[0].tess = tess; | |||
1647 | tess = NULL((void*)0); | |||
1648 | /*@+kepttrans@*/ | |||
1649 | ||||
1650 | AIM_ALLOC(mesh->meshRef->bnds, refineInstance->groupMap.numAttribute, aimMeshBnd, aimInfo, status){ if (mesh->meshRef->bnds != ((void*)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c", 1650, __func__, 1 , "AIM_ALLOC: %s != NULL", "mesh->meshRef->bnds"); goto cleanup; } size_t memorysize = refineInstance->groupMap.numAttribute ; mesh->meshRef->bnds = (aimMeshBnd *) EG_alloc(memorysize *sizeof(aimMeshBnd)); if (mesh->meshRef->bnds == ((void *)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c" , 1650, __func__, 3, "AIM_ALLOC: %s size %zu type %s", "mesh->meshRef->bnds" , memorysize, "aimMeshBnd"); goto cleanup; } }; | |||
1651 | mesh->meshRef->nbnd = refineInstance->groupMap.numAttribute; | |||
1652 | for (i = 0; i < mesh->meshRef->nbnd; i++) { | |||
1653 | status = aim_initMeshBnd(mesh->meshRef->bnds + i); | |||
1654 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1654, __func__, 0); goto cleanup; }; | |||
1655 | } | |||
1656 | ||||
1657 | for (i = 0; i < mesh->meshRef->nbnd; i++) { | |||
1658 | AIM_STRDUP(mesh->meshRef->bnds[i].groupName, refineInstance->groupMap.attributeName[i], aimInfo, status){ if (mesh->meshRef->bnds[i].groupName != ((void*)0)) { status = -4; aim_status(aimInfo, status, "refineAIM.c", 1658 , __func__, 1, "AIM_STRDUP: %s != NULL!", "mesh->meshRef->bnds[i].groupName" ); goto cleanup; } mesh->meshRef->bnds[i].groupName = EG_strdup (refineInstance->groupMap.attributeName[i]); if (mesh-> meshRef->bnds[i].groupName == ((void*)0)) { status = -4; aim_status (aimInfo, status, "refineAIM.c", 1658, __func__, 2, "AIM_STRDUP: %s %s" , "mesh->meshRef->bnds[i].groupName", refineInstance-> groupMap.attributeName[i]); goto cleanup; } }; | |||
1659 | mesh->meshRef->bnds[i].ID = refineInstance->groupMap.attributeIndex[i]; | |||
1660 | } | |||
1661 | } | |||
1662 | ||||
1663 | mesh->meshData = meshData; | |||
1664 | meshData = NULL((void*)0); | |||
1665 | ||||
1666 | status = CAPS_SUCCESS0; | |||
1667 | ||||
1668 | cleanup: | |||
1669 | if (status != CAPS_SUCCESS0) { | |||
1670 | aim_freeMeshData(meshData); | |||
1671 | AIM_FREE(meshData){ EG_free(meshData); meshData = ((void*)0); }; | |||
1672 | } | |||
1673 | ||||
1674 | if (fileID != 0) GmfCloseMesh(fileID); | |||
1675 | ||||
1676 | destroy_bodyData(1, &bodydata); | |||
1677 | ||||
1678 | AIM_FREE(faceGroups){ EG_free(faceGroups); faceGroups = ((void*)0); }; | |||
1679 | AIM_FREE(edgeGroups){ EG_free(edgeGroups); edgeGroups = ((void*)0); }; | |||
1680 | ||||
1681 | return status; | |||
1682 | } | |||
1683 | ||||
1684 | // ********************** AIM Function Break ***************************** | |||
1685 | static int | |||
1686 | writelibMeshb(void *aimInfo, ego tess, const char *filename) | |||
1687 | { | |||
1688 | int status; // Function return status | |||
1689 | int i, j; | |||
1690 | int state, nglobal, id; | |||
1691 | int nNode, nEdge, nFace; | |||
1692 | int iedge, iface; | |||
1693 | int nNodeVerts, nEdgeVerts, nFaceVerts; | |||
1694 | int nLine, nTri; | |||
1695 | int ptype, pindex, plen, tlen, iglobal; | |||
1696 | int elem[3]; | |||
1697 | const double *points, *uv, *t; | |||
1698 | const int *ptypes, *pindexs, *tris, *tric; | |||
1699 | double xyz[3]; | |||
1700 | ego body; | |||
1701 | int64_t fileID=0; | |||
1702 | int meshVersion; | |||
1703 | ||||
1704 | if (tess == NULL((void*)0)) return CAPS_NULLVALUE-307; | |||
1705 | ||||
1706 | status = EG_statusTessBody(tess, &body, &state, &nglobal); | |||
1707 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1707, __func__, 0); goto cleanup; }; | |||
1708 | ||||
1709 | meshVersion = 2; | |||
1710 | if (EXPORT_MESHB_VERTEX_3(10000000) < nglobal) meshVersion = 3; | |||
1711 | if (EXPORT_MESHB_VERTEX_4(200000000) < nglobal) meshVersion = 4; | |||
1712 | ||||
1713 | fileID = GmfOpenMesh(filename, GmfWrite2, meshVersion, 3); | |||
1714 | ||||
1715 | if (fileID == 0) { | |||
1716 | AIM_ERROR(aimInfo, "Cannot open file: %s\n", filename){ aim_message(aimInfo, CERROR, 0 , "refineAIM.c", 1716, __func__ , "Cannot open file: %s\n", filename); }; | |||
1717 | return CAPS_IOERR-332; | |||
1718 | } | |||
1719 | ||||
1720 | status = GmfSetKwd(fileID, GmfVertices, nglobal); | |||
1721 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1721, __func__, 0); goto cleanup; }; } | |||
1722 | ||||
1723 | // Write nodal coordinates | |||
1724 | for (i = 0; i < nglobal; i++) { | |||
1725 | status = EG_getGlobal(tess, i + 1, &ptype, &pindex, xyz); | |||
1726 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1726, __func__, 0); goto cleanup; }; | |||
1727 | ||||
1728 | status = GmfSetLin(fileID, GmfVertices, xyz[0], | |||
1729 | xyz[1], | |||
1730 | xyz[2], EXPORT_MESHB_VERTEX_ID(1)); | |||
1731 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1731, __func__, 0); goto cleanup; }; } | |||
1732 | ||||
1733 | } | |||
1734 | ||||
1735 | // write out elements | |||
1736 | ||||
1737 | // count the number of EDGE/FACE elements | |||
1738 | nTri = nLine = 0; | |||
1739 | ||||
1740 | status = EG_statusTessBody(tess, &body, &state, &nglobal); | |||
1741 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1741, __func__, 0); goto cleanup; }; | |||
1742 | ||||
1743 | status = EG_getBodyTopos(body, NULL((void*)0), EDGE21, &nEdge, NULL((void*)0)); | |||
1744 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1744, __func__, 0); goto cleanup; }; | |||
1745 | ||||
1746 | for (iedge = 0; iedge < nEdge; iedge++) { | |||
1747 | status = EG_getTessEdge(tess, iedge + 1, &plen, &points, &t); | |||
1748 | if (status == EGADS_DEGEN-24) continue; | |||
1749 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1749, __func__, 0); goto cleanup; }; | |||
1750 | nLine += plen-1; | |||
1751 | } | |||
1752 | ||||
1753 | status = EG_getBodyTopos(body, NULL((void*)0), FACE23, &nFace, NULL((void*)0)); | |||
1754 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1754, __func__, 0); goto cleanup; }; | |||
1755 | ||||
1756 | for (iface = 0; iface < nFace; iface++) { | |||
1757 | status = EG_getTessFace(tess, iface + 1, &plen, &points, &uv, &ptypes, &pindexs, | |||
1758 | &tlen, &tris, &tric); | |||
1759 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1759, __func__, 0); goto cleanup; }; | |||
1760 | nTri += tlen; | |||
1761 | } | |||
1762 | ||||
1763 | // Write out EDGE line elements | |||
1764 | status = GmfSetKwd(fileID, GmfEdges, nLine); | |||
1765 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1765, __func__, 0); goto cleanup; }; } | |||
1766 | ||||
1767 | status = EG_statusTessBody(tess, &body, &state, &nglobal); | |||
1768 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1768, __func__, 0); goto cleanup; }; | |||
1769 | ||||
1770 | status = EG_getBodyTopos(body, NULL((void*)0), EDGE21, &nEdge, NULL((void*)0)); | |||
1771 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1771, __func__, 0); goto cleanup; }; | |||
1772 | ||||
1773 | for (iedge = 0; iedge < nEdge; iedge++) { | |||
1774 | status = EG_getTessEdge(tess, iedge + 1, &plen, &points, &t); | |||
1775 | if (status == EGADS_DEGEN-24) continue; | |||
1776 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1776, __func__, 0); goto cleanup; }; | |||
1777 | ||||
1778 | for (j = 0; j < plen-1; j++) { | |||
1779 | ||||
1780 | status = EG_localToGlobal(tess, -(iedge + 1), j + 1, &elem[0]); | |||
1781 | if (status == EGADS_DEGEN-24) continue; | |||
1782 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1782, __func__, 0); goto cleanup; }; | |||
1783 | ||||
1784 | status = EG_localToGlobal(tess, -(iedge + 1), j + 2, &elem[1]); | |||
1785 | if (status == EGADS_DEGEN-24) continue; | |||
1786 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1786, __func__, 0); goto cleanup; }; | |||
1787 | ||||
1788 | status = GmfSetLin(fileID, GmfEdges, elem[0], | |||
1789 | elem[1], | |||
1790 | iedge + 1); | |||
1791 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1791, __func__, 0); goto cleanup; }; } | |||
1792 | } | |||
1793 | } | |||
1794 | ||||
1795 | // Write FACE triangle elements | |||
1796 | status = GmfSetKwd(fileID, GmfTriangles, nTri); | |||
1797 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1797, __func__, 0); goto cleanup; }; } | |||
1798 | ||||
1799 | status = EG_statusTessBody(tess, &body, &state, &nglobal); | |||
1800 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1800, __func__, 0); goto cleanup; }; | |||
1801 | ||||
1802 | status = EG_getBodyTopos(body, NULL((void*)0), FACE23, &nFace, NULL((void*)0)); | |||
1803 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1803, __func__, 0); goto cleanup; }; | |||
1804 | ||||
1805 | for (iface = 0; iface < nFace; iface++) { | |||
1806 | status = EG_getTessFace(tess, iface + 1, &plen, &points, &uv, &ptypes, &pindexs, | |||
1807 | &tlen, &tris, &tric); | |||
1808 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1808, __func__, 0); goto cleanup; }; | |||
1809 | ||||
1810 | for (j = 0; j < tlen; j++) { | |||
1811 | status = EG_localToGlobal(tess, iface + 1, tris[3*j + 0], &elem[0]); | |||
1812 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1812, __func__, 0); goto cleanup; }; | |||
1813 | status = EG_localToGlobal(tess, iface + 1, tris[3*j + 1], &elem[1]); | |||
1814 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1814, __func__, 0); goto cleanup; }; | |||
1815 | status = EG_localToGlobal(tess, iface + 1, tris[3*j + 2], &elem[2]); | |||
1816 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1816, __func__, 0); goto cleanup; }; | |||
1817 | ||||
1818 | status = GmfSetLin(fileID, GmfTriangles, elem[0], | |||
1819 | elem[1], | |||
1820 | elem[2], | |||
1821 | iface + 1); | |||
1822 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1822, __func__, 0); goto cleanup; }; } | |||
1823 | } | |||
1824 | } | |||
1825 | ||||
1826 | nNodeVerts = nEdgeVerts = nFaceVerts = 0; | |||
1827 | ||||
1828 | status = EG_getBodyTopos(body, NULL((void*)0), NODE20, &nNode, NULL((void*)0)); | |||
1829 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1829, __func__, 0); goto cleanup; }; | |||
1830 | nNodeVerts += nNode; | |||
1831 | ||||
1832 | status = EG_getBodyTopos(body, NULL((void*)0), EDGE21, &nEdge, NULL((void*)0)); | |||
1833 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1833, __func__, 0); goto cleanup; }; | |||
1834 | ||||
1835 | for (iedge = 0; iedge < nEdge; iedge++) { | |||
1836 | status = EG_getTessEdge(tess, iedge + 1, &plen, &points, &t); | |||
1837 | if (status == EGADS_DEGEN-24) continue; | |||
1838 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1838, __func__, 0); goto cleanup; }; | |||
1839 | nEdgeVerts += plen; | |||
1840 | } | |||
1841 | ||||
1842 | status = EG_getBodyTopos(body, NULL((void*)0), FACE23, &nFace, NULL((void*)0)); | |||
1843 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1843, __func__, 0); goto cleanup; }; | |||
1844 | ||||
1845 | for (iface = 0; iface < nFace; iface++) { | |||
1846 | status = EG_getTessFace(tess, iface + 1, &plen, &points, &uv, &ptypes, &pindexs, | |||
1847 | &tlen, &tris, &tric); | |||
1848 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1848, __func__, 0); goto cleanup; }; | |||
1849 | nFaceVerts += plen; | |||
1850 | } | |||
1851 | ||||
1852 | // write out parametric coordinates | |||
1853 | ||||
1854 | // Write NODEs | |||
1855 | status = GmfSetKwd(fileID, GmfVerticesOnGeometricVertices, nNodeVerts); | |||
1856 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1856, __func__, 0); goto cleanup; }; } | |||
1857 | ||||
1858 | status = EG_getBodyTopos(body, NULL((void*)0), NODE20, &nNode, NULL((void*)0)); | |||
1859 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1859, __func__, 0); goto cleanup; }; | |||
1860 | ||||
1861 | for (j = 0; j < nglobal; j++) { | |||
1862 | status = EG_getGlobal(tess, j + 1, &ptype, &pindex, xyz); | |||
1863 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1863, __func__, 0); goto cleanup; }; | |||
1864 | if (ptype == 0) { | |||
1865 | status = GmfSetLin(fileID, GmfVerticesOnGeometricVertices, | |||
1866 | j+1, | |||
1867 | pindex); | |||
1868 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1868, __func__, 0); goto cleanup; }; } | |||
1869 | } | |||
1870 | } | |||
1871 | ||||
1872 | // Write EDGEs | |||
1873 | status = GmfSetKwd(fileID, GmfVerticesOnGeometricEdges, nEdgeVerts); | |||
1874 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1874, __func__, 0); goto cleanup; }; } | |||
1875 | ||||
1876 | status = EG_statusTessBody(tess, &body, &state, &nglobal); | |||
1877 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1877, __func__, 0); goto cleanup; }; | |||
1878 | ||||
1879 | status = EG_getBodyTopos(body, NULL((void*)0), EDGE21, &nEdge, NULL((void*)0)); | |||
1880 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1880, __func__, 0); goto cleanup; }; | |||
1881 | ||||
1882 | for (iedge = 0; iedge < nEdge; iedge++) { | |||
1883 | status = EG_getTessEdge(tess, iedge + 1, &plen, &points, &t); | |||
1884 | if (status == EGADS_DEGEN-24) continue; | |||
1885 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1885, __func__, 0); goto cleanup; }; | |||
1886 | ||||
1887 | for (j = 0; j < plen; j++) { | |||
1888 | ||||
1889 | status = EG_localToGlobal(tess, -(iedge + 1), j + 1, &iglobal); | |||
1890 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1890, __func__, 0); goto cleanup; }; | |||
1891 | ||||
1892 | id = iedge + 1; | |||
1893 | status = GmfSetLin(fileID, GmfVerticesOnGeometricEdges, | |||
1894 | iglobal, | |||
1895 | id, | |||
1896 | t[j], | |||
1897 | (double)id); // refine abuse of dist | |||
1898 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1898, __func__, 0); goto cleanup; }; } | |||
1899 | } | |||
1900 | } | |||
1901 | ||||
1902 | ||||
1903 | // Write FACEs | |||
1904 | status = GmfSetKwd(fileID, GmfVerticesOnGeometricTriangles, nFaceVerts); | |||
1905 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1905, __func__, 0); goto cleanup; }; } | |||
1906 | ||||
1907 | status = EG_statusTessBody(tess, &body, &state, &nglobal); | |||
1908 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1908, __func__, 0); goto cleanup; }; | |||
1909 | ||||
1910 | status = EG_getBodyTopos(body, NULL((void*)0), FACE23, &nFace, NULL((void*)0)); | |||
1911 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1911, __func__, 0); goto cleanup; }; | |||
1912 | ||||
1913 | for (iface = 0; iface < nFace; iface++) { | |||
1914 | status = EG_getTessFace(tess, iface + 1, &plen, &points, &uv, &ptypes, &pindexs, | |||
1915 | &tlen, &tris, &tric); | |||
1916 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1916, __func__, 0); goto cleanup; }; | |||
1917 | ||||
1918 | for (j = 0; j < plen; j++) { | |||
1919 | ||||
1920 | status = EG_localToGlobal(tess, iface + 1, j + 1, &iglobal); | |||
1921 | AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1921, __func__, 0); goto cleanup; }; | |||
1922 | ||||
1923 | id = iface + 1; | |||
1924 | status = GmfSetLin(fileID, GmfVerticesOnGeometricTriangles, | |||
1925 | iglobal, | |||
1926 | id, | |||
1927 | uv[2*j+0], uv[2*j+1], | |||
1928 | (double)id); // refine abuse of dist | |||
1929 | if (status <= 0) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "refineAIM.c", 1929, __func__, 0); goto cleanup; }; } | |||
1930 | } | |||
1931 | } | |||
1932 | ||||
1933 | status = CAPS_SUCCESS0; | |||
1934 | ||||
1935 | cleanup: | |||
1936 | ||||
1937 | if (fileID != 0) GmfCloseMesh(fileID); | |||
1938 | return status; | |||
1939 | } |