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/datautil.cpp
2010-08-25 22:42:57 +01:00

941 lines
40 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. *******
******* ********
******************************************************************
******************************************************************
*/
/*
* datautil.c:
*
* version 1.00 : 12/10/91 (cm) changes made for manual
* version 1.01 : 12/30/91 Get and ReturnHugeBlock are now ptr to function
* version 6.00 : 04/21/92 updated to match version 6 of tecplot.
* version 6.30 : 10/15/92 updated to match binary file version 6.3
* version 6.30a: 05/04/93 (cm) minor changes to prototypes
* version : 11/01/93 (cm) put in D4GW stuff
* version 6.30b: 12/27/93 (cm) fixed missing NumKPts in DumpZone
* version 6.30c: 12/27/93 (cm) put back in D4GW stuff
BEGIN CODELOG TECXXX
C 03/06/96 (BDP)
C Update to V7
C
C 03/14/97 (BDP)
C Added code to main tecplot source. Now can
C be built stand alone or added so TecUtil_ functions
C can access.
C 06/02/98 (bdp)
C v75 coding. Also removed Array of ZoneSpec_s
C structs in favor of zonenames, i,j,and k dimensions
C and zonetype array.
END CODELOG
*/
#include "GLOBAL.h"
#include "TASSERT.h"
#include "Q_UNICODE.h"
#include "SYSTEM.h"
#include "ALLOC.h"
#include "TECXXX.h"
#include "ARRLIST.h"
#include "SET.h"
#include "DATASET.h"
#include "FILESTREAM.h"
#if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
#endif
#include "DATAIO.h"
#include "DATAIO4.h"
#include "DATAUTIL.h"
#include "STRLIST.h"
#include "Q_MSG.h"
#if defined MAKEARCHIVE
#define INITMODULE
#endif
#include "INPUT.h"
using namespace tecplot::strutil;
#if defined MAKEARCHIVE
#define ANGLEEPSILON 1.0e-10
void InitInputSpecs(void)
{
LineThicknessInputSpec.Type = Input_Double;
LineThicknessInputSpec.Min = 0.000001;
LineThicknessInputSpec.Max = 1.0;
LineThicknessInputSpec.InterfaceAdjust.ScaleFact = 100.0;
LineThicknessInputSpec.SuffixModifier = NULL;
PatternLengthInputSpec.Type = Input_Double;
PatternLengthInputSpec.Min = 0.0001;
PatternLengthInputSpec.Max = 1.0;
PatternLengthInputSpec.InterfaceAdjust.ScaleFact = 100.0;
PatternLengthInputSpec.SuffixModifier = NULL;
TextBoxMarginInputSpec.Type = Input_Double;
TextBoxMarginInputSpec.Min = 0.0;
TextBoxMarginInputSpec.Max = 20.0;
TextBoxMarginInputSpec.InterfaceAdjust.ScaleFact = 100.0;
TextBoxMarginInputSpec.SuffixModifier = NULL;
TextLineSpacingInputSpec.Type = Input_Double;
TextLineSpacingInputSpec.Min = 0.0;
TextLineSpacingInputSpec.Max = 5.0;
TextLineSpacingInputSpec.InterfaceAdjust.ScaleFact = 1.0;
TextLineSpacingInputSpec.SuffixModifier = NULL;
ArrowheadSizeInputSpec.Type = Input_Double;
ArrowheadSizeInputSpec.Min = 0.0;
ArrowheadSizeInputSpec.Max = 0.5;
ArrowheadSizeInputSpec.InterfaceAdjust.ScaleFact = 100.0;
ArrowheadSizeInputSpec.SuffixModifier = NULL;
TextAngleInputSpec.Type = Input_Double;
TextAngleInputSpec.Min = -PI - ANGLEEPSILON;
TextAngleInputSpec.Max = PI + ANGLEEPSILON;
TextAngleInputSpec.InterfaceAdjust.ScaleFact = DEGPERRADIANS;
TextAngleInputSpec.SuffixModifier = NULL;
ArrowheadAngleInputSpec.Type = Input_Double;
ArrowheadAngleInputSpec.Min = 1.0 / DEGPERRADIANS - ANGLEEPSILON;
ArrowheadAngleInputSpec.Max = PIOVER2 + ANGLEEPSILON;
ArrowheadAngleInputSpec.InterfaceAdjust.ScaleFact = DEGPERRADIANS;
ArrowheadAngleInputSpec.SuffixModifier = NULL;
}
#endif
void LocalReadBlock(FileStream_s *FileStream,
double *CurVPtr,
FieldDataType_e FieldDataTypeInFile,
HgIndex_t NumValues,
Boolean_t *IsOk)
{
REQUIRE(VALID_REF(IsOk) && VALID_BOOLEAN(*IsOk));
REQUIRE(!(*IsOk) || VALID_REF(FileStream));
REQUIRE(!(*IsOk) || VALID_FIELD_DATA_TYPE(FieldDataTypeInFile));
if (*IsOk)
{
Boolean_t DoRead = (CurVPtr != NULL);
Boolean_t ReadByBlock = (FieldDataType_Double == FieldDataTypeInFile) || !DoRead;
if (ReadByBlock)
{
ReadPureBlock(FileStream,
DoRead,
(void *)CurVPtr,
FieldDataTypeInFile,
0,
NumValues,
IsOk);
}
else
{
LgIndex_t N;
for (N = 0; *IsOk && (N < NumValues); N++)
{
double D = GetNextValue(FileStream, FieldDataTypeInFile, -LARGEDOUBLE, LARGEDOUBLE, IsOk);
if (DoRead)
CurVPtr[N] = D;
}
}
}
}
/*
*
* NOTE: ReadTec only allocates space for NodeMap and VDataBase
* if RawDataSpaceAllocated == FALSE and GetHeaderInfoOnly
* is FALSE.
*
* Also note that all data read in by ReadTec is currently
* limited to be in double precision.
*
*/
Boolean_t STDCALL ReadTec(Boolean_t GetHeaderInfoOnly,
char *FName,
short *IVersion,
char **DataSetTitle,
EntIndex_t *NumZones,
EntIndex_t *NumVars,
StringList_pa *VarNames,
StringList_pa *ZoneNames,
LgIndex_t **NumPtsI,
LgIndex_t **NumPtsJ,
LgIndex_t **NumPtsK,
ZoneType_e **ZoneType,
StringList_pa *UserRec,
Boolean_t RawDataSpaceAllocated,
NodeMap_t ***NodeMap,
double ***VDataBase)
{
Boolean_t InputIsOk = FALSE;
ArrayList_pa ZoneSpecList = NULL;
LgIndex_t *FNNumBndryConns = NULL; /* [NumZones] */
FileStream_s *ReadTecFileStream = NULL;
Set_pa *IsVarCellCentered = NULL; /* [NumZones] */
REQUIRE(VALID_BOOLEAN(GetHeaderInfoOnly));
REQUIRE(VALID_NON_ZERO_LEN_STR(FName));
REQUIRE(VALID_REF(IVersion));
REQUIRE(VALID_REF(DataSetTitle) || DataSetTitle == NULL);
REQUIRE(VALID_REF(NumZones));
REQUIRE(VALID_REF(NumVars));
REQUIRE(VarNames == NULL || VALID_REF(VarNames));
REQUIRE(ZoneNames == NULL || VALID_REF(ZoneNames));
REQUIRE(NumPtsI == NULL || VALID_REF(NumPtsI));
REQUIRE(NumPtsJ == NULL || VALID_REF(NumPtsJ));
REQUIRE(NumPtsK == NULL || VALID_REF(NumPtsK));
REQUIRE(ZoneType == NULL || VALID_REF(ZoneType));
REQUIRE(UserRec == NULL || VALID_REF(UserRec));
REQUIRE(VALID_BOOLEAN(RawDataSpaceAllocated));
REQUIRE(IMPLICATION(!GetHeaderInfoOnly && RawDataSpaceAllocated,
VALID_REF(NodeMap) && VALID_REF(VDataBase)));
#if defined MAKEARCHIVE
InitInputSpecs();
#endif
InputIsOk = OpenBinaryFileAndCheckMagicNumber(&ReadTecFileStream,
FName,
0,
IVersion);
if (InputIsOk)
InputIsOk = ReadDataFileHeader(ReadTecFileStream,
*IVersion,
FALSE,
NumZones,
NumVars,
(SmInteger_t *)NULL,
DataSetTitle,
(Text_s **)NULL,
(Geom_s **)NULL,
(StringList_pa **)NULL,
UserRec,
(AuxData_pa *)NULL,
&IsVarCellCentered,
(Boolean_t *)NULL,
(Boolean_t *)NULL,
&ZoneSpecList,
VarNames,
(ArrayList_pa *)NULL,
(Set_pa *)NULL,
&FNNumBndryConns,
(DataFileType_e *)NULL);
if (InputIsOk)
{
if (*NumZones == 0)
*NumVars = 0;
else if (*IVersion > 112)
{
/*
* This may not be true but we put it hear to remind us to make
* updates to this code when we change the version number.
*/
ErrMsg(translate("ReadTec does not yet support version %d "
"Tecplot binary data files."), *IVersion);
InputIsOk = FALSE;
}
else if (!GetHeaderInfoOnly)
{
EntIndex_t Z;
for (Z = 0; Z < *NumZones && InputIsOk; Z++)
{
InputIsOk = (MemberCount(IsVarCellCentered[Z]) == 0);
if (!InputIsOk)
ErrMsg(translate("Cell centered data not supported by ReadTec."));
}
}
}
if (IsVarCellCentered != NULL)
{
EntIndex_t Z;
for (Z = 0; Z < *NumZones; Z++)
DeallocSet(&IsVarCellCentered[Z]);
FREE_ARRAY(IsVarCellCentered, "Array of IsVarCellCentered sets");
}
if (InputIsOk)
{
EntIndex_t Z;
/*
* Allocate space for the zone info pieces.
*/
if (ZoneNames)
*ZoneNames = StringListAlloc();
if (NumPtsI)
*NumPtsI = ALLOC_ARRAY(*NumZones, LgIndex_t, "numptsi");
if (NumPtsJ)
*NumPtsJ = ALLOC_ARRAY(*NumZones, LgIndex_t, "numptsj");
if (NumPtsK)
*NumPtsK = ALLOC_ARRAY(*NumZones, LgIndex_t, "numptsk");
if (ZoneType)
*ZoneType = ALLOC_ARRAY(*NumZones, ZoneType_e, "zonetype");
for (Z = 0; Z < *NumZones; Z++)
{
ZoneSpec_s *ZoneSpec = GetZoneSpec(ZoneSpecList, Z);
if (ZoneSpec != NULL)
{
if (ZoneNames && *ZoneNames)
StringListAppendString(*ZoneNames, ZoneSpec->Name);
if (NumPtsI && *NumPtsI)
(*NumPtsI)[Z] = ZoneSpec->NumPtsI;
if (NumPtsJ && *NumPtsJ)
(*NumPtsJ)[Z] = ZoneSpec->NumPtsJ;
if (NumPtsK && *NumPtsK)
(*NumPtsK)[Z] = ZoneSpec->NumPtsK;
if (ZoneType && *ZoneType)
(*ZoneType)[Z] = ZoneSpec->Type;
}
else
{
if (ZoneNames && *ZoneNames)
StringListAppendString(*ZoneNames, NULL);
if (NumPtsI && *NumPtsI)
(*NumPtsI)[Z] = 0;
if (NumPtsJ && *NumPtsJ)
(*NumPtsJ)[Z] = 0;
if (NumPtsK && *NumPtsK)
(*NumPtsK)[Z] = 0;
if (ZoneType && *ZoneType)
(*ZoneType)[Z] = ZoneType_Invalid;
}
}
}
if (!GetHeaderInfoOnly && InputIsOk && (*NumZones > 0))
{
EntIndex_t *VarSharesFromZone = NULL; /* [NumVars] */
Boolean_t *IsVarPassive = NULL; /* [NumVars] */
EntIndex_t *ConnectivitySharesFromZone = NULL; /* [NumZones] */
FieldDataType_e *VarType = NULL;
int CurZone;
int CurVar;
LgIndex_t NumIPts = 0;
LgIndex_t NumJPts = 0;
LgIndex_t NumKPts = 0;
LgIndex_t TotalNumPts;
LgIndex_t I, J;
if ((*NumZones > 0) && !RawDataSpaceAllocated)
{
*VDataBase = ALLOC_ARRAY(*NumZones * (*NumVars), double *, "vdatabase array");
if (*VDataBase == NULL)
{
ErrMsg(translate("Cannot allocate space for field data"));
InputIsOk = FALSE;
}
else
{
int I;
for (I = 0; I < *NumZones*(*NumVars); I++)
(*VDataBase)[I] = NULL;
}
if (InputIsOk)
{
*NodeMap = ALLOC_ARRAY(*NumZones, NodeMap_t *, "nodemap array");
if (*NodeMap == NULL)
{
ErrMsg(translate("Cannot allocate space for nodemap"));
InputIsOk = FALSE;
}
else
{
int I;
for (I = 0; I < *NumZones; I++)
(*NodeMap)[I] = NULL;
}
}
}
if (InputIsOk)
{
VarType = ALLOC_ARRAY(*NumVars + 1, FieldDataType_e, "Var Type");
VarSharesFromZone = ALLOC_ARRAY(*NumVars + 1, EntIndex_t, "VarSharesFromZone");
IsVarPassive = ALLOC_ARRAY(*NumVars + 1, Boolean_t, "IsVarPassive");
ConnectivitySharesFromZone = ALLOC_ARRAY(*NumZones, EntIndex_t, "ConnectivitySharesFromZone");
InputIsOk = (VarType != NULL &&
VarSharesFromZone != NULL &&
IsVarPassive != NULL &&
ConnectivitySharesFromZone != NULL);
}
/* for each zone */
for (CurZone = 0; CurZone < *NumZones && InputIsOk; CurZone++)
{
double X1 = GetNextValue(ReadTecFileStream, FieldDataType_Float, 0.0, 1000.0, &InputIsOk);
if (InputIsOk && (X1 == ZoneMarker))
{
ZoneSpec_s *CurZoneSpec = GetZoneSpec(ZoneSpecList, CurZone);
Boolean_t ZoneIsFinite = (CurZoneSpec->Type != ZoneType_Ordered);
Boolean_t ZoneIsFEPoly = (CurZoneSpec->Type == ZoneType_FEPolygon ||
CurZoneSpec->Type == ZoneType_FEPolyhedron);
Boolean_t InBlockFormat = CurZoneSpec->ZoneLoadInfo.IsInBlockFormat;
for (J = 0; J < *NumVars; J++)
{
VarSharesFromZone[J] = -1; /* eumulate DupVar: no DupVar */
VarType[J] = FieldDataType_Float;
IsVarPassive[J] = FALSE;
}
/* dupvars */
if (*IVersion > 45 && *IVersion < 101 && InputIsOk)
{
EntIndex_t NumDupVars, ZZ;
NumDupVars = (EntIndex_t)GetIoFileInt(ReadTecFileStream, *IVersion, 0, (LgIndex_t) * NumVars, &InputIsOk);
for (J = 0; J < NumDupVars; J++)
{
ZZ = (EntIndex_t)GetIoFileInt(ReadTecFileStream, *IVersion, 0, *NumVars, &InputIsOk) - 1;
VarSharesFromZone[ZZ] = CurZone - 1; /* emulate DupVar: share from previous zone */
}
/* Can't duplicate from the first zone */
if ((NumDupVars > 0) && (CurZone == 0))
{
ErrMsg(translate("Cannot duplicate variables from the first zone since there are "
"no previous zones to duplicate from."));
InputIsOk = FALSE;
}
}
/* get the data type for each variable */
if (*IVersion >= 70 && InputIsOk)
{
for (J = 0; J < *NumVars; J++)
{
VarType[J] = (FieldDataType_e)GetIoFileInt(ReadTecFileStream, *IVersion,
0,
(LgIndex_t)FieldDataType_Bit,
&InputIsOk);
if (!InputIsOk)
{
ErrMsg(translate("Invalid data type - binary input file corrupted"));
InputIsOk = FALSE;
}
}
}
if (InputIsOk)
{
NumIPts = CurZoneSpec->NumPtsI;
NumJPts = CurZoneSpec->NumPtsJ;
NumKPts = CurZoneSpec->NumPtsK;
}
if (ZoneIsFinite)
TotalNumPts = NumIPts;
else
TotalNumPts = (NumIPts * NumJPts * NumKPts);
for (CurVar = 0; CurVar < *NumVars && InputIsOk; CurVar++)
{
if (!RawDataSpaceAllocated && TotalNumPts >= 1)
{
/*
* The calling program did not allocate space for the
* data so do it here.
*/
(*VDataBase)[CurVar+CurZone*(*NumVars)] =
ALLOC_ARRAY(TotalNumPts, double, "raw data");
}
}
if (*IVersion >= 105 && InputIsOk)
{
/* passive variables */
if ((Boolean_t)GetIoFileInt(ReadTecFileStream, *IVersion, 0, 1, &InputIsOk) && InputIsOk)
{
for (CurVar = 0; CurVar < *NumVars && InputIsOk; CurVar++)
{
IsVarPassive[CurVar] = (Boolean_t)GetIoFileInt(ReadTecFileStream,
*IVersion,
0, 1, &InputIsOk);
}
}
}
if (*IVersion >= 101 && InputIsOk)
{
/* variable sharing: equivalent to DupVar for ReadTec */
if ((Boolean_t)GetIoFileInt(ReadTecFileStream, *IVersion, 0, 1, &InputIsOk) && InputIsOk)
{
for (CurVar = 0; CurVar < *NumVars && InputIsOk; CurVar++)
{
EntIndex_t SharedZone = GetIoFileInt(ReadTecFileStream, *IVersion,
-1, MaxNumZonesOrVars - 1,
&InputIsOk);
if (SharedZone != -1 && InputIsOk)
VarSharesFromZone[CurVar] = SharedZone;
}
}
/* face neighbor or FE node connectivity sharing */
if (InputIsOk)
{
EntIndex_t SharedZone = GetIoFileInt(ReadTecFileStream, *IVersion,
-1, MaxNumZonesOrVars - 1,
&InputIsOk);
if (InputIsOk)
ConnectivitySharesFromZone[CurZone] = SharedZone;
}
}
/*
* Non-shared variable min/max (but not for Zombie zones).
*/
if (*IVersion >= 103 && InputIsOk)
{
for (CurVar = 0; CurVar < *NumVars && InputIsOk; CurVar++)
{
if (VarSharesFromZone[CurVar] == -1 && !IsVarPassive[CurVar])
{
/*
* Currently ReadTec doesn't do anything with the
* min/max values.
*/
GetNextValue(ReadTecFileStream, FieldDataType_Double,
-LARGEDOUBLE, LARGEDOUBLE,
&InputIsOk);
GetNextValue(ReadTecFileStream, FieldDataType_Double,
-LARGEDOUBLE, LARGEDOUBLE,
&InputIsOk);
}
}
}
if (InBlockFormat)
{
CurVar = -1;
while (InputIsOk && ((CurVar + 1) < *NumVars))
{
CurVar++;
if ((CurVar < *NumVars) && (TotalNumPts > 0))
{
double *CurVPtr = (*VDataBase)[CurVar+CurZone*(*NumVars)];
J = 0;
if (VarSharesFromZone[CurVar] != -1)
{
LgIndex_t M;
EntIndex_t SourceZone = VarSharesFromZone[CurVar];
double *SourceVPtr = (*VDataBase)[CurVar+SourceZone*(*NumVars)];
for (M = 0; M < TotalNumPts; M++)
CurVPtr[M] = SourceVPtr[M];
}
else if (!IsVarPassive[CurVar])
{
LocalReadBlock(ReadTecFileStream,
CurVPtr,
VarType[CurVar],
TotalNumPts,
&InputIsOk);
}
}
}
if (!InputIsOk)
ErrMsg(translate("Invalid raw data section of binary file"));
}
else if (TotalNumPts > 0)
{
/*
* Zone is not empty and is in POINT format
*/
J = -1;
if (InputIsOk)
{
LgIndex_t N;
N = 0;
while (InputIsOk && (N < TotalNumPts))
{
EntIndex_t CurVar;
for (CurVar = 0; InputIsOk && (CurVar < *NumVars); CurVar++)
{
double *CurVPtr = (*VDataBase)[CurVar+CurZone*(*NumVars)];
if (VarSharesFromZone[CurVar] != -1)
{
EntIndex_t SourceZone = VarSharesFromZone[CurVar];
double *SourceVPtr = (*VDataBase)[CurVar+SourceZone*(*NumVars)];
CurVPtr[N] = SourceVPtr[N];
}
else if (!IsVarPassive[CurVar])
{
double D = GetNextValue(ReadTecFileStream,
VarType[CurVar],
-LARGEDOUBLE,
LARGEDOUBLE,
&InputIsOk);
if (InputIsOk && CurVPtr)
CurVPtr[N] = D;
}
}
if (!InputIsOk)
ErrMsg(translate("Binary datafile corrupted!"));
N++;
}
}
}
if (InputIsOk && *IVersion < 101)
{
if (ZoneIsFinite)
{
/*
* Pre-version 101 had FE connectivity sharing,
* FECONNECT, information here.
*/
Boolean_t DupConnectivity;
if (*IVersion > 61)
DupConnectivity = GetIoFileInt(ReadTecFileStream, *IVersion, 0, 1, &InputIsOk);
else
DupConnectivity = FALSE;
if (DupConnectivity)
ConnectivitySharesFromZone[CurZone] = CurZone - 1; /* previous zone */
else
ConnectivitySharesFromZone[CurZone] = -1;
}
else
ConnectivitySharesFromZone[CurZone] = -1;
}
if (InputIsOk && ZoneIsFinite && !ZoneIsFEPoly)
{
Boolean_t SkipNodemap;
NodeMap_t *NM = NULL;
NodeMap_t *ONM = NULL;
/*
* Allocate the nodemap ptr if necessary Note that if
* RawDataSpaceAllocated is TRUE then (*NodeMap)[CurZone]
* can either contain a valid address (read the connectivity
* list) or be NULL (skip the list).
*/
if (!RawDataSpaceAllocated && NumKPts*NumJPts >= 1)
{
(*NodeMap)[CurZone] = ALLOC_ARRAY(NumKPts * NumJPts, NodeMap_t, "node map");
if ((*NodeMap)[CurZone] == NULL)
ErrMsg(translate("Cannot allocate space for connectivity list",
"See the Tecplot User's Manual for a definition of 'connectivity list'"));
}
if (InputIsOk)
NM = (*NodeMap)[CurZone];
SkipNodemap = (NM == NULL);
if (InputIsOk && ConnectivitySharesFromZone[CurZone] != -1)
{
EntIndex_t SourceZone = ConnectivitySharesFromZone[CurZone];
if (SourceZone >= CurZone)
{
ErrMsg(translate("Zone %d is attempting to share connectivity "
"with a zone that has not yet been loaded."),
CurZone + 1);
InputIsOk = FALSE;
}
else
{
ONM = (*NodeMap)[SourceZone];
if (ONM == NULL)
{
ErrMsg(translate("Zone %d is attempting to share connectivity "
"with a zone that is not finite element."),
CurZone + 1);
InputIsOk = FALSE;
}
}
}
if (InputIsOk)
{
/* load the FE node connectivity */
for (J = 0; J < NumJPts; J++)
for (I = 0; I < NumKPts; I++)
{
LgIndex_t M;
LgIndex_t L = J * NumKPts + I;
if (ConnectivitySharesFromZone[CurZone] != -1)
M = ONM[L];
else
M = GetNextI(ReadTecFileStream, &InputIsOk) - 1;
if (!SkipNodemap)
NM[L] = M;
}
}
}
/* skip over the face neighbor connectivity */
if (*IVersion >= 101 && InputIsOk)
{
EntIndex_t SharedZone = ConnectivitySharesFromZone[CurZone];
if (SharedZone == -1 && FNNumBndryConns[CurZone] != 0)
{
LgIndex_t Connection = 0;
while (Connection < FNNumBndryConns[CurZone] && InputIsOk)
{
/*
* Face neighbor connection have the following format for both
* ASCII and binary:
*
* FaceNeighborMode_LocalOneToOne 3 cz,fz,cz
* FaceNeighborMode_LocalOneToMany nz+4 cz,fz,oz,nz,cz1,cz2,...,czn
* FaceNeighborMode_GlobalOneToOne 4 cz,fz,ZZ,CZ
* FaceNeighborMode_GlobalOneToMany 2*nz+4 cz,fz,oz,nz,ZZ1,CZ1,ZZ2,CZ2,...,ZZn,CZn
*
* Where:
* cz = cell in current zone
* fz = face of cell in current zone
* oz = face obsuration flag (only applies to one-to-many):
* 0 = face partially obscured
* 1 = face entirely obscured
* nz = number of cell or zone/cell associations (only applies to one-to-many)
* ZZ = remote Zone
* CZ = cell in remote zone
*/
(void)GetNextI(ReadTecFileStream, &InputIsOk); /* read cz */
if (!InputIsOk)
ErrMsg(translate("Unexpected end-of-file while reading face neighbor data."));
(void)GetNextI(ReadTecFileStream, &InputIsOk); /* read fz */
if (InputIsOk)
{
/*
* read FaceNeighborMode_LocalOneToOne: cz ||
* FaceNeighborMode_LocalOneToMany: oz ||
* FaceNeighborMode_GlobalOneToOne: ZZ ||
* FaceNeighborMode_GlobalOneToMany: oz
*/
if (CurZoneSpec->FNMode == FaceNeighborMode_LocalOneToOne)
(void)GetNextI(ReadTecFileStream, &InputIsOk);
else if (CurZoneSpec->FNMode == FaceNeighborMode_LocalOneToMany)
(void)GetNextI(ReadTecFileStream, &InputIsOk);
else if (CurZoneSpec->FNMode == FaceNeighborMode_GlobalOneToOne)
(void)GetNextI(ReadTecFileStream, &InputIsOk);
else if (CurZoneSpec->FNMode == FaceNeighborMode_GlobalOneToMany)
(void)GetNextI(ReadTecFileStream, &InputIsOk);
else
CHECK(FALSE);
if (CurZoneSpec->FNMode != FaceNeighborMode_LocalOneToOne && InputIsOk)
{
LgIndex_t NumAssociations = 0;
/*
* read FaceNeighborMode_LocalOneToMany: nz ||
* FaceNeighborMode_GlobalOneToOne: CZ ||
* FaceNeighborMode_GlobalOneToMany: nz
*/
if (CurZoneSpec->FNMode == FaceNeighborMode_LocalOneToMany)
NumAssociations = GetNextI(ReadTecFileStream, &InputIsOk);
else if (CurZoneSpec->FNMode == FaceNeighborMode_GlobalOneToOne)
(void)GetNextI(ReadTecFileStream, &InputIsOk);
else if (CurZoneSpec->FNMode == FaceNeighborMode_GlobalOneToMany)
NumAssociations = GetNextI(ReadTecFileStream, &InputIsOk);
else
CHECK(FALSE);
if (CurZoneSpec->FNMode != FaceNeighborMode_GlobalOneToOne && InputIsOk)
{
LgIndex_t Assoc;
if (CurZoneSpec->FNMode == FaceNeighborMode_LocalOneToMany)
for (Assoc = 0; Assoc < NumAssociations && InputIsOk; Assoc++)
(void)GetNextI(ReadTecFileStream, &InputIsOk); /* read czn */
else if (CurZoneSpec->FNMode == FaceNeighborMode_GlobalOneToMany)
for (Assoc = 0; Assoc < NumAssociations && InputIsOk; Assoc++)
{
(void)GetNextI(ReadTecFileStream, &InputIsOk); /* read ZZn */
(void)GetNextI(ReadTecFileStream, &InputIsOk); /* read CZn */
}
else
CHECK(FALSE);
if (InputIsOk)
Connection += NumAssociations;
}
else if (InputIsOk) /* CurZoneSpec->FNMode == FaceNeighborMode_GlobalOneToOne */
Connection += 1;
}
else if (InputIsOk) /* CurZoneSpec->FNMode == FaceNeighborMode_LocalOneToOne */
Connection += 1;
if (!InputIsOk)
ErrMsg(translate("Corrupt input file: invalid face neighbors."));
}
}
}
}/* face neighbor connectivity */
/* skip over face map section */
if (ZoneIsFEPoly &&
*IVersion >= 110 &&
ConnectivitySharesFromZone[CurZone] != -1 &&
InputIsOk)
{
if (!InBlockFormat)
{
ErrMsg(translate("Poly zones must be in block format"));
InputIsOk = FALSE;
}
if (InputIsOk)
{
HgIndex_t NumFaces = CurZoneSpec->NumPtsK;
if (*IVersion == 110) // ...version 111 moved these to the zone header
{
CurZoneSpec->NumFaceNodes = GetNextI(ReadTecFileStream, &InputIsOk);
CurZoneSpec->NumFaceBndryFaces = GetNextI(ReadTecFileStream, &InputIsOk);
CurZoneSpec->NumFaceBndryItems = GetNextI(ReadTecFileStream, &InputIsOk);
}
HgIndex_t TotalNumFaceNodes = CurZoneSpec->NumFaceNodes;
HgIndex_t TotalNumBndryFaces = CurZoneSpec->NumFaceBndryFaces;
HgIndex_t TotalNumBndryItems = CurZoneSpec->NumFaceBndryItems;
if (CurZoneSpec->Type == ZoneType_FEPolyhedron)
ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, NumFaces + 1, &InputIsOk);
if (InputIsOk)
ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, TotalNumFaceNodes, &InputIsOk);
if (InputIsOk)
ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, NumFaces, &InputIsOk);
if (InputIsOk)
ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, NumFaces, &InputIsOk);
if (TotalNumBndryFaces > 0)
{
if (InputIsOk)
ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, TotalNumBndryFaces + 1, &InputIsOk);
if (InputIsOk)
ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, TotalNumBndryItems, &InputIsOk);
if (InputIsOk)
{
if (*IVersion >= 112)
ReadInt32Block(ReadTecFileStream, FALSE, NULL, 0, TotalNumBndryItems, &InputIsOk);
else
ReadInt16Block(ReadTecFileStream, FALSE, NULL, 0, TotalNumBndryItems, &InputIsOk);
}
}
}
}/* face map section */
}
else
{
ErrMsg(translate("Corrupt input file"));
InputIsOk = FALSE;
}
}
if (VarSharesFromZone)
FREE_ARRAY(VarSharesFromZone, "VarSharesFromZone");
if (IsVarPassive)
FREE_ARRAY(IsVarPassive, "IsVarPassive");
if (ConnectivitySharesFromZone)
FREE_ARRAY(ConnectivitySharesFromZone, "ConnectivitySharesFromZone");
if (VarType)
FREE_ARRAY(VarType, "VarType");
if (!InputIsOk && !RawDataSpaceAllocated)
{
int I;
if (*VDataBase)
{
for (I = 0; I < *NumZones*(*NumVars); I++)
{
if ((*VDataBase)[I])
FREE_ARRAY((*VDataBase)[I], "vdatabase array");
}
FREE_ARRAY(*VDataBase, "vdatabase pointer array");
}
if (*NodeMap)
{
for (I = 0; I < *NumZones; I++)
{
if ((*NodeMap)[I])
FREE_ARRAY((*NodeMap)[I], "connectivity list");
}
FREE_ARRAY(*NodeMap, "connectivity pointer array");
}
}
} /*Reading Raw Data*/
if (FNNumBndryConns != NULL)
FREE_ARRAY(FNNumBndryConns, "FNNumBndryConns");
if (ZoneSpecList)
ArrayListDealloc(&ZoneSpecList, ZoneSpecItemDestructor, 0);
if (ReadTecFileStream)
{
#if defined TECPLOTKERNEL
/* CORE SOURCE CODE REMOVED */
#else
TP_FCLOSE(ReadTecFileStream->File);
free(ReadTecFileStream);
#endif
}
return (InputIsOk);
}
void * STDCALL TecAlloc(size_t size)
{
return (void *)ALLOC_ARRAY(size, char, "TecAlloc");
}
void STDCALL TecFree(void *ptr)
{
/* Hack to remove delete warning... */
char *Tmp = (char *)ptr;
FREE_ARRAY(Tmp, "TecAlloc");
}