This repository has been archived on 2023-11-20. You can view files and clone it, but cannot push or open issues or pull requests.
foam-extend4.1-coherent-io/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/dataio.cpp
2013-07-18 10:15:54 +02:00

695 lines
26 KiB
C++

/*
* NOTICE and LICENSE for Tecplot Input/Output Library (TecIO) - OpenFOAM
*
* Copyright (C) 1988-2009 Tecplot, Inc. All rights reserved worldwide.
*
* Tecplot hereby grants OpenCFD limited authority to distribute without
* alteration the source code to the Tecplot Input/Output library, known
* as TecIO, as part of its distribution of OpenFOAM and the
* OpenFOAM_to_Tecplot converter. Users of this converter are also hereby
* granted access to the TecIO source code, and may redistribute it for the
* purpose of maintaining the converter. However, no authority is granted
* to alter the TecIO source code in any form or manner.
*
* This limited grant of distribution does not supersede Tecplot, Inc.'s
* copyright in TecIO. Contact Tecplot, Inc. for further information.
*
* Tecplot, Inc.
* 3535 Factoria Blvd, Ste. 550
* Bellevue, WA 98006, USA
* Phone: +1 425 653 1200
* http://www.tecplot.com/
*
*/
#include "stdafx.h"
#include "MASTER.h"
#define TECPLOTENGINEMODULE
/*
******************************************************************
******************************************************************
******* ********
****** (C) 1988-2008 Tecplot, Inc. *******
******* ********
******************************************************************
******************************************************************
*/
#define DATAIOMODULE
#include "GLOBAL.h"
#include "TASSERT.h"
#include "Q_UNICODE.h"
#include "TranslatedString.h"
#if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
#else
#ifdef MSWIN
/* Disable warning about conversion from long to short.
Even if we have disabled it in stdafx.h,
we still need to disable here also for
tecio, which includes this cpp file. */
#pragma warning (disable : 4244)
#endif
/*
* Temp text and geom buffers.
*/
static Geom_s TempGeom;
static Text_s TempText;
#endif
#include "DATASET0.h"
#include "SET.h"
#include "FILESTREAM.h"
#include "DATAIO.h"
#include "DATAIO4.h"
#include "STRUTIL.h"
#include "AUXDATA.h"
#include "ARRLIST.h"
#include "STRLIST.h"
#include "ALLOC.h"
#include "DATASET.h"
#include "SYSTEM.h"
#include "Q_MSG.h"
#if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
#endif
using namespace tecplot::strutil;
#if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
#if !defined ENGINE
#endif
#if !defined ENGINE /* TODO(RMS)-M 12/13/2005: ENGINE-P2 - no status feedback */
#endif
#endif /* TECPLOTKERNEL */
/*
* Multi-Purpose datafile header reader. This is designed so that
* not all parts of the header is loaded and so that the task of loading
* the header information is separated out from installing of that
* information into a dataset.
*
*/
Boolean_t ReadDataFileHeader(FileStream_s *FileStream,
short IVersion,
Boolean_t ShowDataIOStatus,
EntIndex_t *NumZones,
EntIndex_t *NumVars,
SmInteger_t *NumCustomLabelSets,
char **DataSetTitle,
Text_s **BaseText,
Geom_s **BaseGeom,
StringList_pa **CustomLabelBase,
StringList_pa *UserRec,
AuxData_pa *DataSetAuxData,
Set_pa **IsVarCellCentered, /* Create an Array dim by zones */
Boolean_t *HasText,
Boolean_t *HasGeoms,
ArrayList_pa *ZoneSpecList,
StringList_pa *VarNames,
ArrayList_pa *VarAuxDataList, /*<AuxData_pa>[NumVars]*/
Set_pa *IsRawFNAvailable, /* classic data only */
LgIndex_t **FNNumBndryConns, /* classic data only */
DataFileType_e *FileType)
{
Boolean_t IsOk = TRUE;
Boolean_t SentError = FALSE;
double X1;
int Pass;
FileOffset_t InitialFilePosition;
REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File));
REQUIRE(IVersion > 0);
REQUIRE(VALID_BOOLEAN(ShowDataIOStatus));
REQUIRE(VALID_REF(NumZones));
REQUIRE(VALID_REF(NumVars));
REQUIRE(VALID_REF(DataSetTitle) || (DataSetTitle == NULL));
REQUIRE(VALID_REF(BaseText) || (BaseText == NULL));
REQUIRE(VALID_REF(BaseGeom) || (BaseGeom == NULL));
REQUIRE(VALID_REF(HasText) || (HasText == NULL));
REQUIRE(VALID_REF(HasGeoms) || (HasGeoms == NULL));
REQUIRE(VALID_REF(ZoneSpecList) || (ZoneSpecList == NULL));
REQUIRE(VALID_REF(VarNames) || (VarNames == NULL));
REQUIRE(VALID_REF(NumCustomLabelSets) || (NumCustomLabelSets == NULL));
REQUIRE(VALID_REF(UserRec) || (UserRec == NULL));
REQUIRE((VALID_REF(DataSetAuxData) &&
(VALID_REF(*DataSetAuxData) || *DataSetAuxData == NULL)) ||
DataSetAuxData == NULL);
REQUIRE((VALID_REF(VarAuxDataList) &&
(VALID_REF(*VarAuxDataList) || *VarAuxDataList == NULL)) ||
VarAuxDataList == NULL);
REQUIRE(VALID_REF(IsVarCellCentered) || (IsVarCellCentered == NULL));
REQUIRE((VALID_REF(CustomLabelBase) && VALID_REF(NumCustomLabelSets)) || (CustomLabelBase == NULL));
REQUIRE(VALID_REF(IsRawFNAvailable) || (IsRawFNAvailable == NULL));
REQUIRE(VALID_REF(FNNumBndryConns) || (FNNumBndryConns == NULL));
REQUIRE(VALID_REF(FileType) || (FileType == NULL));
if (DataSetTitle)
*DataSetTitle = NULL;
if (BaseText)
*BaseText = NULL;
if (BaseGeom)
*BaseGeom = NULL;
if (HasText)
*HasText = FALSE;
if (HasGeoms)
*HasGeoms = FALSE;
if (ZoneSpecList)
*ZoneSpecList = NULL;
if (VarNames)
*VarNames = NULL;
if (NumCustomLabelSets)
*NumCustomLabelSets = 0;
if (CustomLabelBase)
*CustomLabelBase = NULL;
if (DataSetAuxData != NULL)
{
/*
* Note unlike most of the other output only parameters that we nullify,
* DataSetAuxData is both an input and output parameter therefore we do
* not nullify it. The CHECK is here for clarity.
*/
CHECK(VALID_REF(*DataSetAuxData) || *DataSetAuxData == NULL);
}
if (VarAuxDataList != NULL)
{
/*
* Note unlike most of the other output only parameters that we nullify,
* VarAuxDataList is both an input and output parameter therefore we do
* not nullify it. The CHECK is here for clarity.
*/
CHECK(VALID_REF(*VarAuxDataList) || *VarAuxDataList == NULL);
}
if (UserRec)
*UserRec = NULL;
if (IsVarCellCentered)
*IsVarCellCentered = NULL;
if (IsRawFNAvailable)
*IsRawFNAvailable = NULL;
if (FNNumBndryConns)
*FNNumBndryConns = NULL;
if (FileType)
*FileType = DataFileType_Full;
/*
* Pass 1 is used only to count up the number of zones and custom label sets,
* Also determine if there are any preset zone colors.
*/
InitialFilePosition = TP_FTELL(FileStream->File);
for (Pass = 1; IsOk && (Pass <= 2); Pass++)
{
if (Pass == 2)
{
if (TP_FSEEK(FileStream->File, InitialFilePosition, SEEK_SET) != 0)
IsOk = FALSE;
if (IsOk && (*NumZones > 0 && ZoneSpecList != NULL && *ZoneSpecList == NULL))
{
*ZoneSpecList = ArrayListAlloc(*NumZones, ArrayListType_VoidPtr,
ZoneOrVarListAdjustCapacityRequest, 0);
IsOk = (*ZoneSpecList != NULL);
}
if (IsOk && (CustomLabelBase != NULL &&
*CustomLabelBase == NULL &&
*NumCustomLabelSets > 0))
{
*CustomLabelBase = ALLOC_ARRAY(*NumCustomLabelSets, StringList_pa, "CustomLabel Sets");
IsOk = (*CustomLabelBase != NULL);
if (IsOk)
{
SmInteger_t N;
for (N = 0; N < *NumCustomLabelSets; N++)
(*CustomLabelBase)[N] = NULL;
}
}
if (IsOk && (UserRec != NULL && *UserRec == NULL))
{
*UserRec = StringListAlloc();
IsOk = (Boolean_t)(*UserRec != NULL);
}
if (IsOk && (DataSetAuxData != NULL && *DataSetAuxData == NULL))
{
*DataSetAuxData = AuxDataAlloc();
IsOk = (Boolean_t)(*DataSetAuxData != NULL);
}
if (IsOk && (VarAuxDataList != NULL && *VarAuxDataList == NULL) && *NumVars > 0)
{
*VarAuxDataList = ArrayListAlloc(0, ArrayListType_VoidPtr,
ZoneOrVarListAdjustCapacityRequest, 0);
IsOk = (*VarAuxDataList != NULL &&
ArrayListSetVoidPtr(*VarAuxDataList, *NumVars - 1, NULL));
}
if (IsOk &&
(*NumZones > 0) &&
(IsVarCellCentered != NULL) &&
(*IsVarCellCentered == NULL))
{
/*
* First construct the array of sets...
*/
*IsVarCellCentered = ALLOC_ARRAY(*NumZones, Set_pa, "Array of IsVarCellCentered sets");
if (*IsVarCellCentered)
{
EntIndex_t Z;
for (Z = 0; IsOk && (Z < *NumZones); Z++)
{
/*
* Now allocate a set for each zone
*/
(*IsVarCellCentered)[Z] = AllocSet(FALSE);
IsOk = (Boolean_t)((*IsVarCellCentered)[Z] != NULL);
}
}
else
IsOk = FALSE;
}
if (IsOk && *NumZones > 0 && IsRawFNAvailable != NULL)
{
*IsRawFNAvailable = AllocSet(FALSE);
IsOk = (*IsRawFNAvailable != NULL);
}
if (IsOk && *NumZones > 0 && FNNumBndryConns != NULL)
{
*FNNumBndryConns = ALLOC_ARRAY(*NumZones, LgIndex_t, "Array of FNNumBndryConns");
IsOk = (*FNNumBndryConns != NULL);
if (IsOk)
for (LgIndex_t i = 0; i < *NumZones; i++)
(*FNNumBndryConns)[i] = 0;
}
}
if (NumCustomLabelSets != NULL)
*NumCustomLabelSets = 0;
EntIndex_t TotalNumZones = *NumZones; /* ...only meaningful for pass 2 */
*NumZones = 0;
*NumVars = 0;
if (IsOk)
{
char *S = NULL;
int INumVars;
IsOk = ReadInDataFileTypeTitleAndVarNames(FileStream,
IVersion,
((Pass == 2) ? &S : (char **)NULL),
((Pass == 2) ? FileType : (DataFileType_e *)NULL),
&INumVars,
((Pass == 2) ? VarNames : (StringList_pa *)NULL));
if (IsOk)
*NumVars = (EntIndex_t)INumVars;
if ((Pass == 2) && S && IsOk && DataSetTitle)
*DataSetTitle = S;
else if (S != NULL)
FREE_ARRAY(S, "data set title");
}
if (IsOk)
{
#if !defined ENGINE /* TODO(RMS)-M 12/13/2005: ENGINE-P2 - no dialog feedback */
LgIndex_t NumGeoms = 0;
LgIndex_t NumTexts = 0;
#endif
if (IsOk)
X1 = GetNextValue(FileStream, FieldDataType_Float, 0.0, 1000.0, &IsOk);
while (IsOk && (X1 != EndHeaderMarker))
{
if (X1 == ZoneMarker)
{
ZoneSpec_s *ZoneSpec = ZoneSpecAlloc();
Boolean_t OkToLoad = (Pass == 2 &&
IsVarCellCentered != NULL);
IsOk = (ZoneSpec != NULL);
if (IsOk)
{
Boolean_t LocalIsRawFNAvailable;
LgIndex_t LocalFNNumBndryConns;
IsOk = ReadInZoneHeader(FileStream, IVersion, ZoneSpec,
OkToLoad ? (*IsVarCellCentered)[*NumZones] : NULL,
*NumVars, &LocalIsRawFNAvailable,
&LocalFNNumBndryConns);
if (IsOk && OkToLoad && IsRawFNAvailable != NULL)
{
if (LocalIsRawFNAvailable)
IsOk = AddToSet(*IsRawFNAvailable, *NumZones, FALSE);
}
if (IsOk && OkToLoad && FNNumBndryConns != NULL)
(*FNNumBndryConns)[*NumZones] = LocalFNNumBndryConns;
}
if (IsOk &&
ZoneSpecList != NULL &&
Pass == 2)
{
IsOk = (ZoneSpec->ParentZone == BAD_SET_VALUE ||
(ZoneSpec->ParentZone != *NumZones &&
(0 <= ZoneSpec->ParentZone && ZoneSpec->ParentZone < TotalNumZones)));
if (IsOk)
{
ArrayListItem_u CurZoneSpecItem;
CurZoneSpecItem.VoidPtr = (void *)ZoneSpec;
ArrayListSetItem(*ZoneSpecList, *NumZones,
CurZoneSpecItem,
ZoneSpecItemDestructor, 0);
}
else
{
if (ZoneSpec->ParentZone == *NumZones)
ErrMsg(translate("Parent zone assignment for zone %d "
"may not be self referencing."),
*NumZones + 1);
else
ErrMsg(translate("Parent zone assignment for zone %d "
"must be to an existing zone within the datafile."),
*NumZones + 1);
ZoneSpecDealloc(&ZoneSpec);
SentError = TRUE;
}
}
else
ZoneSpecDealloc(&ZoneSpec);
if (IsOk)
(*NumZones)++;
if (*NumZones > MaxNumZonesOrVars)
{
ErrMsg(translate("Exceeding Tecplot's current zone limit of %d. "
"Reduce the number of zones being loaded."), MaxNumZonesOrVars);
IsOk = FALSE;
SentError = TRUE;
}
}
else if (X1 == GeomMarker)
{
#if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
#else
IsOk = ReadInGeometry(FileStream,
IVersion,
FALSE,
&TempGeom,
5000);
#endif
if (IsOk)
{
if (Pass == 1)
{
if (HasGeoms)
*HasGeoms = TRUE;
}
#if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
#endif
}
#if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
#if !defined ENGINE /* TODO(RMS)-M 12/13/2005: ENGINE-P2 - no status feedback */
#endif
#endif
}
else if (X1 == TextMarker)
{
#if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
#else
IsOk = ReadInText(FileStream,
IVersion,
FALSE,
&TempText,
200);
#endif
if (IsOk)
{
if (Pass == 1)
{
if (HasText)
*HasText = TRUE;
}
#if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
#endif
}
#if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
#if !defined ENGINE /* TODO(RMS)-M 12/13/2005: ENGINE-P2 - no status feedback */
#endif
#endif
}
else if (X1 == CustomLabelMarker)
{
Boolean_t OkToLoad;
OkToLoad = (Pass == 2) &&
NumCustomLabelSets &&
(*NumCustomLabelSets < MaxCustomLabelSets) &&
CustomLabelBase;
IsOk = ReadInCustomLabels(FileStream,
IVersion,
OkToLoad,
(OkToLoad ? &(*CustomLabelBase)[*NumCustomLabelSets] : NULL));
if (IsOk && NumCustomLabelSets)
(*NumCustomLabelSets)++;
}
else if (X1 == UserRecMarker)
{
Boolean_t OkToLoad;
char *CurUserRec = NULL;
OkToLoad = (Boolean_t)((Pass == 2) && UserRec);
IsOk = ReadInUserRec(FileStream,
IVersion,
500,
OkToLoad ? &CurUserRec : (char **)NULL);
if (IsOk && OkToLoad)
IsOk = StringListAppendString(*UserRec, CurUserRec);
if (CurUserRec)
FREE_ARRAY(CurUserRec, "temp user rec");
CurUserRec = NULL;
}
else if (X1 == DataSetAuxMarker)
{
Boolean_t OkToLoad;
CHECK(IVersion >= 101);
OkToLoad = (Pass == 2 &&
DataSetAuxData != NULL);
IsOk = ReadInAuxData(FileStream, IVersion,
OkToLoad ? *DataSetAuxData : NULL);
if (!IsOk)
{
ErrMsg(translate("Invalid DATASETAUXDATA record in binary datafile"));
SentError = TRUE;
}
}
else if (X1 == VarAuxMarker)
{
Boolean_t OkToLoad;
LgIndex_t VarNum;
CHECK(IVersion >= 102);
OkToLoad = (Pass == 2 &&
VarAuxDataList != NULL);
VarNum = GetIoFileInt(FileStream, IVersion, 0, *NumVars - 1, &IsOk);
if (IsOk)
{
AuxData_pa VarAuxData;
if (OkToLoad)
{
VarAuxData = (AuxData_pa)ArrayListGetVoidPtr(*VarAuxDataList, VarNum);
if (VarAuxData == NULL)
{
VarAuxData = AuxDataAlloc();
IsOk = (VarAuxData != NULL &&
ArrayListSetVoidPtr(*VarAuxDataList, VarNum, VarAuxData));
}
}
else
VarAuxData = NULL;
IsOk = IsOk && ReadInAuxData(FileStream, IVersion, VarAuxData);
if (!IsOk)
{
ErrMsg(translate("Invalid VARAUXDATA record in binary datafile"));
SentError = TRUE;
}
}
else
{
ErrMsg(translate("Invalid VARAUXDATA variable number association"));
SentError = TRUE;
}
}
else
IsOk = FALSE;
if (IsOk)
X1 = GetNextValue(FileStream, FieldDataType_Float, 0.0, 1000.0, &IsOk);
}
}
}
/*
* Old plt files that did not contain data still contained variable name
* definitions in the header. This is no longer necessary and in fact can
* cause confusion in the data read options dialog. If the number of zones
* in the datafile is zero set the number of variables to 0 and dealloc the
* variable name list.
*/
if (IsOk && (*NumZones == 0) && (*NumVars > 0))
{
*NumVars = 0;
if (VarNames && *VarNames)
{
StringListDealloc(VarNames);
}
}
if (!IsOk)
{
if (ZoneSpecList && *ZoneSpecList)
ArrayListDealloc(ZoneSpecList, ZoneSpecItemDestructor, 0);
if (DataSetTitle && *DataSetTitle)
{
FREE_ARRAY(*DataSetTitle, "DataSetTitle");
*DataSetTitle = NULL;
}
#if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
#endif
if (VarNames && *VarNames)
{
StringListDealloc(VarNames);
}
#if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
#endif
if (UserRec && *UserRec)
StringListDealloc(UserRec);
}
/* If there was an error, get rid of the auxiliary data list. */
if ((DataSetAuxData != NULL && *DataSetAuxData != NULL) &&
(!IsOk))
AuxDataDealloc(DataSetAuxData);
if (!IsOk && !SentError)
ErrMsg(translate("Invalid header in binary datafile"));
/*
* NOTE: Do not close the file. Some calling functions will continue
* to read from this point on.
*/
ENSURE((VarNames == NULL) || (*VarNames == NULL) || StringListValid(*VarNames));
ENSURE(IMPLICATION(UserRec != NULL,
(*UserRec == NULL ||
StringListValid(*UserRec))));
ENSURE(IMPLICATION(DataSetAuxData != NULL,
(*DataSetAuxData == NULL ||
VALID_REF(*DataSetAuxData))));
return (IsOk);
}
#if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
#endif /* TECPLOTKERNEL */
Boolean_t OpenBinaryFileAndCheckMagicNumber(FileStream_s **FileStream,
char *FName,
FileOffset_t StartOffset,
short *IVersion)
{
Boolean_t Result = TRUE;
REQUIRE(VALID_REF(FileStream));
REQUIRE(*FileStream == NULL);
REQUIRE(VALID_REF(FName));
REQUIRE(StartOffset >= 0);
REQUIRE(VALID_REF(IVersion));
#if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
#else
FILE *File = TP_FOPEN(FName, "rb");
if (File == NULL)
Result = FALSE;
#endif
if (Result)
{
*FileStream = FileStreamAlloc(File, TRUE);
Result = (*FileStream != NULL);
}
Result = Result && (TP_FSEEK((*FileStream)->File, StartOffset, SEEK_SET) == 0);
if (Result)
{
*IVersion = GetInputVersion(*FileStream);
/*
* After version 71 we started listing individual valid
* versions. Before that time we just listed ranges. Also,
* note that versions 72, 73, and 74 were invalid.
*/
Result = (/* past valid plt file version ranges follow: */
(40 <= *IVersion && *IVersion <= 71) ||
(*IVersion == 75) ||
(100 <= *IVersion && *IVersion <= TecplotBinaryFileVersion));
/*
* This check is put here to make sure that the above code gets visited
* when the TecplotBinaryFileVersion number changes. When the version
* changes the "past valid plt file version ranges" above and the number
* compared to the TecplotBinaryFileVersion below may need to be
* adjusted such as when we skip a consecutive number as we did between
* version 71 and 75, and between 75 and 100.
*/
CHECK(TecplotBinaryFileVersion == 112);
}
ENSURE(VALID_BOOLEAN(Result));
return (Result);
}
#if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
#if !defined NO_ASSERTS
#endif
#if !defined NO_ASSERTS
#endif
#if !defined ENGINE /* TODO(RMS)-M 12/13/2005: ENGINE-P2 - no status feedback */
#endif
#if !defined ENGINE /* TODO(RMS)-M 12/13/2005: ENGINE-P2 - no status feedback */
#endif
#if !defined ENGINE /* TODO(RMS)-M 12/13/2005: ENGINE-P2 - no status feedback */
#endif
#if !defined ENGINE /* TODO(RMS)-M 12/13/2005: ENGINE-P2 - no status feedback */
#endif
#if !defined ENGINE /* TODO(RMS)-M 12/13/2005: ENGINE-P2 - no status feedback */
#endif
#if !defined ENGINE /* TODO(RMS)-M 12/13/2005: ENGINE-P2 - no status feedback */
#endif
#if !defined ENGINE /* TODO(RMS)-H 12/12/2005: ENGINE: refactor to use just the Interrupted flag as-is */
#else
#endif
#if 0 /* we changed this behavior... not sure when */
#endif
#endif /* TECPLOTKERNEL */