1 #include "stdafx.h"
2 #include "MASTER.h"
3 #define TECPLOTENGINEMODULE
4 /*
5 ******************************************************************
6 ******************************************************************
7 *******                                                   ********
8 ******  (C) 1988-2010 Tecplot, Inc.                        *******
9 *******                                                   ********
10 ******************************************************************
11 ******************************************************************
12 */
13 
14 /*
15  * datautil.c:
16  *
17  * version 1.00 : 12/10/91 (cm) changes made for manual
18  * version 1.01 : 12/30/91 Get and ReturnHugeBlock are now ptr to function
19  * version 6.00 : 04/21/92 updated to match version 6 of tecplot.
20  * version 6.30 : 10/15/92 updated to match binary file version 6.3
21  * version 6.30a: 05/04/93 (cm) minor changes to prototypes
22  * version      : 11/01/93 (cm) put in D4GW stuff
23  * version 6.30b: 12/27/93 (cm) fixed missing NumKPts in DumpZone
24  * version 6.30c: 12/27/93 (cm) put back in D4GW stuff
25 BEGIN CODELOG TECXXX
26 C 03/06/96 (BDP)
27 C   Update to V7
28 C
29 C 03/14/97 (BDP)
30 C   Added code to main tecplot source.  Now can
31 C   be built stand alone or added so TecUtil_ functions
32 C   can access.
33 C 06/02/98 (bdp)
34 C   v75 coding.  Also removed Array of ZoneSpec_s
35 C   structs in favor of zonenames, i,j,and k dimensions
36 C   and zonetype array.
37 END CODELOG
38  */
39 
40 
41 
42 #include "GLOBAL.h"
43 #include "TASSERT.h"
44 #include "Q_UNICODE.h"
45 #include "SYSTEM.h"
46 #include "ALLOC.h"
47 #include "TECXXX.h"
48 #include "ARRLIST.h"
49 #include "SET.h"
50 #include "DATASET.h"
51 #include "FILESTREAM.h"
52 #if defined TECPLOTKERNEL
53 /* CORE SOURCE CODE REMOVED */
54 #endif
55 #include "DATAIO.h"
56 #include "DATAIO4.h"
57 #include "DATAUTIL.h"
58 #include "STRLIST.h"
59 #include "Q_MSG.h"
60 #if defined MAKEARCHIVE
61 #define INITMODULE
62 #endif
63 #include "INPUT.h"
64 
65 using namespace tecplot::strutil;
66 
67 #if defined MAKEARCHIVE
68 #define ANGLEEPSILON 1.0e-10
69 
InitInputSpecs(void)70 void InitInputSpecs(void)
71 {
72     LineThicknessInputSpec.Type                                = Input_Double;
73     LineThicknessInputSpec.Min                                 = 0.000001;
74     LineThicknessInputSpec.Max                                 = 1.0;
75     LineThicknessInputSpec.InterfaceAdjust.ScaleFact           = 100.0;
76     LineThicknessInputSpec.SuffixModifier                      = NULL;
77 
78     PatternLengthInputSpec.Type                                = Input_Double;
79     PatternLengthInputSpec.Min                                 = 0.0001;
80     PatternLengthInputSpec.Max                                 = 1.0;
81     PatternLengthInputSpec.InterfaceAdjust.ScaleFact           = 100.0;
82     PatternLengthInputSpec.SuffixModifier                      = NULL;
83 
84     TextBoxMarginInputSpec.Type                                = Input_Double;
85     TextBoxMarginInputSpec.Min                                 = 0.0;
86     TextBoxMarginInputSpec.Max                                 = 20.0;
87     TextBoxMarginInputSpec.InterfaceAdjust.ScaleFact           = 100.0;
88     TextBoxMarginInputSpec.SuffixModifier                      = NULL;
89 
90     TextLineSpacingInputSpec.Type                              = Input_Double;
91     TextLineSpacingInputSpec.Min                               = 0.0;
92     TextLineSpacingInputSpec.Max                               = 5.0;
93     TextLineSpacingInputSpec.InterfaceAdjust.ScaleFact         = 1.0;
94     TextLineSpacingInputSpec.SuffixModifier                    = NULL;
95 
96 
97     ArrowheadSizeInputSpec.Type                                = Input_Double;
98     ArrowheadSizeInputSpec.Min                                 = 0.0;
99     ArrowheadSizeInputSpec.Max                                 = 0.5;
100     ArrowheadSizeInputSpec.InterfaceAdjust.ScaleFact           = 100.0;
101     ArrowheadSizeInputSpec.SuffixModifier                      = NULL;
102 
103     TextAngleInputSpec.Type                                    = Input_Double;
104     TextAngleInputSpec.Min                                     = -PI - ANGLEEPSILON;
105     TextAngleInputSpec.Max                                     =  PI + ANGLEEPSILON;
106     TextAngleInputSpec.InterfaceAdjust.ScaleFact               = DEGPERRADIANS;
107     TextAngleInputSpec.SuffixModifier                          = NULL;
108 
109     ArrowheadAngleInputSpec.Type                               = Input_Double;
110     ArrowheadAngleInputSpec.Min                                = 1.0 / DEGPERRADIANS - ANGLEEPSILON;
111     ArrowheadAngleInputSpec.Max                                = PIOVER2 + ANGLEEPSILON;
112     ArrowheadAngleInputSpec.InterfaceAdjust.ScaleFact          = DEGPERRADIANS;
113     ArrowheadAngleInputSpec.SuffixModifier                     = NULL;
114 }
115 #endif
116 
117 
118 
119 
LocalReadBlock(FileStream_s * FileStream,double * CurVPtr,FieldDataType_e FieldDataTypeInFile,HgIndex_t NumValues,Boolean_t * IsOk)120 void LocalReadBlock(FileStream_s   *FileStream,
121                     double         *CurVPtr,
122                     FieldDataType_e FieldDataTypeInFile,
123                     HgIndex_t       NumValues,
124                     Boolean_t      *IsOk)
125 {
126     REQUIRE(VALID_REF(IsOk) && VALID_BOOLEAN(*IsOk));
127     REQUIRE(!(*IsOk) || VALID_REF(FileStream));
128     REQUIRE(!(*IsOk) || VALID_FIELD_DATA_TYPE(FieldDataTypeInFile));
129 
130     if (*IsOk)
131     {
132         Boolean_t DoRead = (CurVPtr != NULL);
133         Boolean_t ReadByBlock = (FieldDataType_Double == FieldDataTypeInFile) || !DoRead;
134         if (ReadByBlock)
135         {
136             ReadPureBlock(FileStream,
137                           DoRead,
138                           (void *)CurVPtr,
139                           FieldDataTypeInFile,
140                           0,
141                           NumValues,
142                           IsOk);
143         }
144         else
145         {
146             LgIndex_t N;
147             for (N = 0; *IsOk && (N < NumValues); N++)
148             {
149                 double D = GetNextValue(FileStream, FieldDataTypeInFile, -LARGEDOUBLE, LARGEDOUBLE, IsOk);
150                 if (DoRead)
151                     CurVPtr[N] = D;
152             }
153         }
154     }
155 }
156 
157 
158 
159 
160 /*
161  *
162  * NOTE: ReadTec only allocates space for NodeMap and VDataBase
163  *       if RawDataSpaceAllocated == FALSE and GetHeaderInfoOnly
164  *       is FALSE.
165  *
166  *       Also note that all data read in by ReadTec is currently
167  *       limited to be in double precision.
168  *
169  */
170 
171 
ReadTec(Boolean_t GetHeaderInfoOnly,char * FName,short * IVersion,char ** DataSetTitle,EntIndex_t * NumZones,EntIndex_t * NumVars,StringList_pa * VarNames,StringList_pa * ZoneNames,LgIndex_t ** NumPtsI,LgIndex_t ** NumPtsJ,LgIndex_t ** NumPtsK,ZoneType_e ** ZoneType,StringList_pa * UserRec,AuxData_pa * DatasetAuxData,Boolean_t RawDataSpaceAllocated,NodeMap_t *** NodeMap,double *** VDataBase)172 Boolean_t STDCALL ReadTec(Boolean_t       GetHeaderInfoOnly,
173                           char           *FName,
174                           short          *IVersion,
175                           char          **DataSetTitle,
176                           EntIndex_t     *NumZones,
177                           EntIndex_t     *NumVars,
178                           StringList_pa  *VarNames,
179                           StringList_pa  *ZoneNames,
180                           LgIndex_t     **NumPtsI,
181                           LgIndex_t     **NumPtsJ,
182                           LgIndex_t     **NumPtsK,
183                           ZoneType_e    **ZoneType,
184                           StringList_pa  *UserRec,
185                           AuxData_pa     *DatasetAuxData,
186                           Boolean_t       RawDataSpaceAllocated,
187                           NodeMap_t    ***NodeMap,
188                           double       ***VDataBase)
189 {
190     Boolean_t     InputIsOk         = FALSE;
191     ArrayList_pa  ZoneSpecList      = NULL;
192     LgIndex_t    *FNNumBndryConns   = NULL; /* [NumZones] */
193     FileStream_s *ReadTecFileStream = NULL;
194     Set_pa       *IsVarCellCentered = NULL; /* [NumZones] */
195 
196     REQUIRE(VALID_BOOLEAN(GetHeaderInfoOnly));
197     REQUIRE(VALID_NON_ZERO_LEN_STR(FName));
198     REQUIRE(VALID_REF(IVersion));
199     REQUIRE(VALID_REF(DataSetTitle) || DataSetTitle == NULL);
200     REQUIRE(VALID_REF(NumZones));
201     REQUIRE(VALID_REF(NumVars));
202     REQUIRE(VarNames  == NULL || VALID_REF(VarNames));
203     REQUIRE(ZoneNames == NULL || VALID_REF(ZoneNames));
204     REQUIRE(NumPtsI   == NULL || VALID_REF(NumPtsI));
205     REQUIRE(NumPtsJ   == NULL || VALID_REF(NumPtsJ));
206     REQUIRE(NumPtsK   == NULL || VALID_REF(NumPtsK));
207     REQUIRE(ZoneType  == NULL || VALID_REF(ZoneType));
208     REQUIRE(UserRec   == NULL || VALID_REF(UserRec));
209     REQUIRE(VALID_BOOLEAN(RawDataSpaceAllocated));
210     REQUIRE(IMPLICATION(!GetHeaderInfoOnly && RawDataSpaceAllocated,
211                         VALID_REF(NodeMap) && VALID_REF(VDataBase)));
212 
213 #if defined MAKEARCHIVE
214     InitInputSpecs();
215 #endif
216 
217     InputIsOk  = OpenBinaryFileAndCheckMagicNumber(&ReadTecFileStream,
218                                                    FName,
219                                                    0,
220                                                    IVersion);
221 
222     if (InputIsOk)
223         InputIsOk = ReadDataFileHeader(ReadTecFileStream,
224                                        *IVersion,
225                                        FALSE,
226                                        NumZones,
227                                        NumVars,
228                                        (SmInteger_t *)NULL,
229                                        DataSetTitle,
230                                        (Text_s **)NULL,
231                                        (Geom_s **)NULL,
232                                        (StringList_pa  **)NULL,
233                                        UserRec,
234                                        DatasetAuxData,
235                                        &IsVarCellCentered,
236                                        (Boolean_t *)NULL,
237                                        (Boolean_t *)NULL,
238                                        &ZoneSpecList,
239                                        VarNames,
240                                        (ArrayList_pa *)NULL,
241                                        (Set_pa *)NULL,
242                                        &FNNumBndryConns,
243                                        (DataFileType_e *)NULL);
244 
245 
246 
247     if (InputIsOk)
248     {
249         if (*NumZones == 0)
250             *NumVars = 0;
251         else if (*IVersion > 112)
252         {
253             /*
254              * This may not be true but we put it hear to remind us to make
255              * updates to this code when we change the version number.
256              */
257             ErrMsg(translate("ReadTec does not yet support version %d "
258                              "Tecplot binary data files."), *IVersion);
259             InputIsOk = FALSE;
260         }
261         else if (!GetHeaderInfoOnly)
262         {
263             EntIndex_t Z;
264             for (Z = 0; Z < *NumZones && InputIsOk; Z++)
265             {
266                 InputIsOk = (MemberCount(IsVarCellCentered[Z]) == 0);
267                 if (!InputIsOk)
268                     ErrMsg(translate("Cell centered data not supported by ReadTec."));
269             }
270         }
271     }
272 
273     if (IsVarCellCentered != NULL)
274     {
275         EntIndex_t Z;
276         for (Z = 0; Z < *NumZones; Z++)
277             DeallocSet(&IsVarCellCentered[Z]);
278         FREE_ARRAY(IsVarCellCentered, "Array of IsVarCellCentered sets");
279     }
280 
281     if (InputIsOk)
282     {
283         EntIndex_t Z;
284         /*
285          *  Allocate space for the zone info pieces.
286          */
287         if (ZoneNames)
288             *ZoneNames = StringListAlloc();
289         if (NumPtsI)
290             *NumPtsI  = ALLOC_ARRAY(*NumZones, LgIndex_t, "numptsi");
291         if (NumPtsJ)
292             *NumPtsJ  = ALLOC_ARRAY(*NumZones, LgIndex_t, "numptsj");
293         if (NumPtsK)
294             *NumPtsK  = ALLOC_ARRAY(*NumZones, LgIndex_t, "numptsk");
295         if (ZoneType)
296             *ZoneType = ALLOC_ARRAY(*NumZones, ZoneType_e, "zonetype");
297         for (Z = 0; Z < *NumZones; Z++)
298         {
299             ZoneSpec_s *ZoneSpec = GetZoneSpec(ZoneSpecList, Z);
300             if (ZoneSpec != NULL)
301             {
302                 if (ZoneNames && *ZoneNames)
303                     StringListAppendString(*ZoneNames, ZoneSpec->Name);
304 
305                 if (NumPtsI && *NumPtsI)
306                     (*NumPtsI)[Z] = ZoneSpec->NumPtsI;
307 
308                 if (NumPtsJ && *NumPtsJ)
309                     (*NumPtsJ)[Z] = ZoneSpec->NumPtsJ;
310 
311                 if (NumPtsK && *NumPtsK)
312                     (*NumPtsK)[Z] = ZoneSpec->NumPtsK;
313 
314                 if (ZoneType && *ZoneType)
315                     (*ZoneType)[Z] = ZoneSpec->Type;
316             }
317             else
318             {
319                 if (ZoneNames && *ZoneNames)
320                     StringListAppendString(*ZoneNames, NULL);
321 
322                 if (NumPtsI && *NumPtsI)
323                     (*NumPtsI)[Z] = 0;
324 
325                 if (NumPtsJ && *NumPtsJ)
326                     (*NumPtsJ)[Z] = 0;
327 
328                 if (NumPtsK && *NumPtsK)
329                     (*NumPtsK)[Z] = 0;
330 
331                 if (ZoneType && *ZoneType)
332                     (*ZoneType)[Z] = ZoneType_Invalid;
333             }
334         }
335     }
336     if (!GetHeaderInfoOnly && InputIsOk && (*NumZones > 0))
337     {
338         EntIndex_t      *VarSharesFromZone          = NULL; /* [NumVars] */
339         Boolean_t       *IsVarPassive               = NULL; /* [NumVars] */
340         EntIndex_t      *ConnectivitySharesFromZone = NULL; /* [NumZones] */
341         FieldDataType_e *VarType = NULL;
342         int              CurZone;
343         int              CurVar;
344         LgIndex_t        NumIPts = 0;
345         LgIndex_t        NumJPts = 0;
346         LgIndex_t        NumKPts = 0;
347         LgIndex_t        TotalNumPts;
348         LgIndex_t        I, J;
349 
350         if ((*NumZones > 0) && !RawDataSpaceAllocated)
351         {
352             *VDataBase   = ALLOC_ARRAY(*NumZones * (*NumVars), double *, "vdatabase array");
353             if (*VDataBase == NULL)
354             {
355                 ErrMsg(translate("Cannot allocate space for field data"));
356                 InputIsOk = FALSE;
357             }
358             else
359             {
360                 int I;
361                 for (I = 0; I < *NumZones*(*NumVars); I++)
362                     (*VDataBase)[I] = NULL;
363             }
364 
365             if (InputIsOk)
366             {
367                 *NodeMap = ALLOC_ARRAY(*NumZones, NodeMap_t *, "nodemap array");
368                 if (*NodeMap == NULL)
369                 {
370                     ErrMsg(translate("Cannot allocate space for nodemap"));
371                     InputIsOk = FALSE;
372                 }
373                 else
374                 {
375                     int I;
376                     for (I = 0; I < *NumZones; I++)
377                         (*NodeMap)[I] = NULL;
378                 }
379             }
380         }
381 
382         if (InputIsOk)
383         {
384             VarType           = ALLOC_ARRAY(*NumVars + 1, FieldDataType_e, "Var Type");
385             VarSharesFromZone = ALLOC_ARRAY(*NumVars + 1, EntIndex_t, "VarSharesFromZone");
386             IsVarPassive      = ALLOC_ARRAY(*NumVars + 1, Boolean_t, "IsVarPassive");
387 
388             ConnectivitySharesFromZone = ALLOC_ARRAY(*NumZones, EntIndex_t, "ConnectivitySharesFromZone");
389             InputIsOk = (VarType                    != NULL &&
390                          VarSharesFromZone          != NULL &&
391                          IsVarPassive               != NULL &&
392                          ConnectivitySharesFromZone != NULL);
393         }
394 
395         /* for each zone */
396         for (CurZone = 0; CurZone < *NumZones && InputIsOk; CurZone++)
397         {
398             double X1 = GetNextValue(ReadTecFileStream, FieldDataType_Float, 0.0, 1000.0, &InputIsOk);
399             if (InputIsOk && (X1 == ZoneMarker))
400             {
401                 ZoneSpec_s *CurZoneSpec   = GetZoneSpec(ZoneSpecList, CurZone);
402                 Boolean_t   ZoneIsFinite  = (CurZoneSpec->Type != ZoneType_Ordered);
403                 Boolean_t   ZoneIsFEPoly  = (CurZoneSpec->Type == ZoneType_FEPolygon ||
404                                              CurZoneSpec->Type == ZoneType_FEPolyhedron);
405                 Boolean_t   InBlockFormat = CurZoneSpec->ZoneLoadInfo.IsInBlockFormat;
406                 for (J = 0; J < *NumVars; J++)
407                 {
408                     VarSharesFromZone[J] = -1; /* eumulate DupVar: no DupVar */
409                     VarType[J]           = FieldDataType_Float;
410                     IsVarPassive[J]      = FALSE;
411                 }
412 
413                 /* dupvars */
414                 if (*IVersion > 45 && *IVersion < 101 && InputIsOk)
415                 {
416                     EntIndex_t NumDupVars, ZZ;
417 
418                     NumDupVars = (EntIndex_t)GetIoFileInt(ReadTecFileStream, *IVersion, 0, (LgIndex_t) * NumVars, &InputIsOk);
419                     for (J = 0; J < NumDupVars; J++)
420                     {
421                         ZZ = (EntIndex_t)GetIoFileInt(ReadTecFileStream, *IVersion, 0, *NumVars, &InputIsOk) - 1;
422                         VarSharesFromZone[ZZ] = CurZone - 1; /* emulate DupVar: share from previous zone */
423                     }
424                     /* Can't duplicate from the first zone */
425                     if ((NumDupVars > 0) && (CurZone == 0))
426                     {
427                         ErrMsg(translate("Cannot duplicate variables from the first zone since there are "
428                                          "no previous zones to duplicate from."));
429                         InputIsOk = FALSE;
430                     }
431                 }
432 
433                 /* get the data type for each variable */
434                 if (*IVersion >= 70 && InputIsOk)
435                 {
436                     for (J = 0; J < *NumVars; J++)
437                     {
438                         VarType[J] = (FieldDataType_e)GetIoFileInt(ReadTecFileStream, *IVersion,
439                                                                    0,
440                                                                    (LgIndex_t)FieldDataType_Bit,
441                                                                    &InputIsOk);
442                         if (!InputIsOk)
443                         {
444                             ErrMsg(translate("Invalid data type - binary input file corrupted"));
445                             InputIsOk = FALSE;
446                         }
447                     }
448                 }
449 
450                 if (InputIsOk)
451                 {
452                     NumIPts = CurZoneSpec->NumPtsI;
453                     NumJPts = CurZoneSpec->NumPtsJ;
454                     NumKPts = CurZoneSpec->NumPtsK;
455                 }
456 
457                 if (ZoneIsFinite)
458                     TotalNumPts = NumIPts;
459                 else
460                     TotalNumPts = (NumIPts * NumJPts * NumKPts);
461 
462                 for (CurVar = 0; CurVar < *NumVars && InputIsOk; CurVar++)
463                 {
464                     if (!RawDataSpaceAllocated && TotalNumPts >= 1)
465                     {
466                         /*
467                          * The calling program did not allocate space for the
468                          * data so do it here.
469                          */
470                         (*VDataBase)[CurVar+CurZone*(*NumVars)] =
471                             ALLOC_ARRAY(TotalNumPts, double, "raw data");
472                     }
473                 }
474 
475                 if (*IVersion >= 105 && InputIsOk)
476                 {
477                     /* passive variables */
478                     if ((Boolean_t)GetIoFileInt(ReadTecFileStream, *IVersion, 0, 1, &InputIsOk) && InputIsOk)
479                     {
480                         for (CurVar = 0; CurVar < *NumVars && InputIsOk; CurVar++)
481                         {
482                             IsVarPassive[CurVar] = (Boolean_t)GetIoFileInt(ReadTecFileStream,
483                                                                            *IVersion,
484                                                                            0, 1, &InputIsOk);
485                         }
486                     }
487                 }
488 
489                 if (*IVersion >= 101 && InputIsOk)
490                 {
491                     /* variable sharing: equivalent to DupVar for ReadTec */
492                     if ((Boolean_t)GetIoFileInt(ReadTecFileStream, *IVersion, 0, 1, &InputIsOk) && InputIsOk)
493                     {
494                         for (CurVar = 0; CurVar < *NumVars && InputIsOk; CurVar++)
495                         {
496                             EntIndex_t SharedZone = GetIoFileInt(ReadTecFileStream, *IVersion,
497                                                                  -1, MaxNumZonesOrVars - 1,
498                                                                  &InputIsOk);
499                             if (SharedZone != -1 && InputIsOk)
500                                 VarSharesFromZone[CurVar] = SharedZone;
501                         }
502                     }
503 
504                     /* face neighbor or FE node connectivity sharing */
505                     if (InputIsOk)
506                     {
507                         EntIndex_t SharedZone = GetIoFileInt(ReadTecFileStream, *IVersion,
508                                                              -1, MaxNumZonesOrVars - 1,
509                                                              &InputIsOk);
510                         if (InputIsOk)
511                             ConnectivitySharesFromZone[CurZone] = SharedZone;
512                     }
513                 }
514 
515                 /*
516                  * Non-shared variable min/max (but not for Zombie zones).
517                  */
518                 if (*IVersion >= 103 && InputIsOk)
519                 {
520                     for (CurVar = 0; CurVar < *NumVars && InputIsOk; CurVar++)
521                     {
522                         if (VarSharesFromZone[CurVar] == -1 && !IsVarPassive[CurVar])
523                         {
524                             /*
525                              * Currently ReadTec doesn't do anything with the
526                              * min/max values.
527                              */
528                             GetNextValue(ReadTecFileStream, FieldDataType_Double,
529                                          -LARGEDOUBLE, LARGEDOUBLE,
530                                          &InputIsOk);
531                             GetNextValue(ReadTecFileStream, FieldDataType_Double,
532                                          -LARGEDOUBLE, LARGEDOUBLE,
533                                          &InputIsOk);
534                         }
535                     }
536                 }
537 
538                 if (InBlockFormat)
539                 {
540                     CurVar = -1;
541                     while (InputIsOk && ((CurVar + 1) < *NumVars))
542                     {
543                         CurVar++;
544                         if ((CurVar < *NumVars) && (TotalNumPts > 0))
545                         {
546                             double *CurVPtr  = (*VDataBase)[CurVar+CurZone*(*NumVars)];
547                             J = 0;
548                             if (VarSharesFromZone[CurVar] != -1)
549                             {
550                                 LgIndex_t M;
551                                 EntIndex_t SourceZone = VarSharesFromZone[CurVar];
552                                 double *SourceVPtr = (*VDataBase)[CurVar+SourceZone*(*NumVars)];
553                                 for (M = 0; M < TotalNumPts; M++)
554                                     CurVPtr[M] = SourceVPtr[M];
555                             }
556                             else if (!IsVarPassive[CurVar])
557                             {
558                                 LocalReadBlock(ReadTecFileStream,
559                                                CurVPtr,
560                                                VarType[CurVar],
561                                                TotalNumPts,
562                                                &InputIsOk);
563                             }
564                         }
565                     }
566                     if (!InputIsOk)
567                         ErrMsg(translate("Invalid raw data section of binary file"));
568                 }
569                 else if (TotalNumPts > 0)
570                 {
571                     /*
572                      * Zone is not empty and is in POINT format
573                      */
574                     J = -1;
575                     if (InputIsOk)
576                     {
577                         LgIndex_t N;
578                         N = 0;
579                         while (InputIsOk && (N < TotalNumPts))
580                         {
581                             EntIndex_t CurVar;
582                             for (CurVar = 0; InputIsOk && (CurVar < *NumVars); CurVar++)
583                             {
584                                 double *CurVPtr  = (*VDataBase)[CurVar+CurZone*(*NumVars)];
585                                 if (VarSharesFromZone[CurVar] != -1)
586                                 {
587                                     EntIndex_t SourceZone = VarSharesFromZone[CurVar];
588                                     double *SourceVPtr = (*VDataBase)[CurVar+SourceZone*(*NumVars)];
589                                     CurVPtr[N] = SourceVPtr[N];
590                                 }
591                                 else if (!IsVarPassive[CurVar])
592                                 {
593                                     double D = GetNextValue(ReadTecFileStream,
594                                                             VarType[CurVar],
595                                                             -LARGEDOUBLE,
596                                                             LARGEDOUBLE,
597                                                             &InputIsOk);
598 
599                                     if (InputIsOk && CurVPtr)
600                                         CurVPtr[N] = D;
601                                 }
602                             }
603 
604                             if (!InputIsOk)
605                                 ErrMsg(translate("Binary datafile corrupted!"));
606                             N++;
607                         }
608                     }
609                 }
610 
611                 if (InputIsOk && *IVersion < 101)
612                 {
613                     if (ZoneIsFinite)
614                     {
615                         /*
616                          * Pre-version 101 had FE connectivity sharing,
617                          * FECONNECT, information here.
618                          */
619                         Boolean_t DupConnectivity;
620                         if (*IVersion > 61)
621                             DupConnectivity = GetIoFileInt(ReadTecFileStream, *IVersion, 0, 1, &InputIsOk);
622                         else
623                             DupConnectivity = FALSE;
624 
625                         if (DupConnectivity)
626                             ConnectivitySharesFromZone[CurZone] = CurZone - 1; /* previous zone */
627                         else
628                             ConnectivitySharesFromZone[CurZone] = -1;
629                     }
630                     else
631                         ConnectivitySharesFromZone[CurZone] = -1;
632                 }
633 
634                 if (InputIsOk && ZoneIsFinite && !ZoneIsFEPoly)
635                 {
636                     Boolean_t   SkipNodemap;
637                     NodeMap_t  *NM = NULL;
638                     NodeMap_t  *ONM = NULL;
639                     /*
640                      *  Allocate the nodemap ptr if necessary Note that if
641                      *  RawDataSpaceAllocated is TRUE then (*NodeMap)[CurZone]
642                      *  can either contain a valid address (read the connectivity
643                      *  list) or be NULL (skip the list).
644                      */
645                     if (!RawDataSpaceAllocated && NumKPts*NumJPts >= 1)
646                     {
647                         (*NodeMap)[CurZone] = ALLOC_ARRAY(NumKPts * NumJPts, NodeMap_t, "node map");
648                         if ((*NodeMap)[CurZone] == NULL)
649                             ErrMsg(translate("Cannot allocate space for connectivity list",
650                                              "See the Tecplot User's Manual for a definition of 'connectivity list'"));
651                     }
652 
653                     if (InputIsOk)
654                         NM = (*NodeMap)[CurZone];
655 
656                     SkipNodemap = (NM == NULL);
657 
658                     if (InputIsOk && ConnectivitySharesFromZone[CurZone] != -1)
659                     {
660                         EntIndex_t SourceZone = ConnectivitySharesFromZone[CurZone];
661                         if (SourceZone >= CurZone)
662                         {
663                             ErrMsg(translate("Zone %d is attempting to share connectivity "
664                                              "with a zone that has not yet been loaded."),
665                                    CurZone + 1);
666                             InputIsOk = FALSE;
667                         }
668                         else
669                         {
670                             ONM = (*NodeMap)[SourceZone];
671                             if (ONM == NULL)
672                             {
673                                 ErrMsg(translate("Zone %d is attempting to share connectivity "
674                                                  "with a zone that is not finite element."),
675                                        CurZone + 1);
676                                 InputIsOk = FALSE;
677                             }
678                         }
679                     }
680 
681                     if (InputIsOk)
682                     {
683                         /* load the FE node connectivity */
684                         for (J = 0; J < NumJPts; J++)
685                             for (I = 0; I < NumKPts; I++)
686                             {
687                                 LgIndex_t M;
688                                 LgIndex_t L = J * NumKPts + I;
689                                 if (ConnectivitySharesFromZone[CurZone] != -1)
690                                     M = ONM[L];
691                                 else
692                                     M = GetNextI(ReadTecFileStream, &InputIsOk) - 1;
693                                 if (!SkipNodemap)
694                                     NM[L] = M;
695                             }
696                     }
697                 }
698 
699                 /* skip over the face neighbor connectivity */
700                 if (*IVersion >= 101 && InputIsOk)
701                 {
702                     EntIndex_t SharedZone = ConnectivitySharesFromZone[CurZone];
703                     if (SharedZone == -1 && FNNumBndryConns[CurZone] != 0)
704                     {
705                         LgIndex_t Connection = 0;
706                         while (Connection < FNNumBndryConns[CurZone] && InputIsOk)
707                         {
708                             /*
709                              * Face neighbor connection have the following format for both
710                              * ASCII and binary:
711                              *
712                              *   FaceNeighborMode_LocalOneToOne     3         cz,fz,cz
713                              *   FaceNeighborMode_LocalOneToMany    nz+4      cz,fz,oz,nz,cz1,cz2,...,czn
714                              *   FaceNeighborMode_GlobalOneToOne    4         cz,fz,ZZ,CZ
715                              *   FaceNeighborMode_GlobalOneToMany   2*nz+4    cz,fz,oz,nz,ZZ1,CZ1,ZZ2,CZ2,...,ZZn,CZn
716                              *
717                              *   Where:
718                              *       cz = cell in current zone
719                              *       fz = face of cell in current zone
720                              *       oz = face obsuration flag (only applies to one-to-many):
721                              *              0 = face partially obscured
722                              *              1 = face entirely obscured
723                              *       nz = number of cell or zone/cell associations (only applies to one-to-many)
724                              *       ZZ = remote Zone
725                              *       CZ = cell in remote zone
726                              */
727                             (void)GetNextI(ReadTecFileStream, &InputIsOk); /* read cz */
728                             if (!InputIsOk)
729                                 ErrMsg(translate("Unexpected end-of-file while reading face neighbor data."));
730 
731                             (void)GetNextI(ReadTecFileStream, &InputIsOk); /* read fz */
732 
733                             if (InputIsOk)
734                             {
735                                 /*
736                                  * read FaceNeighborMode_LocalOneToOne:   cz ||
737                                  *      FaceNeighborMode_LocalOneToMany:  oz ||
738                                  *      FaceNeighborMode_GlobalOneToOne:  ZZ ||
739                                  *      FaceNeighborMode_GlobalOneToMany: oz
740                                  */
741                                 if (CurZoneSpec->FNMode == FaceNeighborMode_LocalOneToOne)
742                                     (void)GetNextI(ReadTecFileStream, &InputIsOk);
743                                 else if (CurZoneSpec->FNMode == FaceNeighborMode_LocalOneToMany)
744                                     (void)GetNextI(ReadTecFileStream, &InputIsOk);
745                                 else if (CurZoneSpec->FNMode == FaceNeighborMode_GlobalOneToOne)
746                                     (void)GetNextI(ReadTecFileStream, &InputIsOk);
747                                 else if (CurZoneSpec->FNMode == FaceNeighborMode_GlobalOneToMany)
748                                     (void)GetNextI(ReadTecFileStream, &InputIsOk);
749                                 else
750                                     CHECK(FALSE);
751 
752                                 if (CurZoneSpec->FNMode != FaceNeighborMode_LocalOneToOne && InputIsOk)
753                                 {
754                                     LgIndex_t NumAssociations = 0;
755                                     /*
756                                      * read FaceNeighborMode_LocalOneToMany:  nz ||
757                                      *      FaceNeighborMode_GlobalOneToOne:  CZ ||
758                                      *      FaceNeighborMode_GlobalOneToMany: nz
759                                      */
760                                     if (CurZoneSpec->FNMode == FaceNeighborMode_LocalOneToMany)
761                                         NumAssociations = GetNextI(ReadTecFileStream, &InputIsOk);
762                                     else if (CurZoneSpec->FNMode == FaceNeighborMode_GlobalOneToOne)
763                                         (void)GetNextI(ReadTecFileStream, &InputIsOk);
764                                     else if (CurZoneSpec->FNMode == FaceNeighborMode_GlobalOneToMany)
765                                         NumAssociations = GetNextI(ReadTecFileStream, &InputIsOk);
766                                     else
767                                         CHECK(FALSE);
768 
769                                     if (CurZoneSpec->FNMode != FaceNeighborMode_GlobalOneToOne && InputIsOk)
770                                     {
771                                         LgIndex_t Assoc;
772                                         if (CurZoneSpec->FNMode == FaceNeighborMode_LocalOneToMany)
773                                             for (Assoc = 0; Assoc < NumAssociations && InputIsOk; Assoc++)
774                                                 (void)GetNextI(ReadTecFileStream, &InputIsOk); /* read czn */
775                                         else if (CurZoneSpec->FNMode == FaceNeighborMode_GlobalOneToMany)
776                                             for (Assoc = 0; Assoc < NumAssociations && InputIsOk; Assoc++)
777                                             {
778                                                 (void)GetNextI(ReadTecFileStream, &InputIsOk); /* read ZZn */
779                                                 (void)GetNextI(ReadTecFileStream, &InputIsOk); /* read CZn */
780                                             }
781                                         else
782                                             CHECK(FALSE);
783 
784                                         if (InputIsOk)
785                                             Connection += NumAssociations;
786                                     }
787                                     else if (InputIsOk) /* CurZoneSpec->FNMode == FaceNeighborMode_GlobalOneToOne */
788                                         Connection += 1;
789                                 }
790                                 else if (InputIsOk) /* CurZoneSpec->FNMode == FaceNeighborMode_LocalOneToOne */
791                                     Connection += 1;
792 
793                                 if (!InputIsOk)
794                                     ErrMsg(translate("Corrupt input file: invalid face neighbors."));
795                             }
796                         }
797                     }
798                 }/* face neighbor connectivity */
799                 /* skip over face map section */
800                 if (ZoneIsFEPoly                              &&
801                     *IVersion >= 110                          &&
802                     ConnectivitySharesFromZone[CurZone] != -1 &&
803                     InputIsOk)
804                 {
805                     if (!InBlockFormat)
806                     {
807                         ErrMsg(translate("Poly zones must be in block format"));
808                         InputIsOk = FALSE;
809                     }
810                     if (InputIsOk)
811                     {
812                         HgIndex_t NumFaces = CurZoneSpec->NumPtsK;
813                         if (*IVersion == 110) // ...version 111 moved these to the zone header
814                         {
815                             CurZoneSpec->NumFaceNodes  = GetNextI(ReadTecFileStream, &InputIsOk);
816                             CurZoneSpec->NumFaceBndryFaces = GetNextI(ReadTecFileStream, &InputIsOk);
817                             CurZoneSpec->NumFaceBndryItems = GetNextI(ReadTecFileStream, &InputIsOk);
818                         }
819                         HgIndex_t TotalNumFaceNodes  = CurZoneSpec->NumFaceNodes;
820                         HgIndex_t TotalNumBndryFaces = CurZoneSpec->NumFaceBndryFaces;
821                         HgIndex_t TotalNumBndryItems = CurZoneSpec->NumFaceBndryItems;
822                         if (CurZoneSpec->Type == ZoneType_FEPolyhedron)
823                             ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, NumFaces + 1, &InputIsOk);
824                         if (InputIsOk)
825                             ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, TotalNumFaceNodes, &InputIsOk);
826                         if (InputIsOk)
827                             ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, NumFaces, &InputIsOk);
828                         if (InputIsOk)
829                             ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, NumFaces, &InputIsOk);
830                         if (TotalNumBndryFaces > 0)
831                         {
832                             if (InputIsOk)
833                                 ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, TotalNumBndryFaces + 1, &InputIsOk);
834                             if (InputIsOk)
835                                 ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, TotalNumBndryItems, &InputIsOk);
836                             if (InputIsOk)
837                             {
838                                 if (*IVersion >= 112)
839                                     ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, TotalNumBndryItems, &InputIsOk);
840                                 else
841                                     ReadInt16Block(ReadTecFileStream, FALSE, NULL, 0, TotalNumBndryItems, &InputIsOk);
842                             }
843                         }
844                     }
845                 }/* face map section */
846             }
847             else
848             {
849                 ErrMsg(translate("Corrupt input file"));
850                 InputIsOk = FALSE;
851             }
852         }
853 
854         if (VarSharesFromZone)
855             FREE_ARRAY(VarSharesFromZone, "VarSharesFromZone");
856         if (IsVarPassive)
857             FREE_ARRAY(IsVarPassive, "IsVarPassive");
858         if (ConnectivitySharesFromZone)
859             FREE_ARRAY(ConnectivitySharesFromZone, "ConnectivitySharesFromZone");
860         if (VarType)
861             FREE_ARRAY(VarType, "VarType");
862 
863         if (!InputIsOk && !RawDataSpaceAllocated)
864         {
865             int I;
866             if (*VDataBase)
867             {
868                 for (I = 0; I < *NumZones*(*NumVars); I++)
869                 {
870                     if ((*VDataBase)[I])
871                         FREE_ARRAY((*VDataBase)[I], "vdatabase array");
872                 }
873                 FREE_ARRAY(*VDataBase, "vdatabase pointer array");
874             }
875 
876 
877             if (*NodeMap)
878             {
879                 for (I = 0; I < *NumZones; I++)
880                 {
881                     if ((*NodeMap)[I])
882                         FREE_ARRAY((*NodeMap)[I], "connectivity list");
883                 }
884                 FREE_ARRAY(*NodeMap, "connectivity pointer array");
885             }
886         }
887     } /*Reading Raw Data*/
888 
889     if (FNNumBndryConns != NULL)
890         FREE_ARRAY(FNNumBndryConns, "FNNumBndryConns");
891     if (ZoneSpecList)
892         ArrayListDealloc(&ZoneSpecList, ZoneSpecItemDestructor, 0);
893 
894     if (ReadTecFileStream)
895     {
896 #if defined TECPLOTKERNEL
897 /* CORE SOURCE CODE REMOVED */
898 #else
899         TP_FCLOSE(ReadTecFileStream->File);
900         free(ReadTecFileStream);
901 #endif
902     }
903     return (InputIsOk);
904 }
905 
906 
TecAlloc(size_t size)907 void * STDCALL TecAlloc(size_t size)
908 {
909     return (void *)ALLOC_ARRAY(size, char, "TecAlloc");
910 }
911 
TecFree(void * ptr)912 void STDCALL TecFree(void *ptr)
913 {
914     /* Hack to remove delete warning... */
915     char *Tmp = (char *)ptr;
916     FREE_ARRAY(Tmp, "TecAlloc");
917 }
918 
919 
920