File: | bvtkWriter/bvtkWriter.c |
Warning: | line 30, column 22 Assigned value is garbage or undefined |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * CAPS: Computational Aircraft Prototype Syntheses | |||
3 | * | |||
4 | * Binary VTK 3D Mesh Writer Code | |||
5 | * | |||
6 | * Copyright 2014-2024, 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 | #include <string.h> | |||
13 | #include <math.h> | |||
14 | #include "aimUtil.h" | |||
15 | #include "aimMesh.h" | |||
16 | ||||
17 | #include "bvtkWriter.h" | |||
18 | ||||
19 | #define ELEM_POINT_MAX8 8 | |||
20 | ||||
21 | /* Legacy VTK binary file assumes data stored as BigEndian */ | |||
22 | static | |||
23 | void byteswap(void *x, void *y, size_t size) | |||
24 | { | |||
25 | size_t i; | |||
26 | char *xp = (char *)x; | |||
27 | char *yp = (char *)y; | |||
28 | ||||
29 | for (i = 0; i < size; i++) | |||
30 | *(yp + size-1-i) = *(xp + i); | |||
| ||||
31 | } | |||
32 | ||||
33 | ||||
34 | const char *meshExtension() | |||
35 | { | |||
36 | /*@-observertrans@*/ | |||
37 | return MESHEXTENSION".b.vtk"; | |||
38 | /*@+observertrans@*/ | |||
39 | } | |||
40 | ||||
41 | ||||
42 | int meshWrite(void *aimInfo, aimMesh *mesh) | |||
43 | { | |||
44 | int status; // Function return status | |||
45 | int igroup, i, d, ipnt, ielem, nPoint, nElems; | |||
46 | int elemType, iswap; | |||
47 | int nCell, length, iconn; | |||
48 | char filename[PATH_MAX4096]; | |||
49 | double dswap; | |||
50 | FILE *fp=NULL((void*)0); | |||
51 | aimMeshData *meshData = NULL((void*)0); | |||
52 | ||||
53 | if (mesh == NULL((void*)0)) return CAPS_NULLVALUE-307; | |||
| ||||
54 | if (mesh->meshRef == NULL((void*)0)) return CAPS_NULLVALUE-307; | |||
55 | if (mesh->meshData == NULL((void*)0)) return CAPS_NULLVALUE-307; | |||
56 | ||||
57 | if (mesh->meshData->dim != 2 && mesh->meshData->dim != 3) { | |||
58 | AIM_ERROR(aimInfo, "meshData dim = %d must be 2 or 3!!!", mesh->meshData->dim){ aim_message(aimInfo, CERROR, 0 , "bvtkWriter.c", 58, __func__ , "meshData dim = %d must be 2 or 3!!!", mesh->meshData-> dim); }; | |||
59 | return CAPS_BADVALUE-311; | |||
60 | } | |||
61 | ||||
62 | meshData = mesh->meshData; | |||
63 | ||||
64 | nCell = 0; | |||
65 | length = 0; | |||
66 | for (igroup = 0; igroup < meshData->nElemGroup; igroup++) { | |||
67 | if (meshData->elemGroups[igroup].order != 1) { | |||
68 | AIM_ERROR(aimInfo, "VTK only supports linear mesh elements! group %d order = %d",{ aim_message(aimInfo, CERROR, 0 , "bvtkWriter.c", 69, __func__ , "VTK only supports linear mesh elements! group %d order = %d" , igroup, meshData->elemGroups[igroup].order); } | |||
69 | igroup, meshData->elemGroups[igroup].order){ aim_message(aimInfo, CERROR, 0 , "bvtkWriter.c", 69, __func__ , "VTK only supports linear mesh elements! group %d order = %d" , igroup, meshData->elemGroups[igroup].order); }; | |||
70 | status = CAPS_IOERR-332; | |||
71 | goto cleanup; | |||
72 | } | |||
73 | ||||
74 | // count the number of elements and connectivity table size | |||
75 | nPoint = meshData->elemGroups[igroup].nPoint; | |||
76 | nElems = meshData->elemGroups[igroup].nElems; | |||
77 | ||||
78 | nCell += nElems; | |||
79 | length += nElems*(nPoint+1); | |||
80 | } | |||
81 | ||||
82 | printf("\nWriting Binary VTK file ....\n"); | |||
83 | ||||
84 | snprintf(filename, PATH_MAX4096, "%s%s", mesh->meshRef->fileName, MESHEXTENSION".b.vtk"); | |||
85 | ||||
86 | fp = fopen(filename, "wb"); | |||
87 | if (fp == NULL((void*)0)) { | |||
88 | AIM_ERROR(aimInfo, "Cannot open file: %s\n", filename){ aim_message(aimInfo, CERROR, 0 , "bvtkWriter.c", 88, __func__ , "Cannot open file: %s\n", filename); }; | |||
89 | return CAPS_IOERR-332; | |||
90 | } | |||
91 | ||||
92 | /* header information */ | |||
93 | fprintf(fp,"# vtk DataFile Version 2.0\n"); | |||
94 | fprintf(fp,"CAPS Unstructured Grid\n"); | |||
95 | fprintf(fp,"BINARY\n"); | |||
96 | fprintf(fp,"DATASET UNSTRUCTURED_GRID\n"); | |||
97 | fprintf(fp,"POINTS %d double\n", meshData->nVertex); | |||
98 | ||||
99 | /* write all of the vertices */ | |||
100 | for (i = 0; i < meshData->nVertex; i++) { | |||
101 | for (d = 0; d < 3; d++) { | |||
102 | byteswap(&meshData->verts[i][d], &dswap, sizeof(double)); | |||
103 | status = fwrite(&dswap, sizeof(double), 1, fp); | |||
104 | if (status != 1) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "bvtkWriter.c" , 104, __func__, 0); goto cleanup; }; } | |||
105 | } | |||
106 | } | |||
107 | ||||
108 | /*----------------------------*/ | |||
109 | /* write element connectivity */ | |||
110 | /*----------------------------*/ | |||
111 | fprintf(fp,"CELLS %d %d\n", nCell, length); | |||
112 | ||||
113 | if (meshData->elemMap != NULL((void*)0)) { | |||
114 | ||||
115 | /* Write elements in order from the mesh generator */ | |||
116 | for (i = 0; i < meshData->nTotalElems; i++) { | |||
117 | ||||
118 | igroup = meshData->elemMap[i][0]; | |||
119 | ielem = meshData->elemMap[i][1]; | |||
120 | ||||
121 | nPoint = meshData->elemGroups[igroup].nPoint; | |||
122 | ||||
123 | /* number of points in the element */ | |||
124 | byteswap(&nPoint, &iswap, sizeof(int)); | |||
125 | status = fwrite(&iswap, sizeof(int), 1, fp); | |||
126 | if (status != 1) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "bvtkWriter.c" , 126, __func__, 0); goto cleanup; }; } | |||
127 | ||||
128 | /* VTK is 0-based indexed */ | |||
129 | for (ipnt = 0; ipnt < nPoint; ipnt++) { | |||
130 | iconn = meshData->elemGroups[igroup].elements[nPoint*ielem+ipnt]-1; | |||
131 | byteswap(&iconn, &iswap, sizeof(int)); | |||
132 | status = fwrite(&iswap, sizeof(int), 1, fp); | |||
133 | if (status != 1) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "bvtkWriter.c" , 133, __func__, 0); goto cleanup; }; } | |||
134 | } | |||
135 | } | |||
136 | ||||
137 | } else { | |||
138 | ||||
139 | /* Write elements by grouping */ | |||
140 | for (igroup = 0; igroup < meshData->nElemGroup; igroup++) { | |||
141 | ||||
142 | nPoint = meshData->elemGroups[igroup].nPoint; | |||
143 | nElems = meshData->elemGroups[igroup].nElems; | |||
144 | ||||
145 | for (ielem = 0; ielem < nElems; ielem++) { | |||
146 | ||||
147 | /* number of points in the element */ | |||
148 | byteswap(&nPoint, &iswap, sizeof(int)); | |||
149 | status = fwrite(&iswap, sizeof(int), 1, fp); | |||
150 | if (status != 1) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "bvtkWriter.c" , 150, __func__, 0); goto cleanup; }; } | |||
151 | ||||
152 | /* VTK is 0-based indexed */ | |||
153 | for (ipnt = 0; ipnt < nPoint; ipnt++) { | |||
154 | iconn = meshData->elemGroups[igroup].elements[nPoint*ielem+ipnt]-1; | |||
155 | byteswap(&iconn, &iswap, sizeof(int)); | |||
156 | status = fwrite(&iswap, sizeof(int), 1, fp); | |||
157 | if (status != 1) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "bvtkWriter.c" , 157, __func__, 0); goto cleanup; }; } | |||
158 | } | |||
159 | } | |||
160 | } | |||
161 | ||||
162 | } | |||
163 | ||||
164 | /*----------------------------*/ | |||
165 | /* write cell types */ | |||
166 | /*----------------------------*/ | |||
167 | fprintf(fp,"CELL_TYPES %d\n", nCell); | |||
168 | ||||
169 | if (meshData->elemMap
| |||
170 | ||||
171 | /* Write elements in order from the mesh generator */ | |||
172 | for (i = 0; i < meshData->nTotalElems; i++) { | |||
173 | ||||
174 | igroup = meshData->elemMap[i][0]; | |||
175 | ielem = meshData->elemMap[i][1]; | |||
176 | ||||
177 | if (meshData->elemGroups[igroup].elementTopo == aimLine) elemType = 3; | |||
178 | else if (meshData->elemGroups[igroup].elementTopo == aimTri) elemType = 5; | |||
179 | else if (meshData->elemGroups[igroup].elementTopo == aimQuad) elemType = 9; | |||
180 | else if (meshData->elemGroups[igroup].elementTopo == aimTet) elemType = 10; | |||
181 | else if (meshData->elemGroups[igroup].elementTopo == aimPyramid) elemType = 14; | |||
182 | else if (meshData->elemGroups[igroup].elementTopo == aimPrism) elemType = 13; | |||
183 | else if (meshData->elemGroups[igroup].elementTopo == aimHex) elemType = 12; | |||
184 | ||||
185 | nElems = meshData->elemGroups[igroup].nElems; | |||
186 | ||||
187 | byteswap(&elemType, &iswap, sizeof(int)); | |||
188 | ||||
189 | /* write the element type */ | |||
190 | status = fwrite(&iswap, sizeof(int), 1, fp); | |||
191 | if (status != 1) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "bvtkWriter.c" , 191, __func__, 0); goto cleanup; }; } | |||
192 | } | |||
193 | ||||
194 | } else { | |||
195 | ||||
196 | /* Write elements by grouping */ | |||
197 | for (igroup = 0; igroup < meshData->nElemGroup; igroup++) { | |||
198 | if (meshData->elemGroups[igroup].elementTopo == aimLine) elemType = 3; | |||
199 | else if (meshData->elemGroups[igroup].elementTopo == aimTri) elemType = 5; | |||
200 | else if (meshData->elemGroups[igroup].elementTopo == aimQuad) elemType = 9; | |||
201 | else if (meshData->elemGroups[igroup].elementTopo == aimTet) elemType = 10; | |||
202 | else if (meshData->elemGroups[igroup].elementTopo == aimPyramid) elemType = 14; | |||
203 | else if (meshData->elemGroups[igroup].elementTopo == aimPrism) elemType = 13; | |||
204 | else if (meshData->elemGroups[igroup].elementTopo == aimHex) elemType = 12; | |||
205 | ||||
206 | nElems = meshData->elemGroups[igroup].nElems; | |||
207 | ||||
208 | byteswap(&elemType, &iswap, sizeof(int)); | |||
209 | ||||
210 | /* write the element type */ | |||
211 | for (ielem = 0; ielem < nElems; ielem++) { | |||
212 | status = fwrite(&iswap, sizeof(int), 1, fp); | |||
213 | if (status != 1) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "bvtkWriter.c" , 213, __func__, 0); goto cleanup; }; } | |||
214 | } | |||
215 | } | |||
216 | ||||
217 | } | |||
218 | ||||
219 | /*----------------------------*/ | |||
220 | /* write cell IDs */ | |||
221 | /*----------------------------*/ | |||
222 | fprintf(fp, "CELL_DATA %d\n", nCell); | |||
223 | fprintf(fp, "SCALARS ID int 1\n"); | |||
224 | fprintf(fp, "LOOKUP_TABLE default\n"); | |||
225 | ||||
226 | if (meshData->elemMap != NULL((void*)0)) { | |||
227 | ||||
228 | /* Write elements in order from the mesh generator */ | |||
229 | for (i = 0; i < meshData->nTotalElems; i++) { | |||
230 | ||||
231 | igroup = meshData->elemMap[i][0]; | |||
232 | ||||
233 | /* write the element ID */ | |||
234 | byteswap(&meshData->elemGroups[igroup].ID, &iswap, sizeof(int)); | |||
235 | ||||
236 | status = fwrite(&iswap, sizeof(int), 1, fp); | |||
237 | if (status != 1) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "bvtkWriter.c" , 237, __func__, 0); goto cleanup; }; } | |||
238 | } | |||
239 | ||||
240 | } else { | |||
241 | ||||
242 | /* Write elements by grouping */ | |||
243 | for (igroup = 0; igroup < meshData->nElemGroup; igroup++) { | |||
244 | ||||
245 | nElems = meshData->elemGroups[igroup].nElems; | |||
246 | ||||
247 | /* write the element ID */ | |||
248 | for (ielem = 0; ielem < nElems; ielem++) { | |||
249 | byteswap(&meshData->elemGroups[igroup].ID, &iswap, sizeof(int)); | |||
250 | ||||
251 | status = fwrite(&iswap, sizeof(int), 1, fp); | |||
252 | if (status != 1) { status = CAPS_IOERR-332; AIM_STATUS(aimInfo, status)if (status != 0) { aim_status(aimInfo, status, "bvtkWriter.c" , 252, __func__, 0); goto cleanup; }; } | |||
253 | } | |||
254 | } | |||
255 | ||||
256 | } | |||
257 | ||||
258 | printf("Finished writing Binary VTK file\n\n"); | |||
259 | ||||
260 | status = CAPS_SUCCESS0; | |||
261 | ||||
262 | cleanup: | |||
263 | ||||
264 | if (fp != NULL((void*)0)) fclose(fp); | |||
265 | return status; | |||
266 | } |