2 * NOTICE and LICENSE for Tecplot Input/Output Library (TecIO) - OpenFOAM
4 * Copyright (C) 1988-2009 Tecplot, Inc. All rights reserved worldwide.
6 * Tecplot hereby grants OpenCFD limited authority to distribute without
7 * alteration the source code to the Tecplot Input/Output library, known
8 * as TecIO, as part of its distribution of OpenFOAM and the
9 * OpenFOAM_to_Tecplot converter. Users of this converter are also hereby
10 * granted access to the TecIO source code, and may redistribute it for the
11 * purpose of maintaining the converter. However, no authority is granted
12 * to alter the TecIO source code in any form or manner.
14 * This limited grant of distribution does not supersede Tecplot, Inc.'s
15 * copyright in TecIO. Contact Tecplot, Inc. for further information.
18 * 3535 Factoria Blvd, Ste. 550
19 * Bellevue, WA 98006, USA
20 * Phone: +1 425 653 1200
21 * http://www.tecplot.com/
26 #define TECPLOTENGINEMODULE
29 ******************************************************************
30 ******************************************************************
32 ****** (C) 1988-2008 Tecplot, Inc. *******
34 ******************************************************************
35 ******************************************************************
41 #include "Q_UNICODE.h"
46 #include "FILESTREAM.h"
48 #if defined TECPLOTKERNEL
49 /* CORE SOURCE CODE REMOVED */
69 using namespace tecplot::strutil
;
71 #if !defined(TECPLOTKERNEL) && defined(MSWIN)
72 # pragma warning(disable : 4244)
78 * This module contains mostly low level i/o functions.
81 #if defined DECALPHA || defined COMPAQALPHA
82 #define _IEEE_FP_INEXACT
92 #if defined TECPLOTKERNEL
93 /* CORE SOURCE CODE REMOVED */
96 /**********************************************************************
97 **********************************************************************
98 ********************** INPUT **************************
99 **********************************************************************
100 **********************************************************************/
102 static char FilterFloatChar(float X
)
105 if (((X
>= 32.0) && (X
<= 127.0)) ||
106 ((X
>= 160.0) && (X
<= 255.0)) ||
115 double GetNextValue(FileStream_s
*FileStream
,
116 FieldDataType_e FieldDataType
,
123 REQUIRE(VALID_REF(IsOk
) && VALID_BOOLEAN(*IsOk
));
124 REQUIRE(!(*IsOk
) || VALID_FIELD_DATA_TYPE(FieldDataType
));
125 REQUIRE(!(*IsOk
) || VALID_REF(FileStream
));
129 switch (FieldDataType
)
131 case FieldDataType_Float
:
135 *IsOk
= (TP_FREAD(&XX
, 4, 1, FileStream
->File
) == 1);
137 if (!FileStream
->IsByteOrderNative
)
138 REVERSE_4_BYTES(&XX
);
145 case FieldDataType_Double
:
149 *IsOk
= (TP_FREAD(&XX
, sizeof(double), 1, FileStream
->File
) == 1);
150 if (!FileStream
->IsByteOrderNative
)
151 REVERSE_8_BYTES(&XX
);
158 case FieldDataType_Int32
:
161 *IsOk
= (TP_FREAD(&L
, sizeof(Int32_t
), 1, FileStream
->File
) == 1);
162 if (!FileStream
->IsByteOrderNative
)
167 case FieldDataType_Int16
:
170 *IsOk
= (TP_FREAD(&S
, sizeof(Int16_t
), 1, FileStream
->File
) == 1);
171 if (!FileStream
->IsByteOrderNative
)
176 case FieldDataType_Byte
:
179 *IsOk
= (TP_FREAD(&B
, sizeof(Byte_t
), 1, FileStream
->File
) == 1);
183 case FieldDataType_Bit
:
187 * Reading bit data a value at a time is only valid for a
188 * single bit value. If the file contains a block of more than
189 * one bit value and you attempt to read it a bit at a time it
190 * will not work as Tecplot does not buffer the read. In order
191 * to read a block of bits you must perform a block read.
194 *IsOk
= (TP_FREAD(&B
, sizeof(Byte_t
), 1, FileStream
->File
) == 1);
196 X
= (double)(B
& (Byte_t
)01);
198 default: CHECK(FALSE
); break;
203 if ((X
< VMin
) || (X
> VMax
))
214 LgIndex_t
GetNextI(FileStream_s
*FileStream
,
219 REQUIRE(VALID_REF(IsOk
) && VALID_BOOLEAN(*IsOk
));
220 REQUIRE(!(*IsOk
) || (VALID_REF(FileStream
) && VALID_REF(FileStream
->File
)));
225 *IsOk
= (TP_FREAD((void *) & Int32Val
, 4, 1, FileStream
->File
) == 1);
226 if (!FileStream
->IsByteOrderNative
)
227 REVERSE_4_BYTES(&Int32Val
);
235 LgIndex_t
GetIoFileInt(FileStream_s
*FileStream
,
243 REQUIRE(VALID_REF(IsOk
) && VALID_BOOLEAN(*IsOk
));
244 REQUIRE(!(*IsOk
) || (0 < Version
&& Version
<= TecplotBinaryFileVersion
));
245 REQUIRE(!(*IsOk
) || (VALID_REF(FileStream
) && VALID_REF(FileStream
->File
)));
246 REQUIRE(!(*IsOk
) || IMin
<= IMax
);
256 X
= (float)GetNextValue(FileStream
, FieldDataType_Float
,
257 (double)IMin
- 1.0e-10,
258 (double)IMax
+ 1.0e-10, IsOk
);
261 if (ABS(X
) < (float)MAXINDEX
)
272 I
= GetNextI(FileStream
, IsOk
);
275 if ((I
< IMin
) || (I
> IMax
))
282 * Basically this is "realloc" but apparently "realloc" doesn't behave reliably
285 static Boolean_t
ReallocString(char **String
,
291 REQUIRE(VALID_REF(String
));
292 REQUIRE(*String
== NULL
|| VALID_REF(*String
));
293 REQUIRE((*String
!= NULL
&& NewLength
>= (LgIndex_t
)strlen(*String
)) ||
294 (*String
== NULL
&& NewLength
>= 0));
296 NewString
= ALLOC_ARRAY(NewLength
+ 1, char, "reallocated string");
297 IsOk
= (NewString
!= NULL
);
306 strcpy(NewString
, *String
);
307 FREE_ARRAY(*String
, "old string");
312 ENSURE(VALID_BOOLEAN(IsOk
));
313 ENSURE(IMPLICATION(IsOk
, VALID_REF(*String
)));
319 * Reads a string from all versions of a binary plt file.
322 * Open file stream positioned at the string to read.
324 * Binary file version number.
325 * param MaxCharacters
327 * This value is exactly the number of characters (actually floats, each
328 * one representing a character's ordinal value) to read from the file.
329 * IVersion >= 63 and ProcessData == TRUE
330 * If non-zero, this value represents the largest string to be returned.
331 * In other words, larger strings are read from the file but an allocated
332 * string of up to MaxCharacters is returned. A zero value indicates that
333 * the string size is unlimited and determined only by the actual length
334 * of the string in the file.
336 * Pointer to hold the allocated string if ProcessData == TRUE.
338 * Indicates if the read string should be retrieved.
341 * TRUE if the read was successful with an allocated string *TargetStr
342 * containing the string read (no larger than requested or necessary),
345 Boolean_t
ReadInString(FileStream_s
*FileStream
,
349 Boolean_t ProcessData
)
351 Boolean_t IsOk
= TRUE
;
353 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
354 REQUIRE(0 < IVersion
&& IVersion
<= TecplotBinaryFileVersion
);
355 REQUIRE(IMPLICATION(IVersion
< 63 || ProcessData
, MaxCharacters
>= 0));
356 REQUIRE(IMPLICATION(ProcessData
, VALID_REF(TargetStr
)));
357 REQUIRE(VALID_BOOLEAN(ProcessData
));
362 * One word per character. Read Exactly "MaxCharacters" number of words.
368 *TargetStr
= ALLOC_ARRAY(MaxCharacters
+ 1, char, "target string");
369 IsOk
= (*TargetStr
!= NULL
);
375 for (I
= 0; IsOk
&& I
< MaxCharacters
; I
++)
377 X
= (float)GetNextValue(FileStream
, FieldDataType_Float
, 0.0, 127.0, &IsOk
);
381 (*TargetStr
)[I
] = FilterFloatChar(X
);
384 (*TargetStr
)[I
] = '\0';
388 ErrMsg(translate("Cannot allocate memory for string during read",
389 "'string' meaning the computer science data type"));
394 #define MAX_STRBUFFER_LEN 4095
395 static char StrBuffer
[MAX_STRBUFFER_LEN
+1];
396 LgIndex_t StrBufferLen
= 0;
397 LgIndex_t TargetStrLen
= 0;
399 LgIndex_t CharValue
= 0;
406 CharValue
= GetIoFileInt(FileStream
, IVersion
, 0, 255, &IsOk
);
407 if (IsOk
&& ProcessData
)
409 /* massage the character if necessary */
410 if ((CharValue
< 32 && CharValue
!= '\0' && CharValue
!= '\n') ||
411 (CharValue
>= 128 && CharValue
< 160))
415 * if the limit is not exceded, stuff the
416 * character into the buffer
418 if (CharValue
!= '\0' &&
419 (I
< MaxCharacters
|| MaxCharacters
== 0))
421 StrBuffer
[StrBufferLen
] = (char)CharValue
;
425 if (CharValue
== '\0' ||
426 StrBufferLen
== MAX_STRBUFFER_LEN
)
428 if (StrBufferLen
!= 0 || *TargetStr
== NULL
)
430 StrBuffer
[StrBufferLen
] = '\0';
431 TargetStrLen
+= StrBufferLen
;
432 IsOk
= ReallocString(TargetStr
, TargetStrLen
);
434 strcat(*TargetStr
, StrBuffer
);
435 StrBufferLen
= 0; /* reset the string buffer */
442 while (IsOk
&& (char)CharValue
!= '\0');
444 /* if we failed cleanup if necessary */
449 FREE_ARRAY(*TargetStr
, "failed read string");
454 ENSURE(IMPLICATION(ProcessData
,
455 (VALID_REF(*TargetStr
) || *TargetStr
== NULL
)));
456 ENSURE(VALID_BOOLEAN(IsOk
));
462 static void ReadDoubleBlock(FileStream_s
*FileStream
,
465 LgIndex_t StartIndex
,
471 double *DPtr
= Buffer
+ StartIndex
;
472 *IsOk
= (TP_FREAD(DPtr
, sizeof(double), NumValues
, FileStream
->File
) == (size_t)NumValues
);
473 if (!FileStream
->IsByteOrderNative
&& *IsOk
)
476 for (N
= 0; N
< NumValues
; N
++)
477 REVERSE_8_BYTES(&DPtr
[N
]);
481 *IsOk
= (TP_FSEEK(FileStream
->File
, NumValues
* sizeof(double), SEEK_CUR
) == 0);
486 static void ReadFloatBlock(FileStream_s
*FileStream
,
489 LgIndex_t StartIndex
,
495 float *FPtr
= Buffer
+ StartIndex
;
496 *IsOk
= (TP_FREAD(FPtr
, sizeof(float), NumValues
, FileStream
->File
) == (size_t)NumValues
);
497 if (!FileStream
->IsByteOrderNative
&& *IsOk
)
500 for (N
= 0; N
< NumValues
; N
++)
501 REVERSE_4_BYTES(&FPtr
[N
]);
505 *IsOk
= (TP_FSEEK(FileStream
->File
, NumValues
* sizeof(float), SEEK_CUR
) == 0);
511 static void ReadBitBlock(FileStream_s
*FileStream
,
518 * Do not allow reading of bit values if startindex is not 0.
519 * (This means geometries cannot use bit data.
521 LgIndex_t NumBytes
= (NumValues
+ 7) / 8;
524 *IsOk
= (TP_FREAD(Buffer
,
527 FileStream
->File
) == (size_t)NumBytes
);
530 *IsOk
= (TP_FSEEK(FileStream
->File
, NumBytes
* sizeof(Byte_t
), SEEK_CUR
) == 0);
535 void ReadByteBlock(FileStream_s
*FileStream
,
538 HgIndex_t StartIndex
,
544 *IsOk
= (TP_FREAD(Buffer
+ StartIndex
,
547 FileStream
->File
) == (size_t)NumValues
);
550 *IsOk
= (TP_FSEEK(FileStream
->File
, NumValues
* sizeof(Byte_t
), SEEK_CUR
) == 0);
556 void ReadInt16Block(FileStream_s
*FileStream
,
559 HgIndex_t StartIndex
,
565 Int16_t
*IntPtr
= Buffer
+ StartIndex
;
566 *IsOk
= (TP_FREAD(IntPtr
,
569 FileStream
->File
) == (size_t)NumValues
);
571 if (!FileStream
->IsByteOrderNative
&& *IsOk
)
574 for (N
= 0; N
< NumValues
; N
++)
575 REVERSE_2_BYTES(&IntPtr
[N
]);
579 *IsOk
= (TP_FSEEK(FileStream
->File
, NumValues
* sizeof(Int16_t
), SEEK_CUR
) == 0);
584 void ReadInt16BlockToInt32(FileStream_s
*FileStream
,
587 HgIndex_t StartIndex
,
591 REQUIRE(VALID_REF(FileStream
));
592 REQUIRE(VALID_BOOLEAN(DoRead
));
593 REQUIRE(VALID_REF(Buffer
));
594 REQUIRE(StartIndex
>= 0);
595 REQUIRE(NumValues
>= 0);
596 REQUIRE(VALID_REF(IsOk
) && VALID_BOOLEAN(*IsOk
));
600 HgIndex_t EndIndex
= StartIndex
+ NumValues
;
601 for (HgIndex_t ValueIndex
= StartIndex
; *IsOk
&& ValueIndex
< EndIndex
; ValueIndex
++)
604 *IsOk
= (TP_FREAD(&Value
, sizeof(Int16_t
), 1, FileStream
->File
) == 1);
605 if (!FileStream
->IsByteOrderNative
&& *IsOk
)
606 REVERSE_2_BYTES(&Value
);
607 Buffer
[ValueIndex
] = (Int32_t
)Value
;
611 *IsOk
= (TP_FSEEK(FileStream
->File
, NumValues
* sizeof(Int16_t
), SEEK_CUR
) == 0);
616 void ReadInt32Block(FileStream_s
*FileStream
,
619 HgIndex_t StartIndex
,
625 Int32_t
*IntPtr
= Buffer
+ StartIndex
;
626 *IsOk
= (TP_FREAD(IntPtr
,
629 FileStream
->File
) == (size_t)NumValues
);
631 if (!FileStream
->IsByteOrderNative
&& *IsOk
)
634 for (N
= 0; N
< NumValues
; N
++)
635 REVERSE_4_BYTES(&IntPtr
[N
]);
639 *IsOk
= (TP_FSEEK(FileStream
->File
, NumValues
* sizeof(Int32_t
), SEEK_CUR
) == 0);
644 void ReadPureBlock(FileStream_s
*FileStream
,
647 FieldDataType_e FieldDataType
,
648 HgIndex_t StartIndex
,
652 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
653 REQUIRE(VALID_BOOLEAN(DoRead
));
654 REQUIRE(!DoRead
|| VALID_REF(Buffer
));
655 REQUIRE(VALID_FIELD_DATA_TYPE(FieldDataType
));
656 REQUIRE(StartIndex
>= 0);
657 REQUIRE(NumValues
>= 0);
658 REQUIRE(VALID_REF(IsOk
) && VALID_BOOLEAN(*IsOk
));
660 switch (FieldDataType
)
662 case FieldDataType_Float
:
664 ReadFloatBlock(FileStream
,
671 case FieldDataType_Double
:
673 ReadDoubleBlock(FileStream
,
680 case FieldDataType_Bit
:
684 ErrMsg(translate("Internal Error: Attempt to read bit data at non-zero offset",
685 "see Tecplot User's manual for a definition of 'bit' data"));
689 ReadBitBlock(FileStream
,
695 case FieldDataType_Byte
:
697 ReadByteBlock(FileStream
,
704 case FieldDataType_Int16
:
706 ReadInt16Block(FileStream
,
713 case FieldDataType_Int32
:
715 ReadInt32Block(FileStream
,
722 case FieldDataType_IJKFunction
: /* Not used yet */
723 case FieldDataType_Int64
: /* Not used yet */
724 default: CHECK(FALSE
); break;
726 ENSURE(VALID_BOOLEAN(*IsOk
));
731 void ReadBlock(FileStream_s
*FileStream
,
732 FieldData_pa FieldData
,
734 FieldDataType_e FieldDataTypeInFile
,
735 HgIndex_t StartIndex
,
739 REQUIRE(VALID_REF(IsOk
) && VALID_BOOLEAN(*IsOk
));
740 REQUIRE(IMPLICATION(IsOk
, VALID_REF(FileStream
)));
741 REQUIRE(IMPLICATION(IsOk
, VALID_FIELD_DATA_TYPE(FieldDataTypeInFile
)));
742 REQUIRE(VALID_BOOLEAN(DoRead
));
743 REQUIRE(IMPLICATION(DoRead
, VALID_REF(FieldData
)));
746 * Bit data is packed into bytes. Since Tecplot doesn't buffer reads it can
747 * not perform bit by bit value reads and therefore must only perform block
750 Boolean_t ReadByBlock
= IMPLICATION(DoRead
, GetFieldDataType(FieldData
) == FieldDataTypeInFile
);
751 REQUIRE(ReadByBlock
|| (FieldDataTypeInFile
!= FieldDataType_Bit
));
755 LgIndex_t NumValues
= EndIndex
- StartIndex
+ 1;
760 data_array
= GetFieldDataVoidPtr(FieldData
);
763 ReadPureBlock(FileStream
,
774 for (N
= 0; *IsOk
&& (N
< NumValues
); N
++)
776 double D
= GetNextValue(FileStream
, FieldDataTypeInFile
, -LARGEDOUBLE
, LARGEDOUBLE
, IsOk
);
778 SetFieldValue(FieldData
, N
+ StartIndex
, D
);
786 void ReadClassicOrderedCCBlock(FileStream_s
*DataFileStream
,
787 FieldData_pa FieldData
,
788 FieldDataType_e FieldDataTypeInFile
,
789 LgIndex_t NumIPtsInFile
,
790 LgIndex_t NumJPtsInFile
,
791 LgIndex_t NumKPtsInFile
,
794 REQUIRE(IMPLICATION(*IsOk
, VALID_REF(DataFileStream
)));
795 REQUIRE(IMPLICATION(*IsOk
, VALID_FIELD_DATA_TYPE(FieldDataTypeInFile
)));
796 REQUIRE(VALID_REF(FieldData
));
797 REQUIRE(NumIPtsInFile
>= 0);
798 REQUIRE(NumJPtsInFile
>= 0);
799 REQUIRE(NumKPtsInFile
>= 0);
800 REQUIRE(VALID_REF(IsOk
) && VALID_BOOLEAN(*IsOk
));
805 LgIndex_t NumIJPts
= NumIPtsInFile
* NumJPtsInFile
;
806 LgIndex_t IEnd
= MAX(NumIPtsInFile
- 1, 1);
807 LgIndex_t JEnd
= MAX(NumJPtsInFile
- 1, 1);
808 LgIndex_t KEnd
= MAX(NumKPtsInFile
- 1, 1);
809 LgIndex_t NumValues
= (IEnd
* JEnd
* KEnd
);
810 Boolean_t IsLinear
= ((NumJPtsInFile
== 1 && NumKPtsInFile
== 1) ||
811 (NumIPtsInFile
== 1 && NumKPtsInFile
== 1) ||
812 (NumIPtsInFile
== 1 && NumJPtsInFile
== 1));
814 ReadBlock(DataFileStream
, FieldData
, TRUE
, FieldDataTypeInFile
,
815 0, NumValues
- 1, IsOk
);
817 for (K
= 0; K
< KEnd
&& IsOk
; K
++)
818 for (J
= 0; J
< JEnd
&& IsOk
; J
++)
820 LgIndex_t CellIndex
= 0 + (J
* NumIPtsInFile
) + (K
* NumIJPts
);
821 ReadBlock(DataFileStream
, FieldData
, TRUE
, FieldDataTypeInFile
,
822 CellIndex
, CellIndex
+ IEnd
- 1, IsOk
);
826 ENSURE(VALID_BOOLEAN(*IsOk
));
831 static void AdjustCustomColor(short IVersion
,
832 ColorIndex_t
*BColor
)
834 REQUIRE(0 < IVersion
&& IVersion
<= TecplotBinaryFileVersion
);
835 REQUIRE(VALID_REF(BColor
));
837 if ((IVersion
< 70) && (*BColor
>= 15) && (*BColor
<= 22))
843 * ReadInDataFileTypeTitleAndVarNames replaces ReadInDataFileTitleAndVarNames
844 * and reads in the filetype as well in files with version >= 109.
846 Boolean_t
ReadInDataFileTypeTitleAndVarNames(FileStream_s
*FileStream
,
849 DataFileType_e
*FileType
,
851 StringList_pa
*VarNames
)
854 Boolean_t IsOk
= TRUE
;
856 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
857 REQUIRE(0 < IVersion
&& IVersion
<= TecplotBinaryFileVersion
);
858 REQUIRE(VALID_REF(DataSetTitle
) || (DataSetTitle
== NULL
));
859 REQUIRE(VALID_REF(FileType
) || (FileType
== NULL
));
860 REQUIRE(VALID_REF(NumVars
));
861 REQUIRE(VALID_REF(VarNames
) || (VarNames
== NULL
));
865 *DataSetTitle
= NULL
;
869 *FileType
= (DataFileType_e
)GetIoFileInt(FileStream
,
872 DataFileType_Solution
,
875 GetIoFileInt(FileStream
,
878 DataFileType_Solution
,
881 if (ReadInString(FileStream
,
883 ((IVersion
< 63) ? 80 : MaxChrsDatasetTitle
),
885 (Boolean_t
)(DataSetTitle
!= NULL
)))
888 TrimLeadAndTrailSpaces(*DataSetTitle
);
889 *NumVars
= GetIoFileInt(FileStream
, IVersion
, 0, MAXZONEMAP
, &IsOk
);
894 if (IsOk
&& (*NumVars
> MaxNumZonesOrVars
))
896 ErrMsg(translate("Too many variables"));
900 if (IsOk
&& VarNames
)
904 /* allocate a string list filled with NULL's */
905 *VarNames
= StringListAlloc();
906 IsOk
= (*VarNames
!= NULL
);
908 IsOk
= StringListSetString(*VarNames
, *NumVars
- 1, NULL
);
912 if (*VarNames
!= NULL
)
913 StringListDealloc(VarNames
);
914 ErrMsg(translate("Out of space while allocating var names"));
919 for (CurVar
= 0; IsOk
&& (CurVar
< *NumVars
); CurVar
++)
923 IsOk
= ReadInString(FileStream
,
925 ((IVersion
< 63) ? 5 : MaxChrsVarName
),
926 VarNames
? &VName
: NULL
,
927 (Boolean_t
)(VarNames
!= NULL
));
928 if (IsOk
&& VarNames
)
932 /* NULL variable names are converted to empty names */
933 VName
= ALLOC_ARRAY(1, char, "empty variable name");
936 TrimLeadAndTrailSpaces(VName
);
939 * variables are not allowed to have litteral new line characters
940 * within them but they can sneek in from ASCII data files so
941 * convert any to their appropriate two character representation
943 IsOk
= ReplaceNewlineWithBackslashN(&VName
);
945 IsOk
= IsOk
&& StringListSetString(*VarNames
, CurVar
, VName
);
947 FREE_ARRAY(VName
, "variable name");
952 if (VarNames
&& *VarNames
)
953 StringListDealloc(VarNames
);
954 ErrMsg(translate("Out of space while allocating variable names"));
957 ENSURE(VALID_BOOLEAN(IsOk
));
966 static Boolean_t
ReadInPresetZoneColor(FileStream_s
*FileStream
,
968 ZoneSpec_s
*ZoneSpec
)
970 Boolean_t IsOk
= TRUE
;
973 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
974 REQUIRE(0 < IVersion
&& IVersion
<= TecplotBinaryFileVersion
);
975 REQUIRE(VALID_REF(ZoneSpec
));
977 ZoneColor
= GetIoFileInt(FileStream
, IVersion
, -1, LastBasicColor
, &IsOk
);
980 if (VALID_BASIC_COLOR(ZoneColor
))
982 ZoneSpec
->ZoneLoadInfo
.PresetZoneColor
= (EntIndex_t
)ZoneColor
;
983 AdjustCustomColor(IVersion
, &ZoneSpec
->ZoneLoadInfo
.PresetZoneColor
);
985 else if (ZoneColor
!= -1)
989 ENSURE(VALID_BOOLEAN(IsOk
));
995 static void ConvertCommonTimeToSolutionTime(ZoneSpec_s
*ZoneSpec
)
997 REQUIRE(VALID_REF(ZoneSpec
));
998 REQUIRE(ZoneSpec
->AuxData
== NULL
|| VALID_REF(ZoneSpec
->AuxData
));
1000 LgIndex_t ItemIndex
;
1001 if (ZoneSpec
->AuxData
!= NULL
&&
1002 AuxDataGetItemIndex(ZoneSpec
->AuxData
, AuxData_Common_Time
, &ItemIndex
))
1004 const char *SameName
;
1009 AuxDataGetItemByIndex(ZoneSpec
->AuxData
, ItemIndex
,
1010 &SameName
, &Value
, &Type
, &Retain
);
1011 CHECK(ustrcmp(AuxData_Common_Time
, SameName
) == 0);
1012 CHECK(Type
== AuxDataType_String
);
1014 char *EndPtr
= NULL
;
1015 double SolutionTime
= strtod((const char *)Value
, &EndPtr
);
1016 if (EndPtr
!= (char *)Value
)
1018 /* we only allow white space to trail a value */
1019 while (isspace(*EndPtr
))
1022 if (EndPtr
!= (char *)Value
&& *EndPtr
== '\0')
1024 ZoneSpec
->SolutionTime
= SolutionTime
;
1025 ZoneSpec
->StrandID
= STRAND_ID_PENDING
;
1026 AuxDataDeleteItemByIndex(ZoneSpec
->AuxData
, ItemIndex
);
1032 * Pass1 for a zone reads in and initializes the zone structures.
1033 * These structures are released later if the user elects to not read them
1036 Boolean_t
ReadInZoneHeader(FileStream_s
*FileStream
,
1038 ZoneSpec_s
*ZoneSpec
,
1039 Set_pa IsVarCellCentered
,
1041 Boolean_t
*IsRawFNAvailable
,
1042 LgIndex_t
*FNNumBndryConns
)
1045 Boolean_t IsOk
= TRUE
;
1048 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
1049 REQUIRE(0 < IVersion
&& IVersion
<= TecplotBinaryFileVersion
);
1050 REQUIRE(VALID_REF(ZoneSpec
));
1051 REQUIRE(IsVarCellCentered
== NULL
|| VALID_REF(IsVarCellCentered
));
1052 REQUIRE(NumVars
>= 0);
1053 REQUIRE(VALID_REF(IsRawFNAvailable
));
1054 REQUIRE(VALID_REF(FNNumBndryConns
));
1056 SetZoneSpecDefaults(ZoneSpec
);
1058 if (IsVarCellCentered
!= NULL
)
1060 /* assign default variable value location: nodal */
1061 ClearSet(IsVarCellCentered
);
1062 IsOk
= ExpandSet(IsVarCellCentered
, NumVars
, FALSE
);
1066 IsOk
= ReadInString(FileStream
, IVersion
,
1067 ((IVersion
< 63) ? 10 : MaxChrsZnTitle
),
1071 if (IsOk
&& ZoneSpec
->Name
== NULL
)
1073 /* NULL zone names are converted to empty names */
1074 ZoneSpec
->Name
= ALLOC_ARRAY(1, char, "empty zone name");
1075 IsOk
= (ZoneSpec
->Name
!= NULL
);
1077 strcpy(ZoneSpec
->Name
, "");
1081 TrimLeadAndTrailSpaces(ZoneSpec
->Name
);
1085 Boolean_t IsZoneFinite
;
1086 DataFormat_e ZoneDataFormat
;
1088 I1
= GetIoFileInt(FileStream
, IVersion
, 0, 3, &IsOk
);
1090 if ((I1
< 0) || (I1
> 3))
1095 ZoneDataFormat
= (DataFormat_e
)I1
;
1097 IsZoneFinite
= (ZoneDataFormat
== DataFormat_FEPoint
||
1098 ZoneDataFormat
== DataFormat_FEBlock
);
1100 ZoneSpec
->ZoneLoadInfo
.IsInBlockFormat
= (ZoneDataFormat
== DataFormat_IJKBlock
||
1101 ZoneDataFormat
== DataFormat_FEBlock
);
1104 IsOk
= ReadInPresetZoneColor(FileStream
, IVersion
, ZoneSpec
);
1107 GetNextValue(FileStream
, FieldDataType_Float
, -LARGEDOUBLE
, LARGEDOUBLE
, &IsOk
); /* Old ZPlane Value */
1111 ZoneSpec
->NumPtsI
= GetIoFileInt(FileStream
, IVersion
, 0, MAXINDEX
, &IsOk
);
1112 ZoneSpec
->NumPtsJ
= GetIoFileInt(FileStream
, IVersion
, 0, MAXINDEX
, &IsOk
);
1114 ZoneSpec
->NumPtsK
= GetIoFileInt(FileStream
, IVersion
, 0, MAXINDEX
, &IsOk
);
1116 ZoneSpec
->NumPtsK
= 1;
1121 /* If IMax,JMax, & KMax are all zero then this zone was "zombied" by
1122 a partial read to make layout files align. */
1124 if (!((ZoneSpec
->NumPtsI
== 0) &&
1125 (ZoneSpec
->NumPtsJ
== 0) &&
1126 (ZoneSpec
->NumPtsK
== 0)) &&
1127 ((ZoneSpec
->NumPtsI
<= 0) ||
1128 (ZoneSpec
->NumPtsJ
<= 0) ||
1129 (ZoneSpec
->NumPtsK
< 0) ||
1130 ((!IsZoneFinite
&& (ZoneSpec
->NumPtsK
== 0)))))
1132 ErrMsg(translate("Datafile is corrupted"));
1140 ZoneSpec
->Type
= (ZoneType_e
)(ZoneSpec
->NumPtsK
+ 1);
1141 switch (ZoneSpec
->Type
)
1143 case ZoneType_FETriangle
: ZoneSpec
->NumPtsK
= 3; break;
1144 case ZoneType_FEQuad
: ZoneSpec
->NumPtsK
= 4; break;
1145 case ZoneType_FETetra
: ZoneSpec
->NumPtsK
= 4; break;
1146 case ZoneType_FEBrick
: ZoneSpec
->NumPtsK
= 8; break;
1147 case ZoneType_FELineSeg
: ZoneSpec
->NumPtsK
= 2; break;
1150 ErrMsg(translate("Datafile corrupted: Invalid element type for FE DataSet"));
1157 ZoneSpec
->Type
= ZoneType_FEQuad
;
1158 ZoneSpec
->NumPtsK
= 4;
1163 ZoneSpec
->Type
= ZoneType_Ordered
;
1165 ZoneSpec
->ICellDim
= ZoneSpec
->NumPtsI
- 1;
1166 ZoneSpec
->JCellDim
= ZoneSpec
->NumPtsJ
- 1;
1167 ZoneSpec
->KCellDim
= ZoneSpec
->NumPtsK
- 1;
1172 * Raw and user defined boundary face neighbors connections were not in
1173 * this or previous versions of the binary data files.
1175 *IsRawFNAvailable
= FALSE
;
1176 *FNNumBndryConns
= 0;
1180 if (IsOk
&& (IVersion
>= 107))
1182 ZoneSpec
->ParentZone
= GetIoFileInt(FileStream
, IVersion
, -1, MAXZONEMAP
- 1, &IsOk
);
1184 ErrMsg(translate("Invalid datafile: parent zone assignment must be to an existing zone within the same datafile."));
1187 if (IsOk
&& (IVersion
>= 106))
1189 /* Strand ID and solution time. Strand ID's of STRAND_ID_PENDING, -2, instruct Tecplot to generate strand ID's */
1190 ZoneSpec
->StrandID
= GetIoFileInt(FileStream
, IVersion
, -2, MAXZONEMAP
- 1, &IsOk
);
1191 ZoneSpec
->SolutionTime
= GetNextValue(FileStream
, FieldDataType_Double
, -LARGEDOUBLE
, LARGEDOUBLE
, &IsOk
);
1193 ErrMsg(translate("Invalid datafile: bad StrandID or SolutionTime"));
1196 /* preset zone color */
1197 IsOk
= IsOk
&& ReadInPresetZoneColor(FileStream
, IVersion
, ZoneSpec
);
1200 I1
= (ZoneType_e
)GetIoFileInt(FileStream
, IVersion
, 0, 7, &IsOk
);
1203 case 0: ZoneSpec
->Type
= ZoneType_Ordered
; break;
1204 case 1: ZoneSpec
->Type
= ZoneType_FELineSeg
; break;
1205 case 2: ZoneSpec
->Type
= ZoneType_FETriangle
; break;
1206 case 3: ZoneSpec
->Type
= ZoneType_FEQuad
; break;
1207 case 4: ZoneSpec
->Type
= ZoneType_FETetra
; break;
1208 case 5: ZoneSpec
->Type
= ZoneType_FEBrick
; break;
1209 case 6: ZoneSpec
->Type
= ZoneType_FEPolygon
; break;
1210 case 7: ZoneSpec
->Type
= ZoneType_FEPolyhedron
; break;
1213 ErrMsg(translate("Invalid datafile: unknown zone type."));
1218 /* DataPacking (Always BLOCK starting with file version 112 so removed from binary format) */
1220 ZoneSpec
->ZoneLoadInfo
.IsInBlockFormat
=
1221 ((DataPacking_e
)GetIoFileInt(FileStream
, IVersion
, 0, 1, &IsOk
) == DataPacking_Block
);
1223 ZoneSpec
->ZoneLoadInfo
.IsInBlockFormat
= TRUE
;
1225 /* is the variable value location specified? */
1226 if ((Boolean_t
)GetIoFileInt(FileStream
, IVersion
, 0, 1, &IsOk
) && IsOk
)
1228 /* Variable Value Location foreach Var */
1229 for (Var
= 0; Var
< NumVars
&& IsOk
; Var
++)
1231 if ((Boolean_t
)GetIoFileInt(FileStream
, IVersion
, 0, 1, &IsOk
) && IsOk
&&
1232 IsVarCellCentered
!= NULL
)
1234 IsOk
= (ZoneSpec
->ZoneLoadInfo
.IsInBlockFormat
);
1236 IsOk
= AddToSet(IsVarCellCentered
, Var
, FALSE
);
1238 ErrMsg(translate("Invalid datafile: cell centered "
1239 "variable must be in block format.",
1240 "See the Tecplot User's Manual for a definition of 'block format'"));
1245 /* are raw face neighbors supplied in the data section? */
1246 if (IVersion
>= 108 && IsOk
)
1248 *IsRawFNAvailable
= GetIoFileInt(FileStream
, IVersion
, 0, 1, &IsOk
);
1249 if (*IsRawFNAvailable
&&
1250 (ZoneSpec
->Type
== ZoneType_Ordered
||
1251 ZoneSpec
->Type
== ZoneType_FELineSeg
))
1254 ErrMsg(translate("Invalid datafile: raw face neighbors may not be "
1255 "supplied for ordered or FE line segment zones."));
1259 *IsRawFNAvailable
= FALSE
;
1262 * If raw face neighbors are available in the datafile then Tecplot
1263 * should not auto-assign the neighbors after the load.
1265 ZoneSpec
->FNAreCellFaceNbrsSupplied
= *IsRawFNAvailable
;
1267 /* miscellaneous face neighbor info */
1268 *FNNumBndryConns
= GetIoFileInt(FileStream
, IVersion
, 0, MAXINDEX
, &IsOk
);
1269 if (*FNNumBndryConns
!= 0)
1270 ZoneSpec
->FNMode
= (FaceNeighborMode_e
)GetIoFileInt(FileStream
, IVersion
, 0, 3, &IsOk
);
1272 if (IVersion
>= 108 && IsOk
)
1274 Boolean_t FaceNeighborsComplete
= FALSE
;
1275 if (*FNNumBndryConns
!= 0 &&
1276 ZoneSpec
->Type
!= ZoneType_Ordered
)
1277 FaceNeighborsComplete
= (Boolean_t
)GetIoFileInt(FileStream
, IVersion
, 0, 1, &IsOk
);
1280 * If the user defined face neighbors completely specify all the
1281 * face neighbors then we don't want to auto-assign the cell face
1282 * neighbors after loading. If they are not complete then leave the
1283 * setting (as set above) dependent on the availability of the raw
1287 * This is a rather inefficient way to specify face neighbors.
1289 if (FaceNeighborsComplete
)
1290 ZoneSpec
->FNAreCellFaceNbrsSupplied
= TRUE
;
1293 if (ZoneSpec
->Type
== ZoneType_Ordered
)
1295 /* IMax, JMax, KMax */
1296 ZoneSpec
->NumPtsI
= GetIoFileInt(FileStream
, IVersion
, 0, MAXINDEX
, &IsOk
);
1297 ZoneSpec
->NumPtsJ
= GetIoFileInt(FileStream
, IVersion
, 0, MAXINDEX
, &IsOk
);
1298 ZoneSpec
->NumPtsK
= GetIoFileInt(FileStream
, IVersion
, 0, MAXINDEX
, &IsOk
);
1300 * if not a zombie zone (zombie zone: points in all dimensions are
1301 * zero) then points in each direction must be specified
1304 !(ZoneSpec
->NumPtsI
== 0 &&
1305 ZoneSpec
->NumPtsJ
== 0 &&
1306 ZoneSpec
->NumPtsK
== 0) &&
1307 (ZoneSpec
->NumPtsI
== 0 ||
1308 ZoneSpec
->NumPtsJ
== 0 ||
1309 ZoneSpec
->NumPtsK
== 0))
1311 ErrMsg(translate("Invalid data file: incorrect specification of "
1312 "I, J, or K points for ordered data set."));
1318 ZoneSpec
->NumPtsI
= GetIoFileInt(FileStream
, IVersion
, 0, MAXINDEX
, &IsOk
);
1319 if (ZoneSpec
->Type
== ZoneType_FEPolygon
|| ZoneSpec
->Type
== ZoneType_FEPolyhedron
)
1321 ZoneSpec
->NumPtsK
= GetIoFileInt(FileStream
, IVersion
, 0, MAXINDEX
, &IsOk
); // ...NumFaces
1322 if (IVersion
>= 111)
1324 ZoneSpec
->NumFaceNodes
= GetIoFileInt(FileStream
, IVersion
, 0, MAXINDEX
, &IsOk
);
1325 ZoneSpec
->NumFaceBndryFaces
= GetIoFileInt(FileStream
, IVersion
, 0, MAXINDEX
, &IsOk
);
1326 ZoneSpec
->NumFaceBndryItems
= GetIoFileInt(FileStream
, IVersion
, 0, MAXINDEX
, &IsOk
);
1331 switch (ZoneSpec
->Type
)
1333 case ZoneType_FETriangle
: ZoneSpec
->NumPtsK
= 3; break;
1334 case ZoneType_FEQuad
: ZoneSpec
->NumPtsK
= 4; break;
1335 case ZoneType_FETetra
: ZoneSpec
->NumPtsK
= 4; break;
1336 case ZoneType_FEBrick
: ZoneSpec
->NumPtsK
= 8; break;
1337 case ZoneType_FELineSeg
: ZoneSpec
->NumPtsK
= 2; break;
1340 ErrMsg(translate("Invalid data file: invalid element type for FE data set."));
1345 ZoneSpec
->NumPtsJ
= GetIoFileInt(FileStream
, IVersion
, 0, MAXINDEX
, &IsOk
);
1347 ZoneSpec
->ICellDim
= GetIoFileInt(FileStream
, IVersion
, 0, MAXINDEX
, &IsOk
);
1348 ZoneSpec
->JCellDim
= GetIoFileInt(FileStream
, IVersion
, 0, MAXINDEX
, &IsOk
);
1349 ZoneSpec
->KCellDim
= GetIoFileInt(FileStream
, IVersion
, 0, MAXINDEX
, &IsOk
);
1352 /* Zone Auxiliary Data indicator followed by Zone Auxiliary Data */
1353 for (I1
= GetIoFileInt(FileStream
, IVersion
, 0, 1, &IsOk
);
1355 I1
= GetIoFileInt(FileStream
, IVersion
, 0, 1, &IsOk
))
1357 if (ZoneSpec
->AuxData
== NULL
)
1358 ZoneSpec
->AuxData
= AuxDataAlloc();
1359 IsOk
= (ZoneSpec
->AuxData
!= NULL
);
1361 IsOk
= ReadInAuxData(FileStream
, IVersion
, ZoneSpec
->AuxData
);
1366 * Convert AuxZone's Common.Time from non-time aware data files to zone
1367 * solution time if it exists.
1369 if (IVersion
< 106 && IsOk
)
1370 ConvertCommonTimeToSolutionTime(ZoneSpec
);
1372 ENSURE(VALID_BOOLEAN(IsOk
));
1380 * Pass1 for Custom labels simply acknowledges that a custom label was
1381 * parsed and skips over the labels.
1384 Boolean_t
ReadInCustomLabels(FileStream_s
*FileStream
,
1387 StringList_pa
*CustomLabelBase
)
1389 LgIndex_t NumLabels
;
1391 Boolean_t IsOk
= TRUE
;
1393 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
1394 REQUIRE(IVersion
> 0);
1395 REQUIRE(VALID_BOOLEAN(OkToLoad
));
1396 REQUIRE(!(OkToLoad
) || VALID_REF(CustomLabelBase
));
1398 NumLabels
= (short)GetIoFileInt(FileStream
, IVersion
, 1, MAXINDEX
, &IsOk
);
1399 if (IsOk
&& NumLabels
!= 0 && OkToLoad
)
1401 *CustomLabelBase
= StringListAlloc();
1402 IsOk
= (*CustomLabelBase
!= NULL
);
1404 ErrMsg(translate("Cannot allocate memory for Custom Labels."));
1407 for (I
= 0; IsOk
&& (I
< NumLabels
); I
++)
1409 char *TLabel
= NULL
;
1411 IsOk
= ReadInString(FileStream
, IVersion
,
1415 TrimLeadAndTrailSpaces(TLabel
);
1417 if (IsOk
&& OkToLoad
)
1419 #if defined TECPLOTKERNEL
1420 /* CORE SOURCE CODE REMOVED */
1422 IsOk
= StringListAppendString(*CustomLabelBase
, TLabel
);
1424 FREE_ARRAY(TLabel
, "custom label");
1426 ErrMsg(translate("Cannot allocate memory for Custom Label."));
1430 ErrMsg(translate("Invalid custom axis label record in binary datafile"));
1432 ENSURE(VALID_BOOLEAN(IsOk
));
1433 ENSURE(!(IsOk
&& NumLabels
!= 0 && OkToLoad
) ||
1434 StringListValid(*CustomLabelBase
));
1439 Boolean_t
ReadInUserRec(FileStream_s
*FileStream
,
1441 int MaxCharactersAllowed
,
1442 char **UserRec
) /* NULL if to ignore */
1444 if (!ReadInString(FileStream
, IVersion
,
1445 MaxCharactersAllowed
,
1447 (Boolean_t
)(UserRec
!= NULL
)))
1449 ErrMsg(translate("Invalid USERREC record in binary datafile"));
1458 Boolean_t
ReadInAuxData(FileStream_s
*FileStream
,
1463 Boolean_t DoCollectData
;
1464 char *AuxName
= NULL
;
1465 LgIndex_t AuxValueType
;
1466 char *AuxValue
= NULL
;
1468 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
1469 REQUIRE(0 < IVersion
&& IVersion
<= TecplotBinaryFileVersion
);
1470 REQUIRE(AuxData
== NULL
|| VALID_REF(AuxData
));
1472 DoCollectData
= (AuxData
!= NULL
);
1473 IsOk
= ReadInString(FileStream
,
1475 MaxChrsVarName
, /* ... seems reasonable */
1478 if (IsOk
&& DoCollectData
&& !AuxDataIsValidName(AuxName
))
1480 ErrMsg(translate("Invalid auxiliary data name."));
1485 * currently only one value type is supported
1486 * 0: AuxiliaryValueFormat_String
1490 AuxValueType
= GetIoFileInt(FileStream
, IVersion
, 0, 0, &IsOk
);
1491 if (IsOk
&& (AuxValueType
!= (LgIndex_t
)AuxDataType_String
))
1493 ErrMsg(translate("Unsupported auxiliary data type"));
1499 IsOk
= ReadInString(FileStream
,
1501 MaxChrsAuxValueString
,
1504 if (IsOk
&& DoCollectData
)
1505 IsOk
= AuxDataSetItem(AuxData
,
1506 AuxName
, (ArbParam_t
)AuxValue
,
1510 /* cleanup: auxiliary data made a copy of the name and value */
1511 if (AuxName
!= NULL
)
1512 FREE_ARRAY(AuxName
, "data set auxiliary data item name");
1513 if (AuxValue
!= NULL
)
1514 FREE_ARRAY(AuxValue
, "data set auxiliary data item value");
1516 ENSURE(VALID_BOOLEAN(IsOk
));
1521 static void GetZoneAttachment(FileStream_s
*FileStream
,
1524 Boolean_t
*IsAttached
,
1527 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
1528 REQUIRE(VALID_REF(Z
));
1529 REQUIRE(VALID_REF(IsAttached
));
1530 REQUIRE(VALID_REF(IsOk
) && VALID_BOOLEAN(*IsOk
));
1533 *Z
= (EntIndex_t
)GetIoFileInt(FileStream
, IVersion
, -1, MAXZONEMAP
, IsOk
);
1543 *IsAttached
= FALSE
;
1548 ENSURE(VALID_BOOLEAN(*IsAttached
));
1549 ENSURE(VALID_BOOLEAN(*IsOk
));
1554 static Boolean_t
ReadMacroFunctionCommand(FileStream_s
*FileStream
,
1557 char **MacroFunctionCommand
)
1559 Boolean_t Result
= FALSE
;
1560 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
1561 REQUIRE(IVersion
> 0);
1562 REQUIRE(VALID_BOOLEAN(OkToLoad
));
1563 REQUIRE(VALID_REF(MacroFunctionCommand
));
1565 Result
= ReadInString(FileStream
, IVersion
, 0, MacroFunctionCommand
, OkToLoad
);
1567 ENSURE(VALID_BOOLEAN(Result
));
1573 * Pass1 for Geometries simply acknowledges that a geometry was
1574 * parsed and skips over the geometry.
1576 Boolean_t
ReadInGeometry(FileStream_s
*FileStream
,
1580 LgIndex_t MaxDataPts
)
1584 FieldDataType_e FFT
;
1585 Boolean_t IsOk
= TRUE
;
1586 TranslatedString ErrMsgString
= translate("Invalid geometry record");
1588 REQUIRE(VALID_REF(Geom
));
1591 FFT
= FieldDataType_Float
;
1593 FFT
= FieldDataType_Double
;
1596 I
= GetIoFileInt(FileStream
, IVersion
, 0, 1, &IsOk
);
1598 I
= GetIoFileInt(FileStream
, IVersion
, 0, 4, &IsOk
);
1601 Geom
->PositionCoordSys
= CoordSys_Grid
;
1603 Geom
->PositionCoordSys
= CoordSys_Frame
;
1605 * I == 2 is for CoordSys_FrameOffset and is not used currently
1607 * I == 3 is for the old window coordinate system
1610 Geom
->PositionCoordSys
= CoordSys_Grid3D
;
1613 ErrMsgString
= translate("Invalid geometry coordinate system");
1617 Geom
->Scope
= (Scope_e
)GetIoFileInt(FileStream
, IVersion
, 0, 1, &IsOk
);
1618 if (IVersion
>= 102)
1619 Geom
->DrawOrder
= (DrawOrder_e
)GetIoFileInt(FileStream
, IVersion
, 0, 1, &IsOk
);
1620 Geom
->AnchorPos
.Generic
.V1
= GetNextValue(FileStream
, FFT
, -LARGEDOUBLE
, LARGEDOUBLE
, &IsOk
);
1621 Geom
->AnchorPos
.Generic
.V2
= GetNextValue(FileStream
, FFT
, -LARGEDOUBLE
, LARGEDOUBLE
, &IsOk
);
1623 Geom
->AnchorPos
.Generic
.V3
= GetNextValue(FileStream
, FFT
, -LARGEDOUBLE
, LARGEDOUBLE
, &IsOk
);
1625 Geom
->AnchorPos
.Generic
.V3
= 0.0;
1627 GetZoneAttachment(FileStream
, IVersion
, &Geom
->Zone
, &Geom
->AttachToZone
, &IsOk
);
1629 Geom
->BColor
= (SmInteger_t
)GetIoFileInt(FileStream
, IVersion
, 0, 255, &IsOk
);
1631 AdjustCustomColor(IVersion
, &Geom
->BColor
);
1635 Geom
->FillBColor
= (SmInteger_t
)GetIoFileInt(FileStream
, IVersion
, 0, 255, &IsOk
);
1636 Geom
->IsFilled
= (Boolean_t
)GetIoFileInt(FileStream
, IVersion
, 0, 1, &IsOk
);
1637 AdjustCustomColor(IVersion
, &Geom
->FillBColor
);
1641 Geom
->FillBColor
= Geom
->BColor
;
1642 Geom
->IsFilled
= FALSE
;
1647 Geom
->GeomType
= (GeomType_e
)GetIoFileInt(FileStream
, IVersion
, 0, 5, &IsOk
);
1648 if (Geom
->GeomType
== GeomType_LineSegs3D
)
1651 * GeomType_LineSegs3D is deprecated, converter to GeomType_LineSegs
1652 * with CoordSys_Grid3D instead
1654 Geom
->GeomType
= GeomType_LineSegs
;
1655 Geom
->PositionCoordSys
= CoordSys_Grid3D
; /*...should have been anyway */
1660 Geom
->GeomType
= (GeomType_e
)GetIoFileInt(FileStream
, IVersion
, 0, 4, &IsOk
);
1664 * Check geom coord sys versus geom type
1666 if (Geom
->PositionCoordSys
== CoordSys_Grid3D
&&
1667 Geom
->GeomType
!= GeomType_LineSegs
)
1669 ErrMsgString
= translate("Mismatch between geometry coordinate system and geometry type");
1675 Geom
->LinePattern
= (LinePattern_e
)GetIoFileInt(FileStream
, IVersion
, 0, (LgIndex_t
)LinePattern_DashDotDot
, &IsOk
);
1679 Geom
->LinePattern
= (LinePattern_e
)((int)Geom
->GeomType
% 2);
1680 Geom
->GeomType
= (GeomType_e
)((int)Geom
->GeomType
/ 10);
1683 if ((IVersion
< 49) && ((short)(Geom
->GeomType
) == 2))
1685 Geom
->GeomType
= GeomType_Rectangle
;
1686 Geom
->IsFilled
= TRUE
;
1689 if ((IVersion
< 70) && ((short)(Geom
->GeomType
) > 1))
1690 Geom
->GeomType
= (GeomType_e
)((short)Geom
->GeomType
+ 1);
1692 ResetString(&Geom
->MacroFunctionCommand
, NULL
, TRUE
);
1694 Geom
->ImageResizeFilter
= ImageResizeFilter_Texture
;
1698 Geom
->PatternLength
= GetNextValue(FileStream
, FFT
,
1699 PatternLengthInputSpec
.Min
,
1700 PatternLengthInputSpec
.Max
,
1702 Geom
->LineThickness
= GetNextValue(FileStream
, FFT
,
1703 LineThicknessInputSpec
.Min
,
1704 LineThicknessInputSpec
.Max
,
1706 Geom
->NumEllipsePts
= (SmInteger_t
)GetIoFileInt(FileStream
, IVersion
, 2, MaxPtsCircleOrEllipse
, &IsOk
);
1707 Geom
->ArrowheadStyle
= (ArrowheadStyle_e
)GetIoFileInt(FileStream
, IVersion
, 0, (LgIndex_t
)ArrowheadStyle_Hollow
, &IsOk
);
1708 Geom
->ArrowheadAttachment
= (ArrowheadAttachment_e
)GetIoFileInt(FileStream
, IVersion
,
1710 (LgIndex_t
)ArrowheadAttachment_AtBothEnds
,
1713 Geom
->ArrowheadSize
= GetNextValue(FileStream
, FFT
,
1714 ArrowheadSizeInputSpec
.Min
,
1715 ArrowheadSizeInputSpec
.Max
,
1717 Geom
->ArrowheadAngle
= GetNextValue(FileStream
, FFT
,
1718 ArrowheadAngleInputSpec
.Min
,
1719 ArrowheadAngleInputSpec
.Max
,
1724 IsOk
= ReadMacroFunctionCommand(FileStream
,
1727 &Geom
->MacroFunctionCommand
);
1728 } /* version >= 75 */
1729 } /* version >= 70 */
1732 Geom
->LineThickness
= 0.001;
1733 Geom
->PatternLength
= 0.02;
1734 Geom
->ArrowheadStyle
= ArrowheadStyle_Plain
;
1735 Geom
->ArrowheadAttachment
= ArrowheadAttachment_None
;
1736 Geom
->ArrowheadSize
= 0.05;
1737 Geom
->ArrowheadAngle
= 12.0 / DEGPERRADIANS
;
1742 GetNextValue(FileStream
, FieldDataType_Float
, -LARGEDOUBLE
, LARGEDOUBLE
, &IsOk
);
1743 GetNextValue(FileStream
, FieldDataType_Float
, -LARGEDOUBLE
, LARGEDOUBLE
, &IsOk
);
1744 GetNextValue(FileStream
, FieldDataType_Float
, -LARGEDOUBLE
, LARGEDOUBLE
, &IsOk
);
1748 Geom
->DataType
= FieldDataType_Float
;
1750 Geom
->DataType
= (FieldDataType_e
)GetIoFileInt(FileStream
, IVersion
, 1, 2, &IsOk
);
1751 CHECK(VALID_GEOM_FIELD_DATA_TYPE(Geom
->DataType
));
1753 Geom
->Clipping
= Clipping_ClipToViewport
; /* default value for pre 101 versions */
1754 if (IVersion
>= 101)
1756 Geom
->Clipping
= (Clipping_e
)GetIoFileInt(FileStream
, IVersion
, 0, 2, &IsOk
);
1758 * The second clipping value was deprecated during v10 development and thus removed.
1759 * This moved Clipping_ClipToFrame to the 2nd position from the 3rd, so we convert
1760 * value 2 to ClipToFrame to support files made during v10 developement.
1762 if (Geom
->Clipping
== (Clipping_e
)2)
1763 Geom
->Clipping
= Clipping_ClipToFrame
;
1766 if (IVersion
< 50 ||
1767 Geom
->GeomType
== GeomType_LineSegs
)
1769 Geom
->NumSegments
= (SmInteger_t
)GetIoFileInt(FileStream
, IVersion
, 1, MaxGeoSegments
, &IsOk
);
1770 #if defined TECPLOTKERNEL
1771 /* CORE SOURCE CODE REMOVED */
1775 while ((S
+ 1 < Geom
->NumSegments
) &&
1776 !feof(FileStream
->File
) && IsOk
)
1779 Geom
->NumSegPts
[S
] = GetIoFileInt(FileStream
, IVersion
, 1, MAXINDEX
, &IsOk
);
1780 if ((I
+ Geom
->NumSegPts
[S
] > MaxDataPts
) && OkToLoad
)
1782 ErrMsgString
= translate("Geometry is too big");
1787 ReadBlock(FileStream
, Geom
->GeomData
.Generic
.V1Base
, OkToLoad
, Geom
->DataType
, I
, I
+ Geom
->NumSegPts
[S
] - 1, &IsOk
);
1788 ReadBlock(FileStream
, Geom
->GeomData
.Generic
.V2Base
, OkToLoad
, Geom
->DataType
, I
, I
+ Geom
->NumSegPts
[S
] - 1, &IsOk
);
1789 if (Geom
->PositionCoordSys
== CoordSys_Grid3D
)
1790 ReadBlock(FileStream
, Geom
->GeomData
.Generic
.V3Base
, OkToLoad
, Geom
->DataType
, I
, I
+ Geom
->NumSegPts
[S
] - 1, &IsOk
);
1791 I
+= Geom
->NumSegPts
[S
];
1794 if (IsOk
&& (Geom
->GeomType
== GeomType_Rectangle
)) /* IVersion < 50 */
1798 CopyFieldValue(Geom
->GeomData
.Generic
.V1Base
, 0, Geom
->GeomData
.Generic
.V1Base
, 2);
1799 CopyFieldValue(Geom
->GeomData
.Generic
.V2Base
, 0, Geom
->GeomData
.Generic
.V2Base
, 2);
1803 else if (Geom
->GeomType
== GeomType_Rectangle
||
1804 Geom
->GeomType
== GeomType_Ellipse
)
1807 XX
= GetNextValue(FileStream
, Geom
->DataType
, -LARGEDOUBLE
, LARGEDOUBLE
, &IsOk
);
1808 YY
= GetNextValue(FileStream
, Geom
->DataType
, -LARGEDOUBLE
, LARGEDOUBLE
, &IsOk
);
1811 SetFieldValue(Geom
->GeomData
.XYZ
.XBase
, 0, XX
);
1812 SetFieldValue(Geom
->GeomData
.XYZ
.YBase
, 0, YY
);
1814 Geom
->NumSegments
= 1;
1815 Geom
->NumSegPts
[0] = 1;
1820 CHECK((Geom
->GeomType
== GeomType_Square
) ||
1821 (Geom
->GeomType
== GeomType_Circle
));
1822 XX
= GetNextValue(FileStream
, Geom
->DataType
, -LARGEDOUBLE
, LARGEDOUBLE
, &IsOk
);
1825 SetFieldValue(Geom
->GeomData
.XYZ
.XBase
, 0, XX
);
1827 Geom
->NumSegments
= 1;
1828 Geom
->NumSegPts
[0] = 1;
1832 ErrMsg(ErrMsgString
);
1838 * Pass1 for text simply acknowledges that a text was
1839 * parsed and skips over the text.
1841 Boolean_t
ReadInText(FileStream_s
*FileStream
,
1845 LgIndex_t MaxTextLen
)
1848 FieldDataType_e FFT
;
1849 SmInteger_t TextLength
= 0;
1850 Boolean_t IsOk
= TRUE
;
1851 TranslatedString ErrMsgString
= translate("Invalid text record");
1853 REQUIRE(VALID_REF(Text
));
1856 FFT
= FieldDataType_Float
;
1858 FFT
= FieldDataType_Double
;
1861 I
= GetIoFileInt(FileStream
, IVersion
, 0, 1, &IsOk
);
1863 I
= GetIoFileInt(FileStream
, IVersion
, 0, 4, &IsOk
);
1866 Text
->PositionCoordSys
= CoordSys_Grid
;
1868 Text
->PositionCoordSys
= CoordSys_Frame
;
1870 * I == 2 is for CoordSys_FrameOffset and is not used currently
1872 * I == 3 is for the old window coordinate system
1875 Text
->PositionCoordSys
= CoordSys_Grid3D
;
1878 ErrMsgString
= translate("Invalid text coordinate system.");
1882 Text
->Scope
= (Scope_e
)GetIoFileInt(FileStream
, IVersion
, 0, 1, &IsOk
);
1883 Text
->AnchorPos
.Generic
.V1
= GetNextValue(FileStream
, FFT
, -LARGEDOUBLE
, LARGEDOUBLE
, &IsOk
);
1884 Text
->AnchorPos
.Generic
.V2
= GetNextValue(FileStream
, FFT
, -LARGEDOUBLE
, LARGEDOUBLE
, &IsOk
);
1885 if (IVersion
>= 101)
1886 Text
->AnchorPos
.Generic
.V3
= GetNextValue(FileStream
, FFT
, -LARGEDOUBLE
, LARGEDOUBLE
, &IsOk
);
1888 Text
->AnchorPos
.Generic
.V3
= 0.0; /* default value for pre 101 versions */
1891 Text
->TextShape
.Font
= (Font_e
)GetIoFileInt(FileStream
, IVersion
, 0, (LgIndex_t
)Font_CourierBold
, &IsOk
);
1893 Text
->TextShape
.Font
= Font_Helvetica
;
1895 GetNextValue(FileStream
, FFT
, -LARGEDOUBLE
, LARGEDOUBLE
, &IsOk
);
1898 if (Text
->PositionCoordSys
== CoordSys_Grid
)
1899 Text
->TextShape
.SizeUnits
= Units_Grid
;
1901 Text
->TextShape
.SizeUnits
= Units_Frame
;
1904 Text
->TextShape
.SizeUnits
= (Units_e
)GetIoFileInt(FileStream
, IVersion
, 0, (LgIndex_t
)Units_Point
, &IsOk
);
1906 Text
->TextShape
.Height
= GetNextValue(FileStream
, FFT
, -LARGEDOUBLE
, LARGEDOUBLE
, &IsOk
);
1909 Text
->Box
.BoxType
= (TextBox_e
)GetIoFileInt(FileStream
, IVersion
, 0, (LgIndex_t
)TextBox_Hollow
, &IsOk
);
1912 if (Text
->Box
.BoxType
== TextBox_Hollow
)
1913 Text
->Box
.BoxType
= TextBox_Filled
;
1914 else if (Text
->Box
.BoxType
== TextBox_Filled
)
1915 Text
->Box
.BoxType
= TextBox_Hollow
;
1917 Text
->Box
.Margin
= GetNextValue(FileStream
, FFT
,
1918 TextBoxMarginInputSpec
.Min
,
1919 TextBoxMarginInputSpec
.Max
,
1922 Text
->Box
.LineThickness
= GetNextValue(FileStream
, FFT
,
1923 LineThicknessInputSpec
.Min
,
1924 LineThicknessInputSpec
.Max
,
1927 Text
->Box
.LineThickness
= 0.01;
1928 Text
->Box
.BColor
= (ColorIndex_t
)GetIoFileInt(FileStream
, IVersion
, 0, 255, &IsOk
);
1929 Text
->Box
.FillBColor
= (ColorIndex_t
)GetIoFileInt(FileStream
, IVersion
, 0, 255, &IsOk
);
1930 AdjustCustomColor(IVersion
, &Text
->Box
.BColor
);
1931 AdjustCustomColor(IVersion
, &Text
->Box
.FillBColor
);
1935 Text
->Box
.BoxType
= TextBox_None
;
1936 Text
->Box
.Margin
= 0.0;
1937 Text
->Box
.BColor
= White_C
;
1938 Text
->Box
.FillBColor
= Black_C
;
1942 Text
->Angle
= GetIoFileInt(FileStream
, IVersion
, -720, 720, &IsOk
) / DEGPERRADIANS
;
1943 Text
->LineSpacing
= 1;
1944 Text
->Anchor
= TextAnchor_Left
;
1948 Text
->Angle
= GetNextValue(FileStream
, FFT
,
1949 TextAngleInputSpec
.Min
,
1950 TextAngleInputSpec
.Max
,
1952 Text
->LineSpacing
= GetNextValue(FileStream
, FFT
,
1953 TextLineSpacingInputSpec
.Min
,
1954 TextLineSpacingInputSpec
.Max
,
1956 Text
->Anchor
= (TextAnchor_e
)GetIoFileInt(FileStream
, IVersion
, 0, (LgIndex_t
)TextAnchor_HeadRight
, &IsOk
);
1959 GetZoneAttachment(FileStream
, IVersion
, &Text
->Zone
, &Text
->AttachToZone
, &IsOk
);
1961 Text
->BColor
= (ColorIndex_t
)GetIoFileInt(FileStream
, IVersion
, 0, 255, &IsOk
);
1962 AdjustCustomColor(IVersion
, &Text
->BColor
);
1964 TextLength
= (short)GetIoFileInt(FileStream
, IVersion
, 0, 5000, &IsOk
);
1966 ResetString(&Text
->MacroFunctionCommand
, NULL
, TRUE
);
1968 Text
->Clipping
= Clipping_ClipToViewport
; /* default value for pre 101 versions */
1973 for (I
= 0; I
< TextLength
; I
++)
1975 S
= (short)GetIoFileInt(FileStream
, IVersion
, 0, 1000, &IsOk
);
1976 if (OkToLoad
&& (I
<= MaxTextLen
))
1977 Text
->Text
[I
] = (char)S
;
1980 Text
->Text
[MIN(TextLength
, MaxTextLen
)] = '\0';
1988 IsOk
= ReadMacroFunctionCommand(FileStream
,
1991 &Text
->MacroFunctionCommand
);
1992 } /* IVersion >= 75 */
1994 if (IVersion
>= 101)
1997 * The second clipping value was deprecated during v10 development and thus removed.
1998 * This moved Clipping_ClipToFrame to the 2nd position from the 3rd, so we convert
1999 * value 2 to ClipToFrame to support files made during v10 developement.
2001 Text
->Clipping
= (Clipping_e
)GetIoFileInt(FileStream
, IVersion
, 0, 2, &IsOk
);
2002 if (Text
->Clipping
== (Clipping_e
)2)
2003 Text
->Clipping
= Clipping_ClipToFrame
;
2006 if (ReadInString(FileStream
,
2012 REQUIRE(!(S
|| OkToLoad
) || VALID_REF(Text
->Text
));
2015 #if defined TECPLOTKERNEL
2016 /* CORE SOURCE CODE REMOVED */
2017 #endif /* TECPLOTKERNEL */
2020 strcpy(Text
->Text
, S
);
2022 FREE_ARRAY(S
, "Release temp string for new text label");
2025 Text
->Text
[0] = '\0';
2032 ErrMsg(ErrMsgString
);
2038 static Boolean_t
CompareVersion(float Version
,
2039 char *VersionString
,
2040 Boolean_t IsByteOrderNative
)
2042 char *VersionBuf
= (char *) & Version
;
2044 REQUIRE(VALID_REF(VersionString
));
2046 if (IsByteOrderNative
)
2047 return ((VersionString
[0] == VersionBuf
[0]) &&
2048 (VersionString
[1] == VersionBuf
[1]) &&
2049 (VersionString
[2] == VersionBuf
[2]) &&
2050 (VersionString
[3] == VersionBuf
[3]));
2052 return ((VersionString
[3] == VersionBuf
[0]) &&
2053 (VersionString
[2] == VersionBuf
[1]) &&
2054 (VersionString
[1] == VersionBuf
[2]) &&
2055 (VersionString
[0] == VersionBuf
[3]));
2058 static float ValidVersions
[] = {7.0F
,
2059 6.3F
, 6.2F
, 6.1F
, 6.0F
,
2061 4.7F
, 4.6F
, 4.5F
, 4.4F
, 4.3F
, 4.2F
, 4.1F
, 4.0F
2063 #define NUMVALIDVERSIONS ((int)(sizeof(ValidVersions)/sizeof(ValidVersions[0])))
2067 * Extra caution taken here in case value read is invalid float
2069 static Boolean_t
GetDoubleVersion(char *VersionString
,
2070 float *FInputVersion
,
2071 Boolean_t IsByteOrderNative
)
2074 REQUIRE(VALID_REF(FInputVersion
));
2076 for (I
= 0; I
< NUMVALIDVERSIONS
; I
++)
2077 if (CompareVersion(ValidVersions
[I
], VersionString
, IsByteOrderNative
))
2079 *FInputVersion
= ValidVersions
[I
];
2086 static short GetNewInputVersion(FileStream_s
*FileStream
)
2095 Boolean_t IsOk
= TRUE
;
2097 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
2098 REQUIRE(FileStream
->IsByteOrderNative
);
2100 if (TP_FREAD(Buf
, 4, 1, FileStream
->File
) != 1)
2103 if (strncmp(Buf
, "#!TD", 4))
2106 if (TP_FREAD(Buf
, 4, 1, FileStream
->File
) != 1)
2113 while ((I
< 4) && isdigit(Buf
[I
]))
2114 IVersion
= IVersion
* 10 + Buf
[I
++] - '0';
2118 else if (IVersion
> TecplotBinaryFileVersion
)
2120 ErrMsg(translate("Binary file version newer than Tecplot version. "
2121 "Upgrade Tecplot or use an older Preplot to produce "
2127 * Determine Byte Order.
2130 OneValue
= GetIoFileInt(FileStream
,
2139 FileStream
->IsByteOrderNative
= (OneValue
== 1);
2145 * Return value of zero is to be considered as an invalid
2146 * tecplot binary datafile header. Actually binary files
2147 * older than version 4.0 (return value of 40) are not supported
2148 * (See notes in preplot.c).
2150 short GetInputVersion(FileStream_s
*FileStream
)
2152 Boolean_t IsOk
= TRUE
;
2153 float FInputVersion
;
2155 char VersionString
[4];
2156 FileOffset_t StartOffset
= 0;
2159 * First check to see if file uses new
2160 * input version format.
2163 /* keep track of our start offset */
2164 StartOffset
= TP_FTELL(FileStream
->File
);
2166 IVersion
= GetNewInputVersion(FileStream
);
2168 if (IVersion
> TecplotBinaryFileVersion
)
2169 return IVersion
; /* unsupported version */
2170 else if (IVersion
== 0)
2172 /* rewind to clear any errors and seek to the start offset */
2173 rewind(FileStream
->File
);
2174 IsOk
= (TP_FSEEK(FileStream
->File
, StartOffset
, SEEK_SET
) == 0);
2176 if (IsOk
&& TP_FREAD(VersionString
, 4, 1, FileStream
->File
) == 1)
2178 /* try both native and foreign versions numbers */
2179 if (!GetDoubleVersion(VersionString
, &FInputVersion
, FileStream
->IsByteOrderNative
))
2181 FileStream
->IsByteOrderNative
= !FileStream
->IsByteOrderNative
; /* ...reverse the byte order */
2182 IsOk
= GetDoubleVersion(VersionString
, &FInputVersion
, FileStream
->IsByteOrderNative
);
2185 IVersion
= ROUNDS(FInputVersion
* 10);
2195 #if defined TECPLOTKERNEL
2196 /* CORE SOURCE CODE REMOVED */
2197 #if !defined ENGINE /* TODO(RMS)-H 12/12/2005: ENGINE: refactor to use just the Interrupted flag as-is */
2204 /**********************************************************************
2205 **********************************************************************
2206 ********************** OUTPUT **************************
2207 **********************************************************************
2208 **********************************************************************/
2212 * Byte blocks cannot be unaligned or reversed in bytes
2214 Boolean_t
WriteBinaryByteBlock(FileStream_s
*FileStream
,
2215 const Byte_t
*ByteValues
,
2216 const HgIndex_t NumValues
)
2218 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
2219 REQUIRE(VALID_REF(ByteValues
));
2220 REQUIRE(NumValues
>= 0);
2222 Boolean_t IsOk
= TP_FWRITE(ByteValues
,
2225 FileStream
->File
) == (size_t)NumValues
;
2227 ENSURE(VALID_BOOLEAN(IsOk
));
2232 * Type Byte_t cannot be unaligned or reversed in byte order
2234 static inline Boolean_t
WriteBinaryByte(FileStream_s
*FileStream
,
2237 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
2238 Boolean_t IsOk
= WriteBinaryByteBlock(FileStream
, &ByteValue
, 1);
2239 ENSURE(VALID_BOOLEAN(IsOk
));
2245 template <typename T
>
2246 void CopyAndReverseUnalignedBytes(T
*DstBuffer
,
2247 const Byte_t
*SrcBuffer
)
2249 REQUIRE(VALID_REF(DstBuffer
));
2250 REQUIRE(VALID_REF(SrcBuffer
));
2251 size_t typeSize
= sizeof(T
);
2252 for (size_t ii
= 0; ii
< typeSize
; ii
++)
2253 ((Byte_t
*)(DstBuffer
))[ii
] = ((Byte_t
*)(SrcBuffer
))[typeSize
-1-ii
];
2258 template <typename T
>
2259 void CopyUnalignedBytes(T
*DstBuffer
,
2260 const Byte_t
*SrcBuffer
)
2262 REQUIRE(VALID_REF(DstBuffer
));
2263 REQUIRE(VALID_REF(SrcBuffer
));
2264 for (size_t ii
= 0; ii
< sizeof(T
); ii
++)
2265 ((Byte_t
*)(DstBuffer
))[ii
] = ((Byte_t
*)(SrcBuffer
))[ii
];
2270 template <typename T
>
2271 Boolean_t
WriteBinaryDataUnaligned(FileStream_s
*FileStream
,
2272 const Byte_t
*ValueBuffer
,
2273 const Boolean_t ValueInNativeOrder
)
2275 REQUIRE(VALID_REF(FileStream
) && VALID_FILE_HANDLE(FileStream
->File
));
2276 REQUIRE(VALID_REF(ValueBuffer
));
2277 REQUIRE(VALID_BOOLEAN(ValueInNativeOrder
));
2280 if (ValueInNativeOrder
!= FileStream
->IsByteOrderNative
)
2281 CopyAndReverseUnalignedBytes
<T
>(&DataValue
, ValueBuffer
);
2283 CopyUnalignedBytes
<T
>(&DataValue
, ValueBuffer
);
2285 Boolean_t IsOk
= TP_FWRITE(&DataValue
, sizeof(T
), 1, FileStream
->File
) == 1;
2287 ENSURE(VALID_BOOLEAN(IsOk
));
2293 * This is used in many places and requires the value be in proper order.
2295 Boolean_t
WriteBinaryInt16(FileStream_s
*FileStream
,
2299 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
2300 REQUIRE("Value can be any Int16_t");
2301 IsOk
= WriteBinaryDataUnaligned
<Int16_t
>(FileStream
, (Byte_t
*) & Value
, TRUE
/*ValueInNativeOrder*/);
2302 ENSURE(VALID_BOOLEAN(IsOk
));
2307 * This is used in many places and requires the value be in proper order.
2309 Boolean_t
WriteBinaryInt32(FileStream_s
*FileStream
,
2313 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
2314 REQUIRE("Value can be any Int32_t");
2315 IsOk
= WriteBinaryDataUnaligned
<Int32_t
>(FileStream
, (Byte_t
*) & Value
, TRUE
/*ValueInNativeOrder*/);
2316 ENSURE(VALID_BOOLEAN(IsOk
));
2322 template <typename T
>
2323 Boolean_t
WriteBinaryBlockUnaligned(FileStream_s
*FileStream
,
2324 const Byte_t
*Values
,
2325 const HgIndex_t NumValues
,
2326 const Boolean_t ValuesInNativeOrdering
)
2328 Boolean_t IsOk
= TRUE
;
2329 Boolean_t WriteEachValueSeparately
;
2331 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
2332 REQUIRE(VALID_REF(Values
));
2333 REQUIRE(NumValues
>= 0);
2334 REQUIRE(VALID_BOOLEAN(ValuesInNativeOrdering
));
2336 WriteEachValueSeparately
= (ValuesInNativeOrdering
!= FileStream
->IsByteOrderNative
);
2338 if (WriteEachValueSeparately
)
2340 for (HgIndex_t NIndex
= 0; IsOk
&& NIndex
< NumValues
; NIndex
++)
2342 IsOk
= WriteBinaryDataUnaligned
<T
>(FileStream
, Values
+ NIndex
* sizeof(T
), ValuesInNativeOrdering
);
2348 size_t NumBytesToWrite
= NumValues
* sizeof(T
);
2349 size_t NumBytesWritten
= TP_FWRITE(Values
, sizeof(Byte_t
), NumBytesToWrite
, FileStream
->File
);
2350 IsOk
= NumBytesToWrite
== NumBytesWritten
;
2352 IsOk
= WriteBinaryByteBlock(FileStream
, Values
, NumValues
* sizeof(T
));
2356 ENSURE(VALID_BOOLEAN(IsOk
));
2362 * Use Byte_t instead of Int16_t to support unaligned values
2364 Boolean_t
WriteBinaryInt16BlockUnaligned(FileStream_s
*FileStream
,
2365 Byte_t
*Int16Values
,
2366 HgIndex_t NumValues
,
2367 Boolean_t ValuesInNativeOrdering
)
2369 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
2370 REQUIRE(VALID_REF(Int16Values
));
2371 REQUIRE(NumValues
>= 0);
2372 REQUIRE(VALID_BOOLEAN(ValuesInNativeOrdering
));
2374 Boolean_t IsOk
= WriteBinaryBlockUnaligned
<Int16_t
>(FileStream
,
2377 ValuesInNativeOrdering
);
2378 ENSURE(VALID_BOOLEAN(IsOk
));
2384 * Use Byte_t instead of Int32_t to support unaligned values
2386 Boolean_t
WriteBinaryInt32BlockUnaligned(FileStream_s
*FileStream
,
2387 Byte_t
*Int32Values
,
2388 HgIndex_t NumValues
,
2389 Boolean_t ValuesInNativeOrdering
)
2391 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
2392 REQUIRE(VALID_REF(Int32Values
));
2393 REQUIRE(NumValues
>= 0);
2394 REQUIRE(VALID_BOOLEAN(ValuesInNativeOrdering
));
2396 Boolean_t IsOk
= WriteBinaryBlockUnaligned
<Int32_t
>(FileStream
,
2399 ValuesInNativeOrdering
);
2400 ENSURE(VALID_BOOLEAN(IsOk
));
2408 Boolean_t
WriteBinaryReal(FileStream_s
*FileStream
,
2410 FieldDataType_e FieldDataType
)
2412 Boolean_t IsOk
= FALSE
; /* ...quite compiler */
2414 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
2415 REQUIRE((FieldDataType
== FieldDataType_Float
) ||
2416 (FieldDataType
== FieldDataType_Double
) ||
2417 (FieldDataType
== FieldDataType_Byte
));
2419 switch (FieldDataType
)
2421 case FieldDataType_Float
:
2423 float FloatVal
= CONVERT_DOUBLE_TO_FLOAT(RR
);
2424 IsOk
= WriteBinaryDataUnaligned
<float>(FileStream
, (Byte_t
*) & FloatVal
, TRUE
/*NativeOrdering*/);
2426 case FieldDataType_Double
:
2428 double DoubleVal
= CLAMP_DOUBLE(RR
);
2429 IsOk
= WriteBinaryDataUnaligned
<double>(FileStream
, (Byte_t
*) & DoubleVal
, TRUE
/*NativeOrdering*/);
2431 case FieldDataType_Byte
:
2433 /* Note: type Byte cannot be unaligned or reversed in bytes */
2441 IsOk
= WriteBinaryByte(FileStream
, B
);
2443 default: CHECK(FALSE
); break;
2446 ENSURE(VALID_BOOLEAN(IsOk
));
2451 Boolean_t
WriteFieldDataType(FileStream_s
*FileStream
,
2452 FieldDataType_e FDT
,
2453 Boolean_t WriteBinary
)
2456 return (WriteBinaryInt32(FileStream
, (LgIndex_t
)FDT
));
2462 case FieldDataType_Float
: S
= fprintf(FileStream
->File
, "SINGLE "); break;
2463 case FieldDataType_Double
: S
= fprintf(FileStream
->File
, "DOUBLE "); break;
2464 case FieldDataType_Int32
: S
= fprintf(FileStream
->File
, "LONGINT "); break;
2465 case FieldDataType_Int16
: S
= fprintf(FileStream
->File
, "SHORTINT "); break;
2466 case FieldDataType_Byte
: S
= fprintf(FileStream
->File
, "BYTE "); break;
2467 case FieldDataType_Bit
: S
= fprintf(FileStream
->File
, "BIT "); break;
2468 default: CHECK(FALSE
);
2470 return (FPRINTFOK(S
));
2476 template <typename T
>
2477 Boolean_t
WriteBinaryChecksumByteValues(FileStream_s
*FileStream
,
2478 const Byte_t
*ByteValues
,
2479 const HgIndex_t NumValues
)
2481 REQUIRE(VALID_REF(FileStream
) && VALID_FILE_HANDLE(FileStream
->File
));
2482 REQUIRE(VALID_REF(ByteValues
));
2483 REQUIRE(NumValues
>= 1);
2487 IsOk
= WriteBinaryDataUnaligned
<T
>(FileStream
, ByteValues
, TRUE
);
2489 IsOk
= WriteBinaryBlockUnaligned
<T
>(FileStream
, ByteValues
, NumValues
, TRUE
);
2491 #if defined TECPLOTKERNEL
2492 /* CORE SOURCE CODE REMOVED */
2494 ENSURE(VALID_BOOLEAN(IsOk
));
2499 * For FieldData of Type Bit, use WriteBinaryFieldDataBlockOfTypeBit instead.
2501 template <typename T
>
2502 Boolean_t
WriteBinaryFieldDataBlockOfType(FileStream_s
*FileStream
,
2503 const FieldData_pa FieldData
,
2504 const LgIndex_t StartOffset
,
2505 const LgIndex_t NumValues
)
2507 #if defined TECPLOTKERNEL
2508 /* CORE SOURCE CODE REMOVED */
2511 Boolean_t IsOk
= FALSE
;
2512 if (IsFieldDataDirectAccessAllowed(FieldData
))
2514 Byte_t
*ByteArray
= GetFieldDataBytePtr(FieldData
) + StartOffset
* sizeof(T
);
2515 IsOk
= WriteBinaryChecksumByteValues
<T
>(FileStream
, ByteArray
, (HgIndex_t
)NumValues
);
2519 for (LgIndex_t Offset
= StartOffset
; Offset
< NumValues
; Offset
++)
2521 T ValueBuffer
= (T
)GetFieldValue(FieldData
, Offset
);
2522 Byte_t
*ByteValue
= (Byte_t
*) & ValueBuffer
;
2523 IsOk
= WriteBinaryChecksumByteValues
<T
>(FileStream
, ByteValue
, 1);
2526 ENSURE(VALID_BOOLEAN(IsOk
));
2530 static Boolean_t
WriteBinaryFieldDataBlockOfTypeBit(FileStream_s
*FileStream
,
2531 const FieldData_pa FieldData
,
2532 const LgIndex_t StartOffset
, /* Not used */
2533 const LgIndex_t NumValues
)
2535 #if defined TECPLOTKERNEL
2536 /* CORE SOURCE CODE REMOVED */
2539 Boolean_t IsOk
= FALSE
;
2540 size_t NumBytes
= 1 + (NumValues
- 1) / 8;
2541 if (IsFieldDataDirectAccessAllowed(FieldData
))
2543 Byte_t
*ByteArray
= GetFieldDataBytePtr(FieldData
);
2544 IsOk
= WriteBinaryChecksumByteValues
<Byte_t
>(FileStream
, ByteArray
, (HgIndex_t
)NumBytes
);
2548 // Bits are written out a Byte at a time and since we only come in here every 8th
2549 // bit, make sure to assemble a Byte value from the next 8 bits.
2550 for (LgIndex_t Offset
= 0; Offset
< NumValues
; Offset
+= 8)
2552 Byte_t ValueBuffer
= 0;
2553 for (int ii
= 0; ii
< 8; ii
++)
2555 Byte_t CurBit
= (Byte_t
)GetFieldValue(FieldData
, Offset
+ ii
);
2556 ValueBuffer
|= (CurBit
<< ii
);
2558 IsOk
= WriteBinaryChecksumByteValues
<Byte_t
>(FileStream
, &ValueBuffer
, 1);
2561 ENSURE(VALID_BOOLEAN(IsOk
));
2567 Boolean_t
WriteBinaryFieldDataBlock(FileStream_s
*FileStream
,
2568 FieldData_pa FieldData
,
2569 LgIndex_t StartOffset
,
2570 LgIndex_t NumValues
)
2572 #if defined TECPLOTKERNEL
2573 /* CORE SOURCE CODE REMOVED */
2576 Boolean_t IsOk
= FALSE
;
2577 switch (GetFieldDataType(FieldData
))
2579 case FieldDataType_Float
: IsOk
= WriteBinaryFieldDataBlockOfType
<float>(FileStream
, FieldData
, StartOffset
, NumValues
); break;
2580 case FieldDataType_Double
: IsOk
= WriteBinaryFieldDataBlockOfType
<double>(FileStream
, FieldData
, StartOffset
, NumValues
); break;
2581 case FieldDataType_Int32
: IsOk
= WriteBinaryFieldDataBlockOfType
<Int32_t
>(FileStream
, FieldData
, StartOffset
, NumValues
); break;
2582 case FieldDataType_Int16
: IsOk
= WriteBinaryFieldDataBlockOfType
<Int16_t
>(FileStream
, FieldData
, StartOffset
, NumValues
); break;
2583 case FieldDataType_Byte
: IsOk
= WriteBinaryFieldDataBlockOfType
<Byte_t
>(FileStream
, FieldData
, StartOffset
, NumValues
); break;
2584 case FieldDataType_Bit
: IsOk
= WriteBinaryFieldDataBlockOfTypeBit(FileStream
, FieldData
, StartOffset
, NumValues
); break;
2585 default: CHECK(FALSE
); break;
2588 ENSURE(VALID_BOOLEAN(IsOk
));
2593 static Boolean_t
WriteASCIIFieldDataValue(FileStream_s
*FileStream
,
2594 FieldData_pa FieldData
,
2596 SmInteger_t AsciiPrecision
)
2598 Boolean_t IsOk
= FALSE
; /* ...quiet compiler */
2600 #if defined TECPLOTKERNEL
2601 /* CORE SOURCE CODE REMOVED */
2605 char buffer
[100*MAX_SIZEOFUTF8CHAR
];
2606 char *AsciiValue
= buffer
;
2608 #ifdef TECPLOTKERNEL
2609 /* CORE SOURCE CODE REMOVED */
2612 V
= GetFieldValue(FieldData
, Offset
);
2614 switch (GetFieldDataType(FieldData
))
2616 case FieldDataType_Float
:
2617 case FieldDataType_Double
:
2618 /*IsOk = FPRINTFOK(fprintf(FileStream->File," %.*E",(int)AsciiPrecision,V)); */
2619 sprintf(buffer
, " %.*E", (int)AsciiPrecision
, V
);
2621 case FieldDataType_Int32
:
2622 /* IsOk = FPRINTFOK(fprintf(FileStream->File," %*d",(int)AsciiPrecision,ROUNDL(V))); */
2623 sprintf(buffer
, " %*d", (int)AsciiPrecision
, ROUNDL(V
));
2625 case FieldDataType_Int16
:
2626 /* IsOk = FPRINTFOK(fprintf(FileStream->File," %6d",ROUND2(V))); */
2627 sprintf(buffer
, " %6d", ROUND2(V
));
2629 case FieldDataType_Byte
:
2630 /* IsOk = FPRINTFOK(fprintf(FileStream->File," %3d",ROUNDS(V))); */
2631 sprintf(buffer
, " %3d", ROUNDS(V
));
2633 case FieldDataType_Bit
:
2634 /* IsOk = FPRINTFOK(fprintf(FileStream->File," %c",((V == 0) ? '0' : '1'))); */
2635 sprintf(buffer
, " %c", ((V
== 0) ? '0' : '1'));
2637 default: CHECK(FALSE
); break;
2639 IsOk
= FPRINTFOK(fprintf(FileStream
->File
, buffer
));
2640 #if defined TECPLOTKERNEL
2641 /* CORE SOURCE CODE REMOVED */
2643 ENSURE(VALID_BOOLEAN(IsOk
));
2650 Boolean_t
WriteCCFieldDataBlock(FileStream_s
*FileStream
,
2651 FieldData_pa FieldData
,
2652 Boolean_t IsOrderedData
,
2656 Boolean_t WriteBinary
,
2657 SmInteger_t AsciiPrecision
)
2659 Boolean_t IsOk
= TRUE
;
2660 LgIndex_t NumValues
;
2662 LgIndex_t NumIJPts
= -1;
2663 LgIndex_t IEnd
= -1;
2664 LgIndex_t JEnd
= -1;
2665 LgIndex_t KEnd
= -1;
2666 Boolean_t IsLinear
= -1;
2668 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
2669 REQUIRE(VALID_REF(FieldData
));
2670 REQUIRE(VALID_BOOLEAN(IsOrderedData
));
2671 REQUIRE(NumIPts
>= 0);
2672 REQUIRE(NumJPts
>= 0);
2673 REQUIRE(NumKPts
>= 0);
2674 REQUIRE(VALID_BOOLEAN(WriteBinary
));
2675 REQUIRE(IMPLICATION(!WriteBinary
, AsciiPrecision
>= 0));
2678 * As of version 103 Tecplot writes binary data files so that ordered cell
2679 * centered field data includes the ghost cells. This makes it much easier
2680 * for Tecplot to map the data when reading by simply writing out
2681 * FieldData->NumValues. As of version 104 the ghost cells of the slowest
2682 * moving index are not included but that does effect the output as it is
2683 * still FieldData->NumValues.
2685 if (IsOrderedData
&& !WriteBinary
)
2688 * Ordered ASCII output is always layed out using
2689 * DataValueStructure_Classic format.
2691 NumIJPts
= NumIPts
* NumJPts
;
2692 IEnd
= MAX(NumIPts
- 1, 1);
2693 JEnd
= MAX(NumJPts
- 1, 1);
2694 KEnd
= MAX(NumKPts
- 1, 1);
2695 NumValues
= (IEnd
* JEnd
* KEnd
);
2696 IsLinear
= ((NumJPts
== 1 && NumKPts
== 1) ||
2697 (NumIPts
== 1 && NumKPts
== 1) ||
2698 (NumIPts
== 1 && NumJPts
== 1));
2702 NumValues
= GetFieldDataNumValues(FieldData
);
2707 IsOk
= WriteBinaryFieldDataBlock(FileStream
, FieldData
, 0, NumValues
);
2711 LgIndex_t NumValuesPerLine
= 80 / (AsciiPrecision
+ 5);
2712 if (IsOrderedData
&& !IsLinear
)
2714 LgIndex_t ValueIndex
= 0;
2715 for (K
= 0; K
< KEnd
&& IsOk
; K
++)
2716 for (J
= 0; J
< JEnd
&& IsOk
; J
++)
2717 for (I
= 0; I
< IEnd
&& IsOk
; I
++)
2719 LgIndex_t CellIndex
= I
+ (J
* NumIPts
) + (K
* NumIJPts
);
2720 IsOk
= WriteASCIIFieldDataValue(FileStream
,
2724 if ((ValueIndex
+ 1) % NumValuesPerLine
== 0 || ValueIndex
== NumValues
- 1)
2725 IsOk
= (fputc('\n', FileStream
->File
) != EOF
);
2731 for (I
= 0; I
< NumValues
&& IsOk
; I
++)
2733 IsOk
= WriteASCIIFieldDataValue(FileStream
,
2737 if ((I
+ 1) % NumValuesPerLine
== 0 || I
== NumValues
- 1)
2738 IsOk
= (fputc('\n', FileStream
->File
) != EOF
);
2743 ENSURE(VALID_BOOLEAN(IsOk
));
2748 Boolean_t
DumpDatafileString(FileStream_s
*FileStream
,
2750 Boolean_t WriteBinary
)
2752 Boolean_t IsOk
= TRUE
;
2753 const char *CPtr
= S
;
2756 const char *CPtr
= S
;
2757 while (IsOk
&& CPtr
&& *CPtr
)
2758 IsOk
= WriteBinaryInt32(FileStream
, (LgIndex_t
)(unsigned char) * CPtr
++);
2760 IsOk
= WriteBinaryInt32(FileStream
, 0);
2764 fputc('"', FileStream
->File
);
2765 while (CPtr
&& *CPtr
)
2770 fputc('\\', FileStream
->File
);
2771 fputc('\\', FileStream
->File
);
2772 fputc('n', FileStream
->File
);
2776 if ((*CPtr
== '"') || (*CPtr
== '\\'))
2777 fputc('\\', FileStream
->File
);
2778 fputc(*CPtr
++, FileStream
->File
);
2781 fputc('"', FileStream
->File
);
2782 IsOk
= (fputc('\n', FileStream
->File
) != EOF
);
2788 static void WriteAsciiColor(FILE *File
,
2791 if (Color
>= FirstCustomColor
&& Color
<= LastCustomColor
)
2792 fprintf(File
, "CUST%1d ", Color
- FirstCustomColor
+ 1);
2797 case Black_C
: fprintf(File
, "BLACK "); break;
2798 case Red_C
: fprintf(File
, "RED "); break;
2799 case Green_C
: fprintf(File
, "GREEN "); break;
2800 case Blue_C
: fprintf(File
, "BLUE "); break;
2801 case Cyan_C
: fprintf(File
, "CYAN "); break;
2802 case Yellow_C
: fprintf(File
, "YELLOW "); break;
2803 case Purple_C
: fprintf(File
, "PURPLE "); break;
2804 case White_C
: fprintf(File
, "WHITE "); break;
2809 static void WriteAsciiTextGeomBasics(FILE* File
,
2810 CoordSys_e CoordSys
,
2811 Boolean_t AttachToZone
,
2816 Boolean_t WriteGridDataAsPolar
,
2817 AnchorPos_u
const* AnchorPos
,
2820 REQUIRE(VALID_REF(File
));
2821 REQUIRE(VALID_TEXT_COORDSYS(CoordSys
) || VALID_GEOM_COORDSYS(CoordSys
));
2822 REQUIRE(VALID_BOOLEAN(AttachToZone
));
2823 REQUIRE(IMPLICATION(AttachToZone
, Zone
>= 0));
2824 REQUIRE(VALID_ENUM(Scope
, Scope_e
));
2825 REQUIRE(VALID_BOOLEAN(IncludeZ
));
2826 REQUIRE(VALID_BOOLEAN(WriteGridDataAsPolar
));
2827 REQUIRE(VALID_REF(AnchorPos
));
2829 fprintf(File
, "CS=");
2830 if (CoordSys
== CoordSys_Frame
)
2831 fprintf(File
, "FRAME");
2832 else if (CoordSys
== CoordSys_Grid
)
2833 fprintf(File
, "GRID");
2835 * Not currently used
2837 else if (CoordSys == CoordSys_FrameOffset)
2838 fprintf(File,"FRAMEOFFSET");
2840 else if (CoordSys
== CoordSys_Grid3D
)
2841 fprintf(File
, "GRID3D");
2845 if (CoordSys
== CoordSys_Grid
&& !IncludeZ
&& WriteGridDataAsPolar
)
2847 fprintf(File
, "\nTHETA=%.12G,R=%.12G",
2848 ScaleFact
*AnchorPos
->ThetaR
.Theta
,
2849 ScaleFact
*AnchorPos
->ThetaR
.R
);
2854 fprintf(File
, "\nX=%.12G,Y=%.12G",
2855 ScaleFact
*AnchorPos
->XYZ
.X
,
2856 ScaleFact
*AnchorPos
->XYZ
.Y
);
2858 fprintf(File
, ",Z=%.12G", ScaleFact
*AnchorPos
->XYZ
.Z
);
2862 fprintf(File
, "\nZN=%d", Zone
+ 1);
2864 fprintf(File
, "\nC=");
2865 WriteAsciiColor(File
, Color
);
2867 fprintf(File
, "\nS=");
2868 if (Scope
== Scope_Global
)
2869 fprintf(File
, "GLOBAL");
2870 else if (Scope
== Scope_Local
)
2871 fprintf(File
, "LOCAL");
2879 bool DumpGeometry(FileStream_s
* FileStream
,
2881 Boolean_t WriteBinary
,
2882 Boolean_t WriteGridDataAsPolar
)
2887 FieldDataType_e FDT
;
2889 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
2890 REQUIRE(VALID_REF(Geom
));
2891 REQUIRE(Geom
->GeomType
!= GeomType_Image
);
2895 WriteBinaryReal(FileStream
, GeomMarker
, FieldDataType_Float
);
2896 if (Geom
->PositionCoordSys
== CoordSys_Grid
)
2897 WriteBinaryInt32(FileStream
, 0);
2898 else if (Geom
->PositionCoordSys
== CoordSys_Frame
)
2899 WriteBinaryInt32(FileStream
, 1);
2901 * Not currently used
2903 else if (Geom
->PositionCoordSys
== CoordSys_FrameOffset
)
2904 WriteBinaryInt32(FileStream
, 2);
2907 * PositionCoordSys == 3 is for old window coordinate system
2909 else if (Geom
->PositionCoordSys
== CoordSys_Grid3D
)
2910 WriteBinaryInt32(FileStream
, 4);
2914 WriteBinaryInt32(FileStream
, (LgIndex_t
)Geom
->Scope
);
2915 WriteBinaryInt32(FileStream
, (LgIndex_t
)Geom
->DrawOrder
);
2916 WriteBinaryReal(FileStream
, Geom
->AnchorPos
.Generic
.V1
, FieldDataType_Double
);
2917 WriteBinaryReal(FileStream
, Geom
->AnchorPos
.Generic
.V2
, FieldDataType_Double
);
2918 WriteBinaryReal(FileStream
, Geom
->AnchorPos
.Generic
.V3
, FieldDataType_Double
);
2919 if (Geom
->AttachToZone
)
2920 WriteBinaryInt32(FileStream
, (LgIndex_t
)Geom
->Zone
);
2922 WriteBinaryInt32(FileStream
, (LgIndex_t
) - 1);
2923 WriteBinaryInt32(FileStream
, (LgIndex_t
)Geom
->BColor
);
2924 WriteBinaryInt32(FileStream
, (LgIndex_t
)Geom
->FillBColor
);
2925 WriteBinaryInt32(FileStream
, (LgIndex_t
)Geom
->IsFilled
);
2926 CHECK(Geom
->GeomType
!= GeomType_LineSegs3D
); /* deprecated */
2927 WriteBinaryInt32(FileStream
, (LgIndex_t
)Geom
->GeomType
);
2928 WriteBinaryInt32(FileStream
, (LgIndex_t
)Geom
->LinePattern
);
2929 WriteBinaryReal(FileStream
, Geom
->PatternLength
, FieldDataType_Double
);
2930 WriteBinaryReal(FileStream
, Geom
->LineThickness
, FieldDataType_Double
);
2931 WriteBinaryInt32(FileStream
, (LgIndex_t
)Geom
->NumEllipsePts
);
2932 WriteBinaryInt32(FileStream
, (LgIndex_t
)Geom
->ArrowheadStyle
);
2933 WriteBinaryInt32(FileStream
, (LgIndex_t
)Geom
->ArrowheadAttachment
);
2934 WriteBinaryReal(FileStream
, Geom
->ArrowheadSize
, FieldDataType_Double
);
2936 WriteBinaryReal(FileStream
, Geom
->ArrowheadAngle
, FieldDataType_Double
);
2938 /* MACRO FUNCTION COMMAND */
2939 DumpDatafileString(FileStream
, Geom
->MacroFunctionCommand
, TRUE
);
2942 * Assume geometry has X,Y (and Z) all using same field
2945 FDT
= GetGeomFieldDataType(Geom
);
2946 WriteFieldDataType(FileStream
, FDT
, TRUE
);
2947 WriteBinaryInt32(FileStream
, (LgIndex_t
)Geom
->Clipping
);
2949 if (Geom
->GeomType
== GeomType_LineSegs
)
2952 WriteBinaryInt32(FileStream
, Geom
->NumSegments
);
2954 for (S
= 0; IsOk
&& (S
< Geom
->NumSegments
); S
++)
2956 WriteBinaryInt32(FileStream
, Geom
->NumSegPts
[S
]);
2957 WriteBinaryFieldDataBlock(FileStream
, Geom
->GeomData
.Generic
.V1Base
, I
, Geom
->NumSegPts
[S
]);
2958 IsOk
= WriteBinaryFieldDataBlock(FileStream
, Geom
->GeomData
.Generic
.V2Base
, I
, Geom
->NumSegPts
[S
]) == TRUE
;
2959 if (Geom
->PositionCoordSys
== CoordSys_Grid3D
)
2960 IsOk
= WriteBinaryFieldDataBlock(FileStream
, Geom
->GeomData
.Generic
.V3Base
, I
, Geom
->NumSegPts
[S
]) == TRUE
;
2961 I
+= Geom
->NumSegPts
[S
];
2964 else if (Geom
->GeomType
== GeomType_Rectangle
||
2965 Geom
->GeomType
== GeomType_Ellipse
)
2967 WriteBinaryReal(FileStream
, GetFieldValue(Geom
->GeomData
.XYZ
.XBase
, 0), FDT
);
2968 IsOk
= WriteBinaryReal(FileStream
, GetFieldValue(Geom
->GeomData
.XYZ
.YBase
, 0), FDT
) == TRUE
;
2972 CHECK((Geom
->GeomType
== GeomType_Square
) ||
2973 (Geom
->GeomType
== GeomType_Circle
));
2974 IsOk
= WriteBinaryReal(FileStream
, GetFieldValue(Geom
->GeomData
.XYZ
.XBase
, 0), FDT
) == TRUE
;
2981 if (Geom
->PositionCoordSys
== CoordSys_Frame
)
2986 fprintf(FileStream
->File
, "GEOMETRY\nF=POINT\n");
2987 WriteAsciiTextGeomBasics(FileStream
->File
,
2988 Geom
->PositionCoordSys
,
2994 WriteGridDataAsPolar
,
2998 switch (Geom
->LinePattern
)
3000 case LinePattern_Solid
: fprintf(FileStream
->File
, "L=SOLID\n"); break;
3001 case LinePattern_Dashed
: fprintf(FileStream
->File
, "L=DASHED\n"); break;
3002 case LinePattern_DashDot
: fprintf(FileStream
->File
, "L=DASHDOT\n"); break;
3003 case LinePattern_Dotted
: fprintf(FileStream
->File
, "L=DOTTED\n"); break;
3004 case LinePattern_LongDash
: fprintf(FileStream
->File
, "L=LONGDASH\n"); break;
3005 case LinePattern_DashDotDot
: fprintf(FileStream
->File
, "L=DASHDOTDOT\n"); break;
3006 default: CHECK(FALSE
); break;
3008 fprintf(FileStream
->File
, "PL=%.12G\n",
3009 Geom
->PatternLength
*PatternLengthInputSpec
.InterfaceAdjust
.ScaleFact
);
3010 fprintf(FileStream
->File
, "LT=%.12G\n",
3011 Geom
->LineThickness
*LineThicknessInputSpec
.InterfaceAdjust
.ScaleFact
);
3015 fprintf(FileStream
->File
, "FC=");
3016 WriteAsciiColor(FileStream
->File
, Geom
->FillBColor
);
3019 if (Geom
->Clipping
== Clipping_ClipToViewport
)
3020 fprintf(FileStream
->File
, "CLIPPING=CLIPTOVIEWPORT\n");
3021 else if (Geom
->Clipping
== Clipping_ClipToFrame
)
3022 fprintf(FileStream
->File
, "CLIPPING=CLIPTOFRAME\n");
3026 if (Geom
->DrawOrder
== DrawOrder_AfterData
)
3027 fprintf(FileStream
->File
, "DRAWORDER=AFTERDATA\n");
3028 else if (Geom
->DrawOrder
== DrawOrder_BeforeData
)
3029 fprintf(FileStream
->File
, "DRAWORDER=BEFOREDATA\n");
3033 /* Macro function command */
3034 fprintf(FileStream
->File
, "MFC=");
3035 DumpDatafileString(FileStream
, Geom
->MacroFunctionCommand
, FALSE
);
3037 if ((Geom
->GeomType
== GeomType_Circle
) || (Geom
->GeomType
== GeomType_Ellipse
))
3038 fprintf(FileStream
->File
, "EP=%ld\n", (long)Geom
->NumEllipsePts
);
3040 if (Geom
->GeomType
== GeomType_LineSegs
&& Geom
->PositionCoordSys
!= CoordSys_Grid3D
)
3042 switch (Geom
->ArrowheadStyle
)
3044 case ArrowheadStyle_Plain
: fprintf(FileStream
->File
, "AST=PLAIN\n"); break;
3045 case ArrowheadStyle_Filled
: fprintf(FileStream
->File
, "AST=FILLED\n"); break;
3046 case ArrowheadStyle_Hollow
: fprintf(FileStream
->File
, "AST=HOLLOW\n"); break;
3047 default: CHECK(FALSE
); break;
3050 switch (Geom
->ArrowheadAttachment
)
3052 case ArrowheadAttachment_None
: break;
3053 case ArrowheadAttachment_AtBeginning
: fprintf(FileStream
->File
, "AAT=BEGINNING\n"); break;
3054 case ArrowheadAttachment_AtEnd
: fprintf(FileStream
->File
, "AAT=END\n"); break;
3055 case ArrowheadAttachment_AtBothEnds
: fprintf(FileStream
->File
, "AAT=BOTH\n"); break;
3056 default: CHECK(FALSE
); break;
3058 if (Geom
->ArrowheadAttachment
!= ArrowheadAttachment_None
)
3060 fprintf(FileStream
->File
, "ASZ=%.12G\n",
3061 Geom
->ArrowheadSize
*ArrowheadSizeInputSpec
.InterfaceAdjust
.ScaleFact
);
3062 fprintf(FileStream
->File
, "AAN=%.12G\n",
3063 Geom
->ArrowheadAngle
*ArrowheadAngleInputSpec
.InterfaceAdjust
.ScaleFact
);
3067 switch (Geom
->GeomType
)
3069 case GeomType_LineSegs
:
3071 fprintf(FileStream
->File
, "T=LINE\n");
3072 fprintf(FileStream
->File
, "DT=");
3073 WriteFieldDataType(FileStream
, GetFieldDataType(Geom
->GeomData
.Generic
.V1Base
), FALSE
);
3074 fputc('\n', FileStream
->File
);
3075 fprintf(FileStream
->File
, "%d\n", (int)Geom
->NumSegments
);
3077 for (I
= 0; IsOk
&& (I
< Geom
->NumSegments
); I
++)
3079 fprintf(FileStream
->File
, "%ld\n", (long)Geom
->NumSegPts
[I
]);
3080 for (Index
= 0; Index
< Geom
->NumSegPts
[I
]; Index
++)
3082 fprintf(FileStream
->File
, "%.12G ", GetFieldValue(Geom
->GeomData
.Generic
.V1Base
, SegIndex
+ Index
)*ScaleFact
);
3083 fprintf(FileStream
->File
, "%.12G", GetFieldValue(Geom
->GeomData
.Generic
.V2Base
, SegIndex
+ Index
)*ScaleFact
);
3084 if (Geom
->PositionCoordSys
== CoordSys_Grid3D
)
3085 IsOk
= FPRINTFOK(fprintf(FileStream
->File
, " %.12G\n", GetFieldValue(Geom
->GeomData
.Generic
.V3Base
, SegIndex
+ Index
)));
3087 IsOk
= (Boolean_t
)(fputc('\n', FileStream
->File
) != EOF
);
3089 SegIndex
+= Geom
->NumSegPts
[I
];
3092 case GeomType_Rectangle
:
3094 fprintf(FileStream
->File
, "T=RECTANGLE %.12G %.12G\n",
3095 GetFieldValue(Geom
->GeomData
.XYZ
.XBase
, 0)*ScaleFact
,
3096 GetFieldValue(Geom
->GeomData
.XYZ
.YBase
, 0)*ScaleFact
);
3098 case GeomType_Square
:
3100 fprintf(FileStream
->File
, "T=SQUARE %.12G\n",
3101 GetFieldValue(Geom
->GeomData
.XYZ
.XBase
, 0)*ScaleFact
);
3103 case GeomType_Circle
:
3105 fprintf(FileStream
->File
, "T=CIRCLE %.12G\n",
3106 GetFieldValue(Geom
->GeomData
.XYZ
.XBase
, 0)*ScaleFact
);
3108 case GeomType_Ellipse
:
3110 fprintf(FileStream
->File
, "T=ELLIPSE %.12G %.12G\n",
3111 GetFieldValue(Geom
->GeomData
.XYZ
.XBase
, 0)*ScaleFact
,
3112 GetFieldValue(Geom
->GeomData
.XYZ
.YBase
, 0)*ScaleFact
);
3114 default: CHECK(FALSE
);
3122 bool DumpText(FileStream_s
* FileStream
,
3124 Boolean_t WriteBinary
,
3125 Boolean_t WriteGridDataAsPolar
)
3127 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
3128 REQUIRE(VALID_REF(Text
));
3129 REQUIRE(VALID_BOOLEAN(WriteBinary
));
3130 REQUIRE(VALID_BOOLEAN(WriteGridDataAsPolar
));
3134 WriteBinaryReal(FileStream
, TextMarker
, FieldDataType_Float
);
3135 if (Text
->PositionCoordSys
== CoordSys_Grid
)
3136 WriteBinaryInt32(FileStream
, 0);
3137 else if (Text
->PositionCoordSys
== CoordSys_Frame
)
3138 WriteBinaryInt32(FileStream
, 1);
3140 * Not currently used
3142 else if (Geom
->PositionCoordSys
== CoordSys_FrameOffset
)
3143 WriteBinaryInt32(FileStream
, 2);
3146 * 3 is used for old window coordinate system
3148 else if (Text
->PositionCoordSys
== CoordSys_Grid3D
)
3149 WriteBinaryInt32(FileStream
, 4);
3153 WriteBinaryInt32(FileStream
, (LgIndex_t
)Text
->Scope
);
3154 WriteBinaryReal(FileStream
, Text
->AnchorPos
.Generic
.V1
, FieldDataType_Double
);
3155 WriteBinaryReal(FileStream
, Text
->AnchorPos
.Generic
.V2
, FieldDataType_Double
);
3156 WriteBinaryReal(FileStream
, Text
->AnchorPos
.Generic
.V3
, FieldDataType_Double
);
3157 WriteBinaryInt32(FileStream
, (LgIndex_t
)Text
->TextShape
.Font
);
3158 WriteBinaryInt32(FileStream
, (LgIndex_t
)Text
->TextShape
.SizeUnits
);
3159 WriteBinaryReal(FileStream
, Text
->TextShape
.Height
, FieldDataType_Double
);
3160 WriteBinaryInt32(FileStream
, (LgIndex_t
)Text
->Box
.BoxType
);
3161 WriteBinaryReal(FileStream
, Text
->Box
.Margin
, FieldDataType_Double
);
3162 WriteBinaryReal(FileStream
, Text
->Box
.LineThickness
, FieldDataType_Double
);
3163 WriteBinaryInt32(FileStream
, (LgIndex_t
)Text
->Box
.BColor
);
3164 WriteBinaryInt32(FileStream
, (LgIndex_t
)Text
->Box
.FillBColor
);
3165 WriteBinaryReal(FileStream
, Text
->Angle
, FieldDataType_Double
);
3166 WriteBinaryReal(FileStream
, Text
->LineSpacing
, FieldDataType_Double
);
3167 WriteBinaryInt32(FileStream
, (LgIndex_t
)Text
->Anchor
);
3168 if (Text
->AttachToZone
)
3169 WriteBinaryInt32(FileStream
, (LgIndex_t
)Text
->Zone
);
3171 WriteBinaryInt32(FileStream
, (LgIndex_t
) - 1);
3172 WriteBinaryInt32(FileStream
, (LgIndex_t
)Text
->BColor
);
3177 Boolean_t IncludeZ
= Text
->PositionCoordSys
== CoordSys_Grid3D
;
3178 if (Text
->PositionCoordSys
== CoordSys_Frame
)
3182 fprintf(FileStream
->File
, "TEXT\n");
3183 WriteAsciiTextGeomBasics(FileStream
->File
,
3184 Text
->PositionCoordSys
,
3190 WriteGridDataAsPolar
,
3193 fprintf(FileStream
->File
, "HU=");
3194 switch (Text
->TextShape
.SizeUnits
)
3196 case Units_Grid
: fprintf(FileStream
->File
, "GRID\n"); break;
3197 case Units_Frame
: fprintf(FileStream
->File
, "FRAME\n"); break;
3198 case Units_Point
: fprintf(FileStream
->File
, "POINT\n"); break;
3199 case Units_AxisPercentage
: /* Not allowed */
3200 default: CHECK(FALSE
); break;
3203 fprintf(FileStream
->File
, "LS=%.4G ", Text
->LineSpacing
);
3205 fprintf(FileStream
->File
, "AN=");
3206 switch (Text
->Anchor
)
3208 case TextAnchor_Left
: fprintf(FileStream
->File
, "LEFT\n"); break;
3209 case TextAnchor_Center
: fprintf(FileStream
->File
, "CENTER\n"); break;
3210 case TextAnchor_Right
: fprintf(FileStream
->File
, "RIGHT\n"); break;
3211 case TextAnchor_MidLeft
: fprintf(FileStream
->File
, "MIDLEFT\n"); break;
3212 case TextAnchor_MidCenter
: fprintf(FileStream
->File
, "MIDCENTER\n"); break;
3213 case TextAnchor_MidRight
: fprintf(FileStream
->File
, "MIDRIGHT\n"); break;
3214 case TextAnchor_HeadLeft
: fprintf(FileStream
->File
, "HEADLEFT\n"); break;
3215 case TextAnchor_HeadCenter
: fprintf(FileStream
->File
, "HEADCENTER\n"); break;
3216 case TextAnchor_HeadRight
: fprintf(FileStream
->File
, "HEADRIGHT\n"); break;
3217 default: CHECK(FALSE
); break;
3220 switch (Text
->Box
.BoxType
)
3222 case TextBox_Hollow
: fprintf(FileStream
->File
, "BX=Hollow "); break;
3223 case TextBox_Filled
: fprintf(FileStream
->File
, "BX=Filled "); break;
3226 fprintf(FileStream
->File
, "BXM=%.4G ", Text
->Box
.Margin
*100);
3227 fprintf(FileStream
->File
, "LT=%.4G ", Text
->Box
.LineThickness
*100.0);
3228 fprintf(FileStream
->File
, "BXO="); WriteAsciiColor(FileStream
->File
, Text
->Box
.BColor
);
3229 fprintf(FileStream
->File
, "BXF="); WriteAsciiColor(FileStream
->File
, Text
->Box
.FillBColor
);
3231 fprintf(FileStream
->File
, "\nF=");
3232 switch (Text
->TextShape
.Font
)
3234 case Font_Helvetica
: fprintf(FileStream
->File
, "HELV"); break;
3235 case Font_HelveticaBold
: fprintf(FileStream
->File
, "HELV-BOLD"); break;
3236 case Font_Times
: fprintf(FileStream
->File
, "TIMES"); break;
3237 case Font_TimesBold
: fprintf(FileStream
->File
, "TIMES-BOLD"); break;
3238 case Font_TimesItalic
: fprintf(FileStream
->File
, "TIMES-ITALIC"); break;
3239 case Font_TimesItalicBold
: fprintf(FileStream
->File
, "TIMES-ITALIC-BOLD"); break;
3240 case Font_Courier
: fprintf(FileStream
->File
, "COURIER"); break;
3241 case Font_CourierBold
: fprintf(FileStream
->File
, "COURIER-BOLD"); break;
3242 case Font_Greek
: fprintf(FileStream
->File
, "GREEK"); break;
3243 case Font_Math
: fprintf(FileStream
->File
, "MATH"); break;
3244 case Font_UserDefined
: fprintf(FileStream
->File
, "USER-DEF"); break;
3245 default: CHECK(FALSE
); break;
3247 if (Text
->TextShape
.SizeUnits
== Units_Frame
)
3251 fprintf(FileStream
->File
, "\nH=%.12G A=%.12G",
3252 Text
->TextShape
.Height
*ScaleFact
,
3253 Text
->Angle
*DEGPERRADIANS
);
3258 fprintf(FileStream
->File
, "\nMFC=");
3260 DumpDatafileString(FileStream
, Text
->MacroFunctionCommand
, WriteBinary
);
3264 if (Text
->Clipping
== Clipping_ClipToViewport
)
3265 fprintf(FileStream
->File
, "CLIPPING=CLIPTOVIEWPORT\n");
3266 else if (Text
->Clipping
== Clipping_ClipToFrame
)
3267 fprintf(FileStream
->File
, "CLIPPING=CLIPTOFRAME\n");
3273 WriteBinaryInt32(FileStream
, (LgIndex_t
)Text
->Clipping
);
3277 fprintf(FileStream
->File
, "T=");
3279 return DumpDatafileString(FileStream
, Text
->Text
, WriteBinary
) == TRUE
;
3282 Boolean_t
DumpCustomAxisLabels(FileStream_s
*FileStream
,
3283 Boolean_t WriteBinary
,
3284 StringList_pa LabelBase
)
3286 Boolean_t IsOk
= TRUE
;
3287 LgIndex_t Index
= 0;
3288 LgIndex_t Count
= 0;
3290 REQUIRE(VALID_REF(FileStream
) && VALID_REF(FileStream
->File
));
3291 REQUIRE(VALID_BOOLEAN(WriteBinary
));
3292 REQUIRE(StringListValid(LabelBase
));
3294 Count
= StringListCount(LabelBase
);
3297 WriteBinaryReal(FileStream
, CustomLabelMarker
, FieldDataType_Float
);
3298 WriteBinaryInt32(FileStream
, Count
);
3302 fprintf(FileStream
->File
, " CUSTOMLABELS = \n");
3305 for (Index
= 0, IsOk
= TRUE
; Index
< Count
&& IsOk
; Index
++)
3307 const char *CurLabel
= StringListGetStringRef(LabelBase
, Index
);
3308 IsOk
= DumpDatafileString(FileStream
, CurLabel
, WriteBinary
);
3311 ENSURE(VALID_BOOLEAN(IsOk
));
3317 Boolean_t
WriteBinaryMagic(FileStream_s
*FileStream
)
3320 * Write an integer value of 1 to the file. This is used
3321 * by the reader to determine byte order of the file.
3323 return (WriteBinaryInt32(FileStream
, 1));
3328 bool writeBinaryVersionNumber(FileStream_s
& fileStream
,
3335 CHECK(strlen(buffer
) == 4);
3336 return fprintf(fileStream
.File
,
3341 #if defined TECPLOTKERNEL
3342 /* CORE SOURCE CODE REMOVED */
3346 #if !defined NO_ASSERTS
3348 #if defined ALLOW_USERDEF_NO_NEIGHBORING_ELEMENT
3351 #if 0 /* not used yet */
3353 #if defined TECPLOTKERNEL
3355 #if defined TECPLOTKERNEL