From de564957bc3db08d571c9613a569b089606371c5 Mon Sep 17 00:00:00 2001 From: mattijs Date: Wed, 16 Feb 2011 13:44:26 +0000 Subject: [PATCH] COMP: tecio : move out of thirdparty --- .../dataConversion/foamToTecplot360/Allwmake | 14 + .../foamToTecplot360/Make/options | 4 +- .../foamToTecplot360/tecio/Runmake | 277 + .../tecio/examples/arrow/Arrow.plt | Bin 0 -> 1412 bytes .../tecio/examples/arrow/Makefile | 11 + .../tecio/examples/arrow/arrow.cpp | 530 ++ .../tecio/examples/arrow/arrow.vcproj | 172 + .../tecio/examples/comtest/Makefile | 11 + .../tecio/examples/comtest/comtest.c | 492 ++ .../tecio/examples/comtest/comtest.f | 467 ++ .../tecio/examples/comtest/comtest.f90 | 467 ++ .../tecio/examples/comtest/comtestc.vcproj | 346 + .../tecio/examples/comtest/comtestf.vfproj | 26 + .../examples/faceneighbors/FaceNeighbors.plt | Bin 0 -> 756 bytes .../tecio/examples/faceneighbors/Makefile | 11 + .../examples/faceneighbors/faceneighbors.cpp | 354 + .../faceneighbors/faceneighbors.vcproj | 172 + .../tecio/examples/gridsolution/Makefile | 11 + .../examples/gridsolution/gridsolution.cpp | 376 + .../examples/gridsolution/gridsolution.vcproj | 321 + .../tecio/examples/ij_ordered/Makefile | 11 + .../tecio/examples/ij_ordered/ij_ordered.cpp | 149 + .../tecio/examples/ij_ordered/ij_ordered.plt | Bin 0 -> 584 bytes .../examples/ij_ordered/ij_ordered.vcproj | 172 + .../tecio/examples/multiplefiles/Makefile | 11 + .../tecio/examples/multiplefiles/file1.plt | Bin 0 -> 448 bytes .../tecio/examples/multiplefiles/file2.plt | Bin 0 -> 356 bytes .../examples/multiplefiles/multiplefiles.cpp | 214 + .../multiplefiles/multiplefiles.vcproj | 172 + .../multiplepolygons/HexagonsAndOctagon.plt | Bin 0 -> 1480 bytes .../tecio/examples/multiplepolygons/Makefile | 11 + .../multiplepolygons/multiplepolygons.cpp | 569 ++ .../multiplepolygons/multiplepolygons.vcproj | 172 + .../tecio/examples/octagon/Makefile | 11 + .../tecio/examples/octagon/Octagon.plt | Bin 0 -> 520 bytes .../tecio/examples/octagon/octagon.cpp | 248 + .../tecio/examples/octagon/octagon.vcproj | 172 + .../tecio/examples/pyramid/Makefile | 11 + .../tecio/examples/pyramid/pyramid.cpp | 222 + .../tecio/examples/pyramid/pyramid.plt | Bin 0 -> 600 bytes .../tecio/examples/pyramid/pyramid.vcproj | 172 + .../tecio/examples/simtest/Makefile | 11 + .../tecio/examples/simtest/simtest.c | 100 + .../tecio/examples/simtest/simtest.f | 98 + .../tecio/examples/simtest/simtest.f90 | 98 + .../tecio/examples/simtest/simtestc.vcproj | 346 + .../tecio/examples/simtest/simtestf.vfproj | 26 + .../tecio/examples/squares/Makefile | 11 + .../tecio/examples/squares/squares.cpp | 124 + .../tecio/examples/squares/squares.plt | Bin 0 -> 1304 bytes .../tecio/examples/squares/squares.vcproj | 172 + .../tecio/examples/text/Makefile | 11 + .../tecio/examples/text/text.cpp | 112 + .../tecio/examples/text/text.plt | Bin 0 -> 264 bytes .../tecio/examples/text/text.vcproj | 172 + .../foamToTecplot360/tecio/pltview.cpp | 559 ++ .../foamToTecplot360/tecio/readme.txt | 51 + .../foamToTecplot360/tecio/tecsrc/ALLOC.h | 205 + .../foamToTecplot360/tecio/tecsrc/ARRLIST.h | 626 ++ .../foamToTecplot360/tecio/tecsrc/AUXDATA.h | 130 + .../foamToTecplot360/tecio/tecsrc/DATAIO.h | 63 + .../foamToTecplot360/tecio/tecsrc/DATAIO4.h | 213 + .../foamToTecplot360/tecio/tecsrc/DATASET.h | 90 + .../foamToTecplot360/tecio/tecsrc/DATASET0.h | 404 + .../foamToTecplot360/tecio/tecsrc/DATASHR.h | 70 + .../foamToTecplot360/tecio/tecsrc/DATAUTIL.h | 116 + .../foamToTecplot360/tecio/tecsrc/FACE.h | 149 + .../tecio/tecsrc/FILESTREAM.h | 75 + .../foamToTecplot360/tecio/tecsrc/GEOM.h | 71 + .../foamToTecplot360/tecio/tecsrc/GEOM2.h | 46 + .../foamToTecplot360/tecio/tecsrc/GLOBAL.h | 7271 +++++++++++++++++ .../foamToTecplot360/tecio/tecsrc/INPUT.h | 196 + .../foamToTecplot360/tecio/tecsrc/MASTER.h | 684 ++ .../foamToTecplot360/tecio/tecsrc/Make/files | 21 + .../tecio/tecsrc/Make/options | 7 + .../tecio/tecsrc/Make/tecioOptions | 20 + .../foamToTecplot360/tecio/tecsrc/Q_MSG.h | 72 + .../foamToTecplot360/tecio/tecsrc/Q_UNICODE.h | 93 + .../foamToTecplot360/tecio/tecsrc/SET.h | 283 + .../foamToTecplot360/tecio/tecsrc/STRLIST.h | 122 + .../foamToTecplot360/tecio/tecsrc/STRUTIL.h | 218 + .../foamToTecplot360/tecio/tecsrc/SYSTEM.h | 67 + .../foamToTecplot360/tecio/tecsrc/TASSERT.h | 513 ++ .../foamToTecplot360/tecio/tecsrc/TECIO.h | 24 + .../foamToTecplot360/tecio/tecsrc/TECXXX.h | 698 ++ .../foamToTecplot360/tecio/tecsrc/TEXT.h | 62 + .../tecio/tecsrc/TranslatedString.cpp | 362 + .../tecio/tecsrc/TranslatedString.h | 293 + .../foamToTecplot360/tecio/tecsrc/VERSION.h | 23 + .../foamToTecplot360/tecio/tecsrc/alloc.cpp | 161 + .../foamToTecplot360/tecio/tecsrc/arrlist.cpp | 1671 ++++ .../foamToTecplot360/tecio/tecsrc/auxdata.cpp | 809 ++ .../foamToTecplot360/tecio/tecsrc/dataio.cpp | 695 ++ .../foamToTecplot360/tecio/tecsrc/dataio4.cpp | 3357 ++++++++ .../foamToTecplot360/tecio/tecsrc/dataset.cpp | 283 + .../tecio/tecsrc/dataset0.cpp | 1668 ++++ .../tecio/tecsrc/datautil.cpp | 941 +++ .../tecio/tecsrc/filestream.cpp | 78 + .../foamToTecplot360/tecio/tecsrc/geom2.cpp | 89 + .../foamToTecplot360/tecio/tecsrc/q_msg.cpp | 415 + .../tecio/tecsrc/q_unicode.cpp | 447 + .../foamToTecplot360/tecio/tecsrc/set.cpp | 696 ++ .../foamToTecplot360/tecio/tecsrc/stdafx.h | 130 + .../foamToTecplot360/tecio/tecsrc/strlist.cpp | 1065 +++ .../foamToTecplot360/tecio/tecsrc/strutil.cpp | 936 +++ .../foamToTecplot360/tecio/tecsrc/tassert.cpp | 261 + .../foamToTecplot360/tecio/tecsrc/tecxxx.cpp | 4812 +++++++++++ .../foamToTecplot360/tecio2009.zip | Bin 0 -> 1314306 bytes 108 files changed, 40069 insertions(+), 2 deletions(-) create mode 100755 applications/utilities/postProcessing/dataConversion/foamToTecplot360/Allwmake create mode 100755 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/Runmake create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/arrow/Arrow.plt create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/arrow/Makefile create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/arrow/arrow.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/arrow/arrow.vcproj create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/Makefile create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtest.c create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtest.f create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtest.f90 create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtestc.vcproj create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtestf.vfproj create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/faceneighbors/FaceNeighbors.plt create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/faceneighbors/Makefile create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/faceneighbors/faceneighbors.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/faceneighbors/faceneighbors.vcproj create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/gridsolution/Makefile create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/gridsolution/gridsolution.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/gridsolution/gridsolution.vcproj create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/ij_ordered/Makefile create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/ij_ordered/ij_ordered.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/ij_ordered/ij_ordered.plt create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/ij_ordered/ij_ordered.vcproj create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplefiles/Makefile create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplefiles/file1.plt create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplefiles/file2.plt create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplefiles/multiplefiles.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplefiles/multiplefiles.vcproj create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplepolygons/HexagonsAndOctagon.plt create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplepolygons/Makefile create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplepolygons/multiplepolygons.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplepolygons/multiplepolygons.vcproj create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/octagon/Makefile create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/octagon/Octagon.plt create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/octagon/octagon.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/octagon/octagon.vcproj create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/pyramid/Makefile create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/pyramid/pyramid.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/pyramid/pyramid.plt create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/pyramid/pyramid.vcproj create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/Makefile create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtest.c create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtest.f create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtest.f90 create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtestc.vcproj create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtestf.vfproj create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/squares/Makefile create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/squares/squares.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/squares/squares.plt create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/squares/squares.vcproj create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/text/Makefile create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/text/text.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/text/text.plt create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/text/text.vcproj create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/pltview.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/readme.txt create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/ALLOC.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/ARRLIST.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/AUXDATA.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATAIO.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATAIO4.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATASET.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATASET0.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATASHR.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATAUTIL.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/FACE.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/FILESTREAM.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/GEOM.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/GEOM2.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/GLOBAL.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/INPUT.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/MASTER.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Make/files create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Make/options create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Make/tecioOptions create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Q_MSG.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Q_UNICODE.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/SET.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/STRLIST.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/STRUTIL.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/SYSTEM.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TASSERT.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TECIO.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TECXXX.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TEXT.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TranslatedString.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TranslatedString.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/VERSION.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/alloc.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/arrlist.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/auxdata.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/dataio.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/dataio4.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/dataset.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/dataset0.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/datautil.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/filestream.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/geom2.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/q_msg.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/q_unicode.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/set.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/stdafx.h create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/strlist.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/strutil.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/tassert.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/tecxxx.cpp create mode 100644 applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio2009.zip diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/Allwmake b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/Allwmake new file mode 100755 index 0000000000..935e8e3993 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/Allwmake @@ -0,0 +1,14 @@ +#!/bin/sh +# +# Build optional components (eg, may depend on third-party libraries) +# ----------------------------------------------------------------------------- +cd ${0%/*} || exit 1 # run from this directory +set -x + +# build tecio +wmake libso tecio/tecsrc + +# build converter +wmake + +# ----------------------------------------------------------------- end-of-file diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/Make/options b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/Make/options index 97a2251f7b..4776ad7d64 100644 --- a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/Make/options +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/Make/options @@ -1,5 +1,5 @@ EXE_INC = \ - -I$(WM_THIRD_PARTY_DIR)/tecio/tecsrc/lnInclude \ + -Itecio/tecsrc/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude @@ -10,4 +10,4 @@ EXE_LIBS = \ -lfiniteVolume \ -lgenericPatchFields \ -lmeshTools \ - -L$(FOAM_EXT_LIBBIN) -ltecio + -ltecio diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/Runmake b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/Runmake new file mode 100755 index 0000000000..a22d0c0a86 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/Runmake @@ -0,0 +1,277 @@ +#!/bin/sh + +MAKEWHAT= +EXTRAFLAGS= +STRIPFLAG=-s +isrelease=n +skipcompile=n +if test $# -ge 1 ; then + Platname=$1 + shift + while test $# -ge 1 + do + if test "$1" = "-release" ; then + isrelease=y + elif test "$1" = "-skipcompile" ; then + skipcompile=y + elif test "$1" = "-tecio" ; then + MAKEWHAT=tecio.a + else + EXTRAFLAGS="$EXTRAFLAGS $1" + fi + shift + done +else + echo "Choose platform:" + echo " " + echo " macux.104" + echo " macix64.105" + echo " sgix.62" + echo " sgix3.62" + echo " sgix.65" + echo " sgix64.65" + echo " sgix2.65" + echo " sun4.57" + echo " sun464.57" + echo " sun86.54" + echo " ibmx.43" + echo " ibmx64.43" + echo " ibmx.51" + echo " ibmx64.51" + echo " ibmx64.53" + echo " decalpha.32" + echo " compaq.51" + echo " hp7xx.11" + echo " hp7xx64.11" + echo " hpi64.11" + echo " linux.24" + echo " linuxi64.24" + echo " linux.22" + echo " linuxa.22" + echo " linuxg248x64.26" + echo " linuxg27x64.26" + echo " crayc90" + echo "->\c" + read Platname + + echo "Choose:" + echo " 1. Make tecio.a only" + echo " 2. Make tecio.a and pltview" + + read choice + + if test $choice -eq 1 ;then + MAKEWHAT=tecio.a + fi +fi + +MAKECMD=make +LINKFLAGS= +LINKLIBS= +AR=ar +ARFLAGS=qv +DISTSUBDIR2= + +case $Platname in + mac*) CCOMP=g++ + FINALCFLAGS="-arch ppc -arch i386 -arch ppc64 -arch x86_64 -DDARWIN -DLONGIS64 -I/usr/X11R6/include" + STRIPFLAG=-Wl,-x + LINKFLAGS="-arch ppc -arch i386 -arch ppc64 -arch x86_64" + ;; + sgix.65-64) CCOMP=CC + FINALCFLAGS="-DIRISX -DLONGIS64 -mips4 -64" + LINKFLAGS="-mips4 -64" + ;; + sgix64.65) CCOMP=CC + FINALCFLAGS="-DIRISX -DLONGIS64 -mips4 -64" + LINKFLAGS="-mips4 -64" + ;; + sgix.65) CCOMP=CC + FINALCFLAGS="-DIRISX -mips4 -n32" + LINKFLAGS="-mips4 -n32" + ;; + sgix2.65) CCOMP=CC + FINALCFLAGS="-DIRISX -o32" + LINKFLAGS="-o32" + ;; + sgix.62-64) CCOMP=CC + FINALCFLAGS="-DIRISX -DIRIX62 -DLONGIS64 -mips4 -64" + LINKFLAGS="-mips4 -64" + ;; + sgix.62) CCOMP=CC + FINALCFLAGS="-DIRISX -DIRIX62 -mips4 -n32" + LINKFLAGS="-mips4 -n32" + ;; + sgix1.62) CCOMP=CC + FINALCFLAGS="-DIRISX -DIRIX62 -mips1 -32" + LINKFLAGS="-mips1 -32" + ;; + sgix3.62) CCOMP=CC + FINALCFLAGS="-DIRISX -DIRIX62 -mips3 -n32" + LINKFLAGS="-mips3 -n32" + ;; + ibmx.*) CCOMP=xlC + FINALCFLAGS=-DIBMRS6000X + ;; + ibmx64.*) CCOMP=xlC + FINALCFLAGS="-DIBMRS6000X -DLONGIS64 -q64" + ARFLAGS="-X64 qv" + ;; + compaq.51) CCOMP=cxx + FINALCFLAGS="-DCOMPAQX -I/usr/include -ieee_with_inexact" + ;; + decalpha.32)CCOMP=cc + FINALCFLAGS="-DDECALPHAX -I/usr/include -ieee_with_inexact" + ;; + hp7xx.*-64) CCOMP=aCC + FINALCFLAGS="+DD64 +DS2.0 -AA -DHPX -DLONGIS64 -I/usr/include/X11R6 -I/usr/include/Motif2.1" + LINKFLAGS="+DA2.0W +DD64 +DS2.0W" + ;; + hp7xx64.11) CCOMP=aCC + FINALCFLAGS="+DA2.0W +DD64 +DS2.0W -AA -DHPX -DLONGIS64 -I/usr/include/X11R6 -I/usr/include/Motif2.1" + LINKFLAGS="+DA2.0W +DD64 +DS2.0W" + ;; + hpi64.11) CCOMP=aCC + FINALCFLAGS="+DD64 -AA -DHPX -DLONGIS64 -I/usr/include/X11R6 -I/usr/include/Motif2.1" + LINKFLAGS="+DD64" + ;; + hp7xx.11) CCOMP=aCC + FINALCFLAGS="+DAportable -AA -DHPX -I/usr/include/X11R6 -I/usr/include/Motif2.1" + LINKFLAGS="+DAportable" + ;; + crayc90) CCOMP=cc + FINALCFLAGS="-DCRAY -DUNIXX" + ;; + linux*i64.*)CCOMP=g++ + FINALCFLAGS="-fPIC -DLINUX -DLINUXI64" + ;; + linux*64.*) CCOMP=g++ + FINALCFLAGS="-fPIC -DLINUX -DLINUX64" + ;; + linux*) CCOMP=g++ + FINALCFLAGS="-fPIC -DLINUX" + ;; + sun4.54) CCOMP=/opt/SUNWspro/bin/CC + FINALCFLAGS="-DSUN -DSUNSOLARISX -I/usr/openwin/include -I/usr/dt/include -library=libC -library=Cstd -library=no%rwtools7 -library=no%rwtools7_dbg -xO1" + LINKFLAGS="-library=libC -library=Cstd -library=no%rwtools7 -library=no%rwtools7_dbg" + MAKECMD=/usr/ccs/bin/make + AR=/opt/SUNWspro/bin/CC + ARFLAGS="-xar -o" + ;; + sun4.55) CCOMP=/opt/SUNWspro/bin/CC + FINALCFLAGS="-DSUN -DSUNSOLARISX -I/usr/openwin/include -I/usr/dt/include -library=libC -library=Cstd -library=no%rwtools7 -library=no%rwtools7_dbg -xO1" + LINKFLAGS="-library=libC -library=Cstd -library=no%rwtools7 -library=no%rwtools7_dbg" + MAKECMD=/usr/ccs/bin/make + AR=/opt/SUNWspro/bin/CC + ARFLAGS="-xar -o" + ;; + sun4.57) CCOMP=/opt/SUNWspro/bin/CC + FINALCFLAGS="-DSUNSOLARISX -I/usr/openwin/include -I/usr/dt/include -library=libC -library=Cstd -library=no%rwtools7 -library=no%rwtools7_dbg -xO1" + LINKFLAGS="-library=libC -library=Cstd -library=no%rwtools7 -library=no%rwtools7_dbg" + MAKECMD=/usr/ccs/bin/make + AR=/opt/SUNWspro/bin/CC + ARFLAGS="-xar -o" + ;; + sun4.57-64) CCOMP=/opt/SUNWspro/bin/CC + FINALCFLAGS="-DSUNSOLARISX -DLONGIS64 -KPIC -xarch=v9 -I/usr/openwin/include -I/usr/dt/include -library=libC -library=Cstd -library=no%rwtools7 -library=no%rwtools7_dbg -xO1" + LINKFLAGS="-KPIC -xarch=v9 -library=libC -library=Cstd -library=no%rwtools7 -library=no%rwtools7_dbg" + MAKECMD=/usr/ccs/bin/make + AR=/opt/SUNWspro/bin/CC + ARFLAGS="-xar -o" + ;; + sun464.57) CCOMP=/opt/SUNWspro/bin/CC + FINALCFLAGS="-DSUNSOLARISX -DLONGIS64 -KPIC -xarch=v9 -I/usr/openwin/include -I/usr/dt/include -library=libC -library=Cstd -library=no%rwtools7 -library=no%rwtools7_dbg -xO1" + LINKFLAGS="-KPIC -xarch=v9 -library=libC -library=Cstd -library=no%rwtools7 -library=no%rwtools7_dbg" + MAKECMD=/usr/ccs/bin/make + AR=/opt/SUNWspro/bin/CC + ARFLAGS="-xar -o" + ;; + sun464.59) CCOMP=/opt/SUNWspro/bin/CC + FINALCFLAGS="-DSUNSOLARISX -DLONGIS64 -KPIC -m64 -xarch=generic -I/usr/openwin/include -I/usr/dt/include -library=libC -library=Cstd -library=no%rwtools7 -library=no%rwtools7_dbg -xO1" + LINKFLAGS="-KPIC -m64 -xarch=generic -library=libC -library=Cstd -library=no%rwtools7 -library=no%rwtools7_dbg" + MAKECMD=/usr/ccs/bin/make + AR=/opt/SUNWspro/bin/CC + ARFLAGS="-xar -o" + ;; + sun86.54) CCOMP=/opt/SUNWspro/bin/CC + FINALCFLAGS="-DSUN -DSUNSOLARISX -I/usr/openwin/include -I/usr/dt/include" + MAKECMD=/usr/ccs/bin/make + AR=/opt/SUNWspro/bin/CC + ARFLAGS="-xar -o" + ;; + *) echo "Err: Invalid platform" + exit + ;; +esac + +if test "$isrelease" = "y" ; then + EXTRAFLAGS="$EXTRAFLAGS -DNO_ASSERTS" +else + STRIPFLAG= +fi + +if test "$skipcompile" = "n" ; then + rm -f *.o */*.o *.a > /dev/null 2>&1 +fi + +rm -f *.a > /dev/null 2>&1 + + + +FINALCFLAGS="$FINALCFLAGS $EXTRAFLAGS -DUSEENUM -DTHREED" +# +# NOTE: Used to use make here but had problems with using remsh to run +# make multiple times to get 64 bit and 32 bit versions of libraries.... +# +# $MAKECMD $MAKEWHAT AR=$AR CC=$CCOMP LINKFLAGS="$LINKFLAGS" STRIPFLAG=$STRIPFLAG CFLAGS="$EXTRAFLAGS -DUSEENUM -DTHREED $FINALCFLAGS" +# +# +# + +cd tecsrc + +BASELIST=`/bin/ls -1 *.cpp` + +OBJLIST= +for file in $BASELIST +do + OBJNAME=`echo $file | sed 's/\.cpp/.o/'` + OBJLIST="$OBJLIST tecsrc/$OBJNAME" +done + + + +if test "$skipcompile" = "n" ; then + for file in $BASELIST + do + case $file in + tecxxx.cpp) ARCHIVEFLAG=-DMAKEARCHIVE;; + arrlist.cpp) ARCHIVEFLAG=-DMAKEARCHIVE;; + datautil.cpp) ARCHIVEFLAG=-DMAKEARCHIVE;; + *) ARCHIVEFLAG= ;; + esac + echo "$CCOMP $FINALCFLAGS $ARCHIVEFLAG -c $file" + $CCOMP $FINALCFLAGS $ARCHIVEFLAG -c $file + done +fi + +cd .. + +pwd + + +echo "$AR $ARFLAGS tecio.a $OBJLIST" +$AR $ARFLAGS tecio.a $OBJLIST +if test -f /bin/ranlib ; then + /bin/ranlib tecio.a; +elif test -f /usr/bin/ranlib ; then + /usr/bin/ranlib tecio.a; +elif test -f /usr/ucb/ranlib ; then + /usr/ucb/ranlib tecio.a; +fi + +echo "$CCOMP -I./tecsrc -DMAKEARCHIVE $FINALCFLAGS -c pltview.cpp" +$CCOMP -I./tecsrc -DMAKEARCHIVE $FINALCFLAGS -c pltview.cpp + +echo "$CCOMP $FINALCFLAGS pltview.o tecio.a $LINKFLAGS $LINKLIBS $STRIPFLAG -lm -o pltview" +$CCOMP $FINALCFLAGS pltview.o tecio.a $LINKFLAGS $LINKLIBS $STRIPFLAG -lm -o pltview diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/arrow/Arrow.plt b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/arrow/Arrow.plt new file mode 100644 index 0000000000000000000000000000000000000000..ee207b04df6aaba46a2454f97f3ce51226b5c642 GIT binary patch literal 1412 zcmbW0JxT;Y5QS&`SvL?|#K6E{L@zLlk%Qz;DS9i^>EbndZ7sa5H1=|um30K0Sa4FnHeJ0MMzKyYG@r6L{RJa$8 z1=i=ni$Lv-K+S`IO$i6Jmt}{Mk0NhJ&PK08V(I!^x)9a{{2hUPPXzkqY|c6td=Fyu zl?%Iqd*^QSjD1E6D(D%BjsuZX-BYY9ED93>xil{stmPg9Wql9sOpo-$8(j<7fBK@Q zX<=TVFZU+5X`{CxZ|oYgi#XeU;9eQ{eWR(fDro<%mccVS?)7HJ&5oPf;y&N(db8tZ z@6*av%(QU02j46+pB4JTg23!C=Fa;~B4jY%4{HE^S70vG!f4hwCbzC7MvgV?<8J`| zNQ6?qn!m-G|1@X6-%{D!xNluG<7+W)9$#;5_P*BN`+EPleOtVFdZMc6k8$WLo!guW j`Cnju`*dd1dX_Mn`M}iSW3EZ(;n9SOpMN=%I +#include "TECIO.h" + +int main() +{ + /* DOCSTART:arrow_tecini.txt*/ + INTEGER4 Debug = 1; + INTEGER4 VIsDouble = 1; + INTEGER4 FileType = 0; + INTEGER4 I; + + /* Open the file and write the Tecplot datafile + * header information + */ + I = TECINI112((char*)"Multiple polyhedral zones", /* Name of the entire + * dataset. + */ + (char*)"X Y Z P", /* Defines the variables for the data + * file. Each zone must contain each of + * the variables listed here. The order + * of the variables in the list is used + * to define the variable number (e.g. + * X is Var 1). + */ + (char*)"Arrow.plt", + (char*)".", /* Scratch Directory */ + &FileType, + &Debug, + &VIsDouble); + + /* DOCEND */ + + + /* After TECINI is called, call TECZNE to create one or more + * zones for your data file. In this example, Zone 1 contains a + * single rectangular solid created as a face-based finite-element + * (i.e. polyhedral zone). The zone has eight points (or nodes), + * six faces and one element. + */ + /* DOCSTART:arrow_teczne_rect.txt*/ + /* TECZNE Parameters */ + INTEGER4 ZoneType = 7; /* sets the zone type + * to polyhedral */ + INTEGER4 NumPts_Rect = 8; + INTEGER4 NumElems_Rect = 1; + INTEGER4 NumFaces_Rect = 6; + INTEGER4 ICellMax = 0; /* not used */ + INTEGER4 JCellMax = 0; /* not used */ + INTEGER4 KCellMax = 0; /* not used */ + double SolutionTime = 0.0; + INTEGER4 StrandID = 0; + INTEGER4 ParentZone = 0; + INTEGER4 IsBlock = 1; + INTEGER4 NumFaceConnections = 0; /* not used */ + INTEGER4 FaceNeighborMode = 1; /* not used */ + INTEGER4 SharConn = 0; + + /* In a rectangular solid, each face is composed of four nodes. + * As such, the total number of face nodes is twenty-four (four + * nodes for each of the six faces). + */ + INTEGER4 TotalNumFaceNodes_Rect = 24; + + /* There is one connected boundary face in this zone (the face on + * the rectangle adjacent to the arrowhead). Refer to the Data + * Format Guide for additional information. */ + INTEGER4 NumConnBndryFaces_Rect = 1; + + /* The connected boundary face has one connection, the face on + * the bottom of the arrowhead. A connection is an element-zone + * tuple that indicates a neighboring element (and its zone) when + * the neighboring element is in a different zone. Generally, + * there will be one boundary connection for each boundary face. + */ + INTEGER4 TotalNumBndryConns_Rect = 1; + + /* For illustrative purposes, the grid variables (X, Y, and Z) + * are nodal variables (i.e. ValueLocation = 1), and the pressure + * variable (P) is a cell-centered variable (i.e. + * ValueLocation = 0). + */ + INTEGER4 ValueLocation[4] = { 1, 1, 1, 0 }; + + I = TECZNE112((char*)"Zone 1: Rectangular Solid", + &ZoneType, + &NumPts_Rect, + &NumElems_Rect, + &NumFaces_Rect, + &ICellMax, + &JCellMax, + &KCellMax, + &SolutionTime, + &StrandID, + &ParentZone, + &IsBlock, + &NumFaceConnections, + &FaceNeighborMode, + &TotalNumFaceNodes_Rect, + &NumConnBndryFaces_Rect, + &TotalNumBndryConns_Rect, + NULL, + ValueLocation, + NULL, + &SharConn); + + /* DOCEND */ + + /* DOCSTART:arrow_tecdat_rect.txt*/ + //set variable values (X_Rect, Y_Rect, Z_Rect & P_Rect) + double *X_Rect = new double[NumPts_Rect]; + double *Y_Rect = new double[NumPts_Rect]; + double *Z_Rect = new double[NumPts_Rect]; + double *P_Rect = new double[NumElems_Rect]; + + for (INTEGER4 ii = 0; ii <= NumPts_Rect / 2; ii += 4) + { + X_Rect[ii] = 0; + X_Rect[ii+1] = 3; + X_Rect[ii+2] = 3; + X_Rect[ii+3] = 0; + + Y_Rect[ii] = 3; + Y_Rect[ii+1] = 3; + Y_Rect[ii+2] = 1; + Y_Rect[ii+3] = 1; + } + + for (INTEGER4 ii = 0; ii < 4; ii++) + Z_Rect[ii] = 0; + + for (INTEGER4 ii = 4; ii < NumPts_Rect; ii++) + Z_Rect[ii] = -2; + + P_Rect[0] = 10; + + + INTEGER4 IsDouble = 1; + I = TECDAT112(&NumPts_Rect, X_Rect, &IsDouble); + I = TECDAT112(&NumPts_Rect, Y_Rect, &IsDouble); + I = TECDAT112(&NumPts_Rect, Z_Rect, &IsDouble); + I = TECDAT112(&NumElems_Rect, P_Rect, &IsDouble); + /* DOCEND */ + + /* DOCSTART:arrow_facenodes_rect.txt*/ + + /* The FaceNodeCounts array is used to describe the number of + * nodes in each face of the zone. The first value in the array + * is the number of nodes in Face 1, the second value is the + * number of nodes in Face 2 and so forth. In this example, each + * face of the zone has four nodes. + */ + + INTEGER4 *FaceNodeCounts_Rect = new INTEGER4[NumFaces_Rect]; + //For this particular zone, each face has the 4 nodes + for (INTEGER4 ii = 0; ii < NumFaces_Rect; ii++) + FaceNodeCounts_Rect[ii] = 4; + + /* The FaceNodes array is used to specify the nodes that compose + * each face. For each face (n of N), the number of nodes used + * to define the face is specified by the nth value in the + * FaceNodeCounts array. For example, if the first value in the + * FaceNodeCounts array is 4 (indicating Face 1 is composed of + * four nodes), the first four values in the FaceNodes array are + * the node numbers of the nodes in Face 1. + * + * ------------ + * WARNING + * When providing the node numbers for each face, you must + * provide the node numbers in a consistent order (either + * clockwise or counter-clockwise. Providing the node numbers + * out of order results in contorted faces. + * ------------ + */ + + INTEGER4 *FaceNodes_Rect = new INTEGER4[TotalNumFaceNodes_Rect]; + + //Nodes for Face 1 + FaceNodes_Rect[0] = 1; + FaceNodes_Rect[1] = 2; + FaceNodes_Rect[2] = 3; + FaceNodes_Rect[3] = 4; + + //Nodes for Face 2 + FaceNodes_Rect[4] = 1; + FaceNodes_Rect[5] = 4; + FaceNodes_Rect[6] = 8; + FaceNodes_Rect[7] = 5; + + //Nodes for Face 3 + FaceNodes_Rect[8] = 5; + FaceNodes_Rect[9] = 8; + FaceNodes_Rect[10] = 7; + FaceNodes_Rect[11] = 6; + + //Nodes for Face 4 + FaceNodes_Rect[12] = 2; + FaceNodes_Rect[13] = 6; + FaceNodes_Rect[14] = 7; + FaceNodes_Rect[15] = 3; + +//Nodes for Face 5 + FaceNodes_Rect[16] = 6; + FaceNodes_Rect[17] = 2; + FaceNodes_Rect[18] = 1; + FaceNodes_Rect[19] = 5; + + //Nodes for Face 6 + FaceNodes_Rect[20] = 3; + FaceNodes_Rect[21] = 7; + FaceNodes_Rect[22] = 8; + FaceNodes_Rect[23] = 4; + /* DOCEND */ + + /* DOCSTART:arrow_neighbors_rect.txt*/ + INTEGER4 *FaceLeftElems_Rect = new INTEGER4[NumFaces_Rect]; + INTEGER4 *FaceRightElems_Rect = new INTEGER4[NumFaces_Rect]; + + /* Since this zone has just one element, all leftelems are + * NoNeighboring Element and all right elems are itself + */ + for (INTEGER4 ii = 0; ii < NumFaces_Rect; ii++) + { + FaceRightElems_Rect[ii] = 1; + FaceLeftElems_Rect[ii] = 0; + } + + /* The negative value in the FaceLeftElems array indicates that + * the face is connected to an element in another zone. In this + * case, Face 4 is connected to a face in Zone 2 (to be defined + * later in the example). The FaceBoundaryConnectionElems array + * lists all of the element numbers in other zones that the + * current zone shares boundary connections with. Similarly, the + * FaceBoundaryConnectionZones array lists all of the zone numbers + * with which the current zone shares boundaries. A negative + * value in the FaceLeftElems or FaceRightElems array indicates + * the position within these arrays that defines the neighboring + * element and zone for a face. + * + * For example, if the FaceBoundaryConnectionElems array is: + * [1 8 2] and the FaceBoundaryConnectionZones array is: [2 5 3], + * a FaceLeftElems or FaceRightElems value of -2 indicates that + * the face in question has a boundary connection with Element 8 + * in Zone 5. + */ + FaceLeftElems_Rect[3] = -1; + /* DOCEND */ + + /* DOCSTART:arrow_tecpoly_rect.txt*/ + /* The FaceBndryConnectionCounts array is used to define the + * number of boundary connections for each face that has a + * boundary connection. For example, if a zone has three boundary + * connections in total (NumConnectedBoundaryFaces), two of those + * boundary connections are in one face, and the remaining + * boundary connection is in a second face, the + * FaceBndryConnectionCounts array would be: [2 1]. + * In this example, the total number of connected boundary faces + * (specified via TECZNE) is equal to one, so the + * FaceBoundaryConnectionCounts array contains a single value (1). + */ + INTEGER4 *FaceBndryConnCounts_Rect = new INTEGER4[NumConnBndryFaces_Rect]; + FaceBndryConnCounts_Rect[0] = 1; + + /* The value(s) in the FaceBndryConnectionElems and + * FaceBndryConnectionZones arrays specify the element number and + * zone number, respectively, that a given boundary connection is + * connected to. In this case, the boundary connection face is + * connected to Element 1 in Zone 2. + */ + INTEGER4 *FaceBndryConnElems_Rect = new INTEGER4[TotalNumBndryConns_Rect]; + INTEGER4 *FaceBndryConnZones_Rect = new INTEGER4[TotalNumBndryConns_Rect]; + + FaceBndryConnElems_Rect[0] = 1; + FaceBndryConnZones_Rect[0] = 2; + + I = TECPOLY112(FaceNodeCounts_Rect, + FaceNodes_Rect, + FaceLeftElems_Rect, + FaceRightElems_Rect, + FaceBndryConnCounts_Rect, + FaceBndryConnElems_Rect, + FaceBndryConnZones_Rect); + + /* cleanup */ + delete X_Rect; + delete Y_Rect; + delete Z_Rect; + delete P_Rect; + delete FaceNodeCounts_Rect; + delete FaceNodes_Rect; + delete FaceLeftElems_Rect; + delete FaceRightElems_Rect; + delete FaceBndryConnCounts_Rect; + delete FaceBndryConnElems_Rect; + delete FaceBndryConnZones_Rect; + /* DOCEND */ + + /* The data for Zone 1 has been written to the data file, so we + * are ready to create Zone 2. For simplicity, we will reuse many + * of the variables created for the rectangular zone that are not + * relevant to this tutorial. */ + + /* Zone 2 (the arrowhead or prism) has a single element composed + * of six nodes and five faces. + */ + + /* DOCSTART:arrow_teczne_prism.txt*/ + //TECZNE Parameters + INTEGER4 NumPts_Prism = 6; + INTEGER4 NumElems_Prism = 1; + INTEGER4 NumFaces_Prism = 5; + + /* The prism is composed of two triangular faces and three + * rectangular faces. The total number of face nodes is the sum + * of the nodes in each triangular face (2 times 3) and the nodes + * in each rectangular face (3 times 4). + */ + INTEGER4 TotalNumFaceNodes_Prism = 18; + + /* As with Zone 1, Zone 2 has one connected boundary face, the + * face that is connected to Zone 1. + */ + INTEGER4 NumConnBndryFaces_Prism = 1; + + /* In this case, we have set the total number of boundary + * connections for the connected face to two. The first boundary + * connection is the connection to Zone 1. The second boundary + * connection is used to indicate that the face is only partially + * obscured by the face from Zone 1. If we omitted the second + * boundary connection, the connected face of the prism would + * disappear if the rectangular zone was deactivated. + */ + INTEGER4 TotalNumBndryConns_Prism = 2; + + I = TECZNE112((char*)"Zone 2: Prism", + &ZoneType, + &NumPts_Prism, + &NumElems_Prism, + &NumFaces_Prism, + &ICellMax, + &JCellMax, + &KCellMax, + &SolutionTime, + &StrandID, + &ParentZone, + &IsBlock, + &NumFaceConnections, + &FaceNeighborMode, + &TotalNumFaceNodes_Prism, + &NumConnBndryFaces_Prism, + &TotalNumBndryConns_Prism, + NULL, + ValueLocation, + NULL, + &SharConn); + /* DOCEND */ + + /* DOCSTART:arrow_tecdat_prism.txt*/ + + + double *X_Prism = new double[NumPts_Prism]; + double *Y_Prism = new double[NumPts_Prism]; + double *Z_Prism = new double[NumPts_Prism]; + + + /* Set the X and Y variable values, one z-plane at a time */ + double ZVal = 0; + for (INTEGER4 ii = 0; ii < 2; ii++) + { + // triangle in Z=ZVal plane + X_Prism[3*ii] = 3; + Y_Prism[3*ii] = 4; + Z_Prism[3*ii] = ZVal; + + X_Prism[3*ii+1] = 7; + Y_Prism[3*ii+1] = 2; + Z_Prism[3*ii+1] = ZVal; + + X_Prism[3*ii+2] = 3; + Y_Prism[3*ii+2] = 0; + Z_Prism[3*ii+2] = ZVal; + + ZVal = ZVal - 2; + } + + /* When we called TecZne, we specified that the variable 4 + * (pressure) is cell-centered. As such, only NumElements number + * of values needs to be written to the data file for the pressure + * variable. + */ + double *P_Prism = new double[NumElems_Prism]; + P_Prism[0] = 20; + + I = TECDAT112(&NumPts_Prism, X_Prism, &IsDouble); + I = TECDAT112(&NumPts_Prism, Y_Prism, &IsDouble); + I = TECDAT112(&NumPts_Prism, Z_Prism, &IsDouble); + I = TECDAT112(&NumElems_Prism, P_Prism, &IsDouble); + /* DOCEND */ + + /* DOCSTART:arrow_facemap_prism.txt*/ + INTEGER4 *FaceNodeCounts_Prism = new INTEGER4[NumFaces_Prism]; + INTEGER4 *FaceNodes_Prism = new INTEGER4[TotalNumFaceNodes_Prism]; + + /* Because of the way we chose to number our faces, the first + * three faces are rectangular and the last two are triangular. + * The numbering of the faces is arbitrary, but the faces must + * be referred to consistently. + */ + for (INTEGER4 ii = 0; ii < 3; ii++) + FaceNodeCounts_Prism[ii] = 4; + + for (INTEGER4 ii = 3; ii < NumFaces_Prism; ii++) + FaceNodeCounts_Prism[ii] = 3; + + //Nodes for Face 1 + FaceNodes_Prism[0] = 1; + FaceNodes_Prism[1] = 3; + FaceNodes_Prism[2] = 6; + FaceNodes_Prism[3] = 4; + + //Nodes for Face 2 + FaceNodes_Prism[4] = 1; + FaceNodes_Prism[5] = 4; + FaceNodes_Prism[6] = 5; + FaceNodes_Prism[7] = 2; + + //Nodes for Face 3 + FaceNodes_Prism[8] = 3; + FaceNodes_Prism[9] = 2; + FaceNodes_Prism[10] = 5; + FaceNodes_Prism[11] = 6; + + //Nodes for Face 4 + FaceNodes_Prism[12] = 5; + FaceNodes_Prism[13] = 4; + FaceNodes_Prism[14] = 6; + +//Nodes for Face 5 + FaceNodes_Prism[15] = 1; + FaceNodes_Prism[16] = 2; + FaceNodes_Prism[17] = 3; + /* DOCEND */ + + /* DOCSTART:arrow_neighbors_prism.txt*/ + /* Since this zone has just one element, all leftelems are + * NoNeighboring Element and all right elems are itself. + */ + INTEGER4 *FaceLeftElems_Prism = new INTEGER4[NumFaces_Prism]; + INTEGER4 *FaceRightElems_Prism = new INTEGER4[NumFaces_Prism]; + + for (INTEGER4 ii = 0; ii < NumFaces_Prism; ii++) + { + FaceRightElems_Prism[ii] = 1; + FaceLeftElems_Prism[ii] = 0; + } + + /* The negative value in the FaceLeftElems array indicates that + * the face is connected to an element in another zone. In this + * case, Face 1 is connected to a face in Zone 1 (as indicated in + * Line 6). The FaceBoundaryConnectionElems array lists all of + * the element numbers in other zones that the current zone shares + * boundary connections with. Similarly, the + * FaceBoundaryConnectionZones array lists all of the zone numbers + * with which the current zone shares boundaries. A negative + * value in the FaceLeftElems or FaceRightElems array indicates + * the position within these arrays that defines the neighboring + * element and zone for a face. + */ + FaceLeftElems_Prism[0] = -1; + /* DOCEND */ + + /* DOCSTART:arrow_tecpoly_prism.txt*/ + + INTEGER4 *FaceBndryConnCounts_Prism = new INTEGER4[NumConnBndryFaces_Prism]; + FaceBndryConnCounts_Prism[0] = 2; + + INTEGER4 *FaceBndryConnElems_Prism = new INTEGER4[TotalNumBndryConns_Prism]; + INTEGER4 *FaceBndryConnZones_Prism = new INTEGER4[TotalNumBndryConns_Prism]; + + /* As previously mentioned, a connected boundary face is a face + * that has either multiple neighboring faces or neighbor(s) that + * belong to another zone. Those cases are sufficient when the + * combination of all of the face’s neighbors completely cover the + * face. However, there are some cases (such as the bottom of the + * arrowhead) where the face is not completely covered by its + * neighbors. In those cases the face is referred to as “partially + * obscured”. A partially obscured face is indicated by + * incrementing the value in TotalNumConnectedBoundaryFaces and + * entering a value of 0 in both the FaceBndryConnectionElems and + * FaceBoundaryConnectionZones arrays for the boundary connection + * for the partially obscured face. + */ + FaceBndryConnElems_Prism[0] = 0; + FaceBndryConnZones_Prism[0] = 0; + + /* Indicates that Face 1 is connected to Element 1 in Zone 1. */ + FaceBndryConnElems_Prism[1] = 1; + FaceBndryConnZones_Prism[1] = 1; + + I = TECPOLY112(FaceNodeCounts_Prism, + FaceNodes_Prism, + FaceLeftElems_Prism, + FaceRightElems_Prism, + FaceBndryConnCounts_Prism, + FaceBndryConnElems_Prism, + FaceBndryConnZones_Prism); + + /* cleanup */ + delete X_Prism; + delete Y_Prism; + delete Z_Prism; + delete P_Prism; + delete FaceNodeCounts_Prism; + delete FaceNodes_Prism; + delete FaceLeftElems_Prism; + delete FaceRightElems_Prism; + delete FaceBndryConnCounts_Prism; + delete FaceBndryConnElems_Prism; + delete FaceBndryConnZones_Prism; + /* DOCEND */ + + /* DOCSTART:arrow_tecend.txt*/ + I = TECEND112(); + /* DOCEND */ + + return 0; +} diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/arrow/arrow.vcproj b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/arrow/arrow.vcproj new file mode 100644 index 0000000000..31f69eedf1 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/arrow/arrow.vcproj @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/Makefile b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/Makefile new file mode 100644 index 0000000000..2c6009b073 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/Makefile @@ -0,0 +1,11 @@ +# Set to appropriate C++ compiler +CPP=g++ +CPPFLAGS=-I../../tecsrc ../../tecio.a +EXECUTABLE=comtest +FILES=$(EXECUTABLE).c + +build: + $(CPP) $(FILES) $(CPPFLAGS) -o $(EXECUTABLE) + +clean: + rm -f $(EXECUTABLE) diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtest.c b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtest.c new file mode 100644 index 0000000000..c290dcef40 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtest.c @@ -0,0 +1,492 @@ +/* + * Complex example C program to write a + * binary data file for Tecplot. This example + * does the following: + * + * 1. Open a data file called "field.plt." + * 2. Open a data file called "line.plt." + * 3. Assign values for X, Y and P. These will be used + * in both the ordered and finite-element data files. + * 4. Write out an ordered zone dimensioned 4 x 5 to "field.plt." + * 5. Assign values for XL and YL arrays. + * 6. Write out data for line plot to "line.plt." Make the data + * use double precision. + * 7. Write out a finite-element zone to "field.plt." + * 8. Write out a text record to "field.plt." + * 9. Write out a geometry (circle) record to "field.plt." + * 10. Close file 1. + * 11. Close file 2. + */ + +#include +#include +#include "TECIO.h" + +int main(void) +{ + float X[5][4], Y[5][4], P[5][4]; + double XL[50], YL[50]; + double SolTime; + INTEGER4 Debug, I, J, K, L, III, NPts, NElm, DIsDouble, VIsDouble, IMax, JMax, KMax; + INTEGER4 ICellMax, JCellMax, KCellMax, ZoneType, Clipping; + INTEGER4 StrandID, ParentZn, FieldFileType, LineFileType; + INTEGER4 SharingZone[3] = {0, 0, 0}; + INTEGER4 IsBlock, NumFaceConnections, FaceNeighborMode, ShareConnectivityFromZone; + INTEGER4 NM[12][4]; + double XP, YP, ZP, FH, LineSpacing, PatternLength; + double BoxMargin, BoxLineThickness, TextAngle; + INTEGER4 AttachToZone, Zone, Scope, PositionCoordSys, FontType, HeightUnits; + INTEGER4 IsFilled, GeomType, LinePattern, NumEllipsePts; + INTEGER4 Anchor, BoxType, BoxColor, BoxFillColor, TextColor, Color, FillColor; + INTEGER4 ArrowheadStyle, ArrowheadAttachment, NumSegments, NumSegPts[1]; + double LineThickness, ArrowheadSize, ArrowheadAngle; + float XGeomData[1], YGeomData[1], ZGeomData[1]; + enum FileType { FULL = 0, GRID = 1, SOLUTION = 2 }; + + Debug = 2; + VIsDouble = 0; + DIsDouble = 0; + FieldFileType = FULL; + LineFileType = FULL; + /* + * Open order.plt and write the header information. + */ + I = TECINI112((char*)"DATASET WITH ONE ORDERED ZONE AND ONE FE-QUAD ZONE OVER 2 TIME STEPS", + (char*)"X Y P", + (char*)"field.plt", + (char*)".", + &FieldFileType, + &Debug, + &VIsDouble); + /* + * Open line.plt and write the header information. + */ + VIsDouble = 1; + I = TECINI112((char*)"DATASET WITH ONE I-ORDERED ZONE", + (char*)"X Y", + (char*)"line.plt", + (char*)".", + &LineFileType, + &Debug, + &VIsDouble); + + /* + * Calculate values for the field variables. + */ + for (J = 0; J < 5; J++) + for (I = 0; I < 4; I++) + { + X[J][I] = (float)(I + 1); + Y[J][I] = (float)(J + 1); + P[J][I] = (float)((I + 1) * (J + 1)); + } + + /* + * Make sure writing to file #1. + */ + III = 1; + I = TECFIL112(&III); + + /* + * Write the zone header information for the ordered zone. + */ + IMax = 4; + JMax = 5; + KMax = 1; + ICellMax = 0; + JCellMax = 0; + KCellMax = 0; + ZoneType = 0; + SolTime = 10.0; + StrandID = 1; + ParentZn = 0; + IsBlock = 1; + NumFaceConnections = 0; + FaceNeighborMode = 0; + ShareConnectivityFromZone = 0; + I = TECZNE112((char*)"Ordered Zone 1", + &ZoneType, + &IMax, + &JMax, + &KMax, + &ICellMax, + &JCellMax, + &KCellMax, + &SolTime, + &StrandID, + &ParentZn, + &IsBlock, + &NumFaceConnections, + &FaceNeighborMode, + NULL, /* PassiveVarList */ + NULL, /* ValueLocation */ + NULL, /* ShareVarFromZone */ + 0, /* TotalNumFaceNodes */ + 0, /* NumConnectedBoundaryFaces */ + 0, /* TotalNumBoundaryConnections */ + &ShareConnectivityFromZone); + /* + * Write out the field data for the ordered zone. + */ + III = IMax * JMax; + I = TECDAT112(&III, &X[0][0], &DIsDouble); + I = TECDAT112(&III, &Y[0][0], &DIsDouble); + I = TECDAT112(&III, &P[0][0], &DIsDouble); + + /* + * Calculate values for the I-ordered zone. + */ + + for (I = 0; I < 50; I++) + { + XL[I] = I + 1; + YL[I] = sin((double)(I + 1) / 20.0); + } + /* + * Switch to the "line.plt" file (file number 2) + * and write out the line plot data. + */ + + III = 2; + I = TECFIL112(&III); + + /* + * Write the zone header information for the XY-data. + */ + IMax = 50; + JMax = 1; + KMax = 1; + SolTime = 0.0; + StrandID = 0; /* StaticZone */ + I = TECZNE112((char*)"XY Line plot", + &ZoneType, + &IMax, + &JMax, + &KMax, + &ICellMax, + &JCellMax, + &KCellMax, + &SolTime, + &StrandID, + &ParentZn, + &IsBlock, + &NumFaceConnections, + &FaceNeighborMode, + 0, /* TotalNumFaceNodes */ + 0, /* NumConnectedBoundaryFaces */ + 0, /* TotalNumBoundaryConnections */ + NULL, /* PassiveVarList */ + NULL, /* ValueLocation */ + NULL, /* ShareVarFromZone */ + &ShareConnectivityFromZone); + /* + * Write out the line plot. + */ + DIsDouble = 1; + III = IMax; + I = TECDAT112(&III, (float *) & XL[0], &DIsDouble); + I = TECDAT112(&III, (float *) & YL[0], &DIsDouble); + + /* + * Switch back to the field plot file and write out + * the finite-element zone. + */ + III = 1; + I = TECFIL112(&III); + + /* + * Move the coordinates so this zone's not on top of the other + */ + for (J = 0; J < 5; J++) + for (I = 0; I < 4; I++) + { + X[J][I] = (float)(I + 6); + Y[J][I] = (float)(J + 1); + P[J][I] = (float)((I + 1) * (J + 1)); + } + + /* + * Write the zone header information for the finite-element zone. + */ + ZoneType = 3; /* FEQuad */ + NPts = 20; /* Number of points */ + NElm = 12; /* Number of elements */ + KMax = 0; /* Unused */ + SolTime = 10.0; + StrandID = 2; + I = TECZNE112((char*)"Finite Zone 1", + &ZoneType, + &NPts, + &NElm, + &KMax, + &ICellMax, + &JCellMax, + &KCellMax, + &SolTime, + &StrandID, + &ParentZn, + &IsBlock, + &NumFaceConnections, + &FaceNeighborMode, + 0, /* TotalNumFaceNodes */ + 0, /* NumConnectedBoundaryFaces */ + 0, /* TotalNumBoundaryConnections */ + NULL, /* PassiveVarList */ + NULL, /* ValueLocation */ + NULL, /* ShareVarFromZone */ + &ShareConnectivityFromZone); + /* + * Write out the field data for the finite-element zone. + */ + IMax = 4; + JMax = 5; + III = IMax * JMax; + DIsDouble = 0; + I = TECDAT112(&III, &X[0][0], &DIsDouble); + I = TECDAT112(&III, &Y[0][0], &DIsDouble); + I = TECDAT112(&III, &P[0][0], &DIsDouble); + + /* + * Calculate and then write out the connectivity list. + * Note: The NM array references cells starting with + * offset of 1. + */ + + for (I = 1; I < IMax; I++) + for (J = 1; J < JMax; J++) + { + K = I + (J - 1) * (IMax - 1); + L = I + (J - 1) * IMax; + NM[K-1][0] = L; + NM[K-1][1] = L + 1; + NM[K-1][2] = L + IMax + 1; + NM[K-1][3] = L + IMax; + } + + I = TECNOD112((INTEGER4 *)NM); + + /* + * Calculate values for the new solution variable. + */ + for (J = 0; J < 5; J++) + for (I = 0; I < 4; I++) + { + P[J][I] = (float)(2.0 * (I + 1) * (J + 1)); + } + + /* + * Write the zone header information for time step 2 + */ + ZoneType = 0; + IMax = 4; + JMax = 5; + KMax = 1; + SolTime = 20.0; + StrandID = 1; + SharingZone[0] = 1; + SharingZone[1] = 1; + SharingZone[2] = 0; /* solution variable is not shared */ + ShareConnectivityFromZone = 0; + + I = TECZNE112((char*)"Ordered Zone 2", + &ZoneType, + &IMax, + &JMax, + &KMax, + &ICellMax, + &JCellMax, + &KCellMax, + &SolTime, + &StrandID, + &ParentZn, + &IsBlock, + &NumFaceConnections, + &FaceNeighborMode, + 0, /* TotalNumFaceNodes */ + 0, /* NumConnectedBoundaryFaces */ + 0, /* TotalNumBoundaryConnections */ + NULL, + NULL, + SharingZone, + &ShareConnectivityFromZone); + + /* + * Write out the solution variable the grid variables are shared. + */ + IMax = 4; + JMax = 5; + III = IMax * JMax; + DIsDouble = 0; + I = TECDAT112(&III, &P[0][0], &DIsDouble); + + /* + * Calculate values for the new solution variable. + */ + for (J = 0; J < 5; J++) + for (I = 0; I < 4; I++) + { + P[J][I] = (float)(3.0 * (I + 1) * (J + 1)); + } + + /* + * Write another time step for the FEZone and share from the first + */ + ZoneType = 3; + SolTime = 20.0; + StrandID = 2; + KMax = 0; + SharingZone[0] = 2; + SharingZone[1] = 2; + SharingZone[2] = 0; /* solution variable is not shared */ + ShareConnectivityFromZone = 2; + I = TECZNE112((char*)"Finite Zone 2", + &ZoneType, + &NPts, + &NElm, + &KMax, + &ICellMax, + &JCellMax, + &KCellMax, + &SolTime, + &StrandID, + &ParentZn, + &IsBlock, + &NumFaceConnections, + &FaceNeighborMode, + 0, /* TotalNumFaceNodes */ + 0, /* NumConnectedBoundaryFaces */ + 0, /* TotalNumBoundaryConnections */ + NULL, /* PassiveVarList */ + NULL, /* ValueLocation */ + SharingZone, + &ShareConnectivityFromZone); + + /* + * Write out the solution variable the grid variables are shared. + */ + IMax = 4; + JMax = 5; + III = IMax * JMax; + DIsDouble = 0; + I = TECDAT112(&III, &P[0][0], &DIsDouble); + + /* + * Prepare to write out text record. Text is positioned + * at 0.5, 0.5 in frame units and has a height + * of 0.05 frame units. + */ + XP = 50.0; + YP = 50.0; + ZP = 0.0; + FH = 5.0; + Scope = 1; /* Local */ + Clipping = 1; /* Clip to frame */ + PositionCoordSys = 1; /* Frame */ + FontType = 1; /* Helv Bold */ + HeightUnits = 1; /* Frame */ + AttachToZone = 0; + Zone = 0; + BoxType = 0; /* None */ + BoxMargin = 5.0; + BoxLineThickness = 0.5; + BoxColor = 3; + BoxFillColor = 7; + TextAngle = 0.0; + Anchor = 0; /* Left */ + LineSpacing = 1.0; + TextColor = 0; /* Black */ + + III = TECTXT112(&XP, + &YP, + &ZP, + &PositionCoordSys, + &AttachToZone, + &Zone, + &FontType, + &HeightUnits, + &FH, + &BoxType, + &BoxMargin, + &BoxLineThickness, + &BoxColor, + &BoxFillColor, + &TextAngle, + &Anchor, + &LineSpacing, + &TextColor, + &Scope, + &Clipping, + (char*)"Hi Mom", + (char*)""); + + /* + * Prepare to write out geometry record (circle). Circle is + * positioned at 25, 25 (in frame units) and has a radius of + * 20 percent. Circle is drawn using a dashed line. + */ + + + XP = 25.0; + YP = 25.0; + ZP = 0.0; + IsFilled = 0; + Color = 0; + FillColor = 7; + GeomType = 3; /* Circle */ + LinePattern = 1; /* Dashed */ + LineThickness = 0.3; + PatternLength = 1.5; + NumEllipsePts = 72; + ArrowheadStyle = 0; + ArrowheadAttachment = 0; + ArrowheadSize = 0.1; + ArrowheadAngle = 15.0; + NumSegments = 1; + NumSegPts[0] = 1; + + XGeomData[0] = 20.0; + YGeomData[0] = 0.0; + ZGeomData[0] = 0.0; + + + III = TECGEO112(&XP, + &YP, + &ZP, + &PositionCoordSys, + &AttachToZone, + &Zone, + &Color, + &FillColor, + &IsFilled, + &GeomType, + &LinePattern, + &PatternLength, + &LineThickness, + &NumEllipsePts, + &ArrowheadStyle, + &ArrowheadAttachment, + &ArrowheadSize, + &ArrowheadAngle, + &Scope, + &Clipping, + &NumSegments, + NumSegPts, + &XGeomData[0], + &YGeomData[0], + &ZGeomData[0], + (char*)""); + + /* + * Close out file 1. + */ + I = TECEND112(); + + /* + * Close out file 2. + */ + III = 2; + I = TECFIL112(&III); + I = TECEND112(); + + return 0; +} diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtest.f b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtest.f new file mode 100644 index 0000000000..c8d6e2ce5a --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtest.f @@ -0,0 +1,467 @@ +C +C Complex example FORTRAN program to write a +C binary data file for Tecplot. This example +C does the following: +C +C 1. Open a data file called "field.plt." +C 2. Open a data file called "line.plt." +C 3. Assign values for X, Y and P. These will be used +C in both the ordered and FE data files. +C 4. Write out an ordered zone dimensioned 4 x 5 to "field.plt." +C 5. Assign values for XL and YL arrays. +C 6. Write out data for line plot to "line.plt." Make the data +C use double precision. +C 7. Write out a finite element zone to "field.plt." +C 8. Write out a text record to "field.plt." +C 9. Write out a geometry (circle) record to "field.plt." +C 10. Close file 1. +C 11. Close file 2. +C + Program ComplexTest + + Include "tecio.inc" + + REAL*4 X(4,5), Y(4,5), P(4,5) + REAL*8 XL(50), YL(50) + REAL*4 XLDummy(1), YLDummy(1) + EQUIVALENCE (XLDummy(1), XL(1)) + EQUIVALENCE (YLDummy(1), YL(1)) + REAL*8 SolTime + INTEGER*4 Debug,I,J,K,L,III,NPts,NElm,DIsDouble,VIsDouble + INTEGER*4 IMax,JMax,KMax,NM(4,12),FileType + INTEGER*4 StrandID,ParentZn + INTEGER*4 SharingZone(3) + REAL*8 XP, YP, ZP, FH, LineSpacing, PatternLength + REAL*8 BoxMargin, BoxLineThickness, TextAngle + INTEGER*4 AttachToZone, Zone, Scope, PositionCoordSys + INTEGER*4 Clipping + INTEGER*4 FontType, HeightUnits, Anchor, BoxType + INTEGER*4 IsFilled, GeomType, LinePattern, NumEllipsePts + INTEGER*4 BoxColor, BoxFillColor, TextColor, Color, FillColor + INTEGER*4 ArrowheadStyle, ArrowheadAttachment, NumSegments + INTEGER*4 NumSegPts(1) + REAL*8 LineThickness, ArrowheadSize, ArrowheadAngle + REAL*4 XGeomData(1), YGeomData(1), ZGeomData(1) + CHARACTER*1 NULCHAR + INTEGER*4 Zero + POINTER (NullPtr,Null) + INTEGER*4 Null(*) + + Debug = 2 + VIsDouble = 0 + FileType = 0 + DIsDouble = 0 + NULCHAR = CHAR(0) + Zero = 0 + NullPtr = 0 +C +C Open field.plt and write the header information. +C + I = TECINI112('DATASET WITH 1 ORDERED ZONE, '// + & '1 QUAD ZONE OVER 2 TIME STEPS'//NULCHAR, + & 'X Y P'//NULCHAR, + & 'field.plt'//NULCHAR, + & '.'//NULCHAR, + & FileType, + & Debug, + & VIsDouble) +C +C Open line.plt and write the header information. +C + VIsDouble = 1 + I = TECINI112('DATASET WITH ONE I-ORDERED ZONE'//NULCHAR, + & 'X Y'//NULCHAR, + & 'line.plt'//NULCHAR, + & '.'//NULCHAR, + & FileType, + & Debug, + & VIsDouble) + +C +C Calculate values for the field variables. +C + Do 10 J = 1,5 + Do 10 I = 1,4 + X(I,J) = I + Y(I,J) = J + P(I,J) = I*J + 10 Continue + +C +C Make sure writing to file #1. +C + III = 1 + I = TECFIL112(III) + +C +C Write the zone header information for the ordered zone. +C + IMax = 4 + JMax = 5 + KMax = 1 + SolTime = 10.0 + StrandID = 1 + ParentZn = 0 + I = TECZNE112('Ordered Zone 1'//NULCHAR, + & 0, ! ZONETYPE + & IMax, + & JMax, + & KMax, + & 0, + & 0, + & 0, + & SolTime, + & StrandID, + & ParentZn, + & 1, ! ISBLOCK + & 0, ! NumFaceConnections + & 0, ! FaceNeighborMode + & 0, ! TotalNumFaceNodes + & 0, ! NumConnectedBoundaryFaces + & 0, ! TotalNumBoundaryConnections + & Null, ! PassiveVarList + & Null, ! ValueLocation + & Null, ! ShareVarFromZone + & 0) ! ShareConnectivityFromZone) + +C +C Write out the field data for the ordered zone. +C + III = IMax*JMax + I = TECDAT112(III,X,DIsDouble) + I = TECDAT112(III,Y,DIsDouble) + I = TECDAT112(III,P,DIsDouble) + +C +C Calculate values for the I-ordered zone. +C + + Do 20 I = 1,50 + XL(I) = I + YL(I) = sin(I/20.0) + 20 Continue +C +C Switch to the 'line.plt' file (file number 2) +C and write out the line plot data. +C + III = 2 + I = TECFIL112(III) +C +C Write the zone header information for the XY-data. +C + IMax = 50 + JMax = 1 + KMax = 1 + SolTime = 0.0 + StrandID = 0 + I = TECZNE112('XY Line plot'//NULCHAR, + & 0, + & IMax, + & JMax, + & KMax, + & 0, + & 0, + & 0, + & SolTime, + & StrandID, + & ParentZn, + & 1, + & 0, + & 0, + & 0, + & 0, + & 0, + & Null, + & Null, + & Null, + & 0) +C +C Write out the line plot. +C + DIsDouble = 1 + III = IMax + I = TECDAT112(III,XLDummy,DIsDouble) + I = TECDAT112(III,YLDummy,DIsDouble) + +C +C Switch back to the field plot file and write out +C the finite-element zone. +C + III = 1 + I = TECFIL112(III) +C +C Move the coordinates so this zone's not on top of the other +C + Do 30 J = 1,5 + Do 30 I = 1,4 + X(I,J) = I+5 + Y(I,J) = J + P(I,J) = I*J + 30 Continue +C +C Write the zone header information for the finite-element zone. +C + NPts = 20 + NElm = 12 + KMax = 1 + SolTime = 10.0 + StrandID = 2 + I = TECZNE112('Finite Zone 1'//NULCHAR, + & 3, ! FEQUADRILATERAL + & NPts, + & NElm, + & KMax, + & 0, + & 0, + & 0, + & SolTime, + & StrandID, + & ParentZn, + & 1, + & 0, + & 0, + & 0, + & 0, + & 0, + & Null, + & Null, + & Null, + & 0) +C +C Write out the field data for the finite-element zone. +C + IMax = 4 + JMax = 5 + III = IMax*JMax + DIsDouble = 0 + I = TECDAT112(III,X,DIsDouble) + I = TECDAT112(III,Y,DIsDouble) + I = TECDAT112(III,P,DIsDouble) + +C +C Calculate and then write out the connectivity list. +C Note: The NM array references cells starting with +C offset of 1. +C + + Do 40 I = 1,IMax-1 + Do 40 J = 1,JMax-1 + K = I+(J-1)*(IMax-1) + L = I+(J-1)*IMax + NM(1,K) = L + NM(2,K) = L+1 + NM(3,K) = L+IMax+1 + NM(4,K) = L+IMax + 40 Continue + + I = TECNOD112(NM) +C +C Calculate vlues for the new solution variable. +C + Do 50 J = 1,5 + Do 50 I = 1,4 + P(I,J) = 2*I*J + 50 Continue +C +C Write the zone header information for time step 2 +C + IMax = 4 + JMax = 5 + KMax = 1 + SolTime = 20.0 + StrandID = 1 + SharingZone(1) = 1 + SharingZone(2) = 1 + SharingZone(3) = 0 + I = TECZNE112('Ordered Zone 2'//NULCHAR, + & 0, ! ORDERED + & IMax, + & JMax, + & KMax, + & 0, + & 0, + & 0, + & SolTime, + & StrandID, + & ParentZn, + & 1, + & 0, + & 0, + & 0, + & 0, + & 0, + & Null, + & Null, + & SharingZone, + & 0) +C +C Write out the solution variable the grid variables are shared. +C + IMax = 4 + JMax = 5 + III = IMax*JMax + DIsDouble = 0 + I = TECDAT112(III,P,DIsDouble) +C +C Calculate values for the new solution variable. +C + Do 60 J = 1,5 + Do 60 I = 1,4 + P(I,J) = 3*I*J + 60 Continue +C +C Write another time step for the FEZone and share from the first +C + SolTime = 20.0 + StrandID = 2 + KMax = 0 + SharingZone(1) = 2 + SharingZone(2) = 2 + SharingZone(3) = 0 + I = TECZNE112('Finite Zone 2'//NULCHAR, + & 3, ! FEQUADRILATERAL + & NPts, + & NElm, + & KMax, + & 0, + & 0, + & 0, + & SolTime, + & StrandID, + & ParentZn, + & 1, + & 0, + & 0, + & 0, + & 0, + & 0, + & Null, + & Null, + & SharingZone, + & 2) +C +C Write out the solution variable the grid variables are shared. +C + IMax = 4 + JMax = 5 + III = IMax*JMax + DIsDouble = 0 + I = TECDAT112(III,P,DIsDouble) + +C +C Prepare to write out text record. Text is positioned +C at 50, 50 in frame units and has a height 5 frame units. +C + XP = 50 + YP = 50 + FH = 5 + Scope = 1 + Clipping = 0 + PositionCoordSys = 1 + FontType = 1 + HeightUnits = 1 + AttachToZone = 0 + Zone = 0 + BoxType = 0 + BoxMargin = 5.0 + BoxLineThickness = 0.5 + BoxColor = 3 + BoxFillColor = 7 + TextAngle = 0.0 + Anchor = 0 + LineSpacing = 1.5 + TextColor = 0 + + III = TECTXT112(XP, + & YP, + & 0.0d0, + & PositionCoordSys, + & AttachToZone, + & Zone, + & FontType, + & HeightUnits, + & FH, + & BoxType, + & BoxMargin, + & BoxLineThickness, + & BoxColor, + & BoxFillColor, + & TextAngle, + & Anchor, + & LineSpacing, + & TextColor, + & Scope, + & Clipping, + & 'Hi Mom'//NULCHAR, + & NULCHAR) + +C +C Prepare to write out geometry record (circle). Circle is +C positioned at 25, 25 in frame units and has a radius of 30. +C Circle is drawn using a dashed line pattern. +C + + + XP = 25 + YP = 25 + ZP = 0.0 + IsFilled = 0 + Color = 0 + FillColor = 7 + GeomType = 2 + LinePattern = 1 + LineThickness = 0.3 + PatternLength = 1 + NumEllipsePts = 72 + ArrowheadStyle = 0 + ArrowheadAttachment = 0 + ArrowheadSize = 0.0 + ArrowheadAngle = 15.0 + NumSegments = 1 + NumSegPts(1) = 1 + + XGeomData(1) = 30 + YGeomData(1) = 0.0 + ZGeomData(1) = 0.0 + + + III = TECGEO112(XP, + & YP, + & ZP, + & PositionCoordSys, + & AttachToZone, + & Zone, + & Color, + & FillColor, + & IsFilled, + & GeomType, + & LinePattern, + & PatternLength, + & LineThickness, + & NumEllipsePts, + & ArrowheadStyle, + & ArrowheadAttachment, + & ArrowheadSize, + & ArrowheadAngle, + & Scope, + & Clipping, + & NumSegments, + & NumSegPts, + & XGeomData, + & YGeomData, + & ZGeomData, + & NULCHAR) + +C +C Close out file 1. +C + I = TECEND112() + +C +C Close out file 2. +C + III = 2 + I = TECFIL112(III) + I = TECEND112() + STOP + END diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtest.f90 b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtest.f90 new file mode 100644 index 0000000000..56b3d560c3 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtest.f90 @@ -0,0 +1,467 @@ +! +! Complex example FORTRAN program to write a +! binary data file for Tecplot. This example +! does the following: +! +! 1. Open a data file called "field.plt." +! 2. Open a data file called "line.plt." +! 3. Assign values for X, Y and P. These will be used +! in both the ordered and FE data files. +! 4. Write out an ordered zone dimensioned 4 x 5 to "field.plt." +! 5. Assign values for XL and YL arrays. +! 6. Write out data for line plot to "line.plt." Make the data +! use double precision. +! 7. Write out a finite element zone to "field.plt." +! 8. Write out a text record to "field.plt." +! 9. Write out a geometry (circle) record to "field.plt." +! 10. Close file 1. +! 11. Close file 2. +! + Program ComplexTest + + Include "tecio.f90" + + REAL*4 X(4,5), Y(4,5), P(4,5) + REAL*8 XL(50), YL(50) + REAL*4 XLDummy(1), YLDummy(1) + EQUIVALENCE (XLDummy(1), XL(1)) + EQUIVALENCE (YLDummy(1), YL(1)) + REAL*8 SolTime + INTEGER*4 Debug,I,J,K,L,III,NPts,NElm,DIsDouble,VIsDouble,FileType + INTEGER*4 IMax,JMax,KMax,NM(4,12) + INTEGER*4 StrandID,ParentZn + INTEGER*4 SharingZone(3) + REAL*8 XP, YP, ZP, FH, LineSpacing, PatternLength + REAL*8 BoxMargin, BoxLineThickness, TextAngle + INTEGER*4 AttachToZone, Zone, Scope, PositionCoordSys + INTEGER*4 Clipping + INTEGER*4 FontType, HeightUnits, Anchor, BoxType + INTEGER*4 IsFilled, GeomType, LinePattern, NumEllipsePts + INTEGER*4 BoxColor, BoxFillColor, TextColor, Color, FillColor + INTEGER*4 ArrowheadStyle, ArrowheadAttachment, NumSegments + INTEGER*4 NumSegPts(1) + REAL*8 LineThickness, ArrowheadSize, ArrowheadAngle + REAL*4 XGeomData(1), YGeomData(1), ZGeomData(1) + CHARACTER*1 NULCHAR + INTEGER*4 Zero + POINTER (NullPtr,Null) + INTEGER*4 Null(*) + + Debug = 2 + VIsDouble = 0 + FileType = 0 + DIsDouble = 0 + NULCHAR = CHAR(0) + Zero = 0 + NullPtr = 0 +! +! Open field.plt and write the header information. +! + I = TECINI112('DATASET WITH 1 ORDERED ZONE, '// & + '1 QUAD ZONE OVER 2 TIME STEPS'//NULCHAR, & + 'X Y P'//NULCHAR, & + 'field.plt'//NULCHAR, & + '.'//NULCHAR, & + FileType, & + Debug, & + VIsDouble) +! +! Open line.plt and write the header information. +! + VIsDouble = 1 + I = TECINI112('DATASET WITH ONE I-ORDERED ZONE'//NULCHAR, & + 'X Y'//NULCHAR, & + 'line.plt'//NULCHAR, & + '.'//NULCHAR, & + FileType, & + Debug, & + VIsDouble) + +! +! Calculate values for the field variables. +! + Do 10 J = 1,5 + Do 10 I = 1,4 + X(I,J) = I + Y(I,J) = J + P(I,J) = I*J + 10 Continue + +! +! Make sure writing to file #1. +! + III = 1 + I = TECFIL112(III) + +! +! Write the zone header information for the ordered zone. +! + IMax = 4 + JMax = 5 + KMax = 1 + SolTime = 10.0 + StrandID = 1 + ParentZn = 0 + I = TECZNE112('Ordered Zone 1'//NULCHAR, & + 0, & ! ZONETYPE + IMax, & + JMax, & + KMax, & + 0, & + 0, & + 0, & + SolTime, & + StrandID, & + ParentZn, & + 1, & ! ISBLOCK + 0, & ! NumFaceConnections + 0, & ! FaceNeighborMode + 0, & ! TotalNumFaceNodes + 0, & ! NumConnectedBoundaryFaces + 0, & ! TotalNumBoundaryConnections + Null, & ! PassiveVarList + Null, & ! ValueLocation + Null, & ! ShareVarFromZone + 0) ! ShareConnectivityFromZone) + +! +! Write out the field data for the ordered zone. +! + III = IMax*JMax + I = TECDAT112(III,X,DIsDouble) + I = TECDAT112(III,Y,DIsDouble) + I = TECDAT112(III,P,DIsDouble) + +! +! Calculate values for the I-ordered zone. +! + + Do 20 I = 1,50 + XL(I) = I + YL(I) = sin(I/20.0) + 20 Continue +! +! Switch to the 'line.plt' file (file number 2) +! and write out the line plot data. +! + III = 2 + I = TECFIL112(III) +! +! Write the zone header information for the XY-data. +! + IMax = 50 + JMax = 1 + KMax = 1 + SolTime = 0.0 + StrandID = 0 + I = TECZNE112('XY Line plot'//NULCHAR, & + 0, & + IMax, & + JMax, & + KMax, & + 0, & + 0, & + 0, & + SolTime, & + StrandID, & + ParentZn, & + 1, & + 0, & + 0, & + 0, & + 0, & + 0, & + Null, & + Null, & + Null, & + 0) +! +! Write out the line plot. +! + DIsDouble = 1 + III = IMax + I = TECDAT112(III,XLDummy,DIsDouble) + I = TECDAT112(III,YLDummy,DIsDouble) + +! +! Switch back to the field plot file and write out +! the finite-element zone. +! + III = 1 + I = TECFIL112(III) +! +! Move the coordinates so this zone's not on top of the other +! + Do 30 J = 1,5 + Do 30 I = 1,4 + X(I,J) = I+5 + Y(I,J) = J + P(I,J) = I*J + 30 Continue +! +! Write the zone header information for the finite-element zone. +! + NPts = 20 + NElm = 12 + KMax = 1 + SolTime = 10.0 + StrandID = 2 + I = TECZNE112('Finite Zone 1'//NULCHAR, & + 3, & ! FEQUADRILATERAL + NPts, & + NElm, & + KMax, & + 0, & + 0, & + 0, & + SolTime, & + StrandID, & + ParentZn, & + 1, & + 0, & + 0, & + 0, & + 0, & + 0, & + Null, & + Null, & + Null, & + 0) +! +! Write out the field data for the finite-element zone. +! + IMax = 4 + JMax = 5 + III = IMax*JMax + DIsDouble = 0 + I = TECDAT112(III,X,DIsDouble) + I = TECDAT112(III,Y,DIsDouble) + I = TECDAT112(III,P,DIsDouble) + +! +! Calculate and then write out the connectivity list. +! Note: The NM array references cells starting with +! offset of 1. +! + + Do 40 I = 1,IMax-1 + Do 40 J = 1,JMax-1 + K = I+(J-1)*(IMax-1) + L = I+(J-1)*IMax + NM(1,K) = L + NM(2,K) = L+1 + NM(3,K) = L+IMax+1 + NM(4,K) = L+IMax + 40 Continue + + I = TECNOD112(NM) +! +! Calculate vlues for the new solution variable. +! + Do 50 J = 1,5 + Do 50 I = 1,4 + P(I,J) = 2*I*J + 50 Continue +! +! Write the zone header information for time step 2 +! + IMax = 4 + JMax = 5 + KMax = 1 + SolTime = 20.0 + StrandID = 1 + SharingZone(1) = 1 + SharingZone(2) = 1 + SharingZone(3) = 0 + I = TECZNE112('Ordered Zone 2'//NULCHAR, & + 0, & ! ORDERED + IMax, & + JMax, & + KMax, & + 0, & + 0, & + 0, & + SolTime, & + StrandID, & + ParentZn, & + 1, & + 0, & + 0, & + 0, & + 0, & + 0, & + Null, & + Null, & + SharingZone, & + 0) +! +! Write out the solution variable the grid variables are shared. +! + IMax = 4 + JMax = 5 + III = IMax*JMax + DIsDouble = 0 + I = TECDAT112(III,P,DIsDouble) +! +! Calculate values for the new solution variable. +! + Do 60 J = 1,5 + Do 60 I = 1,4 + P(I,J) = 3*I*J + 60 Continue +! +! Write another time step for the FEZone and share from the first +! + SolTime = 20.0 + StrandID = 2 + KMax = 0 + SharingZone(1) = 2 + SharingZone(2) = 2 + SharingZone(3) = 0 + I = TECZNE112('Finite Zone 2'//NULCHAR, & + 3, & ! FEQUADRILATERAL + NPts, & + NElm, & + KMax, & + 0, & + 0, & + 0, & + SolTime, & + StrandID, & + ParentZn, & + 1, & + 0, & + 0, & + 0, & + 0, & + 0, & + Null, & + Null, & + SharingZone, & + 2) +! +! Write out the solution variable the grid variables are shared. +! + IMax = 4 + JMax = 5 + III = IMax*JMax + DIsDouble = 0 + I = TECDAT112(III,P,DIsDouble) + +! +! Prepare to write out text record. Text is positioned +! at 50, 50 in frame units and has a height 5 frame units. +! + XP = 50 + YP = 50 + FH = 5 + Scope = 1 + Clipping = 0 + PositionCoordSys = 1 + FontType = 1 + HeightUnits = 1 + AttachToZone = 0 + Zone = 0 + BoxType = 0 + BoxMargin = 5.0 + BoxLineThickness = 0.5 + BoxColor = 3 + BoxFillColor = 7 + TextAngle = 0.0 + Anchor = 0 + LineSpacing = 1.5 + TextColor = 0 + + III = TECTXT112(XP, & + YP, & + 0.0d0, & + PositionCoordSys, & + AttachToZone, & + Zone, & + FontType, & + HeightUnits, & + FH, & + BoxType, & + BoxMargin, & + BoxLineThickness, & + BoxColor, & + BoxFillColor, & + TextAngle, & + Anchor, & + LineSpacing, & + TextColor, & + Scope, & + Clipping, & + 'Hi Mom'//NULCHAR, & + NULCHAR) + +! +! Prepare to write out geometry record (circle). Circle is +! positioned at 25, 25 in frame units and has a radius of 30. +! Circle is drawn using a dashed line pattern. +! + + + XP = 25 + YP = 25 + ZP = 0.0 + IsFilled = 0 + Color = 0 + FillColor = 7 + GeomType = 2 + LinePattern = 1 + LineThickness = 0.3 + PatternLength = 1 + NumEllipsePts = 72 + ArrowheadStyle = 0 + ArrowheadAttachment = 0 + ArrowheadSize = 0.0 + ArrowheadAngle = 15.0 + NumSegments = 1 + NumSegPts(1) = 1 + + XGeomData(1) = 30 + YGeomData(1) = 0.0 + ZGeomData(1) = 0.0 + + + III = TECGEO112(XP, & + YP, & + ZP, & + PositionCoordSys, & + AttachToZone, & + Zone, & + Color, & + FillColor, & + IsFilled, & + GeomType, & + LinePattern, & + PatternLength, & + LineThickness, & + NumEllipsePts, & + ArrowheadStyle, & + ArrowheadAttachment, & + ArrowheadSize, & + ArrowheadAngle, & + Scope, & + Clipping, & + NumSegments, & + NumSegPts, & + XGeomData, & + YGeomData, & + ZGeomData, & + NULCHAR) + +! +! Close out file 1. +! + I = TECEND112() + +! +! Close out file 2. +! + III = 2 + I = TECFIL112(III) + I = TECEND112() + STOP + END diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtestc.vcproj b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtestc.vcproj new file mode 100644 index 0000000000..23da375e8d --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtestc.vcproj @@ -0,0 +1,346 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtestf.vfproj b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtestf.vfproj new file mode 100644 index 0000000000..dc894475f3 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/comtest/comtestf.vfproj @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/faceneighbors/FaceNeighbors.plt b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/faceneighbors/FaceNeighbors.plt new file mode 100644 index 0000000000000000000000000000000000000000..6581f95bdce627599a21174508c20d3b7eabb0b7 GIT binary patch literal 756 zcmb`FO-=$q5Jnpm*DP6%feQ>5pveeJ!-5cWr^bMZpn-(2>`S=!44!}^aRYr{Pqk?l z#Eq4_`Rb>;t9oX-*VCI>S@s*QwlVSmPw)%{+?xM_E?^0d@CF;$LIES#gZ8iB9bQ4_ z$Sz1o!sPh_D&qcYWC9X0*UvsWs-xmFUzpqL? zHCrOhqh853^{4T1P{&C-Sv^n_PC3iRm@wA^wND7(!O4&3HVM+Zlz$1WEO#>R-*@nA r#o9i~?<38g5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/gridsolution/Makefile b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/gridsolution/Makefile new file mode 100644 index 0000000000..d901ed95c1 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/gridsolution/Makefile @@ -0,0 +1,11 @@ +# Set to appropriate C++ compiler +CPP=g++ +CPPFLAGS=-I../../tecsrc ../../tecio.a +EXECUTABLE=gridsolution +FILES=$(EXECUTABLE).cpp + +build: + $(CPP) $(FILES) $(CPPFLAGS) -o $(EXECUTABLE) + +clean: + rm -f $(EXECUTABLE) diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/gridsolution/gridsolution.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/gridsolution/gridsolution.cpp new file mode 100644 index 0000000000..8cf2e54894 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/gridsolution/gridsolution.cpp @@ -0,0 +1,376 @@ +/* This example illustrates using separate grid + * and solution files. + */ + +#include "TECIO.h" +#include "MASTER.h" /* for defintion of NULL */ + +int main() +{ + /* DOCSTART:gridsolution_grid_tecini.txt*/ + INTEGER4 I; /* use to check return values */ + + INTEGER4 Debug = 1; + INTEGER4 VIsDouble = 0; + INTEGER4 FileType = 1; /* 1 = grid file. */ + + I = TECINI112((char*)"Example: Separate grid and solution files", + (char*)"X Y Z", /* Defines the variables for the data file. + * Each zone must contain each of the vars + * listed here. The order of the variables + * in the list is used to define the + * variable number (e.g. X is Variable 1). + * When referring to variables in other + * TecIO functions, you will refer to the + * variable by its number. + */ + (char*)"grid.plt", + (char*)".", /* scratch directory */ + &FileType, + &Debug, + &VIsDouble); + /* DOCEND */ + + /* DOCSTART:gridsolution_grid_teczne.txt*/ + /* TECZNE Parameters */ + INTEGER4 ZoneType = 7; /* FE Polyhedron */ + INTEGER4 NumPts = 20; /* the number of unique + * nodes in the zone. + */ + INTEGER4 NumElems = 1; + INTEGER4 NumFaces = 12; /* the number of unique + * faces in the zone. + */ + INTEGER4 ICellMax = 0; /* not used */ + INTEGER4 JCellMax = 0; /* not used */ + INTEGER4 KCellMax = 0; /* not used */ + double SolutionTime = 0.0; + INTEGER4 StrandID = 1; /* time strand for + * unsteady solution. + */ + INTEGER4 ParentZone = 0; + INTEGER4 IsBlock = 1; + INTEGER4 NumFaceConnections = 0; + INTEGER4 FaceNeighborMode = 1; + INTEGER4 SharConn = 0; + + /* For this zone, the total number of face nodes is + * five times number of faces, because each face + * is a pentagon. + */ + INTEGER4 TotalNumFaceNodes = 5 * NumFaces; + + /* This zone has no connected boundary faces. + */ + INTEGER4 TotalNumBndryFaces = 0; + INTEGER4 TotalNumBndryConns = 0; + + I = TECZNE112((char*)"Dodecahedron", /* Name of the zone. */ + &ZoneType, + &NumPts, + &NumElems, + &NumFaces, + &ICellMax, + &JCellMax, + &KCellMax, + &SolutionTime, + &StrandID, + &ParentZone, + &IsBlock, + &NumFaceConnections, + &FaceNeighborMode, + &TotalNumFaceNodes, + &TotalNumBndryFaces, + &TotalNumBndryConns, + NULL, + NULL, /* All nodal variables */ + NULL, + &SharConn); + /* DOCEND */ + + /* DOCSTART:gridsolution_grid_tecdat.txt*/ + + /* TECDAT Parameters */ + double Phi = 0.5 * (1.0 + sqrt(5.0)); + double Pi = 3.141592653578; + double *X = new double[NumPts]; + double *Y = new double[NumPts]; + double *Z = new double[NumPts]; + int Count = 0; + + for(int J = 0; J <= 4; J++) + { + X[Count] = 2.0 * cos(2.0 / 5.0 * Pi * J); + Y[Count] = 2.0 * sin(2.0 / 5.0 * Pi * J); + Z[Count] = Phi + 1.0; + Count++; + + X[Count] = -X[Count - 1]; + Y[Count] = -Y[Count - 1]; + Z[Count] = -Z[Count - 1]; + Count++; + + X[Count] = 2.0 * Phi * cos(2.0 / 5.0 * Pi * J); + Y[Count] = 2.0 * Phi * sin(2.0 / 5.0 * Pi * J); + Z[Count] = Phi - 1.0; + Count++; + + X[Count] = -X[Count - 1]; + Y[Count] = -Y[Count - 1]; + Z[Count] = -Z[Count - 1]; + Count++; + } + + INTEGER4 IsDouble = 1; + + I = TECDAT112(&NumPts, X, &IsDouble); + I = TECDAT112(&NumPts, Y, &IsDouble); + I = TECDAT112(&NumPts, Z, &IsDouble); + + delete X; + delete Y; + delete Z; + + /* DOCEND */ + + /* DOCSTART:gridsolution_grid_facenodes.txt*/ + /* TecPoly Parameters */ + + /* Create a FaceNodes array, dimensioned by the total number + * of face nodes in the zone. + */ + INTEGER4 *FaceNodes = new INTEGER4[TotalNumFaceNodes]; + int n = 0; + + /* Face Nodes for face 1 of the dodecahedron */ + FaceNodes[n++] = 2; + FaceNodes[n++] = 6; + FaceNodes[n++] = 10; + FaceNodes[n++] = 14; + FaceNodes[n++] = 18; + + /* Face Nodes for face 2 */ + FaceNodes[n++] = 6; + FaceNodes[n++] = 8; + FaceNodes[n++] = 19; + FaceNodes[n++] = 12; + FaceNodes[n++] = 10; + + /* Face Nodes for face 3 */ + FaceNodes[n++] = 3; + FaceNodes[n++] = 12; + FaceNodes[n++] = 10; + FaceNodes[n++] = 14; + FaceNodes[n++] = 16; + + /* Face Nodes for face 4 */ + FaceNodes[n++] = 7; + FaceNodes[n++] = 16; + FaceNodes[n++] = 14; + FaceNodes[n++] = 18; + FaceNodes[n++] = 20; + + /* Face Nodes for face 5 */ + FaceNodes[n++] = 2; + FaceNodes[n++] = 4; + FaceNodes[n++] = 11; + FaceNodes[n++] = 20; + FaceNodes[n++] = 18; + + /* Face Nodes for face 6 */ + FaceNodes[n++] = 2; + FaceNodes[n++] = 4; + FaceNodes[n++] = 15; + FaceNodes[n++] = 8; + FaceNodes[n++] = 6; + + /* Face Nodes for face 7 */ + FaceNodes[n++] = 1; + FaceNodes[n++] = 3; + FaceNodes[n++] = 12; + FaceNodes[n++] = 19; + FaceNodes[n++] = 17; + + /* Face Nodes for face 8 */ + FaceNodes[n++] = 1; + FaceNodes[n++] = 3; + FaceNodes[n++] = 16; + FaceNodes[n++] = 7; + FaceNodes[n++] = 5; + + /* Face Nodes for face 9 */ + FaceNodes[n++] = 5; + FaceNodes[n++] = 7; + FaceNodes[n++] = 20; + FaceNodes[n++] = 11; + FaceNodes[n++] = 9; + + /* Face Nodes for face 10 */ + FaceNodes[n++] = 4; + FaceNodes[n++] = 11; + FaceNodes[n++] = 9; + FaceNodes[n++] = 13; + FaceNodes[n++] = 15; + + /* Face Nodes for face 11 */ + FaceNodes[n++] = 8; + FaceNodes[n++] = 15; + FaceNodes[n++] = 13; + FaceNodes[n++] = 17; + FaceNodes[n++] = 19; + + /* Face Nodes for face 12 */ + FaceNodes[n++] = 1; + FaceNodes[n++] = 5; + FaceNodes[n++] = 9; + FaceNodes[n++] = 13; + FaceNodes[n++] = 17; + + /* DOCEND */ + + /* Specify the number of nodes for each face, and the right and + * left neighboring elements. The neighboring elements can be + * determined using the right-hand rule. For each face, curl + * the fingers of your right hand in the direction of + * incrementing node numbers (i.e. from Node 1 to Node 2 and + * so on). Your thumb will point toward the right element. + * A value of zero indicates that there is no + * neighboring element on that side. A negative value + * indicates that the neighboring element is in another zone. + * In that case, the number is a pointer into the + * FaceBndryConnectionElems and FaceBndryConnectionZones arrays. + */ + + /* DOCSTART:gridsolution_grid_tecpoly.txt*/ + INTEGER4 *FaceNodeCounts = new INTEGER4[NumFaces]; + INTEGER4 *FaceLeftElems = new INTEGER4[NumFaces]; + INTEGER4 *FaceRightElems = new INTEGER4[NumFaces]; + + /* For this particular zone, each face has the 5 nodes. */ + for(int J = 0; J < NumFaces; J++) + FaceNodeCounts[J] = 5; + + /* Set the right and left elements for each face. */ + FaceRightElems[0] = 1; + FaceRightElems[1] = 1; + FaceRightElems[2] = 0; + FaceRightElems[3] = 0; + FaceRightElems[4] = 0; + FaceRightElems[5] = 1; + FaceRightElems[6] = 1; + FaceRightElems[7] = 0; + FaceRightElems[8] = 0; + FaceRightElems[9] = 1; + FaceRightElems[10] = 1; + FaceRightElems[11] = 0; + + FaceLeftElems[0] = 0; + FaceLeftElems[1] = 0; + FaceLeftElems[2] = 1; + FaceLeftElems[3] = 1; + FaceLeftElems[4] = 1; + FaceLeftElems[5] = 0; + FaceLeftElems[6] = 0; + FaceLeftElems[7] = 1; + FaceLeftElems[8] = 1; + FaceLeftElems[9] = 0; + FaceLeftElems[10] = 0; + FaceLeftElems[11] = 1; + + I = TECPOLY112(FaceNodeCounts, + FaceNodes, + FaceLeftElems, + FaceRightElems, + NULL, /* No boundary connections. */ + NULL, + NULL); + + delete FaceNodes; + delete FaceLeftElems; + delete FaceRightElems; + + /* DOCEND */ + + + /* DOCSTART:gridsolution_grid_tecend.txt*/ + I = TECEND112(); + /* DOCEND */ + + /* DOCSTART:gridsolution_solution_tecini.txt*/ + for(int J = 0; J < 5; J++) + { + char SolutionFileName[128]; + sprintf(SolutionFileName, "solution%d.plt", J); + + /* DOCSTART:gridsolution_solution_tecini.txt*/ + FileType = 2; /* 1 = solution file. */ + + I = TECINI112((char*)"Example: Separate grid and solution files", + (char*)"P T", /* Defines the variables for the solution file. + * Note that these are different variables from + * the grid file. + */ + SolutionFileName, + (char*)".", /* scratch directory */ + &FileType, + &Debug, + &VIsDouble); + /* DOCEND */ + + /* DOCSTART:gridsolution_solution_teczne.txt*/ + /* TECZNE Parameters are mostly unchanged from creation of the grid file. */ + TotalNumFaceNodes = 0; + SolutionTime = J; + + char ZoneName[128]; + sprintf(ZoneName, "Dodecahedron Time=%g", SolutionTime); + I = TECZNE112(ZoneName, + &ZoneType, + &NumPts, + &NumElems, + &NumFaces, + &ICellMax, + &JCellMax, + &KCellMax, + &SolutionTime, + &StrandID, + &ParentZone, + &IsBlock, + &NumFaceConnections, + &FaceNeighborMode, + &TotalNumFaceNodes, + &TotalNumBndryFaces, + &TotalNumBndryConns, + NULL, + NULL, /* All nodal variables */ + NULL, + &SharConn); + /* DOCEND */ + + /* DOCSTART:gridsolution_solution_tecdat.txt*/ + + /* TECDAT Parameters */ + double *P = new double[NumPts]; + double *T = new double[NumPts]; + + for(int K = 0; K < NumPts; K++) + { + P[K] = (double)(K + J); + T[K] = 1.0 + K + K; + } + + I = TECDAT112(&NumPts, P, &IsDouble); + I = TECDAT112(&NumPts, T, &IsDouble); + + delete P; + delete T; + + /* DOCEND */ + + /* DOCSTART:gridsolution_solution_tecend.txt*/ + I = TECEND112(); + /* DOCEND */ + } + + return 0; +} diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/gridsolution/gridsolution.vcproj b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/gridsolution/gridsolution.vcproj new file mode 100644 index 0000000000..7e333fd227 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/gridsolution/gridsolution.vcproj @@ -0,0 +1,321 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/ij_ordered/Makefile b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/ij_ordered/Makefile new file mode 100644 index 0000000000..90411d11e2 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/ij_ordered/Makefile @@ -0,0 +1,11 @@ +# Set to appropriate C++ compiler +CPP=g++ +CPPFLAGS=-I../../tecsrc ../../tecio.a +EXECUTABLE=ij_ordered +FILES=$(EXECUTABLE).cpp + +build: + $(CPP) $(FILES) $(CPPFLAGS) -o $(EXECUTABLE) + +clean: + rm -f $(EXECUTABLE) \ No newline at end of file diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/ij_ordered/ij_ordered.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/ij_ordered/ij_ordered.cpp new file mode 100644 index 0000000000..2f13c1f4a3 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/ij_ordered/ij_ordered.cpp @@ -0,0 +1,149 @@ +/* This example creates a simple set of IJ-ordered zones */ +/* DOCSTART:ij_ordered.txt*/ +#include "TECIO.h" +#include "MASTER.h" /* for defintion of NULL */ + +int main() +{ + INTEGER4 Debug = 1; + INTEGER4 VIsDouble = 0; + INTEGER4 FileType = 0; + INTEGER4 I = 0; /* Used to track return codes */ + + /* + * Open the file and write the tecplot datafile + * header information + */ + I = TECINI112((char*)"IJ Ordered Zones", /* Name of the entire + * dataset. + */ + (char*)"X Y P", /* Defines the variables for the data + * file. Each zone must contain each of + * the variables listed here. The order + * of the variables in the list is used + * to define the variable number (e.g. + * X is Var 1). + */ + (char*)"ij_ordered.plt", + (char*)".", /* Scratch Directory */ + &FileType, + &Debug, + &VIsDouble); + + float X1[4]; + float Y1[4]; + float P1[4]; + float X2[4]; + float Y2[4]; + float P2[4]; + + INTEGER4 ICellMax = 0; + INTEGER4 JCellMax = 0; + INTEGER4 KCellMax = 0; + INTEGER4 DIsDouble = 0; + double SolTime = 360.0; + INTEGER4 StrandID = 0; /* StaticZone */ + INTEGER4 ParentZn = 0; + INTEGER4 IsBlock = 1; /* Block */ + INTEGER4 NFConns = 0; + INTEGER4 FNMode = 0; + INTEGER4 TotalNumFaceNodes = 1; + INTEGER4 TotalNumBndryFaces = 1; + INTEGER4 TotalNumBndryConnections = 1; + INTEGER4 ShrConn = 0; + + /*Ordered Zone Parameters*/ + INTEGER4 IMax = 2; + INTEGER4 JMax = 2; + INTEGER4 KMax = 1; + + X1[0] = .125; + Y1[0] = .5; + P1[0] = 5; + + X1[1] = .625; + Y1[1] = .5; + P1[1] = 7.5; + + X1[2] = .125; + Y1[2] = .875; + P1[2] = 10; + + X1[3] = .625; + Y1[3] = .875; + P1[3] = 7.5; + + X2[0] = .375; + Y2[0] = .125; + P2[0] = 5; + + X2[1] = .875; + Y2[1] = .125; + P2[1] = 7.5; + + X2[2] = .375; + Y2[2] = .5; + P2[2] = 10; + + X2[3] = .875; + Y2[3] = .5; + P2[3] = 7.5; + + /* Ordered Zone */ + INTEGER4 ZoneType = 0; + I = TECZNE112((char*)"Ordered Zone", + &ZoneType, + &IMax, + &JMax, + &KMax, + &ICellMax, + &JCellMax, + &KCellMax, + &SolTime, + &StrandID, + &ParentZn, + &IsBlock, + &NFConns, + &FNMode, + &TotalNumFaceNodes, + &TotalNumBndryFaces, + &TotalNumBndryConnections, + NULL, + NULL, + NULL, + &ShrConn); + INTEGER4 III = IMax * JMax * KMax; + I = TECDAT112(&III, X1, &DIsDouble); + I = TECDAT112(&III, Y1, &DIsDouble); + I = TECDAT112(&III, P1, &DIsDouble); + + I = TECZNE112((char*)"Ordered Zone2", + &ZoneType, + &IMax, + &JMax, + &KMax, + &ICellMax, + &JCellMax, + &KCellMax, + &SolTime, + &StrandID, + &ParentZn, + &IsBlock, + &NFConns, + &FNMode, + &TotalNumFaceNodes, + &TotalNumBndryFaces, + &TotalNumBndryConnections, + NULL, + NULL, + NULL, + &ShrConn); + + I = TECDAT112(&III, X2, &DIsDouble); + I = TECDAT112(&III, Y2, &DIsDouble); + I = TECDAT112(&III, P2, &DIsDouble); + + I = TECEND112(); + return 0; +} +/* DOCEND */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/ij_ordered/ij_ordered.plt b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/ij_ordered/ij_ordered.plt new file mode 100644 index 0000000000000000000000000000000000000000..81f210b6c2d7abc0e87795395027da100999e7af GIT binary patch literal 584 zcmY#Z3~>oFG&EvlfB;V*^MN=Ih(Y4TKnw!R zKpX*PF)&0z=>RCr&@k1RRC7UE|3d-Tn1(V35Eo`7jAjBdKp5s1a_lmK8b+Rdo18&* zg6xN3sBvKTL)ZuGA@ma{{Qye8fzl!l5P204Z3hf#kT{G6v4J=NiWdOYd;nqvM=(v$ k?i(QeKmfDr0F?g#N+a8S0B9%39vBUB0~mwU0x_!H0FdibfB*mh literal 0 HcmV?d00001 diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/ij_ordered/ij_ordered.vcproj b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/ij_ordered/ij_ordered.vcproj new file mode 100644 index 0000000000..94c67c6c07 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/ij_ordered/ij_ordered.vcproj @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplefiles/Makefile b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplefiles/Makefile new file mode 100644 index 0000000000..d55d2ee044 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplefiles/Makefile @@ -0,0 +1,11 @@ +# Set to appropriate C++ compiler +CPP=g++ +CPPFLAGS=-I../../tecsrc ../../tecio.a +EXECUTABLE=multiplefiles +FILES=$(EXECUTABLE).cpp + +build: + $(CPP) $(FILES) $(CPPFLAGS) -o $(EXECUTABLE) + +clean: + rm -f $(EXECUTABLE) \ No newline at end of file diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplefiles/file1.plt b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplefiles/file1.plt new file mode 100644 index 0000000000000000000000000000000000000000..b0c368e03f3ff83c0a739471d901361b130eb257 GIT binary patch literal 448 zcmXxgO=U(sbvz`0<#=dOFJX!u*o-H4AcYcScQm8WgegQR%nUq_{&J|U#gH!Vtzd0g zEIoxe>|qD8&p_s5qfNVKcY`1#zNqen{3+e>BY95qqpyCMYxC3G8t8c!*S!!H?A?L> NL+-+jJ8wvH@fYTVE^Yt- literal 0 HcmV?d00001 diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplefiles/multiplefiles.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplefiles/multiplefiles.cpp new file mode 100644 index 0000000000..b79085ff56 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplefiles/multiplefiles.cpp @@ -0,0 +1,214 @@ +/* This example illustrates working with TecFil to create multiple + * plt files simultaneously. + */ +#if defined _MSC_VER +#pragma warning (disable: 4996) /* Windows strcpy warning off */ +#endif +/* DOCSTART:mulitplefiles.txt */ +#include "TECIO.h" +#include "MASTER.h" /* for defintion of NULL */ +#include + +int main() +{ + /* + * Open the file and write the tecplot datafile + * header information + */ + INTEGER4 Debug = 1; + INTEGER4 VIsDouble = 0; + INTEGER4 FileType = 0; + INTEGER4 I = 0; /* Used to check the return value */ + + I = TECINI112((char*)"SIMPLE DATASET", /* Name of the entire dataset.*/ + + (char*)"X1 Y1 P1", /* Defines the variables for the data + * file. Each zone must contain each of + * the variables listed here. The order + * of the variables in the list is used + * to define the variable number (e.g. + * X1 is Var 1). + */ + (char*)"file1.plt", + (char*)".", /* Scratch Directory */ + &FileType, + &Debug, + &VIsDouble); + + /* Set the parameters for TecZne */ + INTEGER4 ZoneType = 0; /* sets the zone type to + * ordered + */ + INTEGER4 IMax = 2; /* Create an IJ-ordered zone, + * by using IMax and JMax + * values that are greater + * than one, and setting KMax + * to one. + */ + INTEGER4 JMax = 2; + INTEGER4 KMax = 1; + + double SolTime = 0; + INTEGER4 StrandID = 0; /* StaticZone */ + INTEGER4 ParentZn = 0; /* used for surface streams */ + + INTEGER4 ICellMax = 0; /* not used */ + INTEGER4 JCellMax = 0; /* not used */ + INTEGER4 KCellMax = 0; /* not used */ + + INTEGER4 IsBlock = 1; /* Block */ + + INTEGER4 NFConns = 0; /* this example does not use + * face neighbors */ + INTEGER4 FNMode = 0; + INTEGER4 TotalNumFaceNodes = 1; + INTEGER4 TotalNumBndryFaces = 1; + INTEGER4 TotalNumBndryConn = 1; + INTEGER4 ShrConn = 0; + + + /* Create an Ordered Zone */ + I = TECZNE112((char*)"Ordered Zone", + &ZoneType, + &IMax, + &JMax, + &KMax, + &ICellMax, + &JCellMax, + &KCellMax, + &SolTime, + &StrandID, + &ParentZn, + &IsBlock, + &NFConns, + &FNMode, + &TotalNumFaceNodes, + &TotalNumBndryFaces, + &TotalNumBndryConn, + NULL, + NULL, + NULL, + &ShrConn); + + /* Set the variable values for the ordered zone. */ + float X1[4]; + float Y1[4]; + float P1[4]; + + X1[0] = 0.125; + Y1[0] = 0.5; + P1[0] = 7.5; + + X1[1] = 0.625; + Y1[1] = 0.5; + P1[1] = 10.0; + + X1[2] = 0.125; + Y1[2] = 0.875; + P1[2] = 5.0; + + X1[3] = 0.625; + Y1[3] = 0.875; + P1[3] = 7.5; + + INTEGER4 DIsDouble = 0; /* set DIsDouble to 0, for float + * values. + */ + + INTEGER4 III = IMax * JMax * KMax; + I = TECDAT112(&III, X1, &DIsDouble); + I = TECDAT112(&III, Y1, &DIsDouble); + I = TECDAT112(&III, P1, &DIsDouble); + + /* Open a new data file. note: the first file is still open + * because TecEnd was not called. + */ + I = TECINI112((char*)"Auxiliary Data", + (char*)"X1 Y1 P1", + (char*)"file2.plt", + (char*)".", + &FileType, + &Debug, + &VIsDouble); + + /* Switch the active file to the newly created data file + * (file2.plt) which is the second file opened with TECINI112 + * so we use 2. + */ + INTEGER4 WhichFile = 2; + I = TECFIL112(&WhichFile); + + /* Create a second zone, using many of the values from the first + * zone, and write it to the second data file. + */ + + I = TECZNE112((char*)"Ordered Zone2", + &ZoneType, + &IMax, + &JMax, + &KMax, + &ICellMax, + &JCellMax, + &KCellMax, + &SolTime, + &StrandID, + &ParentZn, + &IsBlock, + &NFConns, + &FNMode, + &TotalNumFaceNodes, + &TotalNumBndryFaces, + &TotalNumBndryConn, + NULL, + NULL, + NULL, + &ShrConn); + /* set the variable values for the second zone */ + float X2[4]; + float Y2[4]; + float P2[4]; + + X2[0] = 0.375; + Y2[0] = 0.125; + P2[0] = 5; + + X2[1] = 0.875; + Y2[1] = 0.125; + P2[1] = 7.5; + + X2[2] = 0.375; + Y2[2] = 0.5; + P2[2] = 10; + + Y2[3] = 0.5; + X2[3] = 0.875; + P2[3] = 7.5; + + III = IMax * JMax * KMax; + I = TECDAT112(&III, X2, &DIsDouble); + I = TECDAT112(&III, Y2, &DIsDouble); + I = TECDAT112(&III, P2, &DIsDouble); + + /* Switch to the first file. */ + WhichFile = 1; + I = TECFIL112(&WhichFile); + + /* Create an auxiliary data value and write it to the file */ + char DeformationValue[128]; + strcpy(DeformationValue, "0.98"); + + I = TECAUXSTR112((char*)"DeformationValue", + DeformationValue); + /* Close the first file */ + I = TECEND112(); + + /* The remaining file will become the active file. As such, + * TecFil does not need to be called again to close the second + * file. + */ + I = TECEND112(); + + return 0; +} + +/* DOCEND */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplefiles/multiplefiles.vcproj b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplefiles/multiplefiles.vcproj new file mode 100644 index 0000000000..84651a69d0 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplefiles/multiplefiles.vcproj @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplepolygons/HexagonsAndOctagon.plt b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/multiplepolygons/HexagonsAndOctagon.plt new file mode 100644 index 0000000000000000000000000000000000000000..3b4f3042c69b7ea023e8de723b7e40c5b7f6eaf2 GIT binary patch literal 1480 zcmb7?OG*Pl5QaPP{X!QmL_|hBLE_GhBT;Z8x)4!!K}7^#pn|%ZOSqpic!C_ogZTRX znJQ@}iI{?q`v2~(eoW2k%E8uQqtUE|GPX%i(1vTcgDW_Pbx2?r9zo*|a0&6c#QZH; zYo6f(?o>cUMbcy_*qznVbEPgSM<4OlZAdy-8q53?y31U=-Zt^0$#U=J_YqbYvT7| z!=P`Qrbh2u1bAKAGsd>u_6|ebhgEiz-b5M9>hR)?7g&?i9 zL? + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/octagon/Makefile b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/octagon/Makefile new file mode 100644 index 0000000000..b1a0615165 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/octagon/Makefile @@ -0,0 +1,11 @@ +# Set to appropriate C++ compiler +CPP=g++ +CPPFLAGS=-I../../tecsrc ../../tecio.a +EXECUTABLE=octagon +FILES=$(EXECUTABLE).cpp + +build: + $(CPP) $(FILES) $(CPPFLAGS) -o $(EXECUTABLE) + +clean: + rm -f $(EXECUTABLE) \ No newline at end of file diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/octagon/Octagon.plt b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/octagon/Octagon.plt new file mode 100644 index 0000000000000000000000000000000000000000..e09f4f79b80a9b520bcfb359211fa932e5f2e8c0 GIT binary patch literal 520 zcmY#Z3~>oFG&EvlfB=6Wl?=osK%5A~=|G$h#Cbpr0?a@h0cJ5UL_+BRD9z9?)fu0D zka;;ktN_GOKnycC703pG|4;ztG?Y1jxNKk!g5Ur$L0AAG!~kmkb;LD$ZyyHNDV#!02MV(`~Uy| literal 0 HcmV?d00001 diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/octagon/octagon.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/octagon/octagon.cpp new file mode 100644 index 0000000000..c9d64aece1 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/octagon/octagon.cpp @@ -0,0 +1,248 @@ +/* This example illustrates how to create a zone with a single + * polygonal cell. Please refer to the Data Format Guide for + * additional information, including figures that display node + * numbering. + */ + +#include "TECIO.h" +#include "MASTER.h" /* for defintion of NULL */ + +int main() +{ + /* DOCSTART:octagon_tecini.txt*/ + INTEGER4 Debug = 1; + INTEGER4 VIsDouble = 0; + INTEGER4 FileType = 0; + INTEGER4 I; /* used to check return codes */ + + /* + * Open the file and write the Tecplot datafile + * header information + */ + + I = TECINI112((char*)"Octagon", + (char*)"X Y P", /* Defines the variables for the data + * file. Each zone must contain each + * of the vars listed here. The order + * of the variables in the list is + * used to define the variable number + * (e.g. X is Variable 1). When + * referring to variables in other + * TecIO functions, you will refer to + * thevariable by its number. + */ + (char*)"Octagon.plt", + (char*)".", /* scratch directory */ + &FileType, + &Debug, + &VIsDouble); + /* DOCEND */ + + /* Declare TECZNE variables */ + /* DOCSTART:octagon_teczne.txt*/ + /* In this example, we will create a single octagonal cell in + * Tecplot 360's polyhedral file format. + */ + INTEGER4 ZoneType = 6; /* FEPolygon */ + INTEGER4 NumNodes = 8; /* Number of nodes in the octagon.*/ + INTEGER4 NumElems = 1; /* Number of octagonal elements. */ + INTEGER4 NumFaces = 8; /* Number of faces in the octagon.*/ + INTEGER4 ICellMax = 0; /* Not Used */ + INTEGER4 JCellMax = 0; /* Not Used */ + INTEGER4 KCellMax = 0; /* Not Used */ + double SolTime = 360.0; + INTEGER4 StrandID = 0; /* Static Zone */ + INTEGER4 ParentZn = 0; /* No Parent Zone */ + INTEGER4 IsBlock = 1; /* Block */ + INTEGER4 NFConns = 0; + INTEGER4 FNMode = 0; + + + /* For polygonal zones, the total number of face nodes is equal + * to twice the number of nodes. This is because, each face + * has exactly two nodes. + */ + INTEGER4 NumFaceNodes = 2 * NumNodes; + /* Boundary Faces and Boundary Connections are not used in this + * example. + */ + INTEGER4 NumBFaces = 0; + INTEGER4 NumBConnections = 0; + + INTEGER4 ShrConn = 0; + + I = TECZNE112((char*)"Octagonal Zone", + &ZoneType, + &NumNodes, + &NumElems, + &NumFaces, + &ICellMax, + &JCellMax, + &KCellMax, + &SolTime, + &StrandID, + &ParentZn, + &IsBlock, + &NFConns, + &FNMode, + &NumFaceNodes, + &NumBFaces, + &NumBConnections, + NULL, + NULL, /* When Value Location is not specified, + * Tecplot will treat all variables as + * nodal variables. + */ + NULL, + &ShrConn); + /* DOCEND */ + + /* Establish numbering. + * For this example, we will a single octagonal cell. + * Before defining your variables, you must establish a + * consistent node numbering scheme for your data. Once the + * node numbers are defined, supply the variable values in the + * node numbering order. In this example, node 1 is defined at + * X = 0 and Y = 0. As such, the first value supplied for X + * (i.e. X[0]) is 0. Similarly, the first value supplied for + * Y is 0. + * + * It is important that you refer to node numbers consistently. + * The node numbers will be used later to define the + * connectivity for each element. + */ + + /* TECDAT Variables */ + /* Set up the variable values. The variable values will be + * written to the file using TECDAT. Because we are specifying + * nodal variables (as specified via the ValueLocation + * parameter in TECZNE, each variable is dimensioned by the + * number of points (NumPts) in the Zone. You have the option + * to specify some variables with nodal values and some with + * cell-centered values. Refer to the Binary Function Reference + * for details. + */ + /* DOCSTART:octagon_tecdat.txt*/ + float *X = new float[NumNodes]; + float *Y = new float[NumNodes]; + float *P = new float[NumNodes]; + + //Define the grid values. + X[0] = 0.25; + Y[0] = 0.0; + + X[1] = 0.75; + Y[1] = 0.0; + + X[2] = 1.0; + Y[2] = 0.25; + + X[3] = 1.0; + Y[3] = 0.75; + + X[4] = 0.75; + Y[4] = 1.0; + + X[5] = 0.25; + Y[5] = 1.0; + + X[6] = 0.0; + Y[6] = 0.75; + + X[7] = 0.0; + Y[7] = 0.25; + + for (INTEGER4 ii = 0; ii < 8; ii++) + P[ii] = .5; + + /* Write out the field data using TECDAT */ + INTEGER4 DIsDouble = 0; /* set IsDouble to 0 to use float + * variables. */ + + I = TECDAT112(&NumNodes, X, &DIsDouble); + I = TECDAT112(&NumNodes, Y, &DIsDouble); + I = TECDAT112(&NumNodes, P, &DIsDouble); + + delete X; + delete Y; + delete P; + /* DOCEND */ + + /* Define the Face Nodes. + + * The FaceNodes array is used to indicate which nodes define + * which face. As mentioned earlier, the number of the nodes is + * implicitly defined by the order in which the nodal data is + * provided. The first value of each nodal variable describes + * node 1, the second value describes node 2, and so on. + * + * The face numbering is implicitly defined. Because there are + * two nodes in each face, the first two nodes provided define + * face 1, the next two define face 2 and so on. If there was + * a variable number of nodes used to define the faces, the + * array would be more complicated. + */ + /* DOCSTART:octagon_facenodes.txt*/ + INTEGER4 *FaceNodes = new INTEGER4[NumFaceNodes]; + + /* + * Loop over number of sides, and set each side to two + * consecutive nodes. + */ + for (INTEGER4 ii = 0; ii < 8; ii++) + { + FaceNodes[2*ii] = ii + 1; + FaceNodes[2*ii+1] = ii + 2; + } + FaceNodes[15] = 1; + + /* DOCEND */ + /* Define the right and left elements of each face. + + * The last step for writing out the polyhedral data is to + * define the right and left neighboring elements for each + * face. The neighboring elements can be determined using the + * right-hand rule. For each face, place your right-hand along + * the face which your fingers pointing the direction of + * incrementing node numbers (i.e. from node 1 to node 2). + * Your right thumb will point towards the right element; the + * element on the other side of your hand is the left element. + * + * The number zero is used to indicate that there isn't an + * element on that side of the face. + * + * Because of the way we numbered the nodes and faces, the + * right element for every face is the element itself + * (element 1) and the left element is "no-neighboring element" + * (element 0). + */ + /* DOCSTART:octagon_rightleft.txt*/ + INTEGER4 *FaceLeftElems = new INTEGER4[NumFaces]; + INTEGER4 *FaceRightElems = new INTEGER4[NumFaces]; + + for (INTEGER4 ii = 0; ii < NumFaces; ii++) + { + FaceLeftElems[ii] = 0; + FaceRightElems[ii] = 1; + } + /* DOCEND */ + /* Write the polyhedral data to the file. */ + /* DOCSTART:octagon_tecpoly.txt*/ + I = TECPOLY112(NULL, + FaceNodes, + FaceLeftElems, + FaceRightElems, + NULL, + NULL, + NULL); + + delete FaceNodes; + delete FaceLeftElems; + delete FaceRightElems; + /* DOCEND */ + /* DOCSTART:octagon_tecend.txt*/ + I = TECEND112(); + /* DOCEND */ + + return 0; +} diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/octagon/octagon.vcproj b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/octagon/octagon.vcproj new file mode 100644 index 0000000000..9d33ad0bde --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/octagon/octagon.vcproj @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/pyramid/Makefile b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/pyramid/Makefile new file mode 100644 index 0000000000..38cb009fca --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/pyramid/Makefile @@ -0,0 +1,11 @@ +# Set to appropriate C++ compiler +CPP=g++ +CPPFLAGS=-I../../tecsrc ../../tecio.a +EXECUTABLE=pyramid +FILES=$(EXECUTABLE).cpp + +build: + $(CPP) $(FILES) $(CPPFLAGS) -o $(EXECUTABLE) + +clean: + rm -f $(EXECUTABLE) \ No newline at end of file diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/pyramid/pyramid.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/pyramid/pyramid.cpp new file mode 100644 index 0000000000..864bb754ba --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/pyramid/pyramid.cpp @@ -0,0 +1,222 @@ +/* This example creates a zone with a single polyhedral cell. */ + +/* DOCSTART:pyramid.txt*/ +#include "TECIO.h" +#include "MASTER.h" /* for defintion of NULL */ + +int main() +{ + /* Call TECINI112 */ + INTEGER4 FileType = 0; /* 0 for full file */ + INTEGER4 Debug = 0; + INTEGER4 VIsDouble = 1; + INTEGER4 I = 0; /* use to check return codes */ + + I = TECINI112((char*)"Pyramid", /* Data Set Title */ + (char*)"X Y Z", /* Variable List */ + (char*)"pyramid.plt", /* File Name */ + (char*)".", /* Scratch Directory */ + &(FileType), + &(Debug), + &(VIsDouble)); + + + /* Call TECZNE112 */ + INTEGER4 ZoneType = 7; /* 7 for FEPolyhedron */ + INTEGER4 NumNodes = 5; /* number of unique nodes */ + INTEGER4 NumElems = 1; /* number of elements */ + INTEGER4 NumFaces = 5; /* number of unique faces */ + + INTEGER4 ICellMax = 0; /* Not Used, set to zero */ + INTEGER4 JCellMax = 0; /* Not Used, set to zero */ + INTEGER4 KCellMax = 0; /* Not Used, set to zero */ + + double SolTime = 12.65; /* solution time */ + INTEGER4 StrandID = 0; /* static zone */ + INTEGER4 ParentZone = 0; /* no parent zone */ + + INTEGER4 IsBlock = 1; /* block format */ + + INTEGER4 NFConns = 0; /* not used for FEPolyhedron + * zones + */ + INTEGER4 FNMode = 0; /* not used for FEPolyhedron + * zones + */ + + INTEGER4 *PassiveVarArray = NULL; + INTEGER4 *ValueLocArray = NULL; + INTEGER4 *VarShareArray = NULL; + + INTEGER4 ShrConn = 0; + + /* The number of face nodes in the zone. This example creates + * a zone with a single pyramidal cell. This cell has four + * triangular faces and one rectangular face, yielding a total + * of 16 face nodes. + */ + INTEGER4 NumFaceNodes = 16; + INTEGER4 NumBConns = 0; /* No Boundary Connections */ + INTEGER4 NumBItems = 0; /* No Boundary Items */ + + I = TECZNE112((char*)"Polyhedral Zone (Octahedron)", + &ZoneType, + &NumNodes, + &NumElems, + &NumFaces, + &ICellMax, + &JCellMax, + &KCellMax, + &SolTime, + &StrandID, + &ParentZone, + &IsBlock, + &NFConns, + &FNMode, + &NumFaceNodes, + &NumBConns, + &NumBItems, + PassiveVarArray, + ValueLocArray, + VarShareArray, + &ShrConn); + + /* Initialize arrays of nodal data */ + double *X = new double[NumNodes]; + double *Y = new double[NumNodes]; + double *Z = new double[NumNodes]; + + X[0] = 0; + Y[0] = 0; + Z[0] = 0; + + X[1] = 1; + Y[1] = 1; + Z[1] = 2; + + X[2] = 2; + Y[2] = 0; + Z[2] = 0; + + X[3] = 2; + Y[3] = 2; + Z[3] = 0; + + X[4] = 0; + Y[4] = 2; + Z[4] = 0; + + /* Write the data (using TECDAT112) */ + INTEGER4 DIsDouble = 1; /* One for double precision */ + I = TECDAT112(&NumNodes, X, &DIsDouble); + I = TECDAT112(&NumNodes, Y, &DIsDouble); + I = TECDAT112(&NumNodes, Z, &DIsDouble); + + delete X; + delete Y; + delete Z; + + /* Define the Face Nodes. + + * The FaceNodes array is used to indicate which nodes define + * which face. As mentioned earlier, the number of the nodes is + * implicitly defined by the order in which the nodal data is + * provided. The first value of each nodal variable describes + * node 1, the second value describes node 2, and so on. + * + * The face numbering is implicitly defined. Because there are + * two nodes in each face, the first two nodes provided define + * face 1, the next two define face 2 and so on. If there was + * a variable number of nodes used to define the faces, the + * array would be more complicated. + */ + + INTEGER4 *FaceNodeCounts = new INTEGER4[NumFaces]; + /* The first four faces are triangular, i.e. have three nodes. + * The fifth face is rectangular, i.e. has four nodes. */ + FaceNodeCounts[0] = 3; + FaceNodeCounts[1] = 3; + FaceNodeCounts[2] = 3; + FaceNodeCounts[3] = 3; + FaceNodeCounts[4] = 4; + + INTEGER4 *FaceNodes = new INTEGER4[NumFaceNodes]; + /* Face Nodes for Face 1 */ + FaceNodes[0] = 1; + FaceNodes[1] = 2; + FaceNodes[2] = 3; + + /* Face Nodes for Face 2 */ + FaceNodes[3] = 3; + FaceNodes[4] = 2; + FaceNodes[5] = 4; + + /* Face Nodes for Face 3 */ + FaceNodes[6] = 5; + FaceNodes[7] = 2; + FaceNodes[8] = 4; + + /* Face Nodes for Face 4 */ + FaceNodes[9] = 1; + FaceNodes[10] = 2; + FaceNodes[11] = 5; + + /* Face Nodes for Face 5 */ + FaceNodes[12] = 1; + FaceNodes[13] = 5; + FaceNodes[14] = 4; + FaceNodes[15] = 3; + + /* Define the right and left elements of each face. + * + * The last step for writing out the polyhedral data is to + * define the right and left neighboring elements for each + * face. The neighboring elements can be determined using the + * right-hand rule. For each face, place your right-hand along + * the face which your fingers pointing the direction of + * incrementing node numbers (i.e. from node 1 to node 2). + * Your right thumb will point towards the right element; the + * element on the other side of your hand is the left element. + * + * The number zero is used to indicate that there isn't an + * element on that side of the face. + * + * Because of the way we numbered the nodes and faces, the + * right element for every face is the element itself + * (element 1) and the left element is "no-neighboring element" + * (element 0). + */ + + INTEGER4 *FaceLeftElems = new INTEGER4[NumFaces]; + FaceLeftElems[0] = 1; + FaceLeftElems[1] = 1; + FaceLeftElems[2] = 0; + FaceLeftElems[3] = 0; + FaceLeftElems[4] = 0; + + INTEGER4 *FaceRightElems = new INTEGER4[NumFaces]; + FaceRightElems[0] = 0; + FaceRightElems[1] = 0; + FaceRightElems[2] = 1; + FaceRightElems[3] = 1; + FaceRightElems[4] = 1; + + /* Write the face map (created above) using TECPOLY112. */ + I = TECPOLY112(FaceNodeCounts, /* The face node counts array */ + FaceNodes, /* The face nodes array */ + FaceLeftElems, /* The left elements array */ + FaceRightElems, /* The right elements array */ + NULL, /* No boundary connection counts */ + NULL, /* No boundary connection elements */ + NULL); /* No boundary connection zones */ + + delete FaceNodeCounts; + delete FaceNodes; + delete FaceLeftElems; + delete FaceRightElems; + + I = TECEND112(); + return 0; +} + +/* DOCEND */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/pyramid/pyramid.plt b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/pyramid/pyramid.plt new file mode 100644 index 0000000000000000000000000000000000000000..d85447466118fc7a63af724aa0bd550a2382ac6b GIT binary patch literal 600 zcmb7>I|{-;7=$-I5iC4H#Kx5I0tR9!Xd$9@qJn}C5F5K(!i#tgy^A-{nPg|t?fl`( z%E*OCoxB$L`KSMnca*Vf)=L0c}5+3VC$~~)aq~&gm3BJ6u**)bRC0q#Q zI9J|k^56N@_xk*Pn|5^?uR5uJuk(-cU)4YZG=X;K-r9|xbrm2Fn|t0dsH|a+g5Saq G<)|OuL_vB0 literal 0 HcmV?d00001 diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/pyramid/pyramid.vcproj b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/pyramid/pyramid.vcproj new file mode 100644 index 0000000000..e44e390db6 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/pyramid/pyramid.vcproj @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/Makefile b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/Makefile new file mode 100644 index 0000000000..9e40ebe34b --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/Makefile @@ -0,0 +1,11 @@ +# Set to appropriate C++ compiler +CPP=g++ +CPPFLAGS=-I../../tecsrc ../../tecio.a +EXECUTABLE=simtest +FILES=$(EXECUTABLE).c + +build: + $(CPP) $(FILES) $(CPPFLAGS) -o $(EXECUTABLE) + +clean: + rm -f $(EXECUTABLE) diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtest.c b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtest.c new file mode 100644 index 0000000000..fe35a33234 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtest.c @@ -0,0 +1,100 @@ +/* + * Simple example c program to write a + * binary datafile for tecplot. This example + * does the following: + * + * 1. Open a datafile called "t.plt" + * 2. Assign values for X,Y, and P + * 3. Write out a zone dimensioned 4x5 + * 4. Close the datafile. + */ + +#include "TECIO.h" + +#ifndef NULL +#define NULL 0 +#endif + +enum FileType { FULL = 0, GRID = 1, SOLUTION = 2 }; + +int main(void) +{ + float X[5][4], Y[5][4], P[5][4]; + double SolTime; + INTEGER4 Debug, I, J, III, DIsDouble, VIsDouble, IMax, JMax, KMax, ZoneType, StrandID, ParentZn, IsBlock; + INTEGER4 ICellMax, JCellMax, KCellMax, NFConns, FNMode, ShrConn, FileType; + + Debug = 1; + VIsDouble = 0; + DIsDouble = 0; + IMax = 4; + JMax = 5; + KMax = 1; + ZoneType = 0; /* Ordered */ + SolTime = 360.0; + StrandID = 0; /* StaticZone */ + ParentZn = 0; /* No Parent */ + IsBlock = 1; /* Block */ + ICellMax = 0; + JCellMax = 0; + KCellMax = 0; + NFConns = 0; + FNMode = 0; + ShrConn = 0; + FileType = FULL; + + /* + * Open the file and write the tecplot datafile + * header information + */ + I = TECINI112((char*)"SIMPLE DATASET", + (char*)"X Y P", + (char*)"t.plt", + (char*)".", + &FileType, + &Debug, + &VIsDouble); + + for (J = 0; J < 5; J++) + for (I = 0; I < 4; I++) + { + X[J][I] = (float)(I + 1); + Y[J][I] = (float)(J + 1); + P[J][I] = (float)((I + 1) * (J + 1)); + } + /* + * Write the zone header information. + */ + I = TECZNE112((char*)"Simple Zone", + &ZoneType, + &IMax, + &JMax, + &KMax, + &ICellMax, + &JCellMax, + &KCellMax, + &SolTime, + &StrandID, + &ParentZn, + &IsBlock, + &NFConns, + &FNMode, + 0, /* TotalNumFaceNodes */ + 0, /* NumConnectedBoundaryFaces */ + 0, /* TotalNumBoundaryConnections */ + NULL, /* PassiveVarList */ + NULL, /* ValueLocation = Nodal */ + NULL, /* SharVarFromZone */ + &ShrConn); + /* + * Write out the field data. + */ + III = IMax * JMax; + I = TECDAT112(&III, &X[0][0], &DIsDouble); + I = TECDAT112(&III, &Y[0][0], &DIsDouble); + I = TECDAT112(&III, &P[0][0], &DIsDouble); + + I = TECEND112(); + + return 0; +} diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtest.f b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtest.f new file mode 100644 index 0000000000..d980915100 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtest.f @@ -0,0 +1,98 @@ +C +C Simple example fortran program to write a +C binary datafile for tecplot. This example +C does the following: +C +C 1. Open a datafile called "t.plt" +C 2. Assign values for X,Y, and P +C 3. Write out a zone dimensioned 4x5 +C 4. Close the datafile. +C +C + program test + + INCLUDE 'tecio.inc' + + character*1 NULLCHR + Integer*4 Debug,III,NPts,NElm + + Dimension X(4,5), Y(4,5), P(4,5) + Real*8 SolTime + Integer*4 VIsDouble, FileType + Integer*4 ZoneType,StrandID,ParentZn,IsBlock + Integer*4 ICellMax,JCellMax,KCellMax,NFConns,FNMode,ShrConn + POINTER (NullPtr,Null) + Integer*4 Null(*) + + NULLCHR = CHAR(0) + NullPtr = 0 + Debug = 1 + FileType = 0 + VIsDouble = 0 + IMax = 4 + JMax = 5 + KMax = 1 + ZoneType = 0 + SolTime = 360.0 + StrandID = 0 + ParentZn = 0 + IsBlock = 1 + ICellMax = 0 + JCellMax = 0 + KCellMax = 0 + NFConns = 0 + FNMode = 0 + ShrConn = 0 +C +C... Open the file and write the tecplot datafile +C... header information. +C + I = TecIni112('SIMPLE DATASET'//NULLCHR, + & 'X Y P'//NULLCHR, + & 't.plt'//NULLCHR, + & '.'//NULLCHR, + & FileType, + & Debug, + & VIsDouble) + + Do 10 I = 1,4 + Do 10 J = 1,5 + X(I,J) = I + Y(I,J) = J + P(I,J) = I*J + 10 Continue +C +C... Write the zone header information. +C + I = TecZne112('Simple Zone'//NULLCHR, + & ZoneType, + & IMax, + & JMax, + & KMax, + & ICellMax, + & JCellMax, + & KCellMax, + & SolTime, + & StrandID, + & ParentZn, + & IsBlock, + & NFConns, + & FNMode, + & 0, + & 0, + & 0, + & Null, + & Null, + & Null, + & ShrConn) +C +C... Write out the field data. +C + III = IMax*JMax + I = TecDat112(III,X,0) + I = TecDat112(III,Y,0) + I = TecDat112(III,P,0) + + I = TecEnd112() + Stop + End diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtest.f90 b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtest.f90 new file mode 100644 index 0000000000..1706de5984 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtest.f90 @@ -0,0 +1,98 @@ +! +! Simple example fortran program to write a +! binary datafile for tecplot. This example +! does the following: +! +! 1. Open a datafile called "t.plt" +! 2. Assign values for X,Y, and P +! 3. Write out a zone dimensioned 4x5 +! 4. Close the datafile. +! +! + program test + + INCLUDE 'tecio.f90' + + character*1 NULLCHR + Integer*4 Debug,III,NPts,NElm + + Dimension X(4,5), Y(4,5), P(4,5) + Real*8 SolTime + Integer*4 VIsDouble, FileType + Integer*4 ZoneType,StrandID,ParentZn,IsBlock + Integer*4 ICellMax,JCellMax,KCellMax,NFConns,FNMode,ShrConn + POINTER (NullPtr,Null) + Integer*4 Null(*) + + NULLCHR = CHAR(0) + NullPtr = 0 + Debug = 1 + FileType = 0 + VIsDouble = 0 + IMax = 4 + JMax = 5 + KMax = 1 + ZoneType = 0 + SolTime = 360.0 + StrandID = 0 + ParentZn = 0 + IsBlock = 1 + ICellMax = 0 + JCellMax = 0 + KCellMax = 0 + NFConns = 0 + FNMode = 0 + ShrConn = 0 +! +!... Open the file and write the tecplot datafile +!... header information. +! + I = TecIni112('SIMPLE DATASET'//NULLCHR, & + 'X Y P'//NULLCHR, & + 't.plt'//NULLCHR, & + '.'//NULLCHR, & + FileType, & + Debug, & + VIsDouble) + + Do 10 I = 1,4 + Do 10 J = 1,5 + X(I,J) = I + Y(I,J) = J + P(I,J) = I*J + 10 Continue +! +!... Write the zone header information. +! + I = TecZne112('Simple Zone'//NULLCHR, & + ZoneType, & + IMax, & + JMax, & + KMax, & + ICellMax, & + JCellMax, & + KCellMax, & + SolTime, & + StrandID, & + ParentZn, & + IsBlock, & + NFConns, & + FNMode, & + 0, & + 0, & + 0, & + Null, & + Null, & + Null, & + ShrConn) +! +!... Write out the field data. +! + III = IMax*JMax + I = TecDat112(III,X,0) + I = TecDat112(III,Y,0) + I = TecDat112(III,P,0) + + I = TecEnd112() + Stop + End diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtestc.vcproj b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtestc.vcproj new file mode 100644 index 0000000000..814cc761f3 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtestc.vcproj @@ -0,0 +1,346 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtestf.vfproj b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtestf.vfproj new file mode 100644 index 0000000000..2b20da05b1 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/simtest/simtestf.vfproj @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/squares/Makefile b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/squares/Makefile new file mode 100644 index 0000000000..120b910d62 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/squares/Makefile @@ -0,0 +1,11 @@ +# Set to appropriate C++ compiler +CPP=g++ +CPPFLAGS=-I../../tecsrc ../../tecio.a +EXECUTABLE=squares +FILES=$(EXECUTABLE).cpp + +build: + $(CPP) $(FILES) $(CPPFLAGS) -o $(EXECUTABLE) + +clean: + rm -f $(EXECUTABLE) \ No newline at end of file diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/squares/squares.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/squares/squares.cpp new file mode 100644 index 0000000000..e5d9a0f5e2 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/squares/squares.cpp @@ -0,0 +1,124 @@ +/* This example creates a group of square geometries, each with a + * different fill color */ +#if defined _MSC_VER +#pragma warning (disable: 4996) /* Windows strcpy warning off */ +#endif + +/* DOCSTART:tecgeo.txt*/ +#include "TECIO.h" +#include + +int main() +{ + INTEGER4 Debug = 1; + INTEGER4 VIsDouble = 0; + INTEGER4 FileType = 0; + INTEGER4 I = 0; /* use to check return values */ + + + /* Open the file and write the tecplot datafile + * header information + */ + I = TECINI112((char*)"Square Geometries", + (char*)"X Y P", + (char*)"squares.plt", + (char*)".", + &FileType, + &Debug, + &VIsDouble); + + double ZPos = 0.0; /* N/A for squares */ + double XPos; + double YPos; + + INTEGER4 PosCoordMode = 0; /* use grid coordinates */ + + /* opt not to attach the text to a given zone. When text is + * attached to a given zone, it is displayed only when the zone + * is displayed. + */ + INTEGER4 AttachToZone = 0; + INTEGER4 Zone = 1; + + /* Set the Geometry Style Values */ + INTEGER4 Color = 0; /* set the outline color to + * black + */ + INTEGER4 IsFilled = 1; + INTEGER4 GeomType = 2; /* set the geometry type to + * square + */ + INTEGER4 LinePattern = 5; /* set the line pattern to + * DashDotDot + */ + double PatternLength = .1; + double LineThick = .2; + + /* N/A for square geometries */ + INTEGER4 NumPts = 100; + INTEGER4 ArrowStyle = 1; + INTEGER4 ArrowAttach = 0; + double ArrowSize = 1; + double ArrowAngle = 30; + INTEGER4 NumSegments = 15; + INTEGER4 NumSegPts = 25; + + + INTEGER4 Scope = 1; /* set the text to "local", i.e. + * available in the current frame + * only. + */ + INTEGER4 Clipping = 1; + + /* Specify the length of a side of the square. The units used + * are those defined with PosCoordMode. + */ + float XGeomData = 2.5; + + float YGeomData = 0; /* N/A for square geometries */ + float ZGeomData = 0; /* N/A for square geometries */ + + char * MFC = new char[128]; + strcpy(MFC, "SQUARE"); + + for (INTEGER4 ii = 0; ii <= 7; ii++) + { + INTEGER4 FillColor = ii; + XPos = (double) ii; + YPos = (double) ii; + + I = TECGEO112(&XPos, + &YPos, + &ZPos, + &PosCoordMode, + &AttachToZone, + &Zone, + &Color, + &FillColor, + &IsFilled, + &GeomType, + &LinePattern, + &PatternLength, + &LineThick, + &NumPts, + &ArrowStyle, + &ArrowAttach, + &ArrowSize, + &ArrowAngle, + &Scope, + &Clipping, + &NumSegments, + &NumSegPts, + &XGeomData, + &YGeomData, + &ZGeomData, + MFC); + } + + I = TECEND112(); + + delete MFC; + return 0; +} + +/* DOCEND */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/squares/squares.plt b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/squares/squares.plt new file mode 100644 index 0000000000000000000000000000000000000000..c8e0848cfae0353501b89930becf07c7dd920c72 GIT binary patch literal 1304 zcmY#Z3~>oFG&EvlfPi2iRS3kTK%5A~ML?Vi#0o&{4rS*9>0Btg1W1F_WJ3AHKpF&? zfj9!pVql1b(g9GKq2ahQhzYY3CX7!12LhNFNG%f(vjXv-l^-wpCI#3-=mh%|pcu@o zYLRvB535@2Q;T&if(|~g2l*!uh(m$c5r~6;*cFID0Hg<^Pr(7Zn?Bfs6*9nR1_qd$ zV0!8ACI$zHo8UCuO(3^`+(mykaX{S!qY>c*N(TeuCIP6MU^K!_ECc2y5vZGBG{Q}w hbUiTPBms33j7GSLZNS_l19cOOM!1QcE^gZ73;-e5)xZD% literal 0 HcmV?d00001 diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/squares/squares.vcproj b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/squares/squares.vcproj new file mode 100644 index 0000000000..359ce967c4 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/squares/squares.vcproj @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/text/Makefile b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/text/Makefile new file mode 100644 index 0000000000..415b65fd13 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/text/Makefile @@ -0,0 +1,11 @@ +# Set to appropriate C++ compiler +CPP=g++ +CPPFLAGS=-I../../tecsrc ../../tecio.a +EXECUTABLE=text +FILES=$(EXECUTABLE).cpp + +build: + $(CPP) $(FILES) $(CPPFLAGS) -o $(EXECUTABLE) + +clean: + rm -f $(EXECUTABLE) \ No newline at end of file diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/text/text.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/text/text.cpp new file mode 100644 index 0000000000..66df8d723d --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/text/text.cpp @@ -0,0 +1,112 @@ +/* This example demonstrates adding a text object to a Tecplot + * data file. + */ +#if defined _MSC_VER +#pragma warning (disable: 4996) /* Windows strcpy warning off */ +#endif + +/* DOCSTART:tectxt.txt*/ +#include "TECIO.h" +#include + +int main() +{ + /* Open the file & write the datafile header information */ + INTEGER4 Debug = 1; + INTEGER4 VIsDouble = 0; + INTEGER4 FileType = 0; + INTEGER4 I = 0; /* used to check the return value */ + + I = TECINI112((char*)"Text", + (char*)"X Y P", + (char*)"text.plt", + (char*)".", + &FileType, + &Debug, + &VIsDouble); + + /* Specify the X, Y and Z position of the anchor point */ + double XPos = 0.0; + double YPos = 1.0; + double ZPos = 0.0; /* N/A for 2D text */ + + INTEGER4 PosCoordMode = 0; /* use grid coordinates */ + + /* opt not to attach the text to a given zone. When text is + * attached to a given zone, it is displayed only when the zone + * is displayed. + */ + INTEGER4 AttachToZone = 0; + INTEGER4 Zone = 2; + + + /* Specify the font values */ + INTEGER4 Font = 1; /* Helvetica Bold */ + INTEGER4 FontHeightUnits = 2; /* in grid coordinates */ + double FontHeight = 18; + + /* Set the box style parameters */ + INTEGER4 BoxType = 1; /* filled box */ + double BoxMargin = .5; /* margin between the text + * and the text box + */ + double BoxLineThickness = .1; + INTEGER4 BoxColor = 0; /* set the box line color + * to black. + */ + INTEGER4 BoxFillColor = 1; /* set the box fill color + * to red. + */ + + /* set the font properties */ + double Angle = 30; /* angle of the text */ + INTEGER4 Anchor = 1; /* set the anchor point to + * the center of the text + * box. + */ + double LineSpacing = 1.5; + INTEGER4 TextColor = 7; /* set the font color to + * white + */ + + INTEGER4 Scope = 1; /* set the text to "local", + * i.e. available in the + * current frame only. + */ + INTEGER4 Clipping = 1; + + + char Text[60]; + char MFC[24]; + strcpy(Text, "Sample Text"); + strcpy(MFC, "My Macro"); + + I = TECTXT112(&XPos, + &YPos, + &ZPos, + &PosCoordMode, + &AttachToZone, + &Zone, + &Font, + &FontHeightUnits, + &FontHeight, + &BoxType, + &BoxMargin, + &BoxLineThickness, + &BoxColor, + &BoxFillColor, + &Angle, + &Anchor, + &LineSpacing, + &TextColor, + &Scope, + &Clipping, + Text, + MFC); + + I = TECEND112(); + + return 0; +} + +/* DOCEND */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/text/text.plt b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/text/text.plt new file mode 100644 index 0000000000000000000000000000000000000000..5d0ecd945ad1051efda3afc29c1ee7fcdc53a335 GIT binary patch literal 264 zcmY#Z3~>oFG&EvlfPfGnl?ucaKwJV5VqgZ+5m0s{ln#K>3=Kb>K}?u_m@osw2YVPB zB*z5fFc>+2_|+oo+#gnz*#BAi@se*+09Y+ZJhfQYBIw`)sNNs;AhG{Izz(E+fw&Tg s6`<@yAe{`vML?Vn#2^4t9}L7Gxm+MF0OA}V2Kh+=h_U&Pp<$CV00QeFD*ylh literal 0 HcmV?d00001 diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/text/text.vcproj b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/text/text.vcproj new file mode 100644 index 0000000000..9018c6a89c --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/examples/text/text.vcproj @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/pltview.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/pltview.cpp new file mode 100644 index 0000000000..fd9dd63976 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/pltview.cpp @@ -0,0 +1,559 @@ +/* + * 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/ + * + */ +/* +***************************************************************** +***************************************************************** +******* ******** +****** (C) Copyright 2004-2006 by Tecplot, Inc. ******** +****** (C) Copyright 1989-2003 by AMTEC ENGINEERING INC.******** +******* All Rights Reserved. ******** +******* ******** +***************************************************************** +***************************************************************** +*/ + + +/* +**************************************************************** +****************** BEGIN DEVELOPMENT NOTES ********************* +**************************************************************** + +BEGIN CODELOG PLTVIEW +V 09/04/98 +V **************************************************************** +V * Build 1.0 9-04-98 * +V **************************************************************** +END CODELOG + +********************************************************************* +* IMPORTANT NOTE: Only development notes for "pltview" stand-alone * +* belong in this file. See "ADDONVER.h" for changes * +* related to the add-on. * +********************************************************************* + +**************************************************************** +* V in column 1 marks date information. * +* C in column 1 marks notes on new changes. * +* B in column 1 marks notes on bug fixes. * +**************************************************************** + +**************************************************************** +****************** END DEVELOPMENT NOTES *********************** +**************************************************************** +*/ + +#if defined ADDON +#include "TECADDON.h" +#include "GUIDEFS.h" +#include "GUI.h" +#define READTEC TecUtilReadBinaryData +#define SHOWINFO(S) TecGUITextAppendString(Output_T_D1,S); +#define ERRMSG(S) TecUtilDialogErrMsg(S) +#define ALLOC_ARRAY(N,Type,S) (Type *)TecUtilStringAlloc((N)*sizeof(Type),"debug info") +#define FREE_ARRAY(N,S) TecUtilStringDealloc((char **)&N) +#define STRINGLISTGETSTRING(S,N) TecUtilStringListGetString(S,N) +#define STRINGLISTGETCOUNT(S) TecUtilStringListGetCount(S) +#define STRINGLISTDEALLOC(S) TecUtilStringListDealloc(S) +#else +#include "MASTER.h" +#include "GLOBAL.h" +#include "TASSERT.h" +#define ALLOC_ARRAY(N,Type,S) (Type *)TecAlloc((N)*sizeof(Type)) +#define FREE_ARRAY(N,S) TecFree((void *)N) +#include "ARRLIST.h" +#include "STRLIST.h" +#include "DATAUTIL.h" + +/* +#include "TECADDON.h" +#include "TECXXX.h" +#include "DATAUTIL.h" +#include "STRLIST.h" +*/ + +#define READTEC ReadTec +#define SHOWINFO(S) printf("%s",S); +#define ERRMSG(S) printf("Err: %s\n",S); +#define STRINGLISTGETSTRING(S,N) StringListGetString(S,(N)-1) +#define STRINGLISTGETCOUNT(S) StringListCount(S) +#define STRINGLISTDEALLOC(S) StringListDealloc(S) +#define MaxCharsUserRec 500 +#endif + + +static int GetNumPtsPerCell(ZoneType_e ZoneType) +{ + int NumPts = 0; + switch (ZoneType) + { + case ZoneType_FETriangle : NumPts = 3; break; + case ZoneType_FEQuad : NumPts = 4; break; + case ZoneType_FETetra : NumPts = 4; break; + case ZoneType_FEBrick : NumPts = 8; break; + default : NumPts = 0; + } + return (NumPts); +} + +static int GetNumPts(ZoneType_e ZoneType, + LgIndex_t NumPtsI, + LgIndex_t NumPtsJ, + LgIndex_t NumPtsK) +{ + int NumPts = 0; + switch (ZoneType) + { + case ZoneType_FETriangle : + case ZoneType_FEQuad : + case ZoneType_FETetra : + case ZoneType_FEBrick : + case ZoneType_FEPolygon : + case ZoneType_FEPolyhedron: NumPts = NumPtsI; break; + default : NumPts = NumPtsI*NumPtsJ*NumPtsK; + } + return (NumPts); +} + + + +static void DeallocHeaderInfo(char **DataSetTitle, + StringList_pa *VarNames, + StringList_pa *ZoneNames, + LgIndex_t **NumPtsI, + LgIndex_t **NumPtsJ, + LgIndex_t **NumPtsK, + ZoneType_e **ZoneType, + StringList_pa *UserRec) +{ + if (*DataSetTitle) + FREE_ARRAY(*DataSetTitle, "data set title"); + if (*VarNames) + STRINGLISTDEALLOC(VarNames); + if (*ZoneNames) + STRINGLISTDEALLOC(ZoneNames); + if (*NumPtsI) + FREE_ARRAY(*NumPtsI, "NumPtsI Array"); + if (*NumPtsJ) + FREE_ARRAY(*NumPtsJ, "NumPtsJ Array"); + if (*NumPtsK) + FREE_ARRAY(*NumPtsK, "NumPtsK Array"); + if (*ZoneType) + FREE_ARRAY(*ZoneType, "ZoneType Array"); + if (*UserRec) + STRINGLISTDEALLOC(UserRec); + + *DataSetTitle = NULL; + *VarNames = NULL; + *ZoneNames = NULL; + *NumPtsI = NULL; + *NumPtsJ = NULL; + *NumPtsK = NULL; + *ZoneType = NULL; + *UserRec = NULL; +} + + + +#define MAXCHARSINFOLINE 5000 + + +void ReportFileInfo(char *FName, + Boolean_t LoadRawData, + Boolean_t AllocateRawDataSpaceLocally) +{ + short IVersion; + EntIndex_t NumZones; + EntIndex_t NumVars; + char *DataSetTitle = NULL; + StringList_pa VarNames = NULL; + StringList_pa ZoneNames = NULL; + LgIndex_t *NumPtsI = NULL; + LgIndex_t *NumPtsJ = NULL; + LgIndex_t *NumPtsK = NULL; + ZoneType_e *ZoneType = NULL; + StringList_pa UserRec = NULL; + int CZ, CV; + char InfoLine[MAXCHARSINFOLINE+1]; + double **VDataBase = NULL; + NodeMap_t **NodeMap = NULL; + + /* + * Load in the header information only. + */ + + if (!READTEC(TRUE, + FName, + &IVersion, + &DataSetTitle, + &NumZones, + &NumVars, + &VarNames, + &ZoneNames, + &NumPtsI, + &NumPtsJ, + &NumPtsK, + &ZoneType, + &UserRec, + FALSE, + (NodeMap_t ***)NULL, + (double ***)NULL)) + { + sprintf(InfoLine, "Cannot read file \"%s\"\nor file is not a Tecplot binary data file.\n", FName); + ERRMSG(InfoLine); + } + else + { + Boolean_t IsOk = TRUE; + if (LoadRawData) + { + if (AllocateRawDataSpaceLocally) + { + int NumPts; + VDataBase = ALLOC_ARRAY(NumZones * NumVars, double *, "vdatabase array"); + for (CZ = 0; CZ < NumZones; CZ++) + for (CV = 0; CV < NumVars; CV++) + { + NumPts = GetNumPts(ZoneType[CZ], NumPtsI[CZ], NumPtsJ[CZ], NumPtsK[CZ]); + if (NumPts >= 1) + VDataBase[CZ*NumVars+CV] = ALLOC_ARRAY(NumPts, double, "vdatabase array"); + else + VDataBase[CZ*NumVars+CV] = NULL; + } + + NodeMap = ALLOC_ARRAY(NumZones, NodeMap_t *, "nodemap array"); + for (CZ = 0; CZ < NumZones; CZ++) + { + if (ZoneType[CZ] == ZoneType_Ordered) + NodeMap[CZ] = NULL; + else + { + int PtsPerCell = GetNumPtsPerCell(ZoneType[CZ]); + NodeMap[CZ] = ALLOC_ARRAY(PtsPerCell * NumPtsJ[CZ], + NodeMap_t, "zone nodemap"); + } + } + } + else + { + VDataBase = NULL; + NodeMap = NULL; + } + + /* + * NOTE: If any of the above alloc's failed then no big deal. ReadTec + * itself "skips" vars if memory was not allocated for it. + */ + + DeallocHeaderInfo(&DataSetTitle, + &VarNames, + &ZoneNames, + &NumPtsI, + &NumPtsJ, + &NumPtsK, + &ZoneType, + &UserRec); + + /* + * Reread the datafile. This time load in the header AND the raw data + * Note that VDataBase may be preallocated or may be left up to ReadTec + * to allocate (See AllocateRawDataSpaceLocally above). + */ + if (!READTEC(FALSE, + FName, + &IVersion, + &DataSetTitle, + &NumZones, + &NumVars, + &VarNames, + &ZoneNames, + &NumPtsI, + &NumPtsJ, + &NumPtsK, + &ZoneType, + &UserRec, + AllocateRawDataSpaceLocally, + &NodeMap, + &VDataBase)) + { + if (IVersion > 99) + { + sprintf(InfoLine, + "Error: ***\n" + " This add-on can only display raw nodal data\n" + " and it appears to contain cell centered data.\n"); + SHOWINFO(InfoLine); + } + else + { + sprintf(InfoLine, + "Cannot Read File, %s.\n" + "File may not be a tecplot binary data file.", + FName); + ERRMSG(InfoLine); + } + IsOk = FALSE; + } + } + + SHOWINFO("\n"); + sprintf(InfoLine, "FileName : %s\n", FName); + SHOWINFO(InfoLine); + sprintf(InfoLine, "File Version: %3.1f\n", IVersion / 10.0); + SHOWINFO(InfoLine); + + /* if the file contains filetype, then retrieve that separately since ReadTec should not be changed */ + if (IVersion >= 109) + { + DataFileType_e FileType = DataFileType_Full; + char FileTypeStr[32]; + FILE *F = NULL; + + /* open the file and get the filetype */ + F = fopen(FName, "rb"); + if (F) + { + char Buffer[8]; + Int32_t One; + Int32_t FileTypeInt; + + /* 8 bytes for magic# and version and 4 bytes for Int32 */ + fread(Buffer, sizeof(Buffer[0]), 8, F); + fread(&One, sizeof(One), 1, F); + fread(&FileTypeInt, sizeof(FileTypeInt), 1, F); + FileType = (DataFileType_e)FileTypeInt; + fclose(F); + F = NULL; + } + /* map the filetype */ + switch (FileType) + { + case DataFileType_Full: + strcpy(FileTypeStr, "Full"); + break; + case DataFileType_Grid: + strcpy(FileTypeStr, "Grid"); + break; + case DataFileType_Solution: + strcpy(FileTypeStr, "Solution"); + break; + default: + IsOk = FALSE; + CHECK(FALSE); + break; + } + sprintf(InfoLine, "File Type : %s\n", FileTypeStr); + SHOWINFO(InfoLine); + } + + sprintf(InfoLine, "DataSetTitle: %s\n", DataSetTitle ? DataSetTitle : " "); + SHOWINFO(InfoLine); + sprintf(InfoLine, "NumZones : %d\n", (int)NumZones); + SHOWINFO(InfoLine); + sprintf(InfoLine, "NumVars : %d\n", (int)NumVars); + SHOWINFO(InfoLine); + if (IsOk && (NumZones > 0)) + { + SHOWINFO("Var Names : "); + for (CZ = 0; CZ < NumVars; CZ++) + { + char *VarName = STRINGLISTGETSTRING(VarNames, CZ + 1); + sprintf(InfoLine, "%s", VarName ? VarName : "NULL"); + if (CZ < NumVars - 1) + strcat(InfoLine, ","); + else + strcat(InfoLine, "\n\n"); + SHOWINFO(InfoLine); + if (VarName) + FREE_ARRAY(VarName, "VarName array"); + } + SHOWINFO("ZoneName IMax JMax KMax Node Face Elmt EType\n"); + SHOWINFO("-------------------------------------------------------------------------------\n"); + + for (CZ = 0; CZ < NumZones; CZ++) + { + char *ZoneName = STRINGLISTGETSTRING(ZoneNames, CZ + 1); + if (ZoneType[CZ] != ZoneType_Ordered) + { + if (ZoneType[CZ] == ZoneType_FEPolygon || + ZoneType[CZ] == ZoneType_FEPolyhedron) + sprintf(InfoLine, "%-20s --- --- --- %-8ld %-8ld %-8ld ", + (ZoneName ? ZoneName : "NULL"), + (long)NumPtsI[CZ], + (long)NumPtsK[CZ], + (long)NumPtsJ[CZ]); + else + sprintf(InfoLine, "%-20s --- --- --- %-8ld --- %-8ld ", + (ZoneName ? ZoneName : "NULL"), + (long)NumPtsI[CZ], + (long)NumPtsJ[CZ]); + SHOWINFO(InfoLine); + switch (ZoneType[CZ]) + { + case ZoneType_FETriangle : SHOWINFO("Tri\n"); break; + case ZoneType_FEQuad : SHOWINFO("Quad\n"); break; + case ZoneType_FETetra : SHOWINFO("Tetra\n"); break; + case ZoneType_FEBrick : SHOWINFO("Brick\n"); break; + case ZoneType_FELineSeg : SHOWINFO("LineSeg\n"); break; + case ZoneType_FEPolygon : SHOWINFO("Polygon\n"); break; + case ZoneType_FEPolyhedron: SHOWINFO("Polyhed\n"); break; + default: CHECK(FALSE); break; + } + } + else + { + sprintf(InfoLine, "%-20s %-7ld %-7ld %-7ld --- --- --- ---\n", + (ZoneName ? ZoneName : "NULL"), + (long)NumPtsI[CZ], + (long)NumPtsJ[CZ], + (long)NumPtsK[CZ]); + SHOWINFO(InfoLine); + } + if (ZoneName) + FREE_ARRAY(ZoneName, "ZoneName Array"); + } + } + + if (IsOk) + { + for (CZ = 1; CZ <= STRINGLISTGETCOUNT(UserRec); CZ++) + { + char *S = STRINGLISTGETSTRING(UserRec, CZ); + if (S) + { + int L; + strcpy(InfoLine, "UserRec: "); + L = (int)strlen(InfoLine); + strncat(&InfoLine[L], S, MAXCHARSINFOLINE - L - 2); + strcat(&InfoLine[strlen(InfoLine)], "\n"); + SHOWINFO(InfoLine); + FREE_ARRAY(S, "temp string"); + } + } + + + if (LoadRawData) + { + for (CZ = 0; CZ < NumZones; CZ++) + { + int CV; + for (CV = 0; CV < NumVars; CV++) + if (VDataBase[CZ*NumVars+CV]) + { + int I; + int NumPts = GetNumPts(ZoneType[CZ], NumPtsI[CZ], NumPtsJ[CZ], NumPtsK[CZ]); + int SLen = 0; + sprintf(InfoLine, "\n\nVariable data for zone %d, Var %d\n", CZ + 1, CV + 1); + SHOWINFO(InfoLine); + InfoLine[0] = '\0'; + for (I = 0; I < NumPts; I++) + { + char PString[50]; + if (SLen + 50 > MAXCHARSINFOLINE) + { + SHOWINFO(InfoLine); + InfoLine[0] = '\0'; + SLen = 0; + } + + sprintf(PString, "%lG ", VDataBase[CZ*NumVars+CV][I]); + strcat(InfoLine, PString); + SLen += (int)strlen(PString); + + if ((I % 5) == 4) + { + strcat(InfoLine, "\n"); + SLen++; + } + } + if (*InfoLine) + SHOWINFO(InfoLine); + FREE_ARRAY(VDataBase[CZ*NumVars+CV], "vdatabase double"); + } + if (NodeMap[CZ]) + { + int I, J; + int PtsPerCell = GetNumPtsPerCell(ZoneType[CZ]); + int SLen = 0; + SHOWINFO("\nConnectivity list:\n"); + InfoLine[0] = '\0'; + for (J = 0; J < NumPtsJ[CZ]; J++) + { + if (SLen + 200 > MAXCHARSINFOLINE) + { + SHOWINFO(InfoLine); + InfoLine[0] = '\0'; + SLen = 0; + } + for (I = 0; I < PtsPerCell; I++) + { + char NString[20]; + sprintf(NString, "%u ", (unsigned int)NodeMap[CZ][J*PtsPerCell+I] + 1); + strcat(InfoLine, NString); + SLen += (int)strlen(NString); + } + strcat(InfoLine, "\n"); + SLen++; + } + if (*InfoLine) + SHOWINFO(InfoLine); + FREE_ARRAY(NodeMap[CZ], "nodemap"); + } + } + FREE_ARRAY(NodeMap, "Nodemap base array"); + FREE_ARRAY(VDataBase, "vdatabase base array"); + } + } + + SHOWINFO("\n\n"); + + DeallocHeaderInfo(&DataSetTitle, + &VarNames, + &ZoneNames, + &NumPtsI, + &NumPtsJ, + &NumPtsK, + &ZoneType, + &UserRec); + } +} + + + +#if !defined ADDON +int main(int argc, char *(argv[])) +{ + short CurFile; + + if (argc == 1) + { + printf("Err: Need: pltview file1 [file2] ...\n"); + exit(-1); + } + + for (CurFile = 1; CurFile < argc; CurFile++) + ReportFileInfo(argv[CurFile], FALSE, FALSE); + + return 0; +} +#endif diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/readme.txt b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/readme.txt new file mode 100644 index 0000000000..5b47bdb4ea --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/readme.txt @@ -0,0 +1,51 @@ +*********************************************** +** README ** +*********************************************** + +To build the TecIO library and/or the pltview utility +simply run the Runmake script in this directory. + +If customization is needed it will most likely be done +in GLOBAL.h (to identify machine as 64 bit) and/or in +dataio4.c. Just look for CRAY in dataio4.c and you +will find most of the critical areas. Note that the +existing code defined by CRAY is quite old and has +not been in use for some time. + +Each example has its own Makefile. You may have to adjust +the variables at the top of the Makefile for your platform. + + +ReadTec() + +The ReadTec() is included in the tecio library but is +not supported by Tecplot, Inc. ReadTec is used +to read Tecplot binary data files (all versions at or +older than the Tecplot version providing the tecio +library). See tecsrc/DATAUTIL.h for more information. + +The pltview example app gives an example of using ReadTec +to read just the header from a file as well as loading all +field data from a file./* + * 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/ + * + */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/ALLOC.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/ALLOC.h new file mode 100644 index 0000000000..f07fc07f90 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/ALLOC.h @@ -0,0 +1,205 @@ +/* + * 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/ + * + */ +/* +****************************************************************** +****************************************************************** +******* ******** +****** (C) 1988-2009 Tecplot, Inc. ******* +******* ******** +****************************************************************** +****************************************************************** +*/ +#ifndef ALLOC_H +#define ALLOC_H + +#include "TASSERT.h" +#if defined __cplusplus +#include +#endif + +#if !defined __cplusplus +#define ALLOC_ARRAY(N,Type,str) (Type *)malloc((N)*sizeof(Type)) +#define ALLOC_ITEM(Type,str) (Type *)malloc(sizeof(Type)) +#ifdef _DEBUG +/* NOTE: the pointer is set to 0xFFFF after the free for debug */ +/* versions in the hopes of catching invalid pointer usage */ +#define FREE_ARRAY(X,str) do { free((void *)(X)); *((void **)&(X)) = (void *)0xFFFF; } while (0) +#define FREE_ITEM(X,str) do { free((void *)(X)); *((void **)&(X)) = (void *)0xFFFF; } while (0) +#else +#define FREE_ARRAY(X,str) free((void *)(X)) +#define FREE_ITEM(X,str) free((void *)(X)) +#endif +#else +#ifdef TRACK_MEMORY_USAGE +extern void initMemoryUsageTracking(void); +extern void cleanUpMemoryUsageTracking(void); +extern void trackMemoryAlloc(size_t size); +extern void trackMemoryFree(size_t size); +extern void trackMemoryClearHighMark(void); +extern void trackMemorySaveHighMark(void); +extern void getMemoryUsage(size_t* memoryInUse, + size_t* memoryCurrentHighMark, + size_t* memorySavedHighMark, + size_t* memoryTotalHighMark); +#endif +/* +* Create a version of new that returns NULL instead +* of throwing std::bad_alloc. A lot of code is written using +* ALLOC_ITEM and ALLOC_ARRAY that expect a return value of +* NULL on failure instead of the exception. 2008-05-08 CAM +*/ +#if defined MSWIN && defined _DEBUG +template +inline T *nonExceptionNew(size_t numItems, + const char* fileName, + int lineNumber) +{ + REQUIRE(numItems > 0); + REQUIRE(VALID_REF(fileName)); + REQUIRE(lineNumber > 0); + T* result; + try + { +#ifdef DEBUG_NEW +#ifdef new +#undef new +#define USING_DEBUG_NEW +#endif + result = new(fileName, lineNumber) T[numItems]; +#ifdef USING_DEBUG_NEW +#define new DEBUG_NEW +#undef USING_DEBUG_NEW +#endif +#else + result = new T[numItems]; +#endif + } + catch (std::bad_alloc&) + { + result = NULL; + } +#ifdef TRACK_MEMORY_USAGE + if (result != NULL) + { +#ifdef MSWIN + trackMemoryAlloc(_msize(result)); +#else + trackMemoryAlloc(malloc_usable_size(result)); +#endif + } +#endif + ENSURE(VALID_REF_OR_NULL(result)); + return result; +} +#define ALLOC_ARRAY(N,Type,str) nonExceptionNew((N),__FILE__,__LINE__) +#else +template +inline T *nonExceptionNew(size_t numItems) +{ + REQUIRE(numItems > 0); + T *result; + try + { + result = new T[numItems]; + } + catch (std::bad_alloc&) + { + result = NULL; + } +#ifdef TRACK_MEMORY_USAGE + if (result != NULL) + { +#ifdef MSWIN + trackMemoryAlloc(_msize(result)); +#else + trackMemoryAlloc(malloc_usable_size(result)); +#endif + } +#endif + ENSURE(VALID_REF_OR_NULL(result)); + return result; +} +#define ALLOC_ARRAY(N,Type,str) nonExceptionNew((N)) +#endif +#define ALLOC_ITEM(Type,str) ALLOC_ARRAY(1,Type,str) + +/* +* Although delete doesn't throw exceptions, this function matches +* nonExceptionNew, and also reports the size of the block if we +* are tracking memory. +*/ +template +inline void nonExceptionDelete(T* &ptr) +{ +#if defined MSWIN && !defined NO_ASSERTS + CHECK(!IsBadReadPtr((void*)ptr, 1)); +#endif +#if defined TRACK_MEMORY_USAGE + if (ptr != NULL) + { +#ifdef MSWIN + trackMemoryFree(_msize(ptr)); +#else + trackMemoryFree(malloc_usable_size(ptr)); +#endif + } +#endif + + delete [] ptr; +#if !defined NO_ASSERTS + /* + * NOTE: the pointer is set to 0xFFFF after the free for asserted + * builds in the hopes of catching invalid pointer usage + */ + ptr = (T*)(void*)0xFFFF; +#endif +} +#define FREE_ARRAY(ptr,str) nonExceptionDelete((ptr)) +#define FREE_ITEM(ptr,str) FREE_ARRAY(ptr,str) +#endif + +/** +* The following functor can be used to easily deallocate memory from containers +* that hold pointers to allocated objects. For example: +* +* vector container; +* for (int ii = 0; ii < 10; ii++ +* container.push_back(new MyObject); +* ... do something with the objects ... +* ... now we need to clean up ... +* for_each(container.begin(), +* container.end(), +* DeleteItem()); +*/ +struct DeleteItem +{ + template + void operator()(T*& object) + { + delete object; + object = NULL; + } +}; + +#endif /* ALLOC_H */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/ARRLIST.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/ARRLIST.h new file mode 100644 index 0000000000..0203dae29b --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/ARRLIST.h @@ -0,0 +1,626 @@ +/* + * 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/ + * + */ +/* +***************************************************************** +***************************************************************** +******* ******** +****** Copyright (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +***************************************************************** +***************************************************************** +*/ +#if !defined ARRLIST_h +#define ARRLIST_h + +#if defined EXTERN +# undef EXTERN +#endif +#if defined ARRLISTMODULE +# define EXTERN +#else +# define EXTERN extern +#endif + +typedef enum +{ + ArrayListType_UnsignedChar, + ArrayListType_UnsignedShort, + ArrayListType_UnsignedInt, + ArrayListType_UnsignedLong, + ArrayListType_Int64, + ArrayListType_Char, + ArrayListType_Short, + ArrayListType_Int, + ArrayListType_Long, + ArrayListType_Float, + ArrayListType_Double, + ArrayListType_LgIndex, + ArrayListType_EntIndex, + ArrayListType_SmInteger, + ArrayListType_Boolean, + ArrayListType_ArbParam, + ArrayListType_UnsignedCharPtr, + ArrayListType_UnsignedShortPtr, + ArrayListType_UnsignedIntPtr, + ArrayListType_UnsignedLongPtr, + ArrayListType_Int64Ptr, + ArrayListType_CharPtr, + ArrayListType_ShortPtr, + ArrayListType_IntPtr, + ArrayListType_LongPtr, + ArrayListType_FloatPtr, + ArrayListType_DoublePtr, + ArrayListType_LgIndexPtr, + ArrayListType_EntIndexPtr, + ArrayListType_SmIntegerPtr, + ArrayListType_BooleanPtr, + ArrayListType_ArbParamPtr, + ArrayListType_VoidPtr, + ArrayListType_FunctionPtr, + ArrayListType_Any, + END_ArrayListType_e, + ArrayListType_Invalid = BadEnumValue +} ArrayListType_e; + +typedef union +{ + unsigned char UnsignedChar; + unsigned short UnsignedShort; + unsigned int UnsignedInt; + unsigned long UnsignedLong; + Int64_t Int64; + char Char; + short Short; + int Int; + long Long; + float Float; + double Double; + LgIndex_t LgIndex; + EntIndex_t EntIndex; + SmInteger_t SmInteger; + Boolean_t BBoolean; /* X-Windows uses Boolean */ + ArbParam_t ArbParam; + unsigned char *UnsignedCharPtr; + unsigned short *UnsignedShortPtr; + unsigned int *UnsignedIntPtr; + unsigned long *UnsignedLongPtr; + Int64_t *Int64Ptr; + char *CharPtr; + short *ShortPtr; + int *IntPtr; + long *LongPtr; + float *FloatPtr; + double *DoublePtr; + LgIndex_t *LgIndexPtr; + EntIndex_t *EntIndexPtr; + SmInteger_t *SmIntegerPtr; + Boolean_t *BooleanPtr; + ArbParam_t *ArbParamPtr; + void *VoidPtr; + void (*FunctionPtr)(void); +} ArrayListItem_u; + +/** + * NULL array list item for added convenience of inserting a NULL item without + * having to declare and assign one. Can be used as follows: + * + * IsOk = ArrayListInsertItem(SomeArrayList, SomeIndex, ArrayListNumItem); + * + * NOTE: This value must be set to zero before Tecplot uses array lists. + * memset(&ArrayListNullItem, 0, sizeof(ArrayListType_Any)); + */ +EXTERN ArrayListItem_u ArrayListNullItem; + +/** + * Visitor for traversing an array list. An iterator may not perform any + * operation that will adjust the size of the list. In other words it may not + * insert or delete items from the list. However an iterator may perform a get + * operation or a set operation that do not expand the list size. + * + * param ItemRef + * Reference to the array list item visited. + * param ClientData + * Any client data required for the visitor. + * + * return + * TRUE to continue visiting items, otherwise + * FALSE to discontinue visiting + */ +typedef Boolean_t (*ArrayListItemVisitor_pf)(void *ItemRef, + ArbParam_t ClientData); +#if 0 /* use this stub as a starting place */ +{ + REQUIRE(VALID_REF(TypeRef)); + REQUIRE(VALID_REF(*TypeRef) || *TypeRef == NULL); + + Boolean_t DoContinue = TRUE; + *TypeRef = ( *)ItemRef; + + ENSURE(VALID_BOOLEAN(DoContinue)); + return DoContinue; +} +#endif + + +/** + * Destructor for cleaning up one or more array list items. If a destructor is + * not supplied then the array items are simply discarded. + * + * NOTE: The only change to ArrayListItemVisitor_pf is the policy which + * requires that the return value is TRUE. + * + * param ItemRef + * Reference to the array list item to cleanup. + * param ClientData + * Any client data required for cleanup. + * + * return + * TRUE is a requirement + */ +typedef ArrayListItemVisitor_pf ArrayListItemDestructor_pf; + + +/** + * Duplicator for copying one or more array list items. If a duplicator is not + * supplied then the array items are simply copied. For pointer types this + * means by reference. Note that if a duplicator is used the rules for + * duplication and subsequent cleanup are defined by the client. + * + * param TargetItemRef + * Reference to the array list to receive the duplicate. + * param SourceItemRef + * Reference to the array list item to duplicate. + * param ClientData + * Any client data required for duplication. + * + * return + * TRUE if the duplication was a success + * FALSE otherwise. If the duplication failed it + * is the client's responsibility to cleanup any + * partial duplication + */ +typedef Boolean_t (*ArrayListItemDuplicator_pf)(void *TargetItemRef, + void *SourceItemRef, + ArbParam_t ClientData); +#if 0 /* use this stub as a starting place */ +{ + REQUIRE(VALID_REF(TargetTypeRef)); + REQUIRE(VALID_REF(SourceTypeRef)); + REQUIRE(VALID_REF(*SourceTypeRef) || *SourceTypeRef == NULL); + + Boolean_t IsOk = TRUE; + *TargetTypeRef = ( *)TargetItemRef; + *SourceTypeRef = ( *)SourceItemRef; + + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} +#endif + + +/** + * Adjusts the capacity request as necessary to minimize memory reallocations + * for large lists. Unless the request exceeds the maximum the adjusted + * capacity will be at least as big as requested however it may be larger if it + * is determined that the space requirement is growing faster. If the maximum + * is exceeded zero should be returned. + * + * param ArrayList + * Array list requesting the change in capacity. + * param CurrentCapacity + * Current capacity of the array list. + * param RequestedCapacity + * Capacity request or zero for default size. + * param ClientData + * Any client data needed for the adjustment. + * + * return + * Adjusted capacity that is at least as large as the request or zero if + * unable to satisfy the requested capacity. + */ +typedef LgIndex_t (*ArrayListCapacityRequestAdjuster_pf)(ArrayList_pa ArrayList, + LgIndex_t CurrentCapacity, + LgIndex_t RequestedCapacity, + ArbParam_t ClientData); +#if 0 /* use this stub as a starting place */ +{ + REQUIRE(ArrayListIsValid(ArrayList)); + REQUIRE((RequestedCapacity == 0 && CurrentCapacity == 0) || + RequestedCapacity > ArrayList->Capacity); + + LgIndex_t Result; + + ENSURE(Result == 0 || Result >= RequestedCapacity); + return Result; +} +#endif + + +/* private ArrayList structure: only exposed so STRUTIL can use it */ +typedef struct _ArrayList_s +{ + char *Array; /* byte array for holding the items */ + ArrayListType_e Type; /* type of array items */ + SmInteger_t ItemSize; /* byte size of an individual item */ + LgIndex_t Count; /* number of items in the array */ + LgIndex_t Capacity; /* maximum holding capacity of the array */ + Boolean_t IsVisitingItems; /* indicates if an iteration is in progress */ + ArrayListCapacityRequestAdjuster_pf CapacityRequestAdjuster; + ArbParam_t CapacityRequestAdjusterClientData; +} ArrayList_s; + + +/** + * Compares two array list elements. Note that either string may be + * NULL as array lists allow for NULL elements. + * + * @param Item1 + * Element to compare against Item2. + * @param Item2 + * Element to compare against Item1. + * @param ClientData + * Contextual information that was passed to the 'ArrayListQSort' function. + * + * @return + * - A value less than zero if Item1 is less than Item2. + * - A value of zero if Item1 is equal to Item2. + * - A value greater than zero if Item1 is greater than Item2. + */ +typedef int (STDCALL *ArrayListItemComparator_pf)(ArrayListItem_u Item1, + ArrayListItem_u Item2, + ArbParam_t ClientData); + +EXTERN Boolean_t ArrayListIsValid(ArrayList_pa ArrayList); +EXTERN ArrayListType_e ArrayListGetType(ArrayList_pa ArrayList); +EXTERN Boolean_t ArrayListEnlargeCapacity(ArrayList_pa ArrayList, + LgIndex_t RequestedCapacity); +EXTERN ArrayList_pa ArrayListAlloc(LgIndex_t EstimatedCapacity, + ArrayListType_e Type, + ArrayListCapacityRequestAdjuster_pf CapacityRequestAdjuster, + ArbParam_t CapacityRequestAdjusterClientData); +EXTERN void ArrayListDealloc(ArrayList_pa *ArrayList, + ArrayListItemDestructor_pf ItemDestructor, + ArbParam_t ClientData); +EXTERN void ArrayListDeleteAllItems(ArrayList_pa ArrayList, + ArrayListItemDestructor_pf ItemDestructor, + ArbParam_t ClientData); +EXTERN void ArrayListDeleteItems(ArrayList_pa ArrayList, + LgIndex_t ItemOffset, + LgIndex_t Count, + ArrayListItemDestructor_pf ItemDestructor, + ArbParam_t ClientData); +EXTERN void ArrayListDeleteItem(ArrayList_pa ArrayList, + LgIndex_t ItemOffset, + ArrayListItemDestructor_pf ItemDestructor, + ArbParam_t ClientData); +EXTERN ArrayList_pa ArrayListRemoveItems(ArrayList_pa ArrayList, + LgIndex_t ItemOffset, + LgIndex_t Count); +EXTERN ArrayListItem_u ArrayListRemoveItem(ArrayList_pa ArrayList, + LgIndex_t ItemOffset); +EXTERN Boolean_t ArrayListInsertItem(ArrayList_pa ArrayList, + LgIndex_t ItemOffset, + ArrayListItem_u Item); +EXTERN Boolean_t ArrayListInsert(ArrayList_pa Target, + LgIndex_t ItemOffset, + ArrayList_pa Source); +EXTERN Boolean_t ArrayListVisitItems(ArrayList_pa ArrayList, + LgIndex_t ItemOffset, + LgIndex_t Count, + ArrayListItemVisitor_pf ItemVisitor, + ArbParam_t ClientData); +EXTERN ArrayList_pa ArrayListGetItems(ArrayList_pa ArrayList, + LgIndex_t ItemOffset, + LgIndex_t Count); +EXTERN ArrayListItem_u ArrayListGetItem(ArrayList_pa ArrayList, + LgIndex_t ItemOffset); +EXTERN Boolean_t ArrayListSetItem(ArrayList_pa ArrayList, + LgIndex_t ItemOffset, + ArrayListItem_u Item, + ArrayListItemDestructor_pf ItemDestructor, + ArbParam_t ClientData); +EXTERN Boolean_t ArrayListAppendItem(ArrayList_pa ArrayList, + ArrayListItem_u Item); +EXTERN Boolean_t ArrayListAppend(ArrayList_pa Target, + ArrayList_pa Source); +EXTERN ArrayList_pa ArrayListCopy(ArrayList_pa ArrayList, + ArrayListItemDuplicator_pf ItemDuplicator, + ArbParam_t ClientData); +EXTERN void *ArrayListToArray(ArrayList_pa ArrayList, + ArrayListItemDuplicator_pf ItemDuplicator, + ArbParam_t ClientData); +EXTERN ArrayList_pa ArrayListFromArray(void *Source, + LgIndex_t Count, + ArrayListType_e Type, + ArrayListItemDuplicator_pf ItemDuplicator, + ArbParam_t ClientData); + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif +EXTERN void ArrayListQSort(ArrayList_pa ArrayList, + ArrayListItemComparator_pf Comparator, + ArbParam_t ClientData); +EXTERN Boolean_t ArrayListBSearch(ArrayList_pa ArrayList, + ArrayListItem_u Item, + ArrayListItemComparator_pf Comparator, + ArbParam_t ClientData, + LgIndex_t *ItemIndex); + +#if defined USE_MACROS_FOR_FUNCTIONS +/** + * Gets the array list's internal buffer representation. + * Use ArrayListGetXxx accessors whenever possible as their + * implementation in the release build is as fast as using + * the array directly anyway. + * + * WARNING: + * Some array list functions modify the internal buffer. + * This will invalidate this reference however it is + * the client's responsibility not to make further use + * of it. In addition, this reference should never be + * deallocated directly as the array list assumes the + * responsible for the cleanup. + * + * param ArrayList + * Array list for which a reference to the internal + * buffer is desired. + * + * return + * Reference to the array list's internal buffer. + */ +# define ArrayListGetInternalRef ArrayListGetInternalRef_MACRO +/** + * Gets the item's internal reference at the specified offset in the list. + * + * WARNING: + * Some array list functions modify the internal buffer. + * This will invalidate this reference however it is + * the client's responsibility not to make further use + * of it. In addition, this reference should never be + * deallocated directly as the array list assumes the + * responsible for the cleanup. + * + * param ArrayList + * Array list containing the desired item. + * param ItemOffset + * Offset to the item in the list. + * + * return + * The internal reference to the requested item. + */ +# define ArrayListGetItemInternalRef ArrayListGetItemInternalRef_MACRO +# define ArrayListGetCount ArrayListGetCount_MACRO + +# define ArrayListGetUnsignedChar(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, unsigned char) +# define ArrayListGetUnsignedShort(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, unsigned short) +# define ArrayListGetUnsignedInt(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, unsigned int) +# define ArrayListGetUnsignedLong(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, unsigned long) +# define ArrayListGetInt64(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, Int64_t) +# define ArrayListGetChar(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, char) +# define ArrayListGetShort(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, short) +# define ArrayListGetInt(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, int) +# define ArrayListGetLong(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, long) +# define ArrayListGetFloat(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, float) +# define ArrayListGetDouble(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, double) +# define ArrayListGetLgIndex(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, LgIndex_t) +# define ArrayListGetEntIndex(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, EntIndex_t) +# define ArrayListGetSmInteger(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, SmInteger_t) +# define ArrayListGetBoolean(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, Boolean_t) +# define ArrayListGetArbParam(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, ArbParam_t) +# define ArrayListGetUnsignedCharPtr(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, unsigned char *) +# define ArrayListGetUnsignedShortPtr(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, unsigned short *) +# define ArrayListGetUnsignedIntPtr(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, unsigned int *) +# define ArrayListGetUnsignedLongPtr(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, unsigned long *) +# define ArrayListGetInt64Ptr(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, Int64_t *) +# define ArrayListGetCharPtr(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, char *) +# define ArrayListGetShortPtr(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, short *) +# define ArrayListGetIntPtr(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, int *) +# define ArrayListGetLongPtr(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, long *) +# define ArrayListGetFloatPtr(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, float *) +# define ArrayListGetDoublePtr(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, double *) +# define ArrayListGetLgIndexPtr(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, LgIndex_t *) +# define ArrayListGetEntIndexPtr(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, EntIndex_t *) +# define ArrayListGetSmIntegerPtr(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, SmInteger_t *) +# define ArrayListGetBooleanPtr(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, Boolean_t *) +# define ArrayListGetArbParamPtr(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, ArbParam_t *) +# define ArrayListGetVoidPtr(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, void *) +# define ArrayListGetFunctionPtr(ArrayList, ItemOffset) ArrayListGetTypedItem(ArrayList, ItemOffset, (**)(void)) +#else +# define ArrayListGetInternalRef ArrayListGetInternalRef_FUNC +# define ArrayListGetItemInternalRef ArrayListGetItemInternalRef_FUNC +# define ArrayListGetCount ArrayListGetCount_FUNC + +# define ArrayListGetUnsignedChar(ArrayList, ItemOffset) (*((unsigned char *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetUnsignedShort(ArrayList, ItemOffset) (*((unsigned short *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetUnsignedInt(ArrayList, ItemOffset) (*((unsigned int *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetUnsignedLong(ArrayList, ItemOffset) (*((unsigned long *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetInt64(ArrayList, ItemOffset) (*((Int64_t *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetChar(ArrayList, ItemOffset) (*((char *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetShort(ArrayList, ItemOffset) (*((short *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetInt(ArrayList, ItemOffset) (*((int *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetLong(ArrayList, ItemOffset) (*((long *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetFloat(ArrayList, ItemOffset) (*((float *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetDouble(ArrayList, ItemOffset) (*((double *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetLgIndex(ArrayList, ItemOffset) (*((LgIndex_t *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetEntIndex(ArrayList, ItemOffset) (*((EntIndex_t *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetSmInteger(ArrayList, ItemOffset) (*((SmInteger_t *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetBoolean(ArrayList, ItemOffset) (*((Boolean_t *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetArbParam(ArrayList, ItemOffset) (*((ArbParam_t *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetUnsignedCharPtr(ArrayList, ItemOffset) (*((unsigned char * *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetUnsignedShortPtr(ArrayList, ItemOffset) (*((unsigned short * *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetUnsignedIntPtr(ArrayList, ItemOffset) (*((unsigned int * *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetUnsignedLongPtr(ArrayList, ItemOffset) (*((unsigned long * *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetInt64Ptr(ArrayList, ItemOffset) (*((Int64_t * *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetCharPtr(ArrayList, ItemOffset) (*((char * *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetShortPtr(ArrayList, ItemOffset) (*((short * *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetIntPtr(ArrayList, ItemOffset) (*((int * *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetLongPtr(ArrayList, ItemOffset) (*((long * *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetFloatPtr(ArrayList, ItemOffset) (*((float * *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetDoublePtr(ArrayList, ItemOffset) (*((double * *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetLgIndexPtr(ArrayList, ItemOffset) (*((LgIndex_t * *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetEntIndexPtr(ArrayList, ItemOffset) (*((EntIndex_t * *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetSmIntegerPtr(ArrayList, ItemOffset) (*((SmInteger_t * *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetBooleanPtr(ArrayList, ItemOffset) (*((Boolean_t * *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetArbParamPtr(ArrayList, ItemOffset) (*((ArbParam_t * *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetVoidPtr(ArrayList, ItemOffset) (*((void * *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +# define ArrayListGetFunctionPtr(ArrayList, ItemOffset) (*(((**)(void) *)ArrayListGetItemInternalRef_FUNC(ArrayList, ItemOffset))) +#endif + +#if !defined USE_MACROS_FOR_FUNCTIONS +EXTERN const void *ArrayListGetInternalRef_FUNC(ArrayList_pa ArrayList); +EXTERN const void *ArrayListGetItemInternalRef_FUNC(ArrayList_pa ArrayList, + LgIndex_t ItemOffset); +EXTERN LgIndex_t ArrayListGetCount_FUNC(ArrayList_pa ArrayList); +#endif + +#define ArrayListGetInternalRef_MACRO(ArrayList) ((const void *)((ArrayList)->Array)) +#define ArrayListGetItemInternalRef_MACRO(ArrayList, ItemOffset) ((const void *)&((ArrayList)->Array[(ItemOffset)*(ArrayList)->ItemSize])) +#define ArrayListGetCount_MACRO(ArrayList) ((ArrayList)->Count) +#define ArrayListGetTypedArrayRef(ArrayList, NativeType) ((NativeType *)((ArrayList)->Array)) +#define ArrayListGetTypedItem(ArrayList, ItemOffset, NativeType) (ArrayListGetTypedArrayRef(ArrayList,NativeType)[ItemOffset]) + +/** + * Simple macro to determine if the item offset is within the array list + * capacity. In the debug or checked builds we also perform a lower bound + * assertion check. + */ +#if defined NO_ASSERTS +# define ArrayListOffsetWithinCapacity(ArrayList, ItemOffset) ((ItemOffset) < (ArrayList)->Capacity) +#else +/** + * Using 'assert' rather than 'REQUIRE' because under Windows, REQUIRE (and ASSERT) trickles down to being a + * do-while loop, which doesn't jive well with the comma operator. + */ +# define ArrayListOffsetWithinCapacity(ArrayList, ItemOffset) ((assert((ItemOffset) >= 0),TRUE) && ((ItemOffset) < (ArrayList)->Capacity)) +#endif + +/** + * Places the item at the specified offset. If the offset is beyond the + * end of the list it is sized accordingly and the intervening items + * between the last item of the original state and the last item of the + * new state are guaranteed to be 0. + * + * This is the workhorse of the set and append convenience macros that follow. + * Please note that unlike ArrayListSetItem no destructor facility is provided + * therefore if an item previously occupied 'ItemOffset' it will be replaced. + * + * param ArrayList + * Array list target in which to set the item. + * param ItemOffset + * Offset of the item. + * param Item + * Item to set at the specified offset. Its native type must + * match 'NativeType' + * param NativeType + * Native type of 'Item'. + * + * return + * TRUE if sufficient memory permitted the operation, otherwise FALSE. + */ +#define ArrayListSetTypedItem(ArrayList, ItemOffset, Item, NativeType) \ + ((ArrayListOffsetWithinCapacity((ArrayList), (ItemOffset)) || \ + ArrayListEnlargeCapacity((ArrayList), (ItemOffset)+1)) \ + ? (((((NativeType *)((ArrayList)->Array))[(ItemOffset)]) = (Item)), \ + (((ItemOffset)+1 > (ArrayList)->Count) \ + ? (((ArrayList)->Count = (ItemOffset)+1), TRUE) \ + : (TRUE))) \ + : (FALSE)) + +/** + * This section provides macros for high speed setting and appending to an + * array list of a known type. The only additional overhead incurred versus just + * using a simple array is the cost of testing the array list capacity. + */ +#define ArrayListSetUnsignedChar(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, unsigned char) +#define ArrayListSetUnsignedShort(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, unsigned short) +#define ArrayListSetUnsignedInt(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, unsigned int) +#define ArrayListSetUnsignedLong(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, unsigned long) +#define ArrayListSetInt64(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, Int64_t) +#define ArrayListSetChar(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, char) +#define ArrayListSetShort(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, short) +#define ArrayListSetInt(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, int) +#define ArrayListSetLong(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, long) +#define ArrayListSetFloat(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, float) +#define ArrayListSetDouble(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, double) +#define ArrayListSetLgIndex(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, LgIndex_t) +#define ArrayListSetEntIndex(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, EntIndex_t) +#define ArrayListSetSmInteger(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, SmInteger_t) +#define ArrayListSetBoolean(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, Boolean_t) +#define ArrayListSetArbParam(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, ArbParam_t) +#define ArrayListSetUnsignedCharPtr(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, unsigned char *) +#define ArrayListSetUnsignedShortPtr(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, unsigned short *) +#define ArrayListSetUnsignedIntPtr(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, unsigned int *) +#define ArrayListSetUnsignedLongPtr(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, unsigned long *) +#define ArrayListSetInt64Ptr(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, Int64_t *) +#define ArrayListSetCharPtr(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, char *) +#define ArrayListSetShortPtr(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, short *) +#define ArrayListSetIntPtr(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, int *) +#define ArrayListSetLongPtr(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, long *) +#define ArrayListSetFloatPtr(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, float *) +#define ArrayListSetDoublePtr(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, double *) +#define ArrayListSetLgIndexPtr(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, LgIndex_t *) +#define ArrayListSetEntIndexPtr(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, EntIndex_t *) +#define ArrayListSetSmIntegerPtr(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, SmInteger_t *) +#define ArrayListSetBooleanPtr(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, Boolean_t *) +#define ArrayListSetArbParamPtr(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, ArbParam_t *) +#define ArrayListSetVoidPtr(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, void *) +#define ArrayListSetFunctionPtr(ArrayList, ItemOffset, Item) ArrayListSetTypedItem(ArrayList, ItemOffset, Item, (**)(void)) + +#define ArrayListAppendUnsignedChar(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, unsigned char) +#define ArrayListAppendUnsignedShort(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, unsigned short) +#define ArrayListAppendUnsignedInt(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, unsigned int) +#define ArrayListAppendUnsignedLong(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, unsigned long) +#define ArrayListAppendInt64(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, Int64_t) +#define ArrayListAppendChar(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, char) +#define ArrayListAppendShort(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, short) +#define ArrayListAppendInt(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, int) +#define ArrayListAppendLong(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, long) +#define ArrayListAppendFloat(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, float) +#define ArrayListAppendDouble(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, double) +#define ArrayListAppendLgIndex(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, LgIndex_t) +#define ArrayListAppendEntIndex(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, EntIndex_t) +#define ArrayListAppendSmInteger(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, SmInteger_t) +#define ArrayListAppendBoolean(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, Boolean_t) +#define ArrayListAppendArbParam(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, ArbParam_t) +#define ArrayListAppendUnsignedCharPtr(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, unsigned char *) +#define ArrayListAppendUnsignedShortPtr(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, unsigned short *) +#define ArrayListAppendUnsignedIntPtr(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, unsigned int *) +#define ArrayListAppendUnsignedLongPtr(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, unsigned long *) +#define ArrayListAppendInt64Ptr(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, Int64_t *) +#define ArrayListAppendCharPtr(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, char *) +#define ArrayListAppendShortPtr(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, short *) +#define ArrayListAppendIntPtr(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, int *) +#define ArrayListAppendLongPtr(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, long *) +#define ArrayListAppendFloatPtr(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, float *) +#define ArrayListAppendDoublePtr(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, double *) +#define ArrayListAppendLgIndexPtr(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, LgIndex_t *) +#define ArrayListAppendEntIndexPtr(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, EntIndex_t *) +#define ArrayListAppendSmIntegerPtr(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, SmInteger_t *) +#define ArrayListAppendBooleanPtr(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, Boolean_t *) +#define ArrayListAppendArbParamPtr(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, ArbParam_t *) +#define ArrayListAppendVoidPtr(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, void *) +#define ArrayListAppendFunctionPtr(ArrayList, Item) ArrayListSetTypedItem(ArrayList, (ArrayList)->Count, Item, (**)(void)) + +#endif /* ARRLIST_h */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/AUXDATA.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/AUXDATA.h new file mode 100644 index 0000000000..27c4747a3d --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/AUXDATA.h @@ -0,0 +1,130 @@ +/* + * 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/ + * + */ +/* + ***************************************************************** + ***************************************************************** + ******* ******** + ****** Copyright (C) 1988-2008 Tecplot, Inc. ******* + ******* ******** + ***************************************************************** + ***************************************************************** + */ +#if !defined AUXDATA_h +#define AUXDATA_h + +#if defined EXTERN +# undef EXTERN +#endif +#if defined AUXDATAMODULE +# define EXTERN +#else +# define EXTERN extern +#endif + +/** + */ +EXTERN Boolean_t AuxDataIsValidNameChar(char Char, + Boolean_t IsLeadChar); +/** + */ +EXTERN Boolean_t AuxDataIsValidName(const char *Name); + +/** + */ +EXTERN AuxData_pa AuxDataAlloc(void); + +/** + */ +EXTERN void AuxDataDealloc(AuxData_pa *AuxData); + +/** + */ +EXTERN Boolean_t AuxDataItemDestructor(void *ItemRef, + ArbParam_t ClientData); +/** + */ +EXTERN AuxData_pa AuxDataCopy(AuxData_pa AuxData, + Boolean_t ConsiderRetain); + +/** + */ +EXTERN LgIndex_t AuxDataGetNumItems(AuxData_pa AuxData); + +/** + */ +EXTERN Boolean_t AuxDataGetItemIndex(AuxData_pa AuxData, + const char *Name, + LgIndex_t *ItemIndex); +/** + */ +EXTERN void AuxDataGetItemByIndex(AuxData_pa AuxData, + LgIndex_t Index, + const char **Name, + ArbParam_t *Value, + AuxDataType_e *Type, + Boolean_t *Retain); + +/** + */ +EXTERN Boolean_t AuxDataGetItemByName(AuxData_pa AuxData, + const char *Name, + ArbParam_t *Value, + AuxDataType_e *Type, + Boolean_t *Retain); + +/** + */ +EXTERN Boolean_t AuxDataGetBooleanItemByName(AuxData_pa AuxData, + const char *Name, + Boolean_t *Value, + AuxDataType_e *Type, + Boolean_t *Retain); + +/** + */ +EXTERN Boolean_t AuxDataSetItem(AuxData_pa AuxData, + const char *Name, + ArbParam_t Value, + AuxDataType_e Type, + Boolean_t Retain); + +/** + */ +EXTERN Boolean_t AuxDataDeleteItemByName(AuxData_pa AuxData, + const char *Name); + +/** + */ +EXTERN Boolean_t AuxDataAppendItems(AuxData_pa TargetAuxData, + AuxData_pa SourceAuxData); +/** + */ +EXTERN void AuxDataDeleteItemByIndex(AuxData_pa AuxData, + LgIndex_t Index); + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ + +#endif /* !defined AUXDATA_h */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATAIO.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATAIO.h new file mode 100644 index 0000000000..c57df19edd --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATAIO.h @@ -0,0 +1,63 @@ +/* + * 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/ + * + */ +#if defined EXTERN +#undef EXTERN +#endif +#if defined DATAIOMODULE +#define EXTERN +#else +#define EXTERN extern +#endif + +EXTERN Boolean_t OpenBinaryFileAndCheckMagicNumber(FileStream_s **FileStream, + char *FName, + FileOffset_t StartOffset, + short *IVersion); + +EXTERN 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, + Boolean_t *HasText, + Boolean_t *HasGeoms, + ArrayList_pa *ZoneSpecList, + StringList_pa *VarNames, + ArrayList_pa *VarAuxDataList, /*[NumVars]*/ + Set_pa *IsRawFNAvailable, /* classic data only */ + LgIndex_t **FNNumBndryConns, /* classic data only */ + DataFileType_e *FileType); + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATAIO4.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATAIO4.h new file mode 100644 index 0000000000..7e97dc98f6 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATAIO4.h @@ -0,0 +1,213 @@ +/* + * 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/ + * + */ +#ifndef DATAIO4_H +#define DATAIO4_H +/* +****************************************************************** +****************************************************************** +******* ******** +****** (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +****************************************************************** +****************************************************************** +*/ + +#include + +#if defined EXTERN +#undef EXTERN +#endif +#if defined DATAIO4MODULE +#define EXTERN +#else +#define EXTERN extern +#endif + +EXTERN double GetNextValue(FileStream_s *FileStream, + FieldDataType_e FieldDataType, + double Min, + double Max, + Boolean_t *IsOk); +EXTERN LgIndex_t GetNextI(FileStream_s *FileStream, + Boolean_t *IsOk); +EXTERN LgIndex_t GetIoFileInt(FileStream_s *FileStream, + short Version, + LgIndex_t Min, + LgIndex_t Max, + Boolean_t *IsOk); +EXTERN Boolean_t ReadInString(FileStream_s *FileStream, + short IVersion, + int MaxCharacters, + char **S, + Boolean_t ProcessData); +EXTERN void ReadByteBlock(FileStream_s *FileStream, + Boolean_t DoRead, + Byte_t *Buffer, + HgIndex_t StartIndex, + HgIndex_t NumValues, + Boolean_t *IsOk); +EXTERN void ReadInt16Block(FileStream_s *FileStream, + Boolean_t DoRead, + Int16_t *Buffer, + HgIndex_t StartIndex, + HgIndex_t NumValues, + Boolean_t *IsOk); +EXTERN void ReadInt16BlockToInt32(FileStream_s *FileStream, + Boolean_t DoRead, + Int32_t *Buffer, + HgIndex_t StartIndex, + HgIndex_t NumValues, + Boolean_t *IsOk); +EXTERN void ReadInt32Block(FileStream_s *FileStream, + Boolean_t DoRead, + Int32_t *Buffer, + HgIndex_t StartIndex, + HgIndex_t NumValues, + Boolean_t *IsOk); +EXTERN void ReadPureBlock(FileStream_s *FileStream, + Boolean_t DoRead, + void *Buffer, + FieldDataType_e FieldDataType, + HgIndex_t StartIndex, + HgIndex_t NumValues, + Boolean_t *IsOk); +EXTERN void ReadBlock(FileStream_s *FileStream, + FieldData_pa FieldData, + Boolean_t DoRead, + FieldDataType_e FieldDataTypeInFile, + HgIndex_t StartIndex, + HgIndex_t EndIndex, + Boolean_t *IsOk); +EXTERN void ReadClassicOrderedCCBlock(FileStream_s *DataFileStream, + FieldData_pa FieldData, + FieldDataType_e FieldDataTypeInFile, + LgIndex_t NumIPtsInFile, + LgIndex_t NumJPtsInFile, + LgIndex_t NumKPtsInFile, + Boolean_t *IsOk); +EXTERN Boolean_t ReadInDataFileTypeTitleAndVarNames(FileStream_s *FileStream, + short IVersion, + char **DataSetTitle, + DataFileType_e *FileType, + int *NumVars, + StringList_pa *VarNames); +EXTERN Boolean_t ReadInZoneHeader(FileStream_s *FileStream, + short IVersion, + ZoneSpec_s *ZoneSpec, + Set_pa IsVarCellCentered, + EntIndex_t NumVars, + Boolean_t *IsRawFNAvailable, + LgIndex_t *FNNumBndryConns); +EXTERN Boolean_t ReadInCustomLabels(FileStream_s *FileStream, + short IVersion, + Boolean_t OkToLoad, + StringList_pa *CustomLabelBase); +EXTERN Boolean_t ReadInUserRec(FileStream_s *FileStream, + short IVersion, + int MaxCharactersAllowed, + char **UserRec); +EXTERN Boolean_t ReadInAuxData(FileStream_s *FileStream, + short IVersion, + AuxData_pa AuxData); +EXTERN Boolean_t ReadInGeometry(FileStream_s *FileStream, + short IVersion, + Boolean_t OkToLoad, + Geom_s *G, + LgIndex_t MaxDataPts); +EXTERN Boolean_t ReadInText(FileStream_s *FileStream, + short IVersion, + Boolean_t OkToLoad, + Text_s *T, + LgIndex_t MaxTextLen); +/* + * STDCALL since PreplotAsciiDatafile is sent to RegisterDataSetReader + * which can also be used by addons. + */ +EXTERN Boolean_t STDCALL PreplotAsciiDatafile(char *CurFName, + char *BinaryFName, + char **MessageString); +EXTERN short GetInputVersion(FileStream_s *FileStream); + +EXTERN Boolean_t WriteBinaryInt16BlockUnaligned(FileStream_s *FileStream, + Byte_t *Int16Values, + HgIndex_t NumValues, + Boolean_t ValuesInNativeOrdering); +EXTERN Boolean_t WriteBinaryInt32BlockUnaligned(FileStream_s *FileStream, + Byte_t *Int32Values, + HgIndex_t NumValues, + Boolean_t ValuesInNativeOrdering); +EXTERN Boolean_t WriteBinaryByteBlock(FileStream_s *FileStream, + const Byte_t *ByteValues, + const HgIndex_t NumValues); +EXTERN Boolean_t WriteBinaryInt16(FileStream_s *FileStream, + Int16_t Value); +EXTERN Boolean_t WriteBinaryInt32(FileStream_s *FileStream, + Int32_t Value); +EXTERN Boolean_t WriteBinaryReal(FileStream_s *FileStream, + double RR, + FieldDataType_e FieldDataType); +EXTERN Boolean_t WriteFieldDataType(FileStream_s *FileStream, + FieldDataType_e FDT, + Boolean_t WriteBinary); +EXTERN Boolean_t WriteBinaryFieldDataBlock(FileStream_s *FileStream, + FieldData_pa D, + LgIndex_t StartI, + LgIndex_t NumValues); +EXTERN Boolean_t WriteCCFieldDataBlock(FileStream_s *FileStream, + FieldData_pa FieldData, + Boolean_t IsOrderedData, + LgIndex_t NumIPts, + LgIndex_t NumJPts, + LgIndex_t NumKPts, + Boolean_t WriteBinary, + SmInteger_t AsciiPrecision); +EXTERN Boolean_t DumpDatafileString(FileStream_s *FileStream, + const char *S, + Boolean_t WriteBinary); +bool DumpGeometry(FileStream_s* FileStream, + Geom_s const* Geom, + Boolean_t WriteBinary, + Boolean_t WriteGridDataAsPolar); +bool DumpText(FileStream_s* FileStream, + Text_s const* Text, + Boolean_t WriteBinary, + Boolean_t WriteGridDataAsPolar); +EXTERN Boolean_t DumpCustomAxisLabels(FileStream_s *FileStream, + Boolean_t WriteBinary, + StringList_pa LabelBase); + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +EXTERN Boolean_t WriteBinaryMagic(FileStream_s *FileStream); + +bool writeBinaryVersionNumber(FileStream_s& fileStream, + int versionNumber); + +#endif //DATAIO4_H diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATASET.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATASET.h new file mode 100644 index 0000000000..89cc27ff9c --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATASET.h @@ -0,0 +1,90 @@ +/* + * 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/ + * + */ +#ifndef DATASET_h__ +#define DATASET_h__ + +/* +****************************************************************** +****************************************************************** +******* ******** +****** (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +****************************************************************** +****************************************************************** +*/ + + +/* + * DataSet functions involving zones, vars and the + * DataSet_s structure. See dataset0.c for low level + * dataset functions and dataset2 for higher level + * functions. + */ + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if defined USE_MACROS_FOR_FUNCTIONS +#else +#endif +#endif /* TECPLOTKERNEL */ + +Boolean_t FieldDataItemDestructor(void *ItemRef, + ArbParam_t ClientData); +Boolean_t ZoneSpecItemDestructor(void *ItemRef, + ArbParam_t ClientData); +LgIndex_t ZoneOrVarListAdjustCapacityRequest(ArrayList_pa ZoneOrVarArrayList, + LgIndex_t CurrentCapacity, + LgIndex_t RequestedCapacity, + ArbParam_t ClientData); +void CleanoutZoneSpec(ZoneSpec_s *ZoneSpec); +void ZoneSpecExcludeBndryConnsFromMetrics(ZoneSpec_s* ZoneSpec); +ZoneSpec_s *ZoneSpecAlloc(void); +void ZoneSpecDealloc(ZoneSpec_s **ZoneSpec); +void SetZoneSpecDefaults(ZoneSpec_s *ZoneSpec); + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if defined USE_MACROS_FOR_FUNCTIONS +#else +#endif +#endif + +#define GetZoneSpec(ZoneSpecList,Zone) ((ZoneSpec_s *)ArrayListGetVoidPtr(ZoneSpecList,Zone)) +#define GetZoneAuxData(DataSet, Zone) (GetZoneSpec((DataSet)->ZoneSpecList, (Zone))->AuxData) +#define GetVarSpec(VarSpecList,Var) ((VarSpec_s *)ArrayListGetVoidPtr(VarSpecList,Var)) +#define GetVarAuxData(DataSet, Var) (GetVarSpec((DataSet)->VarSpecList, (Var))->AuxData) +#define GetStrandInfo(StrandInfoList, StrandID) ((StrandInfo_s *)ArrayListGetVoidPtr(StrandInfoList,StrandID)) + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* defined TECPLOTKERNEL */ + +#endif // DATASET_h__ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATASET0.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATASET0.h new file mode 100644 index 0000000000..ee33773f30 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATASET0.h @@ -0,0 +1,404 @@ +/* + * 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/ + * + */ +#if defined EXTERN +#undef EXTERN +#endif +#if defined DATASET0MODULE +#define EXTERN +#else +#define EXTERN extern +#endif + +/* +****************************************************************** +****************************************************************** +******* ******** +****** (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +****************************************************************** +****************************************************************** +*/ + +namespace tecplot +{ +namespace io +{ +class File; +} +} + +EXTERN void OutOfMemoryMsg(void); + +/* + * Turn on DEBUG_FIELDVALUES by default in any build with assertions on + * (including checked builds), but allow turning this off with + * NO_DEBUG_FIELDVALUES + */ +#if !defined NO_ASSERTS && !defined NO_DEBUG_FIELDVALUES && !defined DEBUG_FIELDVALUES +#define DEBUG_FIELDVALUES +#endif + +/* FieldData_a is intentionally not defined to further + * deter usage of this private structure */ +struct _FieldData_a +{ + void *Data; /* ...placed first in the structure for fastest access */ +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# else + void *GetValueCallback[1]; /* ...this field is for TecIO only */ + void *SetValueCallback[1]; /* ...this field is for TecIO only */ +# endif + + /* PRIVATE */ + FieldDataType_e Type; + ValueLocation_e ValueLocation; + LgIndex_t RefCount; + LgIndex_t VarShareRefCount; + LgIndex_t NumValues; +# if defined TECPLOTKERNEL /* TecIO doesn't require these features yet. */ +/* CORE SOURCE CODE REMOVED */ +# endif +}; + + +/* * + * * NOTE: "FieldData_pa" here is an "abstract type". + * * Any routines dealing with the internals workings + * * of FieldData_pa must be in the same file as these + * * routines + * */ + +#if defined USE_MACROS_FOR_FUNCTIONS +#define USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +#endif + +/* + * These are low-level (private) FD manipulation functions. In + * most cases, you should use some higher-level function. These + * macros are supplied for the dataset functions to use. + */ +#if defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +#define GetFieldDataType GetFieldDataType_MACRO +#define GetFieldDataGetFunction GetFieldDataGetFunction_MACRO +#define GetFieldDataSetFunction GetFieldDataSetFunction_MACRO +#define GetFieldDataNumValues GetFieldDataNumValues_MACRO +#define GetFieldDataValueLocation GetFieldDataValueLocation_MACRO +#define IsFieldDataDirectAccessAllowed IsFieldDataDirectAccessAllowed_MACRO +#else +#define GetFieldDataType GetFieldDataType_FUNC +#define GetFieldDataGetFunction GetFieldDataGetFunction_FUNC +#define GetFieldDataSetFunction GetFieldDataSetFunction_FUNC +#define GetFieldDataNumValues GetFieldDataNumValues_FUNC +#define GetFieldDataValueLocation GetFieldDataValueLocation_FUNC +#define IsFieldDataDirectAccessAllowed IsFieldDataDirectAccessAllowed_FUNC +#endif + +#define GetFieldDataType_MACRO(FieldData) ((FieldData)->Type) +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#else /* ...for TecIO only */ +#define GetFieldDataGetFunction_MACRO(FieldData) ((FieldValueGetFunction_pf)(FieldData)->GetValueCallback[0]) +#define GetFieldDataSetFunction_MACRO(FieldData) ((FieldValueSetFunction_pf)(FieldData)->SetValueCallback[0]) +#endif +#define GetFieldDataNumValues_MACRO(FieldData) ((FieldData)->NumValues) +#define GetFieldDataValueLocation_MACRO(FieldData) ((FieldData)->ValueLocation) + +EXTERN double STDCALL GetFieldValueForFloat(const FieldData_pa fd, LgIndex_t pt); +EXTERN double STDCALL GetFieldValueForDouble(const FieldData_pa fd, LgIndex_t pt); +EXTERN double STDCALL GetFieldValueForInt32(const FieldData_pa fd, LgIndex_t pt); +EXTERN double STDCALL GetFieldValueForInt16(const FieldData_pa fd, LgIndex_t pt); +EXTERN double STDCALL GetFieldValueForByte(const FieldData_pa fd, LgIndex_t pt); +EXTERN double STDCALL GetFieldValueForBit(const FieldData_pa fd, LgIndex_t pt); + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#else +#define IsFieldDataDirectAccessAllowed_MACRO(FieldData) ((FieldData)->Data != NULL) +#endif + +#if !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +EXTERN FieldDataType_e GetFieldDataType_FUNC(FieldData_pa FieldData); +EXTERN FieldValueGetFunction_pf GetFieldDataGetFunction_FUNC(FieldData_pa FieldData); +EXTERN FieldValueSetFunction_pf GetFieldDataSetFunction_FUNC(FieldData_pa FieldData); +EXTERN LgIndex_t GetFieldDataNumValues_FUNC(FieldData_pa FieldData); +EXTERN ValueLocation_e GetFieldDataValueLocation_FUNC(FieldData_pa FieldData); +EXTERN Boolean_t IsFieldDataDirectAccessAllowed_FUNC(FieldData_pa FieldData); +#endif + + +/* + * Use separate types for reversed byte data than unreversed data so we + * have better compiler checking. + */ +typedef UInt32_t FloatRev_t; +typedef UInt64_t DoubleRev_t; +typedef UInt16_t Int16Rev_t; +typedef UInt32_t Int32Rev_t; +typedef UInt64_t Int64Rev_t; + + +/* + * Note: there are so many GetFieldData*Ptr functions because we + * want a bunch of error checking. The Type and TypeRev check + * for that type. The Byte, 2Byte, etc. just make sure it is + * that type. + * GetFieldDataVoidPtr checks nothing, and thus should only be + * used with extreme caution (that is, checking the alignment + * and byte order by hand). + */ +#if defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +#define GetFieldDataFloatPtr GetFieldDataFloatPtr_MACRO +#define GetFieldDataFloatRevPtr GetFieldDataFloatRevPtr_MACRO +#define GetFieldDataDoublePtr GetFieldDataDoublePtr_MACRO +#define GetFieldDataDoubleRevPtr GetFieldDataDoubleRevPtr_MACRO +#define GetFieldDataInt64Ptr GetFieldDataInt64Ptr_MACRO +#define GetFieldDataInt64RevPtr GetFieldDataInt64RevPtr_MACRO +#define GetFieldDataInt32Ptr GetFieldDataInt32Ptr_MACRO +#define GetFieldDataInt32RevPtr GetFieldDataInt32RevPtr_MACRO +#define GetFieldDataInt16Ptr GetFieldDataInt16Ptr_MACRO +#define GetFieldDataInt16RevPtr GetFieldDataInt16RevPtr_MACRO +#define GetFieldDataBytePtr GetFieldDataBytePtr_MACRO +#define GetFieldData2BytePtr GetFieldData2BytePtr_MACRO +#define GetFieldData4BytePtr GetFieldData4BytePtr_MACRO +#define GetFieldData8BytePtr GetFieldData8BytePtr_MACRO +#define GetFieldDataVoidPtr GetFieldDataVoidPtr_MACRO /*danger:see above*/ +#else +#define GetFieldDataFloatPtr GetFieldDataFloatPtr_FUNC +#define GetFieldDataFloatRevPtr GetFieldDataFloatRevPtr_FUNC +#define GetFieldDataDoublePtr GetFieldDataDoublePtr_FUNC +#define GetFieldDataDoubleRevPtr GetFieldDataDoubleRevPtr_FUNC +#define GetFieldDataInt64Ptr GetFieldDataInt64Ptr_FUNC +#define GetFieldDataInt64RevPtr GetFieldDataInt64RevPtr_FUNC +#define GetFieldDataInt32Ptr GetFieldDataInt32Ptr_FUNC +#define GetFieldDataInt32RevPtr GetFieldDataInt32RevPtr_FUNC +#define GetFieldDataInt16Ptr GetFieldDataInt16Ptr_FUNC +#define GetFieldDataInt16RevPtr GetFieldDataInt16RevPtr_FUNC +#define GetFieldDataBytePtr GetFieldDataBytePtr_FUNC +#define GetFieldData2BytePtr GetFieldData2BytePtr_FUNC +#define GetFieldData4BytePtr GetFieldData4BytePtr_FUNC +#define GetFieldData8BytePtr GetFieldData8BytePtr_FUNC +#define GetFieldDataVoidPtr GetFieldDataVoidPtr_FUNC /*danger:see above*/ +#endif + +#define GetFieldDataFloatPtr_MACRO(FieldData) ((float *)((FieldData)->Data)) +#define GetFieldDataFloatRevPtr_MACRO(FieldData) ((FloatRev_t *)((FieldData)->Data)) +#define GetFieldDataDoublePtr_MACRO(FieldData) ((double *)((FieldData)->Data)) +#define GetFieldDataDoubleRevPtr_MACRO(FieldData) ((DoubleRev_t *)((FieldData)->Data)) +#define GetFieldDataInt64Ptr_MACRO(FieldData) ((Int64_t *)((FieldData)->Data)) +#define GetFieldDataInt64RevPtr_MACRO(FieldData) ((Int64Rev_t *)((FieldData)->Data)) +#define GetFieldDataInt32Ptr_MACRO(FieldData) ((Int32_t *)((FieldData)->Data)) +#define GetFieldDataInt32RevPtr_MACRO(FieldData) ((Int32Rev_t *)((FieldData)->Data)) +#define GetFieldDataInt16Ptr_MACRO(FieldData) ((Int16_t *)((FieldData)->Data)) +#define GetFieldDataInt16RevPtr_MACRO(FieldData) ((Int16Rev_t *)((FieldData)->Data)) +#define GetFieldDataBytePtr_MACRO(FieldData) ((Byte_t *)((FieldData)->Data)) +#define GetFieldData2BytePtr_MACRO(FieldData) ((UInt16_t *)((FieldData)->Data)) +#define GetFieldData4BytePtr_MACRO(FieldData) ((UInt32_t *)((FieldData)->Data)) +#define GetFieldData8BytePtr_MACRO(FieldData) ((UInt64_t *)((FieldData)->Data)) +#define GetFieldDataVoidPtr_MACRO(FieldData) ((void *)((FieldData)->Data)) /*danger:see above*/ + +#if !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +EXTERN float *GetFieldDataFloatPtr_FUNC(FieldData_pa fd); +EXTERN FloatRev_t *GetFieldDataFloatRevPtr_FUNC(FieldData_pa fd); +EXTERN double *GetFieldDataDoublePtr_FUNC(FieldData_pa fd); +EXTERN DoubleRev_t *GetFieldDataDoubleRevPtr_FUNC(FieldData_pa fd); +EXTERN Int64_t *GetFieldDataInt64Ptr_FUNC(FieldData_pa fd); +EXTERN Int64Rev_t *GetFieldDataInt64RevPtr_FUNC(FieldData_pa fd); +EXTERN Int32_t *GetFieldDataInt32Ptr_FUNC(FieldData_pa fd); +EXTERN Int32Rev_t *GetFieldDataInt32RevPtr_FUNC(FieldData_pa fd); +EXTERN Int16_t *GetFieldDataInt16Ptr_FUNC(FieldData_pa fd); +EXTERN Int16Rev_t *GetFieldDataInt16RevPtr_FUNC(FieldData_pa fd); +EXTERN Byte_t *GetFieldDataBytePtr_FUNC(FieldData_pa fd); +EXTERN UInt16_t *GetFieldData2BytePtr_FUNC(FieldData_pa fd); +EXTERN UInt32_t *GetFieldData4BytePtr_FUNC(FieldData_pa fd); +EXTERN UInt64_t *GetFieldData8BytePtr_FUNC(FieldData_pa fd); +EXTERN void *GetFieldDataVoidPtr_FUNC(FieldData_pa fd); /*danger:see above*/ +#endif + +/** + */ +EXTERN FieldData_pa AllocScratchNodalFieldDataPtr(LgIndex_t NumValues, + FieldDataType_e Type, + Boolean_t ShowErrMsg); + +/** + */ +EXTERN void DeallocScratchNodalFieldDataPtr(FieldData_pa *ScratchFieldData); + +/** + * Assume that indexrange has already been converted to the actual indices. + */ +EXTERN void CalcFieldDataMinMaxUsingRange(FieldData_pa field_data, + double *min_ptr, + double *max_ptr, + LgIndex_t startindex, + IndexRange_s *indexrange); + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +/** + */ +EXTERN void CopyTypedValueArray(FieldDataType_e ValueType, + void *DstArray, + LgIndex_t DstStart, + void *SrcArray, + LgIndex_t SrcStart, + LgIndex_t SrcEnd); + +EXTERN void SwapBytesInTypedValueArray(FieldDataType_e ValueType, + void *SrcArray, + LgIndex_t SrcStart, + LgIndex_t SrcEnd, + LgIndex_t SrcSkip); + +EXTERN void SwapBytesInUnalignedTypedValueArray(FieldDataType_e ValueType, + void *SrcArray, + LgIndex_t SrcStart, + LgIndex_t SrcEnd, + LgIndex_t SrcSkip); + + +/* + * Copies values from "src" to "dst". "src" or "dst" may + * be differing types. Either or both may be V3D data pointers. + */ +EXTERN void CopyFieldDataRange(FieldData_pa dst, + LgIndex_t dst_start, + FieldData_pa src, + LgIndex_t src_start, + LgIndex_t src_end); /* -1 means last point */ + +/* + * Copy all values in field data + */ +EXTERN void CopyFieldData(FieldData_pa dst, + FieldData_pa src); + +/* + * Like CopyFieldData except for single value. + */ +EXTERN void CopyFieldValue(FieldData_pa dst, + LgIndex_t dstindex, + FieldData_pa src, + LgIndex_t srcindex); + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +/* + * Sets all values in the field data pointer "field_data" + * to zero. + */ +EXTERN void SetFieldDataPtrToAllZeros(FieldData_pa field_data); + +/* + * GetFieldValue macro + */ +#if !defined GET_FIELD_VALUE_BY_VIRTUAL_FUNCTION && \ + !defined GET_FIELD_VALUE_BY_FLOAT_ONLY_MACRO && \ + !defined GET_FIELD_VALUE_BY_DOUBLE_ONLY_MACRO && \ + !defined GET_FIELD_VALUE_BY_FLOAT_AND_DOUBLE_MACRO +#if !defined NO_ASSERTS || defined DEBUG_FIELDVALUES +#define GET_FIELD_VALUE_BY_VIRTUAL_FUNCTION +#else +#define GET_FIELD_VALUE_BY_FLOAT_AND_DOUBLE_MACRO +#endif +#endif + +#if defined GET_FIELD_VALUE_BY_VIRTUAL_FUNCTION +#define GetFieldValue(fd,pt) ((GetFieldDataGetFunction(fd))((fd),(pt))) +#elif defined GET_FIELD_VALUE_BY_FLOAT_ONLY_MACRO +#define GetFieldValue(fd,pt) (GetFieldDataGetFunction(fd)==GetFieldValueForFloat \ + ?GetFieldDataFloatPtr(fd)[(pt)] \ + :(GetFieldDataGetFunction(fd))((fd),(pt))) +#elif defined GET_FIELD_VALUE_BY_DOUBLE_ONLY_MACRO +#define GetFieldValue(fd,pt) (GetFieldDataGetFunction(fd)==GetFieldValueForDouble \ + ?GetFieldDataDoublePtr(fd)[(pt)] \ + :(GetFieldDataGetFunction(fd))((fd),(pt))) +#elif defined GET_FIELD_VALUE_BY_FLOAT_AND_DOUBLE_MACRO +#define GetFieldValue(fd,pt) (GetFieldDataGetFunction(fd)==GetFieldValueForFloat \ + ?GetFieldDataFloatPtr(fd)[(pt)] \ + :GetFieldDataGetFunction(fd)==GetFieldValueForDouble \ + ?GetFieldDataDoublePtr(fd)[(pt)] \ + :(GetFieldDataGetFunction(fd))((fd),(pt))) +#else +#error "Need to define one of FIELD_VALUE_MACRO constants" +#endif + + +/* + * SetFieldValue macro + */ +#define SetFieldValue(fd,pt,val) ((GetFieldDataSetFunction(fd))((fd),(pt),(val))) + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ + +#if defined _DEBUG +#define USEFUNCTIONSFORNODEVALUES +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if !defined NO_ASSERTS +#endif +#endif /* TECPLOTKERNEL */ + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATASHR.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATASHR.h new file mode 100644 index 0000000000..ea8b1d26d2 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATASHR.h @@ -0,0 +1,70 @@ +/* + * 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/ + * + */ +#if defined EXTERN +#undef EXTERN +#endif +#if defined DATASHRMODULE +#define EXTERN +#else +#define EXTERN extern +#endif + +/* +***************************************************************** +***************************************************************** +******* ******** +****** Copyright (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +***************************************************************** +***************************************************************** +*/ + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ + +/* + * General set of macros for reference count mananagement. + */ +#define IncStructureReference(V) ((V)->RefCount++) +#define DecStructureReference(V) ((V)->RefCount--) +#define IsStructureShared(V) ((V)->RefCount > 1) +#define IsStructureReferenced(V) ((V)->RefCount > 0) + +/* + * Special set of macros for field data that is having variable sharing between + * zones tracked. Field data maintains two reference counts: The first, + * RefCount, is used to keep track of when the field data needs to be + * deallocated; the second, VarShareRefCount, is used to track variable sharing + * between zones. + */ +#define IncVarStructureReference(V) ((V)->VarShareRefCount++) +#define DecVarStructureReference(V) ((V)->VarShareRefCount--) +#define IsVarStructureShared(V) ((V)->VarShareRefCount > 1) +#define IsVarStructureReferenced(V) ((V)->VarShareRefCount > 0) + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATAUTIL.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATAUTIL.h new file mode 100644 index 0000000000..cf0195fffc --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/DATAUTIL.h @@ -0,0 +1,116 @@ +/* + * 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/ + * + */ +/* + * DATAUTIL.h : COPYRIGHT (C)1987-2002 Tecplot, Inc. + * ALL RIGHTS RESERVED + * + * NOTE: THIS MODULE NOW IS PART OF THE TECPLOT SOURCE + * ONLY EDIT THIS IN THE MAIN TECPLOT SOURCE DIRECTORY. + * + * + */ +#ifndef DATAUTIL_H +#define DATAUTIL_H +#define DATAUTIL_VERSION 61 + +#if defined MAKEARCHIVE +extern void InitInputSpecs(void); +#endif + + +/* + * + * Read a binary tecplot datafile. + * + * @param GetHeaderInfoOnly + * Return only the header info from the datafile. + * + * @param FName + * Name of the file to read. + * + * @param IVersion + * Returns version of the input file. + * + * @param DataSetTitle + * Allocates space for and returns dataset title. + * + * @param NumZones + * Returns the number of zones. + * + * @param NumVars + * Returns the number of variables. + * + * @param VarNames + * Allocates space for and returns the var names. + * + * @param ZoneNames + * Allocates space for and returns the zone names. + * + * @param NumPtsI, NumPtsJ, NumPtsK + * Zone dimensions loaded into LgIndex_t arrays. + * + * @param ZoneNames + * Zone types loaded into ZoneType_e array. + * + * @param UserRec + * Allocates space for and returns the user records. + * + * @param RawDataspaceAllocated + * Only used if GetHeaderInfoOnly is FALSE. TRUE = calling program has alloced space for + * the raw data. FALSE= let ReadTec allocate space for the raw data. + * + * @param NodeMap + * Finite Element connectivity information. ReadTec + * will allocate the space for you if RawDataspaceAllocated is FALSE. + * + * @param VDataBase + * Raw field data loaded into double arrays. ReadTec + * will allocate the space for you if RawDataspaceAllocated is + * FALSE. If RawDataspaceAllocated is TRUE then ReadTec will + * only load the arrays that have non NULL addresses. + * + */ +LIBFUNCTION 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); + +LIBFUNCTION void * STDCALL TecAlloc(size_t size); + +LIBFUNCTION void STDCALL TecFree(void *ptr); + + +#endif /* !DATAUTIL_H */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/FACE.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/FACE.h new file mode 100644 index 0000000000..c0c89a9b43 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/FACE.h @@ -0,0 +1,149 @@ +/* + * 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/ + * + */ +/* +****************************************************************** +****************************************************************** +******* ******** +****** (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +****************************************************************** +****************************************************************** +*/ +#ifndef _FACE_H_ +#define _FACE_H_ + +#if defined EXTERN +#undef EXTERN +#endif +#if defined FACEMODULE +#define EXTERN +#else +#define EXTERN extern +#endif + +namespace tecplot +{ +namespace kernel +{ +class SubElemValueProducerInterface; +} +} + + +/** + */ +inline Boolean_t IsCellFaceLogicallyCollapsed(LgIndex_t I1, + LgIndex_t I2, + LgIndex_t I3, + LgIndex_t I4) +{ + return ((I1 == I2 && I3 == I4) || + (I1 == I4 && I2 == I3) || + (I1 == I3) || + (I2 == I4)); +} + +/** + * IMPORTANT NOTE: + * A face obscuration of FaceObscuration_LogicallyObscured means that the + * face is entirely obscured by either an implicit neighbor for inside faces + * of ordered data or an auto generated neighbor for finite element data. In + * either case, logical obscuration is not considered if user defined + * neighbors have been specified for the face. Therefore, interior faces of + * ordered data can have an indication of FaceObscuration_PartiallyObscured. + */ +typedef enum +{ + FaceObscuration_NotObscured, + FaceObscuration_PartiallyObscured, + FaceObscuration_EntirelyObscured, + FaceObscuration_LogicallyObscured, + END_FaceObscuration_e, + FaceObscuration_Invalid = BadEnumValue +} FaceObscuration_e; + +/** + */ +EXTERN LgIndex_t GetLogicalOrderedNeighbor(LgIndex_t NumIPts, + LgIndex_t NumJPts, + LgIndex_t NumKPts, + LgIndex_t Element, + LgIndex_t Face); + +/** + * Function to determine a cell's neighbor. It calls FaceNeighborGetSurfaceCellNeighbor() + * for classic zones. + */ +EXTERN void GetSurfaceCellNeighbor(CZInfo_s const* CZInfo, + CZData_s const* CZData, + LgIndex_t SurfaceCellIndex, + tecplot::kernel::SubElemValueProducerInterface* NodeValueProducer, + ElemFaceOffset_t PlaneOrFaceOffset, + ElemFaceOffset_t Edge, + LgIndex_t* NeighborSurfaceCellElem, + EntIndex_t* NeighborSurfaceCellZone); +/** + */ +EXTERN FaceObscuration_e GetFaceObscuration(CZInfo_s const* CZInfo, + CZData_s const* CZData, + Set_pa ActiveRelevantZones, + LgIndex_t Element, + LgIndex_t FOffset, + Boolean_t ConsiderValueBlanking, + Boolean_t ConsiderIJKBlanking, + Boolean_t ConsiderDepthBlanking); + +EXTERN EntIndex_t GetNodesPerElementFace(ZoneType_e ZoneType); + +EXTERN EntIndex_t GetFacesPerElement(ZoneType_e ZoneType, + LgIndex_t IMax, + LgIndex_t JMax, + LgIndex_t KMax); + +EXTERN CollapsedStatus_e GetSurfaceCellCollapsedStatus(CZInfo_s const* CZInfo, + CZData_s const* CZData, + tecplot::kernel::SubElemValueProducerInterface* SubElemValueProducer); +EXTERN CollapsedStatus_e GetSurfaceCellCollapsedStatus(CZInfo_s const* CZInfo, + CZData_s const* CZData, + LgIndex_t I1, + LgIndex_t I2, + LgIndex_t I3, + LgIndex_t I4); +EXTERN CollapsedStatus_e GetSurfaceCellLogicalCollapsedStatus(ZoneType_e ZoneType, + LgIndex_t I1, + LgIndex_t I2, + LgIndex_t I3, + LgIndex_t I4); +EXTERN CollapsedStatus_e GetSurfEdgeOrVolFaceLogicalCollapsedStatus(NodeMap_pa NodeMap, + LgIndex_t Element, + EntIndex_t Face); +#if defined ALLOW_USERDEF_NO_NEIGHBORING_ELEMENT +/** + */ +EXTERN Boolean_t IsUserDefFaceNeighborBoundary(FaceNeighbor_pa FaceNeighbor, + LgIndex_t Element, + LgIndex_t Face); +#endif + +#endif diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/FILESTREAM.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/FILESTREAM.h new file mode 100644 index 0000000000..edb10ce253 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/FILESTREAM.h @@ -0,0 +1,75 @@ +/* + * 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/ + * + */ +/* + ***************************************************************** + ***************************************************************** + ******* ******** + ****** Copyright (C) 1988-2008 Tecplot, Inc. ******* + ******* ******** + ***************************************************************** + ***************************************************************** +*/ +#if !defined FILESTREAM_h +#define FILESTREAM_h + +#if defined EXTERN +# undef EXTERN +#endif +#if defined FILESTREAMMODULE +# define EXTERN +#else +# define EXTERN extern +#endif + +typedef struct +{ + FILE *File; + Boolean_t IsByteOrderNative; +} FileStream_s; + +/** + * Creates a structure for associating an open file stream with its byte + * order. The byte order can changed at any time. + * + * @param File + * Handle to a file which can be NULL. + * @param IsByteOrderNative + * TRUE if the file's byte order is native, FALSE if foreign. + * + * @return + * An allocated structure associating an open file to its byte order. + */ +EXTERN FileStream_s *FileStreamAlloc(FILE *File, + Boolean_t IsByteOrderNative); + +/** + * Deallocates the structure associating the file stream with the byte order. + * This function does NOT close the file. + * + * @param FileStream + * Pointer to an open file stream or a pointer to NULL. + */ +EXTERN void FileStreamDealloc(FileStream_s **FileStream); + +#endif diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/GEOM.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/GEOM.h new file mode 100644 index 0000000000..092b92dfd2 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/GEOM.h @@ -0,0 +1,71 @@ +/* + * 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/ + * + */ +/* +***************************************************************** +***************************************************************** +******* ******** +****** Copyright (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +***************************************************************** +***************************************************************** +*/ + +#if defined EXTERN +#undef EXTERN +#endif +#if defined GEOMMODULE +#define EXTERN +#else +#define EXTERN extern +#endif + + +/* * macros for checking CoordSys_e * */ +#define VALID_RECTANGLE_COORDSYS(sys) \ + (((sys)==CoordSys_Frame) || \ + ((sys)==CoordSys_Grid)) +#define VALID_SQUARE_COORDSYS(sys) VALID_RECTANGLE_COORDSYS((sys)) +#define VALID_ELLIPSE_COORDSYS(sys) VALID_RECTANGLE_COORDSYS((sys)) +#define VALID_CIRCLE_COORDSYS(sys) VALID_ELLIPSE_COORDSYS((sys)) +#define VALID_IMAGE_COORDSYS(sys) VALID_RECTANGLE_COORDSYS((sys)) +#define VALID_LINESEG_COORDSYS(sys) \ + (((sys)==CoordSys_Frame) || \ + ((sys)==CoordSys_Grid) || \ + ((sys)==CoordSys_Grid3D)) +#define VALID_GEOM_COORDSYS(sys) \ + (((sys)==CoordSys_Frame) || \ + ((sys)==CoordSys_Grid) || \ + ((sys)==CoordSys_Grid3D)) + +#define VALID_GEOM_TYPE(geomtype) \ + ( VALID_ENUM((geomtype),GeomType_e) && \ + (geomtype)!=GeomType_LineSegs3D ) + +#define VALID_GEOM_FIELD_DATA_TYPE(datatype) \ + ( ( (datatype) == FieldDataType_Float ) || \ + ( (datatype) == FieldDataType_Double ) ) + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/GEOM2.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/GEOM2.h new file mode 100644 index 0000000000..9dcd68acba --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/GEOM2.h @@ -0,0 +1,46 @@ +/* + * 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/ + * + */ +/* +***************************************************************** +***************************************************************** +******* ******** +****** Copyright (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +***************************************************************** +***************************************************************** +*/ +#if defined EXTERN +#undef EXTERN +#endif +#if defined GEOM2MODULE +#define EXTERN +#else +#define EXTERN extern +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ + +EXTERN FieldDataType_e GetGeomFieldDataType(Geom_s const* Geom); diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/GLOBAL.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/GLOBAL.h new file mode 100644 index 0000000000..21e35a947c --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/GLOBAL.h @@ -0,0 +1,7271 @@ +/* + * 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/ + * + */ +/* BEGINREMOVEFROMADDON */ +/* NOTE: All code contained between comments that look like + * BEGINREMOVEFROMADDON + * ENDREMOVEFROMADDON + * are pulled out to create the GLOBAL.h file used in addons. + */ +/* ENDREMOVEFROMADDON */ + +/* +****************************************************************** +****************************************************************** +******* ******** +****** (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +****************************************************************** +****************************************************************** +*/ + +#ifndef _GLOBAL_H +#define _GLOBAL_H + +#if defined EXTERN +#undef EXTERN +#endif +#if defined Q_MAINMODULE && defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#else +#define EXTERN extern +#endif + +#define EXPORT_DEPRECATED_INTERFACES_TO_ADK_ONLY +/* BEGINREMOVEFROMADDON */ +/* + * The reason for wrapping this test with "begin and end remove from addon" key + * words is so that the ADK users doesn't have to see this mess. + */ +#if !defined COREAPI && \ + !defined TECUTILMMODULE && \ + !defined TECUTILOMODULE && \ + !defined TECUTILQMODULE && \ + !defined TECUTILSMODULE +/* we don't want Tecplot internals using deprecated interfaces */ +# undef EXPORT_DEPRECATED_INTERFACES_TO_ADK_ONLY +#endif +/* ENDREMOVEFROMADDON */ + + +/**************************************************************** + * * + * MACROS * + * * + ****************************************************************/ +#if defined TRUE +#undef TRUE +#endif +#if defined FALSE +#undef FALSE +#endif +#if defined MIN +#undef MIN +#endif +#if defined MAX +#undef MAX +#endif +#if defined ROUND +#undef ROUND +#endif +#if defined ROUND2 +#undef ROUND2 +#endif +#if defined TRUNC +#undef TRUNC +#endif + +#define TRUE ((Boolean_t)1) +#define FALSE ((Boolean_t)0) + +/**************************************************************** + * * + * MACROS * + * * + ****************************************************************/ +#define ABS(X) ((X) >= 0 ? (X) : -(X) ) +#define MAX(X,Y) ((X) > (Y) ? (X) : (Y) ) +#define MIN(X,Y) ((X) < (Y) ? (X) : (Y) ) +#define BESTSHOWCOLOR(X) ((X) == White_C ? Black_C : White_C) +#define ROUND_TO_BYTE(X) ((BYTE)((X)+0.499)) +#define ROUNDS(X) ((short)((X)+0.499)) +#define ROUNDL(X) ((LgIndex_t)((X)+0.499)) +#define ROUND2(X) ((X) >= 0 ? ((int)((X)+0.499)) : ((int)((X)-0.499))) +#define TRUNC(X) ((short) (X)) +#define RAD_TO_DEG(rad) (180.*(rad)/PI) +#define DEG_TO_RAD(deg) (PI*(deg)/180.) + +# define CAPITAL(C) ( ('a'<=(C)&&(C)<='z') ? ((C)+('A'-'a')) : (C) ) /* okay for UNICODE */ + +#include "TASSERT.h" + +#if defined TECPLOTKERNEL && defined MSWIN +/* CORE SOURCE CODE REMOVED */ +#else +#define ISEMPTYSTRING(S) ( ((const char*)(S))[0] == '\0' ) +#endif + +#define ISWHITESPACE(C) ((C == ' ') || (C == '\t') || (C == '\n')) +#define ISSEPARATOR(C) ((C == ' ') || (C == '\t') || (C == ',')) +/* clamp the input to the specified range */ +#define CLAMP(value,low,high) ((value)<(low) ? (low) : (value) > (high) ? (high) : (value)) +/* integer division rounds any fraction up (for example n=16,d=3 results in 6) */ +#define INTEGER_DIVIDE_AND_ROUND_UP(n, d) (((int)(n)+(int)(d)-1)/(int)(d)) + +/* BEGINREMOVEFROMADDON */ +/** + * Calcualtes the cell's primary corner or cell centered index from the I, J, + * and K indices. + * + * Consider this IJ zone dimensioned 4 by 3: + * @verbatim + +-------+-------+-------+-------+ + | | | | | + | <8> | <9> | <10> | <11> | <--- ghost cells + | | | | | + |8 |9 |10 |11 | + +-------+-------+-------+-------+ + | | | | | + | <4> | <5> | <6> | <7> | + | | | | | + |4 |5 |6 |7 | + +-------+-------+-------+-------+ + | | | | | + | <0> | <1> | <2> | <3> | + | | | | | + |0 |1 |2 |3 | + +-------+-------+-------+-------+ + . + /|\ + | + | + ghost cells +@endverbatim + */ +#define IJKINDEX(CZData,I,J,K) ((I) + \ + ((J)*(CZData)->NumIPts) + \ + ((K)*(CZData)->NumIJPts)) + +/** + * Calculates the I indice from the cell's primary corner or cell centered + * index. See IJKINDEX() for a picture. + */ +#define IINDEX(CZData,N) ((N) % (CZData)->NumIPts) + +/** + * Calculates the J indice from the cell's primary corner or cell centered + * index. See IJKINDEX() for a picture. + */ +#define JINDEX(CZData,N) (((N) % (CZData)->NumIJPts)/(CZData)->NumIPts) + +/** + * Calculates the K indice from the cell's primary corner or cell centered + * index. See IJKINDEX() for a picture. + */ +#define KINDEX(CZData,N) ((N)/(CZData)->NumIJPts) +/* ENDREMOVEFROMADDON */ + +/* */ +#define SWITCH(Type,A,B) do {Type T = (A); (A) = (B); (B) = T;} while (FALSE) +#define SWITCH_DOUBLES(A,B) SWITCH(double, (A), (B)) +#define FPRINTFOK(x) (Boolean_t)((x) > 0) +#define GRAPHICSARE3D(F) ((F->PlotType == PlotType_Cartesian3D)) + +/* convenience macros for implication, P -> Q, and equivalence, P <-> Q. */ +#define IMPLICATION(P,Q) (!(P) || (Q)) +#define EQUIVALENCE(P,Q) ((P) == (Q)) + +/* suppress compiler warnings about unused parameters */ +#if defined UNUSED +#undef UNUSED +#endif +#define UNUSED(param) (void)param + +/** + * Converts a double into a float value + * + * param val + * double value to be converted + */ +#define CONVERT_DOUBLE_TO_FLOAT(val) \ + ( (val) >= SMALLFLOAT \ + ? ( (val) < LARGEFLOAT \ + ? (float)(val) \ + : (float)LARGEFLOAT \ + ) \ + : ( (val) <= -SMALLFLOAT \ + ? ( (val) > -LARGEFLOAT \ + ? (float)(val) \ + : (float)-LARGEFLOAT \ + ) \ + : (float)0.0 \ + ) \ + ) + + +/** + * Clamps a double at the limits of Tecplot's precision + * + * param val + * double value to be clamped + */ +#define CLAMP_DOUBLE(val) \ + ( (val) >= SMALLDOUBLE \ + ? ( (val) < LARGEDOUBLE \ + ? (double)(val) \ + : (double)LARGEDOUBLE \ + ) \ + : ( (val) <= -SMALLDOUBLE \ + ? ( (val) > -LARGEDOUBLE \ + ? (double)(val) \ + : (double)-LARGEDOUBLE \ + ) \ + : (double)0.0 \ + ) \ + ) + + +/** + * Converts a double into a 4-byte (signed) integer value + * + * param val + * double value to be converted + */ +#define CONVERT_DOUBLE_TO_INT32(val) \ + ( (val) >= 1.0 \ + ? ( (val) < MAXINT32 \ + ? (Int32_t)(val) \ + : (Int32_t)MAXINT32 \ + ) \ + : ( (val) <= -1.0 \ + ? ( (val) > (Int32_t)-MAXINT32 \ + ? (Int32_t)(val) \ + : (Int32_t)-MAXINT32 \ + ) \ + : (Int32_t)0.0 \ + ) \ + ) + + +/** + * Converts a double into a 2-byte (signed) integer value + * + * param val + * double value to be converted + */ +#define CONVERT_DOUBLE_TO_INT16(val) \ + ( (val) >= 1.0 \ + ? ( (val) < MAXINT16 \ + ? (Int16_t)(val) \ + : (Int16_t)MAXINT16 \ + ) \ + : ( (val) <= -1.0 \ + ? ( (val) > (Int16_t)-MAXINT16 \ + ? (Int16_t)(val) \ + : (Int16_t)-MAXINT16 \ + ) \ + : (Int16_t)0.0 \ + ) \ + ) + +/** + * Copies two bytes from SrcBuffer to DstBuffer without causing a page + * fault due to misaligned words. + * + * param DstBuffer + * Pointer the buffer to send the two bytes to + * param SrcBuffer + * Pointer the buffer to get the two bytes from + */ +#define COPY_2_UNALIGNED_BYTES(DstBuffer, SrcBuffer) \ + do { \ + /* cannot check sizeof(SrcBuffer) or sizeof(DstBuffer) because they are */ \ + /* most likely single byte pointers into unaligned blocks of data */ \ + ((Byte_t *)(DstBuffer))[0] = ((Byte_t *)(SrcBuffer))[0]; \ + ((Byte_t *)(DstBuffer))[1] = ((Byte_t *)(SrcBuffer))[1]; \ + } while (FALSE) + +/** + * Copies two bytes from SrcBuffer to DstBuffer swapping the bytes + * as it copies. Will not cause a page fault due to misaligned words. + * + * param DstBuffer + * Pointer the buffer to send the two bytes to + * param SrcBuffer + * Pointer the buffer to get the two bytes from + */ +#define COPY_AND_REVERSE_2_UNALIGNED_BYTES(DstBuffer, SrcBuffer) \ + do { \ + /* cannot check sizeof(SrcBuffer) or sizeof(DstBuffer) because they are */ \ + /* most likely single byte pointers into unaligned blocks of data */ \ + ((Byte_t *)(DstBuffer))[0] = ((Byte_t *)(SrcBuffer))[1]; \ + ((Byte_t *)(DstBuffer))[1] = ((Byte_t *)(SrcBuffer))[0]; \ + } while (FALSE) + +/** + * Copies four bytes from SrcBuffer to DstBuffer without causing a page + * fault due to misaligned words. + * + * param DstBuffer + * Pointer the buffer to send the four bytes to + * param SrcBuffer + * Pointer the buffer to get the four bytes from + */ +#define COPY_4_UNALIGNED_BYTES(DstBuffer, SrcBuffer) \ + do { \ + /* cannot check sizeof(SrcBuffer) or sizeof(DstBuffer) because they are */ \ + /* most likely single byte pointers into unaligned blocks of data */ \ + ((Byte_t *)(DstBuffer))[0] = ((Byte_t *)(SrcBuffer))[0]; \ + ((Byte_t *)(DstBuffer))[1] = ((Byte_t *)(SrcBuffer))[1]; \ + ((Byte_t *)(DstBuffer))[2] = ((Byte_t *)(SrcBuffer))[2]; \ + ((Byte_t *)(DstBuffer))[3] = ((Byte_t *)(SrcBuffer))[3]; \ + } while (FALSE) + +/** + * Copies four bytes from SrcBuffer to DstBuffer swapping the bytes + * as it copies. Will not cause a page fault due to misaligned words. + * + * param DstBuffer + * Pointer the buffer to send the four bytes to + * param SrcBuffer + * Pointer the buffer to get the four bytes from + */ +#define COPY_AND_REVERSE_4_UNALIGNED_BYTES(DstBuffer, SrcBuffer) \ + do { \ + /* cannot check sizeof(SrcBuffer) or sizeof(DstBuffer) because they are */ \ + /* most likely single byte pointers into unaligned blocks of data */ \ + ((Byte_t *)(DstBuffer))[0] = ((Byte_t *)(SrcBuffer))[3]; \ + ((Byte_t *)(DstBuffer))[1] = ((Byte_t *)(SrcBuffer))[2]; \ + ((Byte_t *)(DstBuffer))[2] = ((Byte_t *)(SrcBuffer))[1]; \ + ((Byte_t *)(DstBuffer))[3] = ((Byte_t *)(SrcBuffer))[0]; \ + } while (FALSE) + +/** + * Copies four bytes from SrcBuffer to DstBuffer without causing a page + * fault due to misaligned words. + * + * param DstBuffer + * Pointer the buffer to send the four bytes to + * param SrcBuffer + * Pointer the buffer to get the four bytes from + */ +#define COPY_8_UNALIGNED_BYTES(DstBuffer, SrcBuffer) \ + do { \ + /* cannot check sizeof(SrcBuffer) or sizeof(DstBuffer) because they are */ \ + /* most likely single byte pointers into unaligned blocks of data */ \ + ((Byte_t *)(DstBuffer))[0] = ((Byte_t *)(SrcBuffer))[0]; \ + ((Byte_t *)(DstBuffer))[1] = ((Byte_t *)(SrcBuffer))[1]; \ + ((Byte_t *)(DstBuffer))[2] = ((Byte_t *)(SrcBuffer))[2]; \ + ((Byte_t *)(DstBuffer))[3] = ((Byte_t *)(SrcBuffer))[3]; \ + ((Byte_t *)(DstBuffer))[4] = ((Byte_t *)(SrcBuffer))[4]; \ + ((Byte_t *)(DstBuffer))[5] = ((Byte_t *)(SrcBuffer))[5]; \ + ((Byte_t *)(DstBuffer))[6] = ((Byte_t *)(SrcBuffer))[6]; \ + ((Byte_t *)(DstBuffer))[7] = ((Byte_t *)(SrcBuffer))[7]; \ + } while (FALSE) + +/** + * Copies eight bytes from SrcBuffer to DstBuffer swapping the bytes + * as it copies. Will not cause a page fault due to misaligned words. + * + * param DstBuffer + * Pointer the buffer to send the four bytes to + * param SrcBuffer + * Pointer the buffer to get the four bytes from + */ +#define COPY_AND_REVERSE_8_UNALIGNED_BYTES(DstBuffer, SrcBuffer) \ + do { \ + /* cannot check sizeof(SrcBuffer) or sizeof(DstBuffer) because they are */ \ + /* most likely single byte pointers into unaligned blocks of data */ \ + ((Byte_t *)(DstBuffer))[0] = ((Byte_t *)(SrcBuffer))[7]; \ + ((Byte_t *)(DstBuffer))[1] = ((Byte_t *)(SrcBuffer))[6]; \ + ((Byte_t *)(DstBuffer))[2] = ((Byte_t *)(SrcBuffer))[5]; \ + ((Byte_t *)(DstBuffer))[3] = ((Byte_t *)(SrcBuffer))[4]; \ + ((Byte_t *)(DstBuffer))[4] = ((Byte_t *)(SrcBuffer))[3]; \ + ((Byte_t *)(DstBuffer))[5] = ((Byte_t *)(SrcBuffer))[2]; \ + ((Byte_t *)(DstBuffer))[6] = ((Byte_t *)(SrcBuffer))[1]; \ + ((Byte_t *)(DstBuffer))[7] = ((Byte_t *)(SrcBuffer))[0]; \ + } while (FALSE) + +/** + * Reverses the byte order of the specified 2 byte buffer. + * + * param Buffer + * Pointer to the 2 bytes needing byte order reversal. + */ +#define REVERSE_2_BYTES_1_AT_A_TIME(Buffer) \ + do { \ + Byte_t Byte0 = ((Byte_t *)(Buffer))[0]; \ + CHECK(sizeof(*(Buffer))==1 || sizeof(*(Buffer))==2); \ + ((Byte_t *)(Buffer))[0] = ((Byte_t *)(Buffer))[1]; \ + ((Byte_t *)(Buffer))[1] = Byte0; \ + } while (FALSE) + +#define REVERSE_2_BYTES_2_AT_A_TIME(Buffer) \ + do { \ + UInt16_t data_bits = ((UInt16_t *)(Buffer))[0]; \ + CHECK(sizeof(*(Buffer))==1 || sizeof(*(Buffer))==2); \ + ((UInt16_t *)(Buffer))[0] = (((data_bits)<<8) | \ + ((data_bits&0xff))); \ + } while (FALSE) + +/* REVERSE_2_BYTES_2_AT_A_TIME may actually be slower, needs testing. */ +#define REVERSE_2_BYTES REVERSE_2_BYTES_1_AT_A_TIME + +/** + * Reverses the byte order of the specified 4 byte buffer. + * + * param Buffer + * Pointer to the 4 bytes needing byte order reversal. + * + * How this works: + * + * ABCD + * D--- <<24 (1) + * + * ABCD + * --C- &0x0000ff00 + * -C-- <<8 (2) + * + * ABCD + * -B-- &0x00ff0000 + * --B- >>8 (3) + * + * ABCD + * ---A >>24 (4) + * + * (1) | (2) | (3) | (4) = DCBA. + * + */ +#define REVERSE_4_BYTES_1_AT_A_TIME(Buffer) \ + do { \ + Byte_t Byte0 = ((Byte_t *)(Buffer))[0]; \ + Byte_t Byte1 = ((Byte_t *)(Buffer))[1]; \ + CHECK(sizeof(*(Buffer))==1 || sizeof(*(Buffer))==4); \ + ((Byte_t *)(Buffer))[0] = ((Byte_t *)(Buffer))[3]; \ + ((Byte_t *)(Buffer))[1] = ((Byte_t *)(Buffer))[2]; \ + ((Byte_t *)(Buffer))[2] = Byte1; \ + ((Byte_t *)(Buffer))[3] = Byte0; \ + } while (FALSE) + +#define REVERSE_4_BYTES_4_AT_A_TIME(Buffer) \ + do { \ + UInt32_t data_bits = *((UInt32_t *)(Buffer)); \ + CHECK(sizeof(*(Buffer))==1 || sizeof(*(Buffer))==4); \ + *((UInt32_t *)(Buffer)) = (((data_bits)<<24) | \ + ((data_bits&0x0000ff00)<<8) | \ + ((data_bits&0x00ff0000)>>8) | \ + ((data_bits)>>24)); \ + } while (FALSE) + +#if defined MSWIN +/* + * The DevStuido compiler seems to be the only one that can truly handle this + * when optimization is turned on. + */ +#define REVERSE_4_BYTES REVERSE_4_BYTES_4_AT_A_TIME +#else +#define REVERSE_4_BYTES REVERSE_4_BYTES_1_AT_A_TIME +#endif + +/** + * Reverses the byte order of the specified 8 byte buffer. + * + * param Buffer + * Pointer to the 8 bytes needing byte order reversal. + */ +#define REVERSE_8_BYTES_1_AT_A_TIME(Buffer) \ + do { \ + Byte_t Byte0 = ((Byte_t *)(Buffer))[0]; \ + Byte_t Byte1 = ((Byte_t *)(Buffer))[1]; \ + Byte_t Byte2 = ((Byte_t *)(Buffer))[2]; \ + Byte_t Byte3 = ((Byte_t *)(Buffer))[3]; \ + CHECK(sizeof(*(Buffer))==1 || sizeof(*(Buffer))==8); \ + ((Byte_t *)(Buffer))[0] = ((Byte_t *)(Buffer))[7]; \ + ((Byte_t *)(Buffer))[1] = ((Byte_t *)(Buffer))[6]; \ + ((Byte_t *)(Buffer))[2] = ((Byte_t *)(Buffer))[5]; \ + ((Byte_t *)(Buffer))[3] = ((Byte_t *)(Buffer))[4]; \ + ((Byte_t *)(Buffer))[4] = Byte3; \ + ((Byte_t *)(Buffer))[5] = Byte2; \ + ((Byte_t *)(Buffer))[6] = Byte1; \ + ((Byte_t *)(Buffer))[7] = Byte0; \ + } while (FALSE) + +#define REVERSE_8_BYTES_2_AT_A_TIME(Buffer) \ + do { \ + UInt16_t data_bits_0 = ((UInt16_t *)(Buffer))[0]; \ + UInt16_t data_bits_1 = ((UInt16_t *)(Buffer))[1]; \ + UInt16_t data_bits_2 = ((UInt16_t *)(Buffer))[2]; \ + UInt16_t data_bits_3 = ((UInt16_t *)(Buffer))[3]; \ + CHECK(sizeof(*(Buffer))==1 || sizeof(*(Buffer))==8); \ + ((UInt16_t *)(Buffer))[0] = (((data_bits_3)<<8) | \ + ((data_bits_3&0xff))); \ + ((UInt16_t *)(Buffer))[1] = (((data_bits_2)<<8) | \ + ((data_bits_2&0xff))); \ + ((UInt16_t *)(Buffer))[2] = (((data_bits_1)<<8) | \ + ((data_bits_1&0xff))); \ + ((UInt16_t *)(Buffer))[3] = (((data_bits_0)<<8) | \ + ((data_bits_0&0xff))); \ + } while (FALSE) + +#define REVERSE_8_BYTES_4_AT_A_TIME(Buffer) \ + do { \ + UInt32_t data_bits_0 = ((UInt32_t *)(Buffer))[0]; \ + UInt32_t data_bits_1 = ((UInt32_t *)(Buffer))[1]; \ + CHECK(sizeof(*(Buffer))==1 || sizeof(*(Buffer))==8); \ + ((UInt32_t *)(Buffer))[0] = (((data_bits_1)<<24) | \ + ((data_bits_1&0x0000ff00)<<8) | \ + ((data_bits_1&0x00ff0000)>>8) | \ + ((data_bits_1)>>24)); \ + ((UInt32_t *)(Buffer))[1] = (((data_bits_0)<<24) | \ + ((data_bits_0&0x0000ff00)<<8) | \ + ((data_bits_0&0x00ff0000)>>8) | \ + ((data_bits_0)>>24)); \ + } while (FALSE) + +#define REVERSE_8_BYTES_8_AT_A_TIME(Buffer) \ + do { \ + UInt64_t data_bits = *((UInt64_t *)(Buffer)); \ + CHECK(sizeof(*(Buffer))==1 || sizeof(*(Buffer))==8); \ + *((UInt64_t *)(Buffer)) = (((data_bits)<<56) | \ + ((data_bits&0x000000000000ff00)<<40) | \ + ((data_bits&0x0000000000ff0000)<<24) | \ + ((data_bits&0x00000000ff000000)<<8) | \ + ((data_bits&0x000000ff00000000)>>8) | \ + ((data_bits&0x0000ff0000000000)>>24) | \ + ((data_bits&0x00ff000000000000)>>40) | \ + ((data_bits)>>56)); \ + } while (FALSE) + + +#if defined MSWIN +/* + * The DevStuido compiler seems to be the only one that can truly handle this + * when optimization is turned on. + */ +#define REVERSE_8_BYTES REVERSE_8_BYTES_4_AT_A_TIME +#else +#define REVERSE_8_BYTES REVERSE_8_BYTES_1_AT_A_TIME +#endif + + +/**************************************************************** + * * + * ADD-ON MSWIN IMPORT/EXPORT DEFINITIONS * + * * + ****************************************************************/ +#if defined MSWIN +# define STDCALL __stdcall +#else +# define STDCALL +#endif /* MSWIN */ + +#if defined (__cplusplus) +# define EXTERNC extern "C" +#else +# define EXTERNC +#endif /* __cplusplus */ + +#if defined MSWIN +#if defined AMTEC_INTERNAL_MAKELIBTEC || defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# else +# define TECPLOT_DLLAPI _declspec ( dllimport ) +# endif +#else +# define TECPLOT_DLLAPI +#endif + +#define LINKTOADDON EXTERNC TECPLOT_DLLAPI + + +/* + * + * Usage: + * EXPORTFROMADDON void STDCALL InitTecAddOn(void) { ... } + * + */ +#if defined MSWIN +# define EXPORTFROMADDON EXTERNC _declspec ( dllexport ) +#else +# define EXPORTFROMADDON EXTERNC +#endif /* MSWIN */ + +#define EXPORTFROMDLL EXPORTFROMADDON + +#define InitTecAddOn InitTecAddOn113 +#define TEC_INIT_FUNCTION_NAME "InitTecAddOn113" + +/* BEGINREMOVEFROMADDON */ +/* Use INLINE for static functions that could be optimized as inline. */ +#if defined (__cplusplus) && !defined _DEBUG +# define INLINE inline +#else +# define INLINE static +#endif /* __cplusplus */ +/* ENDREMOVEFROMADDON */ + + +/* BEGINREMOVEFROMADDON */ +#if defined (MSWIN) ||\ + defined (INTERX) ||\ + defined (LINUX) ||\ + defined (SUNSOLARIS86X) ||\ + defined (COMPAQALPHA) ||\ + defined (DEC) ||\ + defined (__LITTLE_ENDIAN__) +#define MACHINE_DOES_INTEL_ORDER +#endif + +#if defined( MACHINE_DOES_INTEL_ORDER ) +# define SwapBytes(IntelOrder) (!(IntelOrder)) +#else +# define SwapBytes(IntelOrder) (IntelOrder) +#endif +/* ENDREMOVEFROMADDON */ + +#if defined DECALPHA || \ + defined LINUXALPHA || \ + defined LINUXI64 || \ + defined LINUX64 || \ + defined MAC64 || \ + defined COMPAQALPHA +#define LONGIS64 +#endif + +/**************************************************************** + * * + * HARD CONSTANTS * + * * + ****************************************************************/ +#define LARGEMEMORY ((size_t)-1) + +/* BEGINREMOVEFROMADDON */ +/* Tclinterp add-on barfs on these huge integer constants */ +/* Note: Tecplot is conservative by one on LARGEINTs max */ +#define LARGEINT64 9223372036854775806LL +/* ENDREMOVEFROMADDON */ +#define LARGEINT32 2147483646 +#define LARGEINT16 32766 +#define LARGEINT8 126 + +/* BEGINREMOVEFROMADDON */ +#define LARGEUINT64 18446744073709551614ULL +/* ENDREMOVEFROMADDON */ +#define LARGEUINT32 4294967294 +#define LARGEUINT16 65534 +#define LARGEUINT8 254 + +#ifdef INDEX_16_BIT +#define MAXINDEX ((LgIndex_t)LARGEINT16) +#else +#define MAXINDEX ((LgIndex_t)LARGEINT32) +#endif +#define MAXZONEMAP MAXINDEX +#define LARGEDOUBLE 1.0e+150 +#define SMALLDOUBLE 1.0e-150 +#define LARGESTEXPONENT 150 +#define SMALLESTEXPONENT -150 + +#define SMALLESTDOUBLE SMALLDOUBLE + +#define LARGESTDOUBLEEXPONENT 308 +#define SMALLESTDOUBLEEXPONENT -307 +#define LARGESTDOUBLE 1.0e+308 +#define LARGEFLOAT 3.40282347E+38 +#define SMALLFLOAT 1.17549435E-38 +#define SMALLSTDOUBLE 1.0e-307 + +/* Visual Studio 2008 defines MAXINT32, MAXINT16 which collide with ours */ +#if defined MAXINT32 +#undef MAXINT32 +#endif +#if defined MAXINT16 +#undef MAXINT16 +#endif + +#define MAXINT32 LARGEINT32 +#define MAXINT16 LARGEINT16 +#define ETX 3 +#define LN2 0.69314718055994530942 +#define LN10 2.30258509299404568402 +#define PIOVER2 1.57079632679489661923 +#define TWOPI 6.28318530717958647692 +#if defined PI +#undef PI +#endif +#define PI 3.14159265358979323846 +#define ANGLEEPSILON 1.0e-10 +#define LARGESTANGLE (4*PI+ANGLEEPSILON) +#define DEGPERRADIANS 57.295779513082323 +#define CMPERINCH 2.54 +#define POINTSPERINCH 72.0 +#define FONTMOVEMARK 192 +#define FONTDECISIONMARK 128 +#define FONTLINEMARK 64 +#define BAD_SET_VALUE ((SetIndex_t)-1) +#define MENU_POSITION_FIRST (0) +#define MENU_POSITION_LAST (-1) +#define INVALID_UNIQUE_ID 0 + +#define BADSETVALUE BAD_SET_VALUE +#define SOLID_TRANSLUCENCY 0 +#define BAD_DISTANCE (-1.0) +/* MIN_CIRCUMFERENTIAL_INDEX is the min J dimension for circular zones */ +#define MIN_CIRCUMFERENTIAL_INDEX 4 + +#define VALID_STRAND_ID(StrandID) (0 <= (StrandID) && (StrandID) < MAXZONEMAP) +#define STRAND_ID_STATIC (-1) +#define STRAND_ID_PENDING (-2) + +/* + * Need 3 passes for "Rest of pie" method but can only use 3 clip planes + * Need only 1 pass for "Piece of pie" method and can use 6 clip planes +*/ +#define MAX_ALLOWABLE_CLIPPASSES 1 +#define MAX_ALLOWABLE_CLIPPLANES 6 + +/* BEGINREMOVEFROMADDON */ +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if defined _DEBUG +#else +#endif +#if 0 /* NOTUSED */ +#endif +#endif /* TECPLOTKERNEL */ +/* ENDREMOVEFROMADDON */ + + +/* + * NOTE: If you change TecplotBinaryFileVersion, you MUST also: + * + * 1. Update preplot: + * - Change this define symbol in preplot.cpp + * - Change version number in the data file format in the comments in preplot.cpp + * - Change the version number of Preplot itself in preplot.cpp + * 2. Maintain the ability to write the old plt file format: + * - Add a new entry to BinaryFileVersion_e + * - Add a concrete class of the VersionWriterInterface, and update + * VersionWriterAbstractFactory to return the correct instance for the previous and + * new BinaryFileVersion_e + * - Abstract away the difference in the two versions behind an interface (if one does + * not yet exist) and create concrete implementations that can write the old and the + * new versions. For a trivial example of this, see FileTypeWriterInterface and its + * associated factory and concrete classes. + */ +#define TecplotBinaryFileVersion 112 +#define TecplotInterfaceVersion 120 +#define TecplotInterfaceVersionStr "120" /* stay in lockstep with TecplotInterfaceVersion */ +#if defined FLEXLM +#define TecplotLicenseVersion 119 /* may vary from TecplotInterfaceVersion */ +#define TecplotLicenseVersionStr "11.9" /* stay in lockstep with TecplotLicenseVersion */ +#else /* FLEXLM */ +#define TecplotLicenseVersion 120 /* may vary from TecplotInterfaceVersion */ +#define TecplotLicenseVersionStr "12.0" /* stay in lockstep with TecplotLicenseVersion */ +#endif /* FLEXLM */ +/* Also change the macro version number in COMMAND.MASTER.h */ + +#define MaxNumZonesOrVars MAXZONEMAP +#define MaxXAxes 5 +#define MaxYAxes 5 +#define MaxGeoSegments 50 +#define MaxPtsCircleOrEllipse 720 +#define MaxFrames 2048 +#define MaxCustomLabelSets 10 +#define MaxFontMoves 20000 +#define MaxColorMapOverrides 16 +#define MaxValueBlankConstraints 8 +#define MaxContourGroups 8 +#define MaxIsoSurfaceGroups 8 +#define MaxSliceGroups 8 + +#define MaxColorMapGroups 8 +#define DefaultNumContLevels 15 + + +#define DefaultColorMapGroup ((SmInteger_t)0) +#define BADGROUPNUMBER ((SmInteger_t)-1) +#define UNUSEDGROUPNUMBER ((SmInteger_t)0) + +#define VALID_ISOSURFACE_GROUP(Group) (((((SmInteger_t)Group) >= 0) && (((SmInteger_t)Group) < MaxIsoSurfaceGroups))) +#define VALID_SLICE_GROUP(Group) (((((SmInteger_t)Group) >= 0) && (((SmInteger_t)Group) < MaxSliceGroups))) +#define VALID_COLORMAP_GROUP(Group) (((((SmInteger_t)Group) >= 0) && (((SmInteger_t)Group) < MaxColorMapGroups))) + + + +/* + * If any of these values changes its corresponding value in preplot.c must + * change to match it so that files created by preplot and Tecplot are + * consistent. + */ +#define MaxChrsDatasetTitle 256 +#define MaxChrsZnTitle 128 +#define MaxChrsVarName 128 +#define MaxChrsZnOrVarName 128 +/* currently limited to MaxLineIndex in preplot.c */ +#define MaxChrsAuxValueString 32000 + +#define MaxNumViews 16 +#define MaxBasicSizes 5 +#define MaxColorMapControlPoints 50 +#define MaxRawColorMapEntries 800 +#define MaxDataSetReaders 100 +#define MaxExtendedCurveFits 100 +#define MaxColorMapCycles 20 + + +/* Dimension Limits */ + +#define MinPaperDimInWorkArea 0.5 +#define MinFrameWidth 0.25 +#define MinFrameHeight 0.25 +#define MinAxisLength 0.1 + + +#define BadEnumValue 255 + +/* BEGINREMOVEFROMADDON */ +/* define class element limits */ +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif +/* ENDREMOVEFROMADDON */ + +/* + * Floating point values are written to layouts with a certain precision. + * A high precision is necessary in some cases (like streamtrace starting locations) + * This used to be set to 12 which was not high enough. It is now set to 16 which + * appears to be sufficient. This also seems to jive with the number of digits of + * precision that are found in "ieee double precision" values which is 53 bits or + * equivalent to approximately 16 digits. -bdp + * + */ +#define STYLE_FLOAT_PRECISION 16 + + +/* + * Auxiliary data common names. + * + * Define Name Data Name Data Type Data Location + * ------------------------------------------ ------------------------------------ --------- ------------- + */ +#define AuxData_Common_Incompressible "Common.Incompressible" /* Boolean_t Dataset */ +#define AuxData_Common_Density "Common.Density" /* double Dataset */ +#define AuxData_Common_SpecificHeat "Common.SpecificHeat" /* double Dataset */ +#define AuxData_Common_SpecificHeatVar "Common.SpecificHeatVar" /* int Dataset */ +#define AuxData_Common_GasConstant "Common.GasConstant" /* double Dataset */ +#define AuxData_Common_GasConstantVar "Common.GasConstantVar" /* int Dataset */ +#define AuxData_Common_Gamma "Common.Gamma" /* double Dataset */ +#define AuxData_Common_GammaVar "Common.GammaVar" /* int Dataset */ +#define AuxData_Common_Viscosity "Common.Viscosity" /* double Dataset */ +#define AuxData_Common_ViscosityVar "Common.ViscosityVar" /* int Dataset */ +#define AuxData_Common_Conductivity "Common.Conductivity" /* double Dataset */ +#define AuxData_Common_ConductivityVar "Common.ConductivityVar" /* int Dataset */ +#define AuxData_Common_AngleOfAttack "Common.AngleOfAttack" /* double Dataset */ +#define AuxData_Common_SpeedOfSound "Common.SpeedOfSound" /* double Dataset */ +#define AuxData_Common_ReferenceU "Common.ReferenceU" /* double Dataset */ +#define AuxData_Common_ReferenceV "Common.ReferenceV" /* double Dataset */ +#define AuxData_Common_XVar "Common.XVar" /* int Dataset */ +#define AuxData_Common_YVar "Common.YVar" /* int Dataset */ +#define AuxData_Common_ZVar "Common.ZVar" /* int Dataset */ +#define AuxData_Common_CVar "Common.CVar" /* int Dataset */ +#define AuxData_Common_UVar "Common.UVar" /* int Dataset */ +#define AuxData_Common_VVar "Common.VVar" /* int Dataset */ +#define AuxData_Common_WVar "Common.WVar" /* int Dataset */ +#define AuxData_Common_VectorVarsAreVelocity "Common.VectorVarsAreVelocity" /* Boolean_t Dataset */ +#define AuxData_Common_PressureVar "Common.PressureVar" /* int Dataset */ +#define AuxData_Common_TemperatureVar "Common.TemperatureVar" /* int Dataset */ +#define AuxData_Common_DensityVar "Common.DensityVar" /* int Dataset */ +#define AuxData_Common_StagnationEnergyVar "Common.StagnationEnergyVar" /* int Dataset */ +#define AuxData_Common_MachNumberVar "Common.MachNumberVar" /* int Dataset */ +#define AuxData_Common_ReferenceMachNumber "Common.ReferenceMachNumber" /* double Dataset */ +#define AuxData_Common_ReferenceW "Common.ReferenceW" /* double Dataset */ +#define AuxData_Common_PrandtlNumber "Common.PrandtlNumber" /* double DataSet */ +#define AuxData_Common_Axisymmetric "Common.Axisymmetric" /* Boolean_t Dataset */ +#define AuxData_Common_AxisOfSymmetryVarAssignment "Common.AxisOfSymmetryVarAssignment" /* int Dataset */ +#define AuxData_Common_AxisValue "Common.AxisValue" /* double Dataset */ +#define AuxData_Common_SteadyState "Common.SteadyState" /* Boolean_t Dataset */ +#define AuxData_Common_TurbulentKineticEnergyVar "Common.TurbulentKineticEnergyVar" /* int Dataset */ +#define AuxData_Common_TurbulentDissipationRateVar "Common.TurbulentDissipationRateVar" /* int Dataset */ +#define AuxData_Common_TurbulentViscosityVar "Common.TurbulentViscosityVar" /* int Dataset */ +#define AuxData_Common_TurbulentFrequencyVar "Common.TurbulentFrequencyVar" /* int Dataset */ +#define AuxData_Common_Gravity "Common.Gravity" /* double Dataset */ +#define AuxData_Common_IsBoundaryZone "Common.IsBoundaryZone" /* Boolean_t Zone */ +#define AuxData_Common_BoundaryCondition "Common.BoundaryCondition" /* BCondition Zone */ +#define AuxData_Common_Time "Common.Time" /* double Zone */ +#define AuxData_Common_Mean "Common.Mean" /* double Variable */ +#define AuxData_Common_Median "Common.Median" /* double Variable */ +#define AuxData_Common_Variance "Common.Variance" /* double Variable */ +#define AuxData_Common_StdDev "Common.StdDev" /* double Variable */ +#define AuxData_Common_AvgDev "Common.AvgDev" /* double Variable */ +#define AuxData_Common_GeoMean "Common.GeoMean" /* double Variable */ +#define AuxData_Common_ChiSqre "Common.ChiSqre" /* double Variable */ + + + + + + + +/* BEGINREMOVEFROMADDON */ +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if defined THREED +#endif +#endif /* TECPLOTKERNEL */ +/* ENDREMOVEFROMADDON */ + +/* Tecplot Add-on Custom Products */ + +/* BEGINREMOVEFROMADDON */ +/* In activeX, the color constants are an enum type, + so the activeX source code parser handles these as + a special case, and the types do not need to be + indicated as with the other hard #define constants */ +/* ENDREMOVEFROMADDON */ + +#define Black_C ((ColorIndex_t)0) +#define Red_C ((ColorIndex_t)1) +#define Green_C ((ColorIndex_t)2) +#define Blue_C ((ColorIndex_t)3) +#define Cyan_C ((ColorIndex_t)4) +#define Yellow_C ((ColorIndex_t)5) +#define Purple_C ((ColorIndex_t)6) +#define White_C ((ColorIndex_t)7) + +#define Custom1_C ((ColorIndex_t)8) +#define Custom2_C ((ColorIndex_t)9) +#define Custom3_C ((ColorIndex_t)10) +#define Custom4_C ((ColorIndex_t)11) +#define Custom5_C ((ColorIndex_t)12) +#define Custom6_C ((ColorIndex_t)13) +#define Custom7_C ((ColorIndex_t)14) +#define Custom8_C ((ColorIndex_t)15) +#define Custom9_C ((ColorIndex_t)16) + +#define Custom10_C ((ColorIndex_t)17) +#define Custom11_C ((ColorIndex_t)18) +#define Custom12_C ((ColorIndex_t)19) +#define Custom13_C ((ColorIndex_t)20) +#define Custom14_C ((ColorIndex_t)21) +#define Custom15_C ((ColorIndex_t)22) +#define Custom16_C ((ColorIndex_t)23) +#define Custom17_C ((ColorIndex_t)24) +#define Custom18_C ((ColorIndex_t)25) +#define Custom19_C ((ColorIndex_t)26) + +#define Custom20_C ((ColorIndex_t)27) +#define Custom21_C ((ColorIndex_t)28) +#define Custom22_C ((ColorIndex_t)29) +#define Custom23_C ((ColorIndex_t)30) +#define Custom24_C ((ColorIndex_t)31) +#define Custom25_C ((ColorIndex_t)32) +#define Custom26_C ((ColorIndex_t)33) +#define Custom27_C ((ColorIndex_t)34) +#define Custom28_C ((ColorIndex_t)35) +#define Custom29_C ((ColorIndex_t)36) + +#define Custom30_C ((ColorIndex_t)37) +#define Custom31_C ((ColorIndex_t)38) +#define Custom32_C ((ColorIndex_t)39) +#define Custom33_C ((ColorIndex_t)40) +#define Custom34_C ((ColorIndex_t)41) +#define Custom35_C ((ColorIndex_t)42) +#define Custom36_C ((ColorIndex_t)43) +#define Custom37_C ((ColorIndex_t)44) +#define Custom38_C ((ColorIndex_t)45) +#define Custom39_C ((ColorIndex_t)46) + +#define Custom40_C ((ColorIndex_t)47) +#define Custom41_C ((ColorIndex_t)48) +#define Custom42_C ((ColorIndex_t)49) +#define Custom43_C ((ColorIndex_t)50) +#define Custom44_C ((ColorIndex_t)51) +#define Custom45_C ((ColorIndex_t)52) +#define Custom46_C ((ColorIndex_t)53) +#define Custom47_C ((ColorIndex_t)54) +#define Custom48_C ((ColorIndex_t)55) +#define Custom49_C ((ColorIndex_t)56) + +#define Custom50_C ((ColorIndex_t)57) +#define Custom51_C ((ColorIndex_t)58) +#define Custom52_C ((ColorIndex_t)59) +#define Custom53_C ((ColorIndex_t)60) +#define Custom54_C ((ColorIndex_t)61) +#define Custom55_C ((ColorIndex_t)62) +#define Custom56_C ((ColorIndex_t)63) + +#define MultiColor_C ((ColorIndex_t)(-1)) +#define NoColor_C ((ColorIndex_t)(-2)) +#define MultiColor2_C ((ColorIndex_t)(-3)) +#define MultiColor3_C ((ColorIndex_t)(-4)) +#define MultiColor4_C ((ColorIndex_t)(-5)) +#define RGBColor_C ((ColorIndex_t)(-6)) +#define MultiColor5_C ((ColorIndex_t)(-7)) +#define MultiColor6_C ((ColorIndex_t)(-8)) +#define MultiColor7_C ((ColorIndex_t)(-9)) +#define MultiColor8_C ((ColorIndex_t)(-10)) +#define InvalidColor_C ((ColorIndex_t)(-255)) + +#define FirstCustomColor Custom1_C +#define LastCustomColor Custom56_C +#define NumCustomColors (LastCustomColor-FirstCustomColor+1) + +#define FirstBasicColor Black_C +#define LastBasicColor LastCustomColor +#define NumBasicColors (LastBasicColor-FirstBasicColor+1) + +/* BEGINREMOVEFROMADDON */ + +/* + * V8 and earlier used this for MultiColor_C. We adjust this + * to the new value in the SetValue layer so old addons work. + */ +#define OldMultiColor_C ((ColorIndex_t)255) +/* + * Gray is only used in the interface for workspace background and + * for insensitive buttons in Motif. + * True Black and True White are also interface only. They draw + * true black or true white - regardless of what the user has set + * the RGB values for the black and white basic colors. + * XOrColor_C is also for interface only. + */ +#define Gray_C (LastBasicColor+1) +#define DarkGray_C (LastBasicColor+2) /* Used for inactive frame border color */ +#define XOrColor_C (LastBasicColor+3) +#define FirstInterfaceColor Gray_C +#define LastInterfaceColor XOrColor_C + +#define NumInterfaceColors (LastInterfaceColor-FirstInterfaceColor+1) +#define NumContourShades (GeneralBase.Limits.MaxNumContourLevels+1) +#define NumColorsInColorTable (NumBasicColors+NumInterfaceColors+NumContourShades) +#define BasicColorOffset (0) +#define InterfaceColorOffset (NumBasicColors) +#define ContourColorOffset (NumBasicColors+NumInterfaceColors) + +#define BadKey (short)31 +#define Plus (short)43 +#define Minus (short)45 +#define RetKey (short)13 +#define DeleteKey (short)127 +#define ShiftDelete (short)128 +#define BackSpace (short)8 +#define LeftArrow (short)29 +#define RightArrow (short)30 +#define UpArrow (short)11 +#define DownArrow (short)10 +#define Toggle (short)19 +#define Esc (short)27 +#define RegFrame (short)18 +#define DoBitDump (short)2 + + +/* File Markers */ +#define ZoneMarker 299.0 +#define GeomMarker 399.0 +#define TextMarker 499.0 +#define CustomLabelMarker 599.0 +#define UserRecMarker 699.0 +#define DataSetAuxMarker 799.0 +#define VarAuxMarker 899.0 +#define EndHeaderMarker 357.0 + + +/* + * Additional objects that have plotter + * pens assigned to them. + */ +#define AxisPen Custom8_C+1 +#define MajGridPen Custom8_C+2 +#define MinGridPen Custom8_C+3 +#define StreamlinePen Custom8_C+4 +#define ColoredLinePen Custom8_C+5 +#define BoundaryPen Custom8_C+6 +#define LabelPen Custom8_C+7 +#define NumPlotterPens Custom8_C+8 +/* AutoSelectPen will select the correct pen from Black_C thru Custom8_C or ColoredLinePen */ +#define AutoSelectPen Custom8_C+9 +#define InvalidPen Custom8_C+99 + +#define FirstObjectPen AxisPen +#define LastObjectPen LabelPen + +#define DelZFactor 0.0001 + +#define BadBaseValue NULL + + +/* + * NOTES ON TYPEDEFS: + * + * TYPEDEF TYPE Suffix + * ------------ ------ + * simple _t + * enumerated _e + * structure _s + * union _u + * abstract _a + * pointer to simple _pt + * pointer to enumerated _pe + * pointer to structure _ps + * pointer to union _pu + * pointer to abstract _pa + * pointer to function _pf + * + * + * The only execption is char * typedef's these use _t + * + * Abstract types are intentionally made to be + * obscure. The programmer should not have to know + * what the underlying structure really is for abstract + * types. + * + */ + + +#ifdef MSWIN +# define DIR_SEPARATOR "\\" +#else +# define DIR_SEPARATOR "/" +#endif + +/* ENDREMOVEFROMADDON */ + +/* BEGINREMOVEFROMADDON */ +#if defined MSWIN +#define TP_FWRITE fwrite +#define TP_FFLUSH fflush +#define TP_FCLOSE fclose + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#else +#define TP_UNLINK remove +#define TP_RMDIR _rmdir +#define TP_FREAD ::fread +#define TP_FOPEN ::fopen +#define TP_FREOPEN ::freopen +#define TP_STAT ::_stat +#define TP_GETENV ::getenv +#endif /* TECPLOTKERNEL */ + +#if defined _WIN64 +#define TP_FSEEK(stream,offset,whence) _fseeki64((stream),(__int64)(offset),(whence)) +#define TP_FTELL _ftelli64 +#else +#define TP_FSEEK(stream, offset, whence) fseek((stream), (long)(offset), (whence)) +#define TP_FTELL ftell +#endif + +#else +#define TP_RMDIR rmdir +#define TP_UNLINK unlink +#define TP_FOPEN fopen +#define TP_FREOPEN freopen +#define TP_FCLOSE fclose +#define TP_FREAD fread +#define TP_FWRITE fwrite +#define TP_FFLUSH fflush +#define TP_FSEEK fseeko +#define TP_FTELL ftello +#define TP_STAT stat +#define _stat stat // ...make the UNIXX and MSWIN platforms have the same syntax to use "struct _stat" +#define TP_GETENV getenv +#endif +/* ENDREMOVEFROMADDON */ + +/**************************************************************** + * * + * SIMPLE TYPEDEFS * + * * + ****************************************************************/ + + + +/* How to define UInt64_t/Int64_t is platform specific, but they are always 8-bytes */ +#if defined MSWIN +typedef unsigned __int64 UInt64_t; +typedef __int64 Int64_t; +#else +#if defined CRAY +typedef unsigned int UInt64_t; +typedef int Int64_t; +#else +#if defined LONGIS64 +typedef unsigned long UInt64_t; +typedef long Int64_t; +#else +typedef unsigned long long UInt64_t; +typedef long long Int64_t; +#endif +#endif +#endif + +#if defined LONGIS64 +typedef unsigned int UInt32_t; +typedef int Int32_t; +typedef int LgInteger_t; +#else +typedef unsigned int UInt32_t; +typedef int Int32_t; +typedef int LgInteger_t; +#endif + +typedef short Int16_t; +typedef unsigned short UInt16_t; +typedef signed char Int8_t; +typedef unsigned char UInt8_t; + +#ifdef INDEX_16_BIT +typedef Int16_t LgIndex_t; +#else +typedef Int32_t LgIndex_t; +#endif +typedef LgIndex_t NodeMap_t; +typedef LgIndex_t ScreenDim_t; + +/** + * ArbParam_t type is used for passing arbitrary integers or pointers in + * parameters. HgIndex_t is used for counting node maps and other things that + * may individually be LgIndex_t, but in total exceed 32-bit. + * The general rule is that these are 4 bytes on "32-bit" machines + * and 8 bytes on "64-bit" machines. + */ +#if defined CRAY +typedef char *ArbParam_t; +typedef long HgIndex_t; +#elif defined LONGIS64 +typedef long ArbParam_t; +typedef long HgIndex_t; +#elif defined MSWIN && (defined _M_IA64 || defined _M_AMD64) +typedef INT_PTR ArbParam_t; +typedef INT_PTR HgIndex_t; +#else +typedef int ArbParam_t; +typedef int HgIndex_t; +#endif + +typedef ArbParam_t UniqueID_t; + +/* 64 bit offset used to hold file offset and size values. */ +typedef Int64_t FileOffset_t; + +/** + * 64 bit offset for memory mapped I/O. + */ +typedef UInt64_t MemMapOffset_t; + +/* + * SmInteger must be at least a short.... + */ + +typedef unsigned char Byte_t; +typedef short SmInteger_t; +typedef SmInteger_t ColorIndex_t; +#ifdef INDEX_16_BIT +typedef Int16_t EntIndex_t; +#else +typedef Int32_t EntIndex_t; +#endif +typedef Int16_t SubZoneIndex_t; + +typedef char Boolean_t; +typedef char *ZoneName_t; +typedef char *VarName_t; +typedef char *LString_t; + +typedef LgIndex_t Strand_t; +typedef LgIndex_t HeapLength_t; +typedef LgIndex_t SegPtsArray_t[MaxGeoSegments]; +typedef double BasicSize_t[MaxBasicSizes]; +typedef double *VarList_t; + +typedef long SetIndex_t; + +typedef unsigned long SetData_t; +typedef SetData_t *SetData_pt; + +/* BEGINREMOVEFROMADDON */ +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ + +/* The following list identifies items that can be inhibited. */ +#define FEATURE_3D (1L << 0) +#define FEATURE_3DVOLUME (1L << 1) +#define FEATURE_2D (1L << 2) +#define FEATURE_XY (1L << 3) +#define FEATURE_DATAALTER (1L << 4) +#define FEATURE_UNSTRUCTUREDDATA (1L << 5) +#define FEATURE_MULTIPLEFRAMES1 (1L << 6) +#define FEATURE_MULTIPLEZONES1 (1L << 7) +#define FEATURE_MULTIPLEFRAMES5 (1L << 8) +#define FEATURE_MULTIPLEZONES5 (1L << 9) +#define FEATURE_MULTIPLEFRAMES10 (1L << 10) +#define FEATURE_MULTIPLEZONES10 (1L << 11) +#define FEATURE_READNONOEMDATA (1L << 12) /* Added 07/22/2000 */ +#define FEATURE_DATALOADERS (1L << 13) /* Added 07/22/2000 */ +#define FEATURE_DATALOADERS_EXCEPTONE (1L << 14) /* Added 11/26/2001 */ +#define FEATURE_LOADONDEMAND (1L << 15) /* Added 09/13/2007 */ +#define FEATURE_MULTIPLEWORKERTHREADS (1L << 16) /* Added 09/13/2007 */ +#define FEATURE_ISOSURFACEGROUPS (1L << 17) /* Added 09/21/2007 */ +#define FEATURE_SLICEGROUPS (1L << 18) /* Added 09/21/2007 */ +#define FEATURE_STREAMTRACEGROUPS (1L << 19) /* Added 09/25/2007 not used yet */ +#define FEATURE_FEPOLYHEDRON (1L << 20) /* Added 09/25/2007 */ +#define FEATURE_FEPOLYGON (1L << 21) /* Added 09/25/2007 */ + +/* + * KnowFeaturesToInhibit must be updated whenever a new + * item is added above. + */ +#define KnownFeaturesToInhibit (FEATURE_3D |\ + FEATURE_3DVOLUME |\ + FEATURE_2D |\ + FEATURE_XY |\ + FEATURE_DATAALTER |\ + FEATURE_UNSTRUCTUREDDATA |\ + FEATURE_MULTIPLEFRAMES1 |\ + FEATURE_MULTIPLEZONES1 |\ + FEATURE_MULTIPLEFRAMES5 |\ + FEATURE_MULTIPLEZONES5 |\ + FEATURE_MULTIPLEFRAMES10 |\ + FEATURE_MULTIPLEZONES10 |\ + FEATURE_READNONOEMDATA |\ + FEATURE_DATALOADERS |\ + FEATURE_DATALOADERS_EXCEPTONE |\ + FEATURE_LOADONDEMAND |\ + FEATURE_MULTIPLEWORKERTHREADS |\ + FEATURE_ISOSURFACEGROUPS |\ + FEATURE_SLICEGROUPS |\ + FEATURE_STREAMTRACEGROUPS |\ + FEATURE_FEPOLYHEDRON |\ + FEATURE_FEPOLYGON) + +#define VALID_FEATURE_INHIBIT_FLAG(feature) (((feature) & KnownFeaturesToInhibit) != 0) +#define VALID_FEATURE_INHIBIT_MASK(mask) (((mask) & ~KnownFeaturesToInhibit)==0) + + + +/* The following are used by the OEM libs, so they need + to be outside of TECPLOTKERNEL */ +typedef unsigned long FeatureFlag_t; +typedef unsigned long FeatureMask_t; + +/* ENDREMOVEFROMADDON */ + +typedef char SymbolChar_t[3]; + +/** + * Face node offset used for identifying which node of a polytope face is + * desired. + */ +typedef LgIndex_t FaceNodeOffset_t; + +/** + * Element face offset used for identifying which face of a polytope element is + * desired. + */ +typedef LgIndex_t ElemFaceOffset_t; + +/** + * Face boundary item offset used for identifying which boundary item of a + * polytope face is desired. + */ +typedef LgIndex_t FaceBndryItemOffset_t; + +/**************************************************************** + * * + * ENUMERATED TYPEDEFS * + * * + ****************************************************************/ + +typedef enum +{ + PlacementPlaneOrientation_X, + PlacementPlaneOrientation_Y, + PlacementPlaneOrientation_Z, + END_PlacementPlaneOrientation_e, + PlacementPlaneOrientation_Invalid = BadEnumValue +} PlacementPlaneOrientation_e; + +typedef enum +{ + StringMode_ASCII, + StringMode_UTF8, + StringMode_Blend, + END_StringMode_e, + StringMode_Invalid = BadEnumValue + +} StringMode_e; + +typedef enum +{ + SidebarSizing_MaxOfAll, + SidebarSizing_Dynamic, + END_SidebarSizing_e, + SidebarSizing_Invalid = BadEnumValue + +} SidebarSizing_e; + +typedef enum +{ + SidebarLocation_Left, + SidebarLocation_Right, /* Not allowed at this time */ + SidebarLocation_Top, /* Not allowed at this time */ + SidebarLocation_Bottom, /* Not allowed at this time */ + END_SidebarLocation_e, + SidebarLocation_Invalid = BadEnumValue + +} SidebarLocation_e; + +typedef enum +{ + MenuItem_Option, + MenuItem_Toggle, + MenuItem_Separator, + MenuItem_SubMenu, + END_MenuItem_e, + MenuItem_Invalid = BadEnumValue +} MenuItem_e; + +typedef enum +{ + StandardMenu_File, + StandardMenu_Edit, + StandardMenu_View, + StandardMenu_Plot, + StandardMenu_Insert, + StandardMenu_Data, + StandardMenu_Frame, + StandardMenu_Workspace, /* deprecated: use Options instead */ + StandardMenu_Tools, + StandardMenu_Help, + StandardMenu_Animate, + StandardMenu_Options, + StandardMenu_Scripting, + END_StandardMenu_e, + StandardMenu_Invalid = BadEnumValue +} StandardMenu_e; + +typedef enum +{ + FieldProbeDialogPage_NodalValues, + FieldProbeDialogPage_CellCenteredValues, + FieldProbeDialogPage_ZoneCellInfo, + FieldProbeDialogPage_FaceNeighbors, + END_FieldProbeDialogPage_e, + FieldProbeDialogPage_Invalid = BadEnumValue +} FieldProbeDialogPage_e; + +/* BEGINREMOVEFROMADDON */ + +/* used for caches of boolean type */ +typedef enum +{ + BooleanCache_False, /* Value is cached and is FALSE */ + BooleanCache_True, /* Value is cached and is TRUE */ + BooleanCache_Uncached, /* Value is not cached. Value is unknown. */ + END_BooleanCache_e, + BooleanCache_Invalid = BadEnumValue +} BooleanCache_e; + +/* + * For determining pick location along a line + */ +typedef enum +{ + LinePickLocation_None, + LinePickLocation_StartHandle, + LinePickLocation_MidLineOnHandle, + LinePickLocation_MidLineOffHandles, + LinePickLocation_EndHandle, + END_LinePickLocation_e, + LinePickLocation_Invalid = BadEnumValue +} LinePickLocation_e; + + +/* + * Defines destination for setting up views: hardware (ie, OpenGL) or + * software (ie, internal transformation matrices). + */ +typedef enum +{ + ViewDest_Hardware, + ViewDest_Software, + END_ViewDest_e, + ViewDest_Invalid = BadEnumValue +} ViewDest_e; + +/* used for identifying the origin of the dataset reader */ +typedef enum +{ + DataSetReaderOrigin_Native, /* created by Tecplot */ + DataSetReaderOrigin_Foreign, /* created by an add-on */ + END_DataSetReaderOrigin_e, + DataSetReaderOrigin_Invalid = BadEnumValue +} DataSetReaderOrigin_e; + +/* used for identifying the origin of the extended curve fit */ +typedef enum +{ + ExtendedCurveFitOrigin_Native, /* created by Tecplot */ + ExtendedCurveFitOrigin_Foreign, /* created by an add-on */ + END_ExtendedCurveFitOrigin_e, + ExtendedCurveFitOrigin_Invalid = BadEnumValue +} ExtendedCurveFitOrigin_e; + +typedef enum +{ + CollapsedStatus_NotCollapsed, + CollapsedStatus_CollapsedToPoint, + CollapsedStatus_CollapsedToLine, + CollapsedStatus_CollapsedToSegmentedLine, + CollapsedStatus_CollapsedToTriangle, + END_CollapsedStatus_e, + CollapsedStatus_Invalid = BadEnumValue +} CollapsedStatus_e; +/* ENDREMOVEFROMADDON */ + +/** + */ +typedef enum +{ + UndoStateCategory_Frame, + UndoStateCategory_Picked, /* picked changes, not the pick itself */ + UndoStateCategory_Text, + UndoStateCategory_Geom, + UndoStateCategory_View, + UndoStateCategory_WorkspaceView, + UndoStateCategory_Style, /* style less text and geometries */ + UndoStateCategory_SpecificStyle, /* meaning that specific undo style will be added by the caller */ + UndoStateCategory_Data, + UndoStateCategory_DataAndStyle, + UndoStateCategory_StyleIncTextGeom, /* style including text and geometires */ + UndoStateCategory_GlobalStyle, /* style less field, map, text and geometries */ + UndoStateCategory_PageAction, + END_UndoStateCategory_e, + UndoStateCategory_Invalid = BadEnumValue +} UndoStateCategory_e; + + +/* + * Used only for Action_PropagateLinking + */ +typedef enum +{ + LinkType_WithinFrame, + LinkType_BetweenFrames, + END_LinkType_e, + LinkType_Invalid = BadEnumValue +} LinkType_e; + +typedef enum +{ + FrameCollection_All, + FrameCollection_Picked, + END_FrameCollection_e, + FrameCollection_Invalid = BadEnumValue +} FrameCollection_e; + + + +typedef enum +{ + LegendProcess_DrawLegend, + LegendProcess_EraseLegend, + LegendProcess_GetExtents, + END_LegendProcess_e, + LegendProcess_Invalid = BadEnumValue +} LegendProcess_e; + + +typedef enum +{ + RGBLegendOrientation_RGB, + RGBLegendOrientation_GBR, + RGBLegendOrientation_BRG, + RGBLegendOrientation_RBG, + RGBLegendOrientation_GRB, + RGBLegendOrientation_BGR, + END_RGBLegendOrientation_e, + RGBLegendOrientation_Invalid = BadEnumValue +} RGBLegendOrientation_e; + + + +/* BEGINREMOVEFROMADDON */ +/* Used by some of the image exporters/animators */ +typedef struct +{ + Byte_t R; + Byte_t G; + Byte_t B; +} RGBTriple_s; + +typedef RGBTriple_s RGBPalette_t[256]; + +/* ENDREMOVEFROMADDON */ + +/* BEGINREMOVEFROMADDON */ +/* The tag on the following line is so that the Windows + build script can parse all of the current state changes + out of this file, and compare them to the state changes + found in the main.c template file. + Do not change or delete the line below.*/ +/*StateChange_e_BeginDef*/ +/* ENDREMOVEFROMADDON */ + +typedef enum +{ + StateChange_VarsAltered, + StateChange_VarsAdded, + StateChange_ZonesDeleted, + StateChange_ZonesAdded, + StateChange_NodeMapsAltered, + StateChange_FrameDeleted, + StateChange_NewTopFrame, /* deprecated: use NewActiveFrame and/or FrameOrderChange */ + StateChange_Style, + StateChange_DataSetReset, + StateChange_NewLayout, + StateChange_CompleteReset, /* deprecated: no longer broadcast */ + StateChange_LineMapAssignment, /* was StateChange_XYMapAssignment */ + StateChange_ContourLevels, + StateChange_ModalDialogLaunch, + StateChange_ModalDialogDismiss, + StateChange_QuitTecplot, + StateChange_ZoneName, + StateChange_VarName, + StateChange_LineMapName, /* was StateChange_XYMapName */ + StateChange_LineMapAddDeleteOrReorder, /* was StateChange_XYMapAddDeleteOrReorder */ + StateChange_View, + StateChange_ColorMap, + StateChange_ContourVar, + StateChange_Streamtrace, + StateChange_NewAxisVariables, + StateChange_MouseModeUpdate, + StateChange_PickListCleared, + StateChange_PickListGroupSelect, + StateChange_PickListSingleSelect, + StateChange_PickListStyle, + StateChange_DataSetFileName, + StateChange_UnsuspendInterface, /* was StateChange_DrawGraphicsOn */ + StateChange_SuspendInterface, /* was StateChange_DrawGraphicsOff */ + StateChange_DataSetLockOn, + StateChange_DataSetLockOff, + StateChange_Text, + StateChange_Geom, + StateChange_DataSetTitle, + StateChange_DrawingInterrupted, + StateChange_PrintPreviewLaunch, + StateChange_PrintPreviewDismiss, + StateChange_AuxDataAdded, + StateChange_AuxDataDeleted, + StateChange_AuxDataAltered, + StateChange_VarsDeleted, + StateChange_TecplotIsInitialized, + StateChange_ImageExported, + StateChange_VariableLockOn, + StateChange_VariableLockOff, + StateChange_PageDeleted, + StateChange_NewTopPage, + StateChange_NewActiveFrame, + StateChange_FrameOrderChanged, + END_StateChange_e, + StateChange_Invalid = BadEnumValue, + /* deprecated values */ + StateChange_DrawGraphicsOn = StateChange_UnsuspendInterface, + StateChange_DrawGraphicsOff = StateChange_SuspendInterface, + StateChange_XYMapAssignment = StateChange_LineMapAssignment, + StateChange_XYMapName = StateChange_LineMapName, + StateChange_XYMapAddDeleteOrReorder = StateChange_LineMapAddDeleteOrReorder +} StateChange_e; + +typedef enum +{ + StateChangeMode_v75, + StateChangeMode_v80, + StateChangeMode_v100, + StateChangeMode_v113, + END_StateChangeMode_e, + StateChangeMode_Invalid = BadEnumValue +} StateChangeMode_e; + +typedef enum +{ + StateChangeCallbackAPI_Classic, + StateChangeCallbackAPI_ChangeOnly, + StateChangeCallbackAPI_ChangePlusClient, + END_StateChangeCallbackAPI_e, + StateChangeCallbackAPI_Invalid = BadEnumValue +} StateChangeCallbackAPI_e; + +typedef enum +{ + AppMode_Normal, + AppMode_Demo, + AppMode_OEM, + END_AppMode_e, + AppMode_Invalid = BadEnumValue +} AppMode_e; + +typedef enum +{ + ProductFlavor_TecplotFocus, + ProductFlavor_Tecplot360, + ProductFlavor_TecplotRS, + ProductFlavor_TecplotSDK, + END_ProductFlavor_e, + ProductFlavor_Invalid = BadEnumValue, + ProductFlavor_Focus = ProductFlavor_TecplotFocus, /* deprecated */ + ProductFlavor_360 = ProductFlavor_Tecplot360, /* deprecated */ + ProductFlavor_RS = ProductFlavor_TecplotRS, /* deprecated */ + ProductFlavor_SDK = ProductFlavor_TecplotSDK /* deprecated */ +} ProductFlavor_e; + +typedef enum +{ + LayoutPackageObject_Image, + LayoutPackageObject_Layout, + LayoutPackageObject_Data, + END_LayoutPackageObject_e, + LayoutPackageObject_Invalid = BadEnumValue +} LayoutPackageObject_e; + +typedef enum +{ + VarLoadMode_ByName, + VarLoadMode_ByPosition, + END_VarLoadMode_e, + VarLoadMode_Invalid = BadEnumValue +} VarLoadMode_e; + +typedef enum +{ + ImageSelection_OnePerFrame, + ImageSelection_WorkspaceOnly, + END_ImageSelection_e, + ImageSelection_Invalid = BadEnumValue +} ImageSelection_e; + +typedef enum +{ + LibraryType_Foreign, + LibraryType_V7Standard, + LibraryType_V7ActiveX, + END_LibraryType_e, + LibraryType_Invalid = BadEnumValue +} LibraryType_e; /* "Add-on types" */ + + +typedef enum +{ + AssignOp_Equals, + AssignOp_PlusEquals, + AssignOp_MinusEquals, + AssignOp_TimesEquals, + AssignOp_DivideEquals, + AssignOp_ConvertFromCm, + AssignOp_ConvertFromIn, + AssignOp_ConvertFromPt, + AssignOp_ConvertFromPix, + END_AssignOp_e, + AssignOp_Invalid = BadEnumValue +} AssignOp_e; + +typedef enum +{ + Dialog_ColorMap, + Dialog_Equation, + Dialog_MacroViewer, + Dialog_ZoneMapStyle, /* was Dialog_PlotAttributes*/ + Dialog_QuickEdit, + Dialog_QuickMacroPanel, + Dialog_ValueBlanking, + Dialog_Probe, /* used for dialog positioning only */ + Dialog_ProbeAt, + Dialog_NewLayout, + Dialog_OpenLayout, + Dialog_Save, + Dialog_SaveAs, + Dialog_LoadData, + Dialog_WriteData, + Dialog_Print, + Dialog_Import, + Dialog_Export, + Dialog_MacroPlay, + Dialog_MacroRecord, + Dialog_AxisEdit, + Dialog_SpatialVars, + Dialog_Reset3DAxes, + Dialog_ThreeDAxisLimits, + Dialog_ThreeDOrientationAxis, + Dialog_Streamtraces, + Dialog_IsoSurfaces, + Dialog_Slices, + Dialog_Contour, + Dialog_VectorLength, + Dialog_VectorVars, + Dialog_VectorArrowheads, + Dialog_VectorReferenceVector, + Dialog_ScatterSizeAndFont, + Dialog_ScatterLegend, + Dialog_ScatterReferenceSymbol, + Dialog_RGBColorVarsAndRange, + Dialog_RGBColorLegend, + Dialog_LineMapLegend, + Dialog_IJKBlanking, + Dialog_DepthBlanking, + Dialog_LightSource, + Dialog_Advanced3DControl, + Dialog_TwoDDrawOrder, + Dialog_PolarDrawingOptions, + Dialog_DataLabels, + Dialog_StyleLinking, + Dialog_Smooth, + Dialog_TransformCoordinates, + Dialog_Rotate2DData, + Dialog_Create1DLine, + Dialog_CreateRectangularZone, + Dialog_CreateCircularZone, + Dialog_DuplicateZone, + Dialog_MirrorZone, + Dialog_CreateZoneFromPolylines, + Dialog_CreateZoneFromValues, + Dialog_DeleteVariables, + Dialog_DeleteZones, + Dialog_ExtractContourLines, + Dialog_ExtractFEBoundary, + Dialog_ExtractIsoSurfaces, + Dialog_ExtractSlices, + Dialog_ExtractSliceFromPlane, + Dialog_ExtractStreamtraces, + Dialog_ExtractSubZone, + Dialog_ExtractDiscretePoints, + Dialog_ExtractPointsFromPolyline, + Dialog_ExtractPointsFromGeometry, + Dialog_LinearInterpolation, + Dialog_InverseDistanceInterpolation, + Dialog_KrigingInterpolation, + Dialog_Triangulate, + Dialog_DataInfo, + Dialog_CurveInfo, + Dialog_DataSpreadsheet, + Dialog_PaperSetup, + Dialog_OrderFrames, + Dialog_RulerGrid, + Dialog_ThreeDViewRotate, + Dialog_ThreeDViewDetails, + Dialog_TranslateMagnify, + Dialog_PrintPreview, + Dialog_ColorPreferences, + Dialog_MiscPreferences, + Dialog_SizePreferences, + Dialog_SaveConfiguration, + Dialog_SaveColorMap, + Dialog_LoadColorMap, + Dialog_HelpAboutTecplot, + Dialog_HelpAboutAddOns, + Dialog_Publish, + Dialog_EditFrame, + Dialog_CopyToClipboard, + Dialog_ThreeDEdge, + Dialog_TimeDetails, + Dialog_Performance, + END_Dialog_e, + Dialog_Invalid = BadEnumValue, + /* deprecated values */ + Dialog_PlotAttributes = Dialog_ZoneMapStyle +} Dialog_e; /* "Tecplot dialog types" */ + +typedef enum +{ + AnchorAlignment_TopLeft, + AnchorAlignment_TopCenter, + AnchorAlignment_TopRight, + AnchorAlignment_MiddleLeft, + AnchorAlignment_MiddleCenter, + AnchorAlignment_MiddleRight, + AnchorAlignment_BottomLeft, + AnchorAlignment_BottomCenter, + AnchorAlignment_BottomRight, + END_AnchorAlignment_e, + AnchorAlignment_Invalid = BadEnumValue +} AnchorAlignment_e; + +/* BEGINREMOVEFROMADDON */ +typedef enum +{ + PositionAtAnchor_Never, + PositionAtAnchor_Once, + PositionAtAnchor_Always, + END_PositionAtAnchor_e, + PositionAtAnchor_Invalid = BadEnumValue +} PositionAtAnchor_e; +/* ENDREMOVEFROMADDON */ + +/* BEGINREMOVEFROMADDON */ +typedef struct +{ + AnchorAlignment_e AnchorAlignment; + Boolean_t AnchorHorizontalInside; + Boolean_t AnchorVerticalInside; + SmInteger_t MinVisibilityPercentage; + LgIndex_t IOffset; + LgIndex_t JOffset; + PositionAtAnchor_e PositionAtAnchor; + Boolean_t HasBeenPositioned; /* not persistent */ +} DialogPosition_s; +/* ENDREMOVEFROMADDON */ + + +#if defined EXPORT_DEPRECATED_INTERFACES_TO_ADK_ONLY +/** + * @deprecated + * Please use \ref CurveInfoMode_e instead. + */ +typedef enum +{ + ProcessXYMode_NotUsed1, /* deprecated: do not use */ + ProcessXYMode_NotUsed2, /* deprecated: do not use */ + ProcessXYMode_NotUsed3, /* deprecated: do not use */ + ProcessXYMode_NotUsed4, /* deprecated: do not use */ + ProcessXYMode_NotUsed5, /* deprecated: do not use */ + ProcessXYMode_NotUsed6, /* deprecated: do not use */ + ProcessXYMode_NotUsed7, /* deprecated: do not use */ + ProcessXYMode_NotUsed8, /* deprecated: do not use */ + ProcessXYMode_NotUsed9, /* deprecated: do not use */ + ProcessXYMode_WriteCurveCoef, /* deprecated: use CurveInfoMode_Coefficients */ + ProcessXYMode_WriteCurvePoints, /* deprecated: use CurveInfoMode_RawData */ + END_ProcessXYMode_e, + ProcessXYMode_Invalid = BadEnumValue +} ProcessXYMode_e; +#endif + +typedef enum +{ + CurveInfoMode_Coefficients, /* ProcessXYMode_WriteCurveCoef */ + CurveInfoMode_RawData, /* ProcessXYMode_WriteCurvePoints */ + CurveInfoMode_Macro, /* ProcessXYMode_WriteCurveCoefMacro */ + END_CurveInfoMode_e, + CurveInfoMode_Invalid = BadEnumValue +} CurveInfoMode_e; + +/* BEGINREMOVEFROMADDON */ +typedef enum +{ + ProcessLineMapMode_Draw, + ProcessLineMapMode_GetXYMinMax, + ProcessLineMapMode_GetDataMinMax, + ProcessLineMapMode_GetSinglePick, + ProcessLineMapMode_CheckOnlyForGroupPick, + ProcessLineMapMode_GetGroupPick, + ProcessLineMapMode_GetFirstValidDataPoint, + ProcessLineMapMode_GetNearestPoint, + ProcessLineMapMode_GetDependentValue, + ProcessLineMapMode_GetRSquaredGoodness, + ProcessLineMapMode_DisplayCurveCoef, + ProcessLineMapMode_WriteCurveCoef, + ProcessLineMapMode_WriteCurvePoints, + ProcessLineMapMode_InsertLabels, + ProcessLineMapMode_GetIndependentValue, + ProcessLineMapMode_WriteCurveCoefMacro, + END_ProcessLineMapMode_e, + ProcessLineMapMode_Invalid = BadEnumValue +} ProcessLineMapMode_e; +/* ENDREMOVEFROMADDON */ + +typedef enum +{ + StyleBase_Factory, + StyleBase_Config, + END_StyleBase_e, + StyleBase_Invalid = BadEnumValue +} StyleBase_e; + + +typedef enum +{ + ReadDataOption_NewData, + ReadDataOption_AppendData, + ReadDataOption_ReplaceData, + END_ReadDataOption_e, + ReadDataOption_Invalid = BadEnumValue +} ReadDataOption_e; + +#if defined EXPORT_DEPRECATED_INTERFACES_TO_ADK_ONLY +/** + * @deprecated + * Please use \ref LabelType_e instead. + */ +typedef enum +{ + NodeLabel_Index, /* deprecated: use LabelType_Index */ + NodeLabel_VarValue, /* deprecated: use LabelType_VarValue */ + NodeLabel_XAndYVarValue, /* deprecated: use LabelType_XAndYVarValue */ + END_NodeLabel_e, + NodeLabel_Invalid = BadEnumValue +} NodeLabel_e; +#endif + +typedef enum +{ + LabelType_Index, /* NodeLabel_Index */ + LabelType_VarValue, /* NodeLabel_VarValue */ + LabelType_XAndYVarValue, /* NodeLabel_XAndYVarValue */ + END_LabelType_e, + LabelType_Invalid = BadEnumValue +} LabelType_e; + + +#if defined EXPORT_DEPRECATED_INTERFACES_TO_ADK_ONLY +/** + * @deprecated + * Please use \ref BorderAction_e instead. + */ +typedef enum +{ + SubBoundaryEditOption_All, /* deprecated: use BorderAction_AddAll */ + SubBoundaryEditOption_Add, /* deprecated: use BorderAction_Add */ + SubBoundaryEditOption_Remove, /* deprecated: use BorderAction_Remove */ + SubBoundaryEditOption_AddOnly, /* deprecated: use BorderAction_AddOnly */ + END_SubBoundaryEditOption_e, + SubBoundaryEditOption_Invalid = BadEnumValue +} SubBoundaryEditOption_e; +#endif + +typedef enum +{ + BorderAction_AddAll, /* SubBoundaryEditOption_All */ + BorderAction_Add, /* SubBoundaryEditOption_Add */ + BorderAction_Remove, /* SubBoundaryEditOption_Remove */ + BorderAction_AddOnly, /* SubBoundaryEditOption_AddOnly */ + END_BorderAction_e, + BorderAction_Invalid = BadEnumValue +} BorderAction_e; + + +typedef enum +{ + PointerStyle_NotUsed1, + PointerStyle_NotUsed2, + PointerStyle_NotUsed3, + PointerStyle_AllDirections, + PointerStyle_NotUsed4, + PointerStyle_NotUsed5, + PointerStyle_NotUsed6, + PointerStyle_UpperLeftBracket, + PointerStyle_UpperRightBracket, + PointerStyle_LeftBracket, + PointerStyle_LowerLeftBracket, + PointerStyle_LowerRightBracket, + PointerStyle_RightBracket, + PointerStyle_BottomBracket, + PointerStyle_TopBracket, + PointerStyle_UpDown, + PointerStyle_LeftRight, + END_PointerStyle_e, + PointerStyle_Invalid = BadEnumValue +} PointerStyle_e; + +typedef enum +{ + CursorStyle_Undefined, + CursorStyle_StandardArrow, + CursorStyle_AdjusterArrow, + CursorStyle_AllDirections, + CursorStyle_Rotate, + CursorStyle_Zoom, + CursorStyle_Locate, + CursorStyle_UpperLeftBracket, + CursorStyle_UpperRightBracket, + CursorStyle_LeftBracket, + CursorStyle_LowerLeftBracket, + CursorStyle_LowerRightBracket, + CursorStyle_RightBracket, + CursorStyle_BottomBracket, + CursorStyle_TopBracket, + CursorStyle_UpDown, + CursorStyle_LeftRight, + CursorStyle_Waiting, + END_CursorStyle_e, + CursorStyle_Invalid = BadEnumValue +} CursorStyle_e; + + +typedef enum +{ + PickSubPosition_All, + PickSubPosition_Top, + PickSubPosition_Bottom, + PickSubPosition_Left, + PickSubPosition_Right, + PickSubPosition_TopLeft, + PickSubPosition_TopRight, + PickSubPosition_BottomLeft, + PickSubPosition_BottomRight, + PickSubPosition_BottomAndTop, + PickSubPosition_LeftAndRight, + END_PickSubPosition_e, + PickSubPosition_Invalid = BadEnumValue +} PickSubPosition_e; + +typedef enum +{ + TecEngInitReturnCode_Ok, + TecEngInitReturnCode_LicenseIsInvalid, + TecEngInitReturnCode_LicenseExpired, + TecEngInitReturnCode_InternalInitializationError, + END_TecEngInitReturnCode_e, + TecEngInitReturnCode_Invalid = BadEnumValue +} TecEngInitReturnCode_e; + +typedef enum +{ + GetValueReturnCode_Ok, + GetValueReturnCode_ResultTypeError, + GetValueReturnCode_SyntaxError, + GetValueReturnCode_ContextError, + GetValueReturnCode_DeprecatedError, + END_GetValueReturnCode_e, + GetValueReturnCode_Invalid = BadEnumValue, + /* deprecated values */ + GetValue_Ok = GetValueReturnCode_Ok, /* deprecated */ + GetValue_ResultTypeError = GetValueReturnCode_ResultTypeError, /* deprecated */ + GetValue_SyntaxError = GetValueReturnCode_SyntaxError, /* deprecated */ + GetValue_ContextError = GetValueReturnCode_ContextError, /* deprecated */ + GetValue_DeprecatedError = GetValueReturnCode_DeprecatedError, /* deprecated */ + GetValue_Invalid = GetValueReturnCode_Invalid /* deprecated */ +} GetValueReturnCode_e; + +typedef enum +{ + SetValueReturnCode_Ok, + SetValueReturnCode_DuplicateValue, + SetValueReturnCode_InvalidCommandOption, + SetValueReturnCode_NoAttachedDatasetError, + SetValueReturnCode_NoAttachedFrameError, + SetValueReturnCode_NotAllowedInConfigError, + SetValueReturnCode_ValueRangeError, + SetValueReturnCode_ValueSyntaxError, + SetValueReturnCode_AssignOpError, + SetValueReturnCode_InvalidVarOrZone, + SetValueReturnCode_InternalMemoryError, + SetValueReturnCode_ContextError1, + SetValueReturnCode_ContextError2, + SetValueReturnCode_OnlyAllowedInConfigError, + SetValueReturnCode_FeatureNotAvailable, + END_SetValueReturnCode_e, + /* BEGINREMOVEFROMADDON */ + /* For now this value is only used in Tecplot code. + * the value is here as an option for the future. */ + SetValueReturnCode_Ignored = SetValueReturnCode_DuplicateValue, + /* ENDREMOVEFROMADDON */ + SetValueReturnCode_Invalid = BadEnumValue, + /* deprecated values */ + SetValue_Ok = SetValueReturnCode_Ok, /* deprecated */ + SetValue_DuplicateValue = SetValueReturnCode_DuplicateValue, /* deprecated */ + SetValue_InvalidCommandOption = SetValueReturnCode_InvalidCommandOption, /* deprecated */ + SetValue_NoAttachedDatasetError = SetValueReturnCode_NoAttachedDatasetError, /* deprecated */ + SetValue_NoAttachedFrameError = SetValueReturnCode_NoAttachedFrameError, /* deprecated */ + SetValue_NotAllowedInConfigError = SetValueReturnCode_NotAllowedInConfigError, /* deprecated */ + SetValue_ValueRangeError = SetValueReturnCode_ValueRangeError, /* deprecated */ + SetValue_ValueSyntaxError = SetValueReturnCode_ValueSyntaxError, /* deprecated */ + SetValue_AssignOpError = SetValueReturnCode_AssignOpError, /* deprecated */ + SetValue_InvalidVarOrZone = SetValueReturnCode_InvalidVarOrZone, /* deprecated */ + SetValue_InternalMemoryError = SetValueReturnCode_InternalMemoryError, /* deprecated */ + SetValue_ContextError1 = SetValueReturnCode_ContextError1, /* deprecated */ + SetValue_ContextError2 = SetValueReturnCode_ContextError2, /* deprecated */ + SetValue_OnlyAllowedInConfigError = SetValueReturnCode_OnlyAllowedInConfigError, /* deprecated */ + SetValue_FeatureNotAvailable = SetValueReturnCode_FeatureNotAvailable, /* deprecated */ + /* BEGINREMOVEFROMADDON */ + SetValue_Ignored = SetValueReturnCode_Ignored, /* deprecated */ + /* ENDREMOVEFROMADDON */ + SetValue_Invalid = SetValueReturnCode_Invalid /* deprecated */ +} SetValueReturnCode_e; + + +typedef enum +{ + ObjectAlign_LeftJustify, + ObjectAlign_RightJustify, + ObjectAlign_Center, + ObjectAlign_Top, + ObjectAlign_Bottom, + END_ObjectAlign_e, + ObjectAlign_Invalid = BadEnumValue +} ObjectAlign_e; + + +/* + * For 3D axis labels only. + */ +typedef enum +{ + LabelAlignment_ByAngle, + LabelAlignment_AlongAxis, + LabelAlignment_PerpendicularToAxis, + END_LabelAlignment_e, + LabelAlignment_Invalid = BadEnumValue +} LabelAlignment_e; /* Label alignment for 3D axis labels only" */ + +/* + * View_SetMagnification added 02/24/03 so all plot types + * can behave the same way "do a 'centered' magnifacation change". + * Line plots will still accept View_Scale option and zoom towards + * the corner so old macros/addons still work. + */ +typedef enum +{ + View_Fit, + View_DataFit, + View_AxisFit, + View_Scale, /* deprecated, Use SetMagnification */ + View_Center, + View_Translate, + View_Zoom, + View_Last, + View_Copy, + View_Paste, + View_Push, /* End of V9 enums */ + View_SetMagnification, + View_NiceFit, + View_AxisNiceFit, + View_MakeCurrentViewNice, + View_AxisMakeCurrentValuesNice, + View_AxisResetToEntireCircle, + View_FitSurfaces, + END_View_e, + View_Invalid = BadEnumValue +} View_e; + + + +typedef enum +{ + WorkspaceView_FitSelectedFrames, + WorkspaceView_FitAllFrames, + WorkspaceView_FitPaper, + WorkspaceView_Maximize, + WorkspaceView_LastView, + WorkspaceView_Zoom, + WorkspaceView_Translate, + WorkspaceView_UnMaximize, + END_WorkspaceView_e, + WorkspaceView_Invalid = BadEnumValue +} WorkspaceView_e; + + +typedef enum +{ + ArrowheadStyle_Plain, + ArrowheadStyle_Filled, + ArrowheadStyle_Hollow, + END_ArrowheadStyle_e, + ArrowheadStyle_Invalid = BadEnumValue, + /* deprecated values */ + Arrowhead_Plain = ArrowheadStyle_Plain, /* deprecated */ + Arrowhead_Filled = ArrowheadStyle_Filled, /* deprecated */ + Arrowhead_Hollow = ArrowheadStyle_Hollow, /* deprecated */ + Arrowhead_Invalid = ArrowheadStyle_Invalid /* deprecated */ +} ArrowheadStyle_e; + + +typedef enum +{ + ArrowheadAttachment_None, + ArrowheadAttachment_AtBeginning, + ArrowheadAttachment_AtEnd, + ArrowheadAttachment_AtBothEnds, + END_ArrowheadAttachment_e, + ArrowheadAttachment_Invalid = BadEnumValue, + /* deprecated values */ + ArrowheadAttach_None = ArrowheadAttachment_None, /* deprecated */ + ArrowheadAttach_AtBeginning = ArrowheadAttachment_AtBeginning, /* deprecated */ + ArrowheadAttach_AtEnd = ArrowheadAttachment_AtEnd, /* deprecated */ + ArrowheadAttach_AtBothEnds = ArrowheadAttachment_AtBothEnds, /* deprecated */ + ArrowheadAttach_Invalid = ArrowheadAttachment_Invalid /* deprecated */ +} ArrowheadAttachment_e; + +typedef enum +{ + Clipping_ClipToViewport, + Clipping_ClipToFrame, + END_Clipping_e, + Clipping_Invalid = BadEnumValue +} Clipping_e; + +typedef enum +{ + StatusInfo_Hover, + StatusInfo_Identify, + StatusInfo_Instruction, + StatusInfo_Working, + StatusInfo_PercentDone, + END_StatusInfo_e, + StatusInfo_Invalid = BadEnumValue +} StatusInfo_e; + + +#if defined EXPORT_DEPRECATED_INTERFACES_TO_ADK_ONLY +/** + * @deprecated + * Please use \ref PlotType_e instead. + */ +typedef enum +{ + FrameMode_Empty, /* deprecated: use PlotType_Automatic */ + FrameMode_ThreeD, /* deprecated: use PlotType_Cartesian3D */ + FrameMode_TwoD, /* deprecated: use PlotType_Cartesian2D */ + FrameMode_XY, /* deprecated: use PlotType_XYLine */ + FrameMode_Sketch, /* deprecated: use PlotType_Sketch */ + END_FrameMode_e, + FrameMode_Invalid = BadEnumValue, + /* deprecated values */ + Frame_Empty = FrameMode_Empty, /* deprecated */ + Frame_ThreeD = FrameMode_ThreeD, /* deprecated */ + Frame_TwoD = FrameMode_TwoD, /* deprecated */ + Frame_XY = FrameMode_XY, /* deprecated */ + Frame_Sketch = FrameMode_Sketch, /* deprecated */ + Frame_Invalid = FrameMode_Invalid /* deprecated */ +} FrameMode_e; +#endif + + +typedef enum +{ + PlotType_Automatic, /* Frame_Empty */ + PlotType_Cartesian3D, /* Frame_ThreeD */ + PlotType_Cartesian2D, /* Frame_TwoD */ + PlotType_XYLine, /* Frame_XY */ + PlotType_Sketch, /* Frame_Sketch */ + PlotType_PolarLine, + END_PlotType_e, + PlotType_Invalid = BadEnumValue +} PlotType_e; + + +#define VALID_PLOTTYPE(PlotType) ( VALID_ENUM((PlotType), PlotType_e) && \ + ((PlotType) != PlotType_Automatic) ) +#define VALID_LINEPLOT_PLOTTYPE(PlotType) ( (PlotType) == PlotType_XYLine || \ + (PlotType) == PlotType_PolarLine ) +#define VALID_FIELDPLOT_PLOTTYPE(PlotType) ( (PlotType) == PlotType_Cartesian2D || \ + (PlotType) == PlotType_Cartesian3D ) +#define PLOTTYPE_USES_FIELDZONES(PlotType) VALID_FIELDPLOT_PLOTTYPE((PlotType)) +#define PLOTTYPE_USES_LINEMAPS(PlotType) VALID_LINEPLOT_PLOTTYPE((PlotType)) +#define VALID_V9_PLOTTYPE(PlotType) ( (PlotType) == PlotType_Sketch || \ + (PlotType) == PlotType_XYLine || \ + (PlotType) == PlotType_Cartesian2D || \ + (PlotType) == PlotType_Cartesian3D ) + + +typedef enum +{ + ContLineCreateMode_OneZonePerContourLevel, + ContLineCreateMode_OneZonePerIndependentPolyline, + END_ContLineCreateMode_e, + ContLineCreateMode_Invalid = BadEnumValue +} ContLineCreateMode_e; + + +typedef enum +{ + PickObjects_None, + PickObjects_Frame, + PickObjects_Axis, + PickObjects_ThreeDOrientationAxis, + PickObjects_Geom, + PickObjects_Text, + PickObjects_ContourLegend, + PickObjects_ContourLabel, + PickObjects_ScatterLegend, + PickObjects_LineLegend, + PickObjects_ReferenceVector, + PickObjects_ReferenceScatterSymbol, + PickObjects_StreamtracePosition, + PickObjects_StreamtraceTermLine, + PickObjects_Paper, + PickObjects_Zone, + PickObjects_XYMapping, /* deprecated: use PickObject_LineMapping */ + PickObjects_StreamtraceCOB, + PickObjects_SliceCOB, + PickObjects_IsoSurfaceCOB, + PickObjects_RGBLegend, + PickObjects_LineMapping, + END_PickObjects_e, + PickObjects_Invalid = BadEnumValue, + /* deprecated values */ + PickObject_None = PickObjects_None, /* deprecated */ + PickObject_Frame = PickObjects_Frame, /* deprecated */ + PickObject_Axis = PickObjects_Axis, /* deprecated */ + PickObject_3DOrientationAxis = PickObjects_ThreeDOrientationAxis, /* deprecated */ + PickObject_Geom = PickObjects_Geom, /* deprecated */ + PickObject_Text = PickObjects_Text, /* deprecated */ + PickObject_ContourLegend = PickObjects_ContourLegend, /* deprecated */ + PickObject_ContourLabel = PickObjects_ContourLabel, /* deprecated */ + PickObject_ScatterLegend = PickObjects_ScatterLegend, /* deprecated */ + PickObject_LineLegend = PickObjects_LineLegend, /* deprecated */ + PickObject_XYLegend = PickObjects_LineLegend, /* deprecated */ + PickObject_ReferenceVector = PickObjects_ReferenceVector, /* deprecated */ + PickObject_ReferenceScatterSymbol = PickObjects_ReferenceScatterSymbol, /* deprecated */ + PickObject_StreamtracePosition = PickObjects_StreamtracePosition, /* deprecated */ + PickObject_StreamtraceTermLine = PickObjects_StreamtraceTermLine, /* deprecated */ + PickObject_Paper = PickObjects_Paper, /* deprecated */ + PickObject_Zone = PickObjects_Zone, /* deprecated */ + PickObject_XYMapping = PickObjects_XYMapping, /* deprecated */ + PickObject_StreamtraceCOB = PickObjects_StreamtraceCOB, /* deprecated */ + PickObject_SliceCOB = PickObjects_SliceCOB, /* deprecated */ + PickObject_IsoSurfaceCOB = PickObjects_IsoSurfaceCOB, /* deprecated */ + PickObject_RGBLegend = PickObjects_RGBLegend, /* deprecated */ + PickObject_LineMapping = PickObjects_LineMapping, /* deprecated */ + PickObject_Invalid = PickObjects_Invalid /* deprecated */ +} PickObjects_e; + + +/* BEGINREMOVEFROMADDON */ +typedef enum +{ + SingleEditState_NotEditing, + SingleEditState_ActivelyEditing, + SingleEditState_WasEditing, + END_SingleEditState_e, + EditingInvalid = BadEnumValue +} SingleEditState_e; + + +typedef enum +{ + AxisSubObject_GridArea, + AxisSubObject_AxisLine, + AxisSubObject_Title, + END_AxisSubObject_e, + AxisSubObject_Invalid = BadEnumValue +} AxisSubObject_e; + +typedef enum +{ + AxisSubPosition_GridMinBorder, + AxisSubPosition_GridMaxBorder, + AxisSubPosition_MainAxisLine, + AxisSubPosition_BackAxisLine, + AxisSubPosition_PerpAxisLine, + AxisSubPosition_PerpBackAxisLine, + END_AxisSubPosition_e, + AxisSubPosition_Invalid = BadEnumValue, + AxisSubPosition_2DStart = AxisSubPosition_GridMinBorder, + AxisSubPosition_2DEnd = AxisSubPosition_MainAxisLine, + AxisSubPosition_PolarStart = AxisSubPosition_GridMinBorder, + AxisSubPosition_PolarEnd = AxisSubPosition_PerpBackAxisLine +} AxisSubPosition_e; +/* ENDREMOVEFROMADDON */ + +/* + * NOTE: The _NoOp value is not at the top so this + * enumeration aligns with the old AltMouseButtonMode_e + * enumeration. + */ +typedef enum +{ + MouseButtonClick_Redraw, + MouseButtonClick_RevertToSelect, + MouseButtonClick_NoOp, + END_MouseButtonClick_e, + MouseButtonClick_Invalid = BadEnumValue +} MouseButtonClick_e; + + +typedef enum +{ + MouseButtonDrag_NoOp, + MouseButtonDrag_ZoomPaper, + MouseButtonDrag_TranslatePaper, + MouseButtonDrag_ZoomData, + MouseButtonDrag_TranslateData, + MouseButtonDrag_RlrBallRtatData, + MouseButtonDrag_SpherRtatData, + MouseButtonDrag_XRotateData, + MouseButtonDrag_YRotateData, + MouseButtonDrag_ZRotateData, + MouseButtonDrag_TwistRotateData, + MouseButtonDrag_ZoomViewer, + MouseButtonDrag_TranslateViewer, + MouseButtonDrag_RlrBallRtatVwr, + MouseButtonDrag_SpherRotateVwr, + MouseButtonDrag_XRotateViewer, + MouseButtonDrag_YRotateViewer, + MouseButtonDrag_ZRotateViewer, + MouseButtonDrag_TwistRotateViewer, + END_MouseButtonDrag_e, + MouseButtonDrag_Invalid = BadEnumValue +} MouseButtonDrag_e; + + +/* BEGINREMOVEFROMADDON */ +typedef struct +{ + MouseButtonClick_e ButtonClick; + MouseButtonDrag_e SimpleDrag; + MouseButtonDrag_e ControlledDrag; + MouseButtonDrag_e AltedDrag; + MouseButtonDrag_e ShiftedDrag; + MouseButtonDrag_e ControlAltedDrag; + MouseButtonDrag_e ControlShiftedDrag; + MouseButtonDrag_e AltShiftedDrag; + MouseButtonDrag_e ControlAltShiftedDrag; +} MouseButtonAction_s; + + +typedef struct +{ + MouseButtonAction_s MiddleButton; + MouseButtonAction_s RightButton; +} MouseActions_s; +/* ENDREMOVEFROMADDON */ + + +typedef enum /* deprecated */ +{ + AltMouseButtonMode_Regen, + AltMouseButtonMode_RevertToSelect, + END_AltMouseButtonMode_e, + AltMouseButtonMode_Invalid = BadEnumValue +} AltMouseButtonMode_e; + + +typedef enum +{ + MouseButtonMode_NoMode, + MouseButtonMode_Select, + MouseButtonMode_Adjust, + MouseButtonMode_Zoom, + MouseButtonMode_Translate, + MouseButtonMode_Probe, + MouseButtonMode_Text, + MouseButtonMode_GeomPolyline, + MouseButtonMode_GeomSquare, + MouseButtonMode_GeomCircle, + MouseButtonMode_GeomRectangle, + MouseButtonMode_GeomEllipse, + MouseButtonMode_GeomSpline, + MouseButtonMode_CreateFrame, + MouseButtonMode_RotateSpherical, + MouseButtonMode_RotateRollerBall, + MouseButtonMode_RotateTwist, + MouseButtonMode_RotateXAxis, + MouseButtonMode_RotateYAxis, + MouseButtonMode_RotateZAxis, + MouseButtonMode_ContourLabel, + MouseButtonMode_ContourAdd, + MouseButtonMode_ContourDelete, + MouseButtonMode_StreamPoints, + MouseButtonMode_StreamEndLine, + MouseButtonMode_ExtractPoints, + MouseButtonMode_ExtractLine, + MouseButtonMode_CreateRectangularZone, + MouseButtonMode_CreateCircularZone, + MouseButtonMode_Slice, + MouseButtonMode_LightSource, + MouseButtonMode_User1, + MouseButtonMode_User2, + MouseButtonMode_User3, + MouseButtonMode_User4, + END_MouseButtonMode_e, + MouseButtonMode_Invalid = BadEnumValue, + /* deprecated values */ + Mouse_NoMode = MouseButtonMode_NoMode, /* deprecated */ + Mouse_Select = MouseButtonMode_Select, /* deprecated */ + Mouse_Adjust = MouseButtonMode_Adjust, /* deprecated */ + Mouse_Zoom = MouseButtonMode_Zoom, /* deprecated */ + Mouse_Translate = MouseButtonMode_Translate, /* deprecated */ + Mouse_Probe = MouseButtonMode_Probe, /* deprecated */ + Mouse_Text = MouseButtonMode_Text, /* deprecated */ + Mouse_GeomPolyline = MouseButtonMode_GeomPolyline, /* deprecated */ + Mouse_GeomSquare = MouseButtonMode_GeomSquare, /* deprecated */ + Mouse_GeomCircle = MouseButtonMode_GeomCircle, /* deprecated */ + Mouse_GeomRectangle = MouseButtonMode_GeomRectangle, /* deprecated */ + Mouse_GeomEllipse = MouseButtonMode_GeomEllipse, /* deprecated */ + Mouse_GeomSpline = MouseButtonMode_GeomSpline, /* deprecated */ + Mouse_CreateFrame = MouseButtonMode_CreateFrame, /* deprecated */ + Mouse_RotateSpherical = MouseButtonMode_RotateSpherical, /* deprecated */ + Mouse_RotateRollerBall = MouseButtonMode_RotateRollerBall, /* deprecated */ + Mouse_RotateTwist = MouseButtonMode_RotateTwist, /* deprecated */ + Mouse_RotateXAxis = MouseButtonMode_RotateXAxis, /* deprecated */ + Mouse_RotateYAxis = MouseButtonMode_RotateYAxis, /* deprecated */ + Mouse_RotateZAxis = MouseButtonMode_RotateZAxis, /* deprecated */ + Mouse_ContourLabel = MouseButtonMode_ContourLabel, /* deprecated */ + Mouse_ContourAdd = MouseButtonMode_ContourAdd, /* deprecated */ + Mouse_ContourDelete = MouseButtonMode_ContourDelete, /* deprecated */ + Mouse_StreamPoints = MouseButtonMode_StreamPoints, /* deprecated */ + Mouse_StreamEndLine = MouseButtonMode_StreamEndLine, /* deprecated */ + Mouse_ExtractPoints = MouseButtonMode_ExtractPoints, /* deprecated */ + Mouse_ExtractLine = MouseButtonMode_ExtractLine, /* deprecated */ + Mouse_CreateRectangularZone = MouseButtonMode_CreateRectangularZone, /* deprecated */ + Mouse_CreateCircularZone = MouseButtonMode_CreateCircularZone, /* deprecated */ + Mouse_Slice = MouseButtonMode_Slice, /* deprecated */ + Mouse_User1 = MouseButtonMode_User1, /* deprecated */ + Mouse_User2 = MouseButtonMode_User2, /* deprecated */ + Mouse_User3 = MouseButtonMode_User3, /* deprecated */ + Mouse_User4 = MouseButtonMode_User4, /* deprecated */ + Mouse_Invalid = MouseButtonMode_Invalid /* deprecated */ +} MouseButtonMode_e; + + +typedef enum +{ + DetailsButtonState_QuickEdit, + DetailsButtonState_ObjectDetails, + DetailsButtonState_ToolDetails, + END_DetailsButtonState_e, + DetailsButtonState_Invalid = BadEnumValue +} DetailsButtonState_e; + + +typedef enum +{ + Event_ButtonPress, + Event_ButtonRelease, + Event_ButtonDoublePress, + Event_Motion, + Event_Drag, + Event_KeyPress, + END_Event_e, + Event_Invalid = BadEnumValue +} Event_e; + + +typedef enum +{ + ObjectDrawMode_DrawFirst, + ObjectDrawMode_Move, + ObjectDrawMode_Remove, + ObjectDrawMode_Place, + END_ObjectDrawMode_e, + ObjectDrawMode_Invalid = BadEnumValue +} ObjectDrawMode_e; + + +typedef enum +{ + ThreeDViewChangeDrawLevel_Full, + ThreeDViewChangeDrawLevel_Trace, + END_ThreeDViewChangeDrawLevel_e, + ThreeDViewChangeDrawLevel_Invalid = BadEnumValue +} ThreeDViewChangeDrawLevel_e; /* "ThreeDViewChangeDrawLevel is deprecated. Use PlotApproximateMode.\n"*/ + +typedef enum +{ + NonCurrentFrameRedrawLevel_Full, + NonCurrentFrameRedrawLevel_Trace, + END_NonCurrentFrameRedrawLevel_e, + NonCurrentFrameRedrawLevel_Invalid = BadEnumValue +} NonCurrentFrameRedrawLevel_e; /* "NonCurrentFrameRedrawLevel is deprecated. Use PlotApproximateMode.\n"*/ + + +/** + * Enumerates the redraw reasons and is passed as an argument to registered + * draw event callbacks. + * + * - RedrawReason_UserReqRedrawActiveFrame:\n + * The full draw event is in response to the "redraw" action function. + * + * - RedrawReason_UserReqTraceActiveFrame:\n + * The approximate draw event is in response to the "redraw" action function. + * + * - RedrawReason_UserReqRedrawAllFrames:\n + * The full draw event is in response to the "redraw all" action function. + * + * - RedrawReason_UserReqTraceAllFrames:\n + * The approximate draw event is in response to the "redraw all" action function. + * + * - RedrawReason_InteractiveDataViewChange:\n + * The draw event is in response to an interactive data view change such as + * rotate, translate, zoom, etc. + * + * - RedrawReason_InteractivePaperViewChange:\n + * The draw event is in response to an interactive paper translate view or + * paper zoom view change. + * + * - RedrawReason_InteractiveStyleChange:\n + * The draw event is in response to an interactive style changes such as + * dragging a contour level or a slice. + * + * - RedrawReason_Animation:\n + * The draw event is in response to an animation. + * + * - RedrawReason_AutoRedraw:\n + * The draw event is in response to an auto redraw. + * + * - RedrawReason_RedrawForcedViewUpdate:\n + * The draw event is in response to forced view update when auto redraw is + * off such as a view fit or movement of the frame. + * + * - RedrawReason_RedrawForcedStyleUpdate:\n + * The draw event is in response to forced view update when auto redraw is + * off such as deleting a contour level. + * + * - RedrawReason_PreFullRedrawTraceOfAllFrames:\n + * The draw event is an approximate redraw done prior to a full redraw. + * + * @sa TecUtilEventAddPreDrawCallback(), TecUtilEventAddPostDrawCallback() + */ +typedef enum +{ + RedrawReason_UserReqRedrawActiveFrame, + RedrawReason_UserReqTraceActiveFrame, + RedrawReason_UserReqRedrawAllFrames, + RedrawReason_UserReqTraceAllFrames, + RedrawReason_InteractiveDataViewChange, + RedrawReason_InteractivePaperViewChange, + RedrawReason_InteractiveStyleChange, + RedrawReason_Animation, + RedrawReason_AutoRedraw, + RedrawReason_RedrawForcedViewUpdate, + RedrawReason_RedrawForcedStyleUpdate, + RedrawReason_PreFullRedrawTraceOfAllFrames, + END_RedrawReason_e, + RedrawReason_Invalid = BadEnumValue, + RedrawReason_UserReqRedrawCurrentFrame = RedrawReason_UserReqRedrawActiveFrame, + RedrawReason_UserReqTraceCurrentFrame = RedrawReason_UserReqTraceActiveFrame +} RedrawReason_e; + +typedef enum +{ + RotationMode_XYZAxis, + RotationMode_Spherical, + RotationMode_RollerBall, + END_RotationMode_e, + RotationMode_Invalid = BadEnumValue +} RotationMode_e; + +typedef enum +{ + RotateAxis_X, + RotateAxis_Y, + RotateAxis_Z, + RotateAxis_Psi, + RotateAxis_Theta, + RotateAxis_Alpha, + RotateAxis_Twist, + RotateAxis_VertRollerBall, + RotateAxis_HorzRollerBall, + RotateAxis_AboutVector, + /* BEGINREMOVEFROMADDON */ + RotateAxis_DontCare, /* internal use only */ + /* ENDREMOVEFROMADDON */ + END_RotateAxis_e, + RotateAxis_Invalid = BadEnumValue +} RotateAxis_e; + +typedef enum +{ + RotateOriginLocation_DefinedOrigin, + RotateOriginLocation_Viewer, + END_RotateOriginLocation_e, + RotateOriginLocation_Invalid = BadEnumValue +} RotateOriginLocation_e; + +/* + * NOTE: This is only used with the $!Reset3DOrigin command. + */ +typedef enum +{ + OriginResetLocation_DataCenter, + OriginResetLocation_ViewCenter, + END_OriginResetLocation_e, + OriginResetLocation_Invalid = BadEnumValue +} OriginResetLocation_e; + +/* + * NOTE: This is only used with the $!CreateSliceZoneFromPlane command. + */ +typedef enum +{ + SliceSource_SurfaceZones, + SliceSource_VolumeZones, + SliceSource_SurfacesOfVolumeZones, + SliceSource_LinearZones, + END_SliceSource_e, + SliceSource_Invalid = BadEnumValue +} SliceSource_e; + + + + + +typedef enum +{ + Input_SmInteger, + Input_Short, + Input_Integer, + Input_Float, + Input_Double, + Input_Radians, + Input_TimeDateDouble, + Input_ElapsedTimeDouble, + END_Input_e, + Input_Invalid = BadEnumValue +} Input_e; + + + +typedef enum +{ + PtSelection_All, + PtSelection_NearestN, + PtSelection_OctantN, + END_PtSelection_e, + PtSelection_Invalid = BadEnumValue +} PtSelection_e; + + + +typedef enum +{ + Drift_None, + Drift_Linear, + Drift_Quad, + END_Drift_e, + Drift_Invalid = BadEnumValue +} Drift_e; + + + +/* atpoint is simple boundary condition. + atpointb2 is better boundary condition. +*/ +typedef enum +{ + DerivPos_atpoint, + DerivPos_atpointb2, + DerivPos_kphalf, + DerivPos_jphalf, + DerivPos_iphalf, + END_DerivPos_e, + DerivPos_Invalid = BadEnumValue +} DerivPos_e; /*"atpoint is the simple boundary condition\n"*/ +/*"atpointb2 is a better boundary condition"*/ + + +typedef enum +{ + LinearInterpMode_DontChange, + LinearInterpMode_SetToConst, + END_LinearInterpMode_e, + LinearInterpMode_Invalid = BadEnumValue +} LinearInterpMode_e; + +typedef enum +{ + VolumeCellInterpolationMode_PiecewiseLinear, + VolumeCellInterpolationMode_TriLinear, + END_VolumeCellInterpolationMode_e, + VolumeCellInterpolationMode_Invalid = BadEnumValue +} VolumeCellInterpolationMode_e; + +typedef enum +{ + PolyCellInterpolationMode_UseCCValue, + PolyCellInterpolationMode_AverageNodes, + END_PolyCellInterpolationMode_e, + PolyCellInterpolationMode_Invalid = BadEnumValue +} PolyCellInterpolationMode_e; + +typedef enum +{ + ConstraintOp2Mode_UseVar, + ConstraintOp2Mode_UseConstant, + END_ConstraintOp2Mode_e, + ConstraintOp2Mode_Invalid = BadEnumValue +} ConstraintOp2Mode_e; + +/** + * Controls how data is loaded for interactive probe events. + * DataProbeVarLoadMode_IncrementallyLoadAll will load as much data as possible within + * load-on-demand time/space thresholds. DataProbeVarLoadMode_LoadRequiredVarsOnly will + * load only the data necessary to complete the probe request. + * DataProbeVarLoadMode_IncrementallyLoadAll is the default. + */ +typedef enum +{ + DataProbeVarLoadMode_IncrementallyLoadAll, + DataProbeVarLoadMode_LoadRequiredVarsOnly, + END_DataProbeVarLoadMode_e, + DataProbeVarLoadMode_Invalid = BadEnumValue +} DataProbeVarLoadMode_e; + +typedef enum +{ + ValueBlankCellMode_AllCorners, + ValueBlankCellMode_AnyCorner, + ValueBlankCellMode_PrimaryValue, + END_ValueBlankCellMode_e, + ValueBlankCellMode_Invalid = BadEnumValue, + /* deprecated values */ + ValueBlankCellMode_PrimaryCorner = ValueBlankCellMode_PrimaryValue +} ValueBlankCellMode_e; + + +/* + * deprecated: ValueBlankMode_e enumeration will not be supported after + * version 8. This API was retained for add-on developers + * using the TecUtilStyleSetLowLevel API. + */ +typedef enum +{ + ValueBlankMode_AndRule, + ValueBlankMode_OrRule, + ValueBlankMode_CornerRule, + END_ValueBlankMode_e, + ValueBlankMode_Invalid = BadEnumValue +} ValueBlankMode_e; /*"DEPRECATED: ValueBlankMode_e will not be supported after version 8"*/ + + +typedef enum +{ + CellBlankedCond_NotBlanked, + CellBlankedCond_PartiallyBlanked, + CellBlankedCond_EntirelyBlanked, + CellBlankedCond_Uncertain, + END_CellBlankedCond_e, + CellBlankedCond_Invalid = BadEnumValue +} CellBlankedCond_e; + + +typedef enum +{ + RelOp_LessThanOrEqual, + RelOp_GreaterThanOrEqual, + RelOp_LessThan, + RelOp_GreaterThan, + RelOp_EqualTo, + RelOp_NotEqualTo, + END_RelOp_e, + RelOp_Invalid = BadEnumValue +} RelOp_e; + + + +typedef enum +{ + IJKBlankMode_BlankInterior, + IJKBlankMode_BlankExterior, + END_IJKBlankMode_e, + IJKBlankMode_Invalid = BadEnumValue +} IJKBlankMode_e; + + +typedef enum +{ + PlotApproximationMode_Automatic, + PlotApproximationMode_NonCurrentAlwaysApproximated, + PlotApproximationMode_AllFramesAlwaysApproximated, + END_PlotApproximationMode_e, + PlotApproximationMode_Invalid = BadEnumValue +} PlotApproximationMode_e; + +typedef enum +{ + SphereScatterRenderQuality_Low, + SphereScatterRenderQuality_Medium, + SphereScatterRenderQuality_High, + END_SphereScatterRenderQuality_e, + SphereScatterRenderQuality_Invalid = BadEnumValue +} SphereScatterRenderQuality_e; + +/* + * NOTE: FillPat_e is deprecated. It must be retained to maintain + * backward compatibility with the TecUtil layer however. + * This has been replaced by Translucency_e. + */ +typedef enum +{ + Pattern_Solid, + Pattern_LowTranslucent, + Pattern_MedTranslucent, + Pattern_HighTranslucent, + END_FillPat_e, + Pattern_Invalid = BadEnumValue +} FillPat_e; /*"DEPRECATED: Replaced by Translucency_e"*/ + + +typedef enum +{ + Translucency_Solid, + Translucency_Low, + Translucency_Medium, + Translucency_High, + END_Translucency_e, + Translucency_Invalid = BadEnumValue +} Translucency_e; + + + +typedef enum +{ + SunRaster_OldFormat, + SunRaster_Standard, + SunRaster_ByteEncoded, + END_SunRaster_e, + SunRaster_Invalid = BadEnumValue +} SunRaster_e; + + +typedef enum +{ + BoundaryCondition_Fixed, + BoundaryCondition_ZeroGradient, + BoundaryCondition_Zero2nd, + END_BoundaryCondition_e, + BoundaryCondition_Invalid = BadEnumValue +} BoundaryCondition_e; + + + +/* Note: + * In 2D: AxisMode_Independent and AxisMode_XYDependent are used; + * in 3D: AxisMode_Independent, AxisMode_XYZDependent, and AxisMode_XYDependent are used. + */ +typedef enum +{ + AxisMode_Independent, + AxisMode_XYZDependent, + AxisMode_XYDependent, + END_AxisMode_e, + AxisMode_Invalid = BadEnumValue +} AxisMode_e;/*"In 2D AxisMode_Independent and AxisMode_XYDependent are used\n"*/ +/*"In 3D AxisMode_Independent, "*/ +/*"AxisMode_XYZDependent, and AxisMode_XYDependent are used."*/ + +typedef enum +{ + Quick_LineColor, + Quick_FillColor, + Quick_TextColor, + END_QuickColorMode_e, + Quick_Invalid = BadEnumValue +} QuickColorMode_e; + + +typedef enum +{ + FillMode_None, + FillMode_UseSpecificColor, + FillMode_UseLineColor, + FillMode_UseBackgroundColor, + END_FillMode_e, + FillMode_Invalid = BadEnumValue +} FillMode_e; + + +typedef enum +{ + LinePattern_Solid, + LinePattern_Dashed, + LinePattern_DashDot, + LinePattern_Dotted, + LinePattern_LongDash, + LinePattern_DashDotDot, + END_LinePattern_e, + LinePattern_Invalid = BadEnumValue +} LinePattern_e; + + + +typedef enum +{ + Join_Miter, + Join_Round, + Join_Bevel, + END_LineJoin_e, + Join_Invalid = BadEnumValue +} LineJoin_e; + + + +typedef enum +{ + Cap_Flat, + Cap_Round, + Cap_Square, + END_LineCap_e, + Cap_Invalid = BadEnumValue +} LineCap_e; + + + +typedef enum +{ + GeomForm_LineSegs, + GeomForm_Rectangle, + GeomForm_Square, + GeomForm_Circle, + GeomForm_Ellipse, + GeomForm_LineSegs3D, /* deprecated: use GeomForm_LineSegs with CoordSys_Grid3D */ + GeomForm_Image, + END_GeomForm_e, + GeomForm_Invalid = BadEnumValue, + /* new value names */ + GeomType_LineSegs = GeomForm_LineSegs, + GeomType_Rectangle = GeomForm_Rectangle, + GeomType_Square = GeomForm_Square, + GeomType_Circle = GeomForm_Circle, + GeomType_Ellipse = GeomForm_Ellipse, + GeomType_LineSegs3D = GeomForm_LineSegs3D, /* deprecated: use GeomType_LineSegs with CoordSys_Grid3D */ + GeomType_Image = GeomForm_Image, + END_GeomType_e = END_GeomForm_e, + GeomType_Invalid = GeomForm_Invalid +} GeomForm_e; + +typedef GeomForm_e GeomType_e; + +typedef enum +{ + VariableDerivationMethod_Fast, + VariableDerivationMethod_Accurate, + END_VariableDerivationMethod_e, + VariableDerivationMethod_Invalid = BadEnumValue +} VariableDerivationMethod_e; + +/** + */ +typedef enum +{ + AuxDataType_String, + END_AuxDataType_e, + AuxDataType_Invalid = BadEnumValue +} AuxDataType_e; + +/** + */ +typedef enum +{ + AuxDataLocation_Zone, + AuxDataLocation_DataSet, + AuxDataLocation_Frame, + AuxDataLocation_Var, + AuxDataLocation_LineMap, + AuxDataLocation_Page, + END_AuxDataLocation_e, + AuxDataLocation_Invalid = BadEnumValue +} AuxDataLocation_e; + + +/* Note: This replaces Element_e */ +typedef enum +{ + ZoneType_Ordered, + ZoneType_FETriangle, + ZoneType_FEQuad, + ZoneType_FETetra, + ZoneType_FEBrick, + ZoneType_FELineSeg, + ZoneType_FEPolygon, + ZoneType_FEPolyhedron, + END_ZoneType_e, + ZoneType_Invalid = BadEnumValue +} ZoneType_e; + +typedef enum +{ + ZoneOrder_I, + ZoneOrder_J, + ZoneOrder_K, + ZoneOrder_IJ, + ZoneOrder_IK, + ZoneOrder_JK, + ZoneOrder_IJK, + END_ZoneOrder_e, + ZoneOrder_Invalid = BadEnumValue +} ZoneOrder_e; + +/* deprecated: replaced by ZoneType_e DataPacking_e */ +typedef enum +{ + DataFormat_IJKBlock, + DataFormat_IJKPoint, + DataFormat_FEBlock, + DataFormat_FEPoint, + END_DataFormat_e, + DataFormat_Invalid = BadEnumValue +} DataFormat_e; + +typedef enum +{ + DataPacking_Block, + DataPacking_Point, + END_DataPacking_e, + DataPacking_Invalid = BadEnumValue +} DataPacking_e; + + + +typedef enum +{ + PD_HPGL, + PD_HPGL2, + PD_PS, + PD_LASERG, /* deprecated */ + PD_EPS, + PD_WINDOWS, /* Windows Print Driver */ + PD_WMF, /* Windows MetaFile (used from Export only) */ + PD_X3D, + END_PrinterDriver_e, + PD_Invalid = BadEnumValue +} PrinterDriver_e; + + + +typedef enum +{ + Image_None, + Image_TIFF, + Image_EPSI2, + Image_FRAME, + END_EPSPreviewImage_e, + Image_Invalid = BadEnumValue +} EPSPreviewImage_e; + +typedef enum +{ + TIFFByteOrder_Intel, + TIFFByteOrder_Motorola, + END_TIFFByteOrder_e, + TIFFByteOrder_Invalid = BadEnumValue +} TIFFByteOrder_e; + +typedef enum +{ + JPEGEncoding_Standard, + JPEGEncoding_Progressive, + END_JPEGEncoding_e, + JPEGEncoding_Invalid = BadEnumValue +} JPEGEncoding_e; + + +typedef enum +{ + FlashImageType_Lossless, + FlashImageType_JPEG, + FlashImageType_Color256, + END_FlashImageType_e, + FlashImageType_Invalid = BadEnumValue, + /* deprecated values */ + FlashImageType_256Color = FlashImageType_Color256 +} FlashImageType_e; + +typedef enum +{ + FlashCompressionType_BestSpeed, + FlashCompressionType_SmallestSize, + END_FlashCompressionType_e, + FlashCompressionType_Invalid = BadEnumValue +} FlashCompressionType_e; + + +typedef enum +{ + ExportFormat_RasterMetafile, + ExportFormat_TIFF, + ExportFormat_SGI, + ExportFormat_SunRaster, + ExportFormat_XWindows, + ExportFormat_PSImage, /* deprecated */ + ExportFormat_HPGL, + ExportFormat_HPGL2, + ExportFormat_PS, + ExportFormat_EPS, + ExportFormat_LaserGraphics, /* deprecated */ + ExportFormat_WindowsMetafile, + ExportFormat_BMP, + ExportFormat_PNG, + ExportFormat_AVI, + ExportFormat_Custom, /* May be used in a future version */ + ExportFormat_JPEG, + ExportFormat_Flash, + ExportFormat_X3D, + ExportFormat_TecplotViewer, + END_ExportFormat_e, + ExportFormat_Invalid = BadEnumValue +} ExportFormat_e; + +typedef enum +{ + AVICompression_ColorPreserving, + AVICompression_LinePreserving, + AVICompression_LosslessUncompressed, + END_AVICompression_e, + AVICompression_Invalid = BadEnumValue +} AVICompression_e; + +typedef enum +{ + AnimationDest_Screen, + AnimationDest_AVI, + AnimationDest_RM, + AnimationDest_Flash, + END_AnimationDest_e, + AnimationDest_Invalid = BadEnumValue +} AnimationDest_e; + + + +typedef enum +{ + AnimationOperation_Forward, + AnimationOperation_Backward, + AnimationOperation_Loop, + AnimationOperation_Bounce, + END_AnimationOperation_e, + AnimationOperation_Invalid = BadEnumValue +} AnimationOperation_e; + +typedef enum +{ + AnimationStep_First, + AnimationStep_Second, + AnimationStep_Current, + AnimationStep_SecondToLast, + AnimationStep_Last, + AnimationStep_Previous, + AnimationStep_Next, + END_AnimationStep_e, + AnimationStep_Invalid = BadEnumValue +} AnimationStep_e; + +typedef enum +{ + ZoneAnimationMode_StepByNumber, + ZoneAnimationMode_GroupStepByNumber, + ZoneAnimationMode_StepByTime, + END_ZoneAnimationMode_e, + ZoneAnimationMode_Invalid = BadEnumValue +} ZoneAnimationMode_e; + +#if defined EXPORT_DEPRECATED_INTERFACES_TO_ADK_ONLY +/** + * @deprecated + * Please use \ref ExportRegion_e instead. + */ +typedef enum +{ + BitDumpRegion_CurrentFrame, + BitDumpRegion_AllFrames, + BitDumpRegion_WorkArea, + END_BitDumpRegion_e, + BitDumpRegion_Invalid = BadEnumValue +} BitDumpRegion_e; +#endif + +typedef enum +{ + ExportRegion_CurrentFrame, + ExportRegion_AllFrames, + ExportRegion_WorkArea, + END_ExportRegion_e, + ExportRegion_Invalid = BadEnumValue +} ExportRegion_e; + +typedef enum +{ + Paper_Letter, + Paper_Double, + Paper_A4, + Paper_A3, + Paper_Custom1, + Paper_Custom2, + END_PaperSize_e, + Paper_Invalid = BadEnumValue +} PaperSize_e; + + + +typedef enum +{ + PaperUnitSpacing_HalfCentimeter, + PaperUnitSpacing_OneCentimeter, + PaperUnitSpacing_TwoCentimeters, + PaperUnitSpacing_QuarterInch, + PaperUnitSpacing_HalfInch, + PaperUnitSpacing_OneInch, + PaperUnitSpacing_TenPoints, + PaperUnitSpacing_TwentyFourPoints, + PaperUnitSpacing_ThirtySixPoints, + PaperUnitSpacing_FiftyPoints, + PaperUnitSpacing_SeventyTwoPoints, + PaperUnitSpacing_OneTenthInch, + PaperUnitSpacing_OneTenthCentimeter, + END_PaperUnitSpacing_e, + PaperUnitSpacing_Invalid = BadEnumValue +} PaperUnitSpacing_e; + + +typedef enum +{ + Palette_Monochrome, + Palette_PenPlotter, + Palette_Color, + END_Palette_e, + Palette_Invalid = BadEnumValue +} Palette_e; + + +typedef enum +{ + PrintRenderType_Vector, + PrintRenderType_Image, + END_PrintRenderType_e, + PrintRenderType_Invalid = BadEnumValue +} PrintRenderType_e; + + +typedef enum +{ + Units_Grid, + Units_Frame, + Units_Point, + Units_Screen, + Units_AxisPercentage, + END_Units_e, + Units_Invalid = BadEnumValue +} Units_e; + + +typedef enum +{ + CoordScale_Linear, + CoordScale_Log, + END_CoordScale_e, + CoordScale_Invalid = BadEnumValue, + /* old names for the same values */ + Scale_Linear = CoordScale_Linear, + Scale_Log = CoordScale_Log, + Scale_Invalid = CoordScale_Invalid +} CoordScale_e; + +/* BEGINREMOVEFROMADDON */ +#define GetLog10(R) ( ((R) < SMALLDOUBLE) ? SMALLESTEXPONENT : ( ((R) > LARGEDOUBLE) ? LARGESTEXPONENT : log10((R)) ) ) +/* ENDREMOVEFROMADDON */ + +typedef enum +{ + CoordSys_Grid, + CoordSys_Frame, + CoordSys_FrameOffset, + CoordSys_Paper, + CoordSys_Screen, + CoordSys_Hardcopy, + CoordSys_Grid3D, + END_CoordSys_e, + CoordSys_Invalid = BadEnumValue +} CoordSys_e; + +/* + * NOTE: CoordSys_FrameOffset always is stored in inches internally. + * in stylesheet this may be written in other units if + * appropriate suffix is added. + * + */ + + + +typedef enum +{ + Scope_Global, + Scope_Local, + END_Scope_e, + Scope_Invalid = BadEnumValue +} Scope_e; + + +typedef enum +{ + TextAnchor_Left, + TextAnchor_Center, + TextAnchor_Right, + TextAnchor_MidLeft, + TextAnchor_MidCenter, + TextAnchor_MidRight, + TextAnchor_HeadLeft, + TextAnchor_HeadCenter, + TextAnchor_HeadRight, + TextAnchor_OnSide, + END_TextAnchor_e, + TextAnchor_Invalid = BadEnumValue +} TextAnchor_e; + + + +typedef enum +{ + TextBox_None, + TextBox_Filled, + TextBox_Hollow, + END_TextBox_e, + TextBox_Invalid = BadEnumValue +} TextBox_e; + + + +typedef enum +{ + GeomShape_Square, + GeomShape_Del, + GeomShape_Grad, + GeomShape_RTri, + GeomShape_LTri, + GeomShape_Diamond, + GeomShape_Circle, + GeomShape_Cube, + GeomShape_Sphere, + GeomShape_Octahedron, + GeomShape_Point, + END_GeomShape_e, + GeomShape_Invalid = BadEnumValue +} GeomShape_e; + + +typedef enum +{ + BasicSize_Tiny, + BasicSize_Small, + BasicSize_Medium, + BasicSize_Large, + BasicSize_Huge, + END_BasicSize_e, + BasicSize_Invalid = BadEnumValue +} BasicSize_e; + + + +/* + * NOTE: LineForm_e is deprecated. It must be retained to maintain + * backward compatibility with the TecUtil layer however. + * This has been replaced by CurveType_e. + */ +typedef enum +{ + LineForm_LineSeg, + LineForm_CurvFit, + LineForm_EToRFit, + LineForm_PowerFit, + LineForm_Spline, + LineForm_ParaSpline, + END_LineForm_e, + LineForm_Invalid = BadEnumValue +} LineForm_e; + + +typedef enum +{ + CurveType_LineSeg, + CurveType_PolynomialFit, + CurveType_EToRFit, + CurveType_PowerFit, + CurveType_Spline, + CurveType_ParaSpline, + CurveType_Extended, + END_CurveType_e, + CurveType_Invalid = BadEnumValue, + CurveType_CurvFit = CurveType_PolynomialFit +} CurveType_e; + +typedef enum +{ + Script_None, + Script_Super, + Script_Sub, + END_Script_e, + Script_Invalid = BadEnumValue +} Script_e; + + +typedef enum +{ + Font_Helvetica, + Font_HelveticaBold, + Font_Greek, + Font_Math, + Font_UserDefined, + Font_Times, + Font_TimesItalic, + Font_TimesBold, + Font_TimesItalicBold, + Font_Courier, + Font_CourierBold, + END_Font_e, + Font_Invalid = BadEnumValue +} Font_e; + +typedef enum +{ + TwoDDrawOrder_ByZone, + TwoDDrawOrder_ByLayer, + END_TwoDDrawOrder_e, + TwoDDrawOrder_Invalid = BadEnumValue +} TwoDDrawOrder_e; + +typedef enum +{ + DrawOrder_AfterData, + DrawOrder_BeforeData, + END_DrawOrder_e, + DrawOrder_Invalid = BadEnumValue +} DrawOrder_e; + +/* + * + * NOTE: Streamtrace_TwoDLine is new. All 2D + * streamtraces are assigned this value. + */ +typedef enum +{ + Streamtrace_SurfaceLine, + Streamtrace_SurfaceRibbon, + Streamtrace_VolumeLine, + Streamtrace_VolumeRibbon, + Streamtrace_VolumeRod, + Streamtrace_TwoDLine, + END_Streamtrace_e, + Streamtrace_Invalid = BadEnumValue +} Streamtrace_e; + + + +typedef enum +{ + StreamDir_Forward, + StreamDir_Reverse, + StreamDir_Both, + END_StreamDir_e, + StreamDir_Invalid = BadEnumValue +} StreamDir_e; + +typedef enum +{ + IsoSurfaceSelection_AllContourLevels, + IsoSurfaceSelection_OneSpecificValue, + IsoSurfaceSelection_TwoSpecificValues, + IsoSurfaceSelection_ThreeSpecificValues, + END_IsoSurfaceSelection_e, + IsoSurfaceSelection_Invalid = BadEnumValue +} IsoSurfaceSelection_e; + + +typedef enum +{ + ValueLocation_CellCentered, + ValueLocation_Nodal, + END_ValueLocation_e, + ValueLocation_Invalid = BadEnumValue +} ValueLocation_e; + +typedef enum +{ + FieldDataType_Reserved, /* never use */ + FieldDataType_Float, + FieldDataType_Double, + FieldDataType_Int32, + FieldDataType_Int16, + FieldDataType_Byte, + FieldDataType_Bit, + END_FieldDataType_e, + FieldDataType_IJKFunction, /* Not used yet */ + FieldDataType_Int64, /* Not used yet */ +#if defined EXPORT_DEPRECATED_INTERFACES_TO_ADK_ONLY + FieldDataType_LongInt = FieldDataType_Int32, + FieldDataType_ShortInt = FieldDataType_Int16, +#endif + FieldDataType_Invalid = BadEnumValue +} FieldDataType_e; + +#define VALID_FIELD_DATA_TYPE(FieldDataType) (VALID_ENUM((FieldDataType),FieldDataType_e) && \ + (FieldDataType)!=FieldDataType_Reserved) + +#if defined EXPORT_DEPRECATED_INTERFACES_TO_ADK_ONLY +/** + * @deprecated + * Please use \ref MeshType_e instead. + */ +typedef enum +{ + Mesh_Wireframe, /* deprecated: use MeshType_Wireframe */ + Mesh_Overlay, /* deprecated: use MeshType_Overlay */ + Mesh_HiddenLine, /* deprecated: use MeshType_HiddenLine */ + END_MeshPlotType_e, + Mesh_Invalid = BadEnumValue +} MeshPlotType_e; +#endif + +typedef enum +{ + MeshType_Wireframe, /* Mesh_Wireframe */ + MeshType_Overlay, /* Mesh_Overlay */ + MeshType_HiddenLine, /* Mesh_HiddenLine */ + END_MeshType_e, + MeshType_Invalid = BadEnumValue +} MeshType_e; + + + + +#if defined EXPORT_DEPRECATED_INTERFACES_TO_ADK_ONLY +/** + * @deprecated + * Please use \ref ContourType_e instead. + */ +typedef enum +{ + Contour_Lines, /* deprecated: use ContourType_Lines */ + Contour_Flood, /* deprecated: use ContourType_Flood */ + Contour_Overlay, /* deprecated: use ContourType_Overlay */ + Contour_AverageCell, /* deprecated: use ContourType_AverageCell */ + Contour_CornerCell, /* deprecated: use ContourType_PrimaryValue */ + END_ContourPlotType_e, + Contour_Invalid = BadEnumValue +} ContourPlotType_e; +#endif + + +typedef enum +{ + ContourType_Lines, /* Contour_Lines */ + ContourType_Flood, /* Contour_Flood */ + ContourType_Overlay, /* Contour_Overlay */ + ContourType_AverageCell, /* Contour_AverageCell */ + ContourType_PrimaryValue, /* Contour_CornerCell */ + END_ContourType_e, + ContourType_Invalid = BadEnumValue +} ContourType_e; + +typedef enum +{ + ContourColoring_RGB, + ContourColoring_Group1, + ContourColoring_Group2, + ContourColoring_Group3, + ContourColoring_Group4, + ContourColoring_Group5, + ContourColoring_Group6, + ContourColoring_Group7, + ContourColoring_Group8, + END_ContourColoring_e, + ContourColoring_Invalid = BadEnumValue +} ContourColoring_e; + +#if defined EXPORT_DEPRECATED_INTERFACES_TO_ADK_ONLY +/** + * @deprecated + * Please use \ref VectorType_e instead. + */ +typedef enum +{ + Vector_TailAtPoint, /* deprecated: use VectorType_TailAtPoint */ + Vector_HeadAtPoint, /* deprecated: use VectorType_HeadAtPoint */ + Vector_MidAtPoint, /* deprecated: use VectorType_MidAtPoint */ + Vector_HeadOnly, /* deprecated: use VectorType_HeadOnly */ + END_VectorPlotType_e, + Vector_Invalid = BadEnumValue +} VectorPlotType_e; +#endif + + +typedef enum +{ + VectorType_TailAtPoint, /* Vector_TailAtPoint */ + VectorType_HeadAtPoint, /* Vector_HeadAtPoint */ + VectorType_MidAtPoint, /* Vector_MidAtPoint */ + VectorType_HeadOnly, /* Vector_HeadOnly */ + END_VectorType_e, + VectorType_Invalid = BadEnumValue +} VectorType_e; + + +/* + * NOTE: ShadePlotType_e is deprecated. It must be retained to maintain + * backward compatibility with the TecUtil layer however. + * This has been replaced by LightingEffect_e. + */ +typedef enum +{ + Shade_SolidColor, + Shade_Paneled, + Shade_Gouraud, + Shade_ColoredPaneled, + Shade_ColoredGouraud, + END_ShadePlotType_e, + Shade_Invalid = BadEnumValue +} ShadePlotType_e; + +/* + * NOTE: LightingEffect_None is deprecated. It must remain + * in the list to allow macro processing of older + * (i.e. early v9) macros. + */ +typedef enum +{ + LightingEffect_Paneled, + LightingEffect_Gouraud, + LightingEffect_None, + END_LightingEffect_e, + LightingEffect_Invalid = BadEnumValue +} LightingEffect_e; + +typedef enum +{ + IJKLines_I, + IJKLines_J, + IJKLines_K, + END_IJKLines_e, + IJKLines_Invalid = BadEnumValue, + /* deprecated values */ + Lines_I = IJKLines_I, /* deprecated */ + Lines_J = IJKLines_J, /* deprecated */ + Lines_K = IJKLines_K, /* deprecated */ + Lines_Invalid = IJKLines_Invalid /* deprecated */ +} IJKLines_e; + +typedef enum +{ + IJKCellType_Planes, + IJKCellType_FacePlanes, + IJKCellType_Volume, + END_IJKCellType_e, + IJKCellType_Invalid = BadEnumValue +} IJKCellType_e; + + +/* + * Ver 6 used PlaneSet. Ver 7 uses CellType and Planes variables. + * + * "PlaneSet" in version 6 vs. IJKPlanes in v7: + * + * 'A' = AllPlanes CellType = IJKCellType_Volume + * 'd','e','f','C' = ComboPlanes CellType = IJKCellType_Planes, IJKPlanes = depends on defC + * 'F' = Faces Planes Only CellType = IJKCellType_FacePlanes + * 'I' = I-Planes CellType = IJKCellType_Planes, IJKPlanes = IJKPlanes_I + * 'J' = J-Planes CellType = IJKCellType_Planes, IJKPlanes = IJKPlanes_J + * 'K' = K-Planes CellType = IJKCellType_Planes, IJKPlanes = IJKPlanes_K + * + * + * NOTE: IJKPlanes_e is still used internally in tecplot (and in the TecUtil layer). + * it has been relagated to communicating which planes of an IJK zone are in + * use. + * + */ + +typedef enum +{ + IJKPlanes_I, + IJKPlanes_J, + IJKPlanes_K, + IJKPlanes_Face, /* used on the panel heap */ + IJKPlanes_IJ, /* deprecated */ + IJKPlanes_JK, /* deprecated */ + IJKPlanes_IK, /* deprecated */ + IJKPlanes_IJK, /* deprecated */ + IJKPlanes_Volume, + IJKPlanes_Unused, + END_IJKPlanes_e, + IJKPlanes_Invalid = BadEnumValue, + /* deprecated values */ + Planes_I = IJKPlanes_I, /* deprecated */ + Planes_J = IJKPlanes_J, /* deprecated */ + Planes_K = IJKPlanes_K, /* deprecated */ + Planes_IJ = IJKPlanes_IJ, /* deprecated */ + Planes_JK = IJKPlanes_JK, /* deprecated */ + Planes_IK = IJKPlanes_IK, /* deprecated */ + Planes_IJK = IJKPlanes_IJK, /* deprecated */ + Planes_Face = IJKPlanes_Face, /* deprecated */ + Planes_Volume = IJKPlanes_Volume, /* deprecated */ + Planes_Unused = IJKPlanes_Unused, /* deprecated */ + Planes_Invalid = IJKPlanes_Invalid /* deprecated */ +} IJKPlanes_e; + + + +typedef enum +{ + SurfacesToPlot_BoundaryFaces, + SurfacesToPlot_ExposedCellFaces, + SurfacesToPlot_IPlanes, + SurfacesToPlot_JPlanes, + SurfacesToPlot_KPlanes, + SurfacesToPlot_IJPlanes, + SurfacesToPlot_JKPlanes, + SurfacesToPlot_IKPlanes, + SurfacesToPlot_IJKPlanes, + SurfacesToPlot_All, + SurfacesToPlot_None, + END_SurfacesToPlot_e, + SurfacesToPlot_Invalid = BadEnumValue +} SurfacesToPlot_e; + +typedef enum +{ + PointsToPlot_SurfaceNodes, /* was _SurfacesOnly */ + PointsToPlot_AllNodes, /* was _All */ + PointsToPlot_SurfaceCellCenters, + PointsToPlot_AllCellCenters, + PointsToPlot_AllConnected, + END_PointsToPlot_e, +#if defined EXPORT_DEPRECATED_INTERFACES_TO_ADK_ONLY + PointsToPlot_SurfacesOnly = PointsToPlot_SurfaceNodes, /* deprecated */ + PointsToPlot_All = PointsToPlot_AllNodes, /* deprecated */ +#endif + PointsToPlot_Invalid = BadEnumValue +} PointsToPlot_e; + + +typedef enum +{ + SliceSurface_XPlanes, + SliceSurface_YPlanes, + SliceSurface_ZPlanes, + SliceSurface_IPlanes, + SliceSurface_JPlanes, + SliceSurface_KPlanes, + END_SliceSurface_e, + SliceSurface_Invalid = BadEnumValue +} SliceSurface_e; + + +typedef enum +{ + ClipPlane_None, + ClipPlane_BelowPrimarySlice, + ClipPlane_AbovePrimarySlice, + END_ClipPlane_e, + ClipPlane_Invalid = BadEnumValue +} ClipPlane_e; + +typedef enum +{ + Skip_ByIndex, + Skip_ByFrameUnits, + END_SkipMode_e, + Skip_Invalid = BadEnumValue +} SkipMode_e; + + +typedef enum +{ + EdgeType_Borders, + EdgeType_Creases, + EdgeType_BordersAndCreases, + END_EdgeType_e, + EdgeType_Invalid = BadEnumValue +} EdgeType_e; + +#if defined EXPORT_DEPRECATED_INTERFACES_TO_ADK_ONLY +/** + * @deprecated + * Please use \ref BorderLocation_e instead. + */ +typedef enum +{ + Boundary_None, /* deprecated: use BoundaryType_None */ + Boundary_Min, /* deprecated: use BoundaryType_Min */ + Boundary_Max, /* deprecated: use BoundaryType_Max */ + Boundary_Both, /* deprecated: use BoundaryType_Both */ + END_BoundPlotType_e, + Boundary_Invalid = BadEnumValue +} BoundPlotType_e; +#endif + +typedef enum +{ + BoundaryType_None, /* Boundary_None */ + BoundaryType_Min, /* Boundary_Min */ + BoundaryType_Max, /* Boundary_Max */ + BoundaryType_Both, /* Boundary_Both */ + END_BoundaryType_e, + BoundaryType_Invalid = BadEnumValue +} BoundaryType_e; /* deprecated */ + +typedef enum +{ + BorderLocation_None, /* Boundary_None */ + BorderLocation_Min, /* Boundary_Min */ + BorderLocation_Max, /* Boundary_Max */ + BorderLocation_Both, /* Boundary_Both */ + END_BorderLocation_e, + BorderLocation_Invalid = BadEnumValue +} BorderLocation_e; + +typedef enum +{ + ContourColorMap_SmRainbow, + ContourColorMap_LgRainbow, + ContourColorMap_Modern, + ContourColorMap_GrayScale, + ContourColorMap_Wild, + ContourColorMap_UserDef, + ContourColorMap_TwoColor, + ContourColorMap_RawUserDef, + END_ContourColorMap_e, + ContourColorMap_Invalid = BadEnumValue, + /* deprecated values */ + ColorMap_SmRainbow = ContourColorMap_SmRainbow, /* deprecated */ + ColorMap_LgRainbow = ContourColorMap_LgRainbow, /* deprecated */ + ColorMap_Modern = ContourColorMap_Modern, /* deprecated */ + ColorMap_GrayScale = ContourColorMap_GrayScale, /* deprecated */ + ColorMap_Wild = ContourColorMap_Wild, /* deprecated */ + ColorMap_UserDef = ContourColorMap_UserDef, /* deprecated */ + ColorMap_TwoColor = ContourColorMap_TwoColor, /* deprecated */ + ColorMap_RawUserDef = ContourColorMap_RawUserDef, /* deprecated */ + ColorMap_Invalid = ContourColorMap_Invalid /* deprecated */ +} ContourColorMap_e; + + + +typedef enum +{ + ErrorBar_Up, + ErrorBar_Down, + ErrorBar_Left, + ErrorBar_Right, + ErrorBar_Horz, + ErrorBar_Vert, + ErrorBar_Cross, + END_ErrorBar_e, + ErrorBar_Invalid = BadEnumValue +} ErrorBar_e; + + + +typedef enum +{ + ContourLineMode_UseZoneLineType, + ContourLineMode_SkipToSolid, + ContourLineMode_DashNegative, + END_ContourLineMode_e, + ContourLineMode_Invalid = BadEnumValue +} ContourLineMode_e; + + +/* BEGINREMOVEFROMADDON */ +typedef enum +{ + Panel_Bad, + Panel_Cell, /* FieldZone */ + Panel_Vector, /* FieldZone */ + Panel_Scatter, /* FieldZone */ + Panel_IJKBorderLine, /* FieldZone IJK border lines */ + Panel_CellEdge, /* FieldZone border lines and creases */ + Panel_FEBoundaryCell, /* FieldZone */ + Panel_NodeLabel, /* FieldZone */ + Panel_CellLabel, /* FieldZone */ + Panel_StreamtraceCell, /* Streamtrace COB */ + Panel_StreamtraceMarker, /* StreamtraceMarker COB (Scatter Symbol) */ + Panel_StreamtraceArrowhead, /* StreamtraceArrowhead COB (Vector) */ + Panel_IsoSurfaceCell, /* IsoSurface COB */ + Panel_IsoSurfaceCellEdge, /* IsoSurface COB border lines and creases (border lines and creases not currently used) */ + Panel_SliceCell, /* Slice COB */ + Panel_SliceVector, /* Slice COB */ + Panel_SliceIJKBorderLine, /* Slice COB IJK border lines */ + Panel_SliceCellEdge, /* Slice COB border lines and creases (creases not currently used) */ + Panel_Geom, /* Misc */ + Panel_Text, /* Misc */ + END_Panel_e, + Panel_Invalid = BadEnumValue +} Panel_e; +/* ENDREMOVEFROMADDON */ + + +typedef enum +{ + MessageBoxType_Error, + MessageBoxType_Warning, + MessageBoxType_Information, + MessageBoxType_Question, /* Ok, Cancel buttons */ + MessageBoxType_YesNo, + MessageBoxType_YesNoCancel, + MessageBoxType_WarningOkCancel, + END_MessageBoxType_e, + MessageBoxType_Invalid = BadEnumValue, + /* deprecated values */ + MessageBox_Error = MessageBoxType_Error, /* deprecated */ + MessageBox_Warning = MessageBoxType_Warning, /* deprecated */ + MessageBox_Information = MessageBoxType_Information, /* deprecated */ + MessageBox_Question = MessageBoxType_Question, /* deprecated */ + MessageBox_YesNo = MessageBoxType_YesNo, /* deprecated */ + MessageBox_YesNoCancel = MessageBoxType_YesNoCancel, /* deprecated */ + MessageBox_WarningOkCancel = MessageBoxType_WarningOkCancel, /* deprecated */ + MessageBox_Invalid = MessageBoxType_Invalid /* deprecated */ +} MessageBoxType_e; + + +typedef enum +{ + MessageBoxReply_Yes, + MessageBoxReply_No, + MessageBoxReply_Cancel, + MessageBoxReply_Ok, + END_MessageBoxReply_e, + MessageBoxReply_Invalid = BadEnumValue +} MessageBoxReply_e; + +typedef enum +{ + NumberFormat_Integer, + NumberFormat_FixedFloat, + NumberFormat_Exponential, + NumberFormat_BestFloat, + NumberFormat_SuperScript, + NumberFormat_CustomLabel, + NumberFormat_LogSuperScript, + NumberFormat_RangeBestFloat, + NumberFormat_DynamicLabel, + NumberFormat_TimeDate, + END_NumberFormat_e, + NumberFormat_Invalid = BadEnumValue +} NumberFormat_e; + +/* For backward compatibility with v9- */ +typedef NumberFormat_e ValueFormat_e; + + +typedef enum +{ + BackingStoreMode_QuickAndDirty, + BackingStoreMode_RealTimeUpdate, + BackingStoreMode_PeriodicUpdate, + END_BackingStoreMode_e, + BackingStoreMode_Invalid = BadEnumValue +} BackingStoreMode_e; + + +typedef enum +{ + TickDirection_In, + TickDirection_Out, + TickDirection_Centered, + END_TickDirection_e, + TickDirection_Invalid = BadEnumValue +} TickDirection_e; + +/* This enumerated type is no longer used as of Tecplot V10. */ +typedef enum +{ + AxisTitlePosition_Left, + AxisTitlePosition_Center, + AxisTitlePosition_Right, + END_AxisTitlePosition_e, + AxisTitlePosition_Invalid = BadEnumValue +} AxisTitlePosition_e; + +typedef enum +{ + AxisTitleMode_NoTitle, + AxisTitleMode_UseVarName, + AxisTitleMode_UseText, + END_AxisTitleMode_e, + AxisTitleMode_Invalid = BadEnumValue +} AxisTitleMode_e; + +typedef enum +{ + AxisAlignment_WithViewport, + AxisAlignment_WithOpposingAxisValue, + AxisAlignment_WithGridMin, + AxisAlignment_WithGridMax, + AxisAlignment_WithSpecificAngle, + AxisAlignment_WithGridAreaTop, + AxisAlignment_WithGridAreaBottom, + AxisAlignment_WithGridAreaLeft, + AxisAlignment_WithGridAreaRight, + END_AxisAlignment_e, + AxisAlignment_Invalid = BadEnumValue +} AxisAlignment_e; + +typedef enum +{ + FunctionDependency_XIndependent, + FunctionDependency_YIndependent, + END_FunctionDependency_e, + FunctionDependency_Invalid = BadEnumValue, + FunctionDependency_ThetaIndependent = FunctionDependency_XIndependent, + FunctionDependency_RIndependent = FunctionDependency_YIndependent +} FunctionDependency_e; + +typedef enum +{ + LegendShow_Yes, + LegendShow_No, + LegendShow_Auto, + END_LegendShow_e, + LegendShow_Invalid = BadEnumValue +} LegendShow_e; + +typedef enum +{ + LineMapSort_None, + LineMapSort_IndependentVar, + LineMapSort_DependentVar, + LineMapSort_SpecificVar, + END_LineMapSort_e, + LineMapSort_Invalid = BadEnumValue +} LineMapSort_e; + +typedef enum +{ + ContLegendLabelLocation_ContourLevels, + ContLegendLabelLocation_Increment, + ContLegendLabelLocation_ColorMapDivisions, + END_ContLegendLabelLocation_e, + ContLegendLabelLocation_Invalid = BadEnumValue +} ContLegendLabelLocation_e; + +typedef enum +{ + ThetaMode_Degrees, + ThetaMode_Radians, + ThetaMode_Arbitrary, + END_ThetaMode_e, + ThetaMode_Invalid = BadEnumValue +} ThetaMode_e; + +typedef enum +{ + Transform_PolarToRect, + Transform_SphericalToRect, + Transform_RectToPolar, + Transform_RectToSpherical, + END_Transform_e, + Transform_Invalid = BadEnumValue +} Transform_e; + +typedef enum +{ + LaunchDialogMode_ModalSync, + LaunchDialogMode_Modeless, + LaunchDialogMode_ModalAsync, + END_LaunchDialogMode_e, + LaunchDialogMode_Invalid = BadEnumValue +} LaunchDialogMode_e; + + +typedef enum +{ + SelectFileOption_ReadSingleFile, + SelectFileOption_ReadMultiFile, + SelectFileOption_AllowMultiFileRead, + SelectFileOption_WriteFile, + SelectFileOption_SelectDirectory, + END_SelectFileOption_e, + SelectFileOption_Invalid = BadEnumValue +} SelectFileOption_e; + +typedef enum +{ + BinaryFileVersion_Tecplot2006, + BinaryFileVersion_Tecplot2008, + BinaryFileVersion_Tecplot2009, + BinaryFileVersion_Current, + END_BinaryFileVersion_e, + BinaryFileVersion_Invalid = BadEnumValue +} BinaryFileVersion_e; + +/* CURRENTLY NOT USED .... */ +typedef enum +{ + ViewActionDrawMode_NoDraw, + ViewActionDrawMode_DrawTrace, + ViewActionDrawMode_DrawFull, + END_ViewActionDrawMode_e, + ViewActionDrawMode_Invalid = BadEnumValue +} ViewActionDrawMode_e; + +typedef enum +{ + PageAction_Create, + PageAction_Delete, + PageAction_Clear, + PageAction_SetCurrentToNext, + PageAction_SetCurrentToPrev, + PageAction_SetCurrentByName, + PageAction_SetCurrentByUniqueID, + END_PageAction_e, + PageAction_Invalid = BadEnumValue +} PageAction_e; + +typedef enum +{ + FrameAction_PushTop, + FrameAction_PopByNumber, + FrameAction_PopAtPosition, + FrameAction_DeleteActive, + FrameAction_FitAllToPaper, + FrameAction_PushByName, + FrameAction_PopByName, + FrameAction_PushByNumber, + FrameAction_ActivateTop, + FrameAction_ActivateNext, + FrameAction_ActivatePrevious, + FrameAction_ActivateAtPosition, + FrameAction_ActivateByName, + FrameAction_ActivateByNumber, + FrameAction_MoveToTopActive, + FrameAction_MoveToTopByName, + FrameAction_MoveToTopByNumber, + FrameAction_MoveToBottomActive, + FrameAction_MoveToBottomByName, + FrameAction_MoveToBottomByNumber, + END_FrameAction_e, + FrameAction_Invalid = BadEnumValue, + FrameAction_Pop = FrameAction_PopByNumber, + FrameAction_Push = FrameAction_PushByNumber, + FrameAction_DeleteTop = FrameAction_DeleteActive +} FrameAction_e; + +typedef enum +{ + DoubleBufferAction_On, + DoubleBufferAction_Off, + DoubleBufferAction_Swap, + END_DoubleBufferAction_e, + DoubleBufferAction_Invalid = BadEnumValue +} DoubleBufferAction_e; + +/* + * PickAction_CheckToAdd had the side effects of popping a frame that was selected + * only if not collecting. Pick_AddAtPosition avoids this. + */ +typedef enum +{ + PickAction_CheckToAdd, /* deprecated: use Pick_AddAtPosition */ + PickAction_AddAll, + PickAction_AddAllInRegion, + PickAction_Edit, + PickAction_Cut, + PickAction_Copy, + PickAction_Clear, + PickAction_Paste, + PickAction_PasteAtPosition, + PickAction_Shift, + PickAction_Magnify, + PickAction_Push, + PickAction_Pop, + PickAction_SetMouseMode, + PickAction_DeselectAll, + PickAction_AddZones, + PickAction_AddXYMaps, /* deprecated: use PickAction_AddLineMaps */ + PickAction_AddLineMaps, + PickAction_AddAtPosition, + END_PickAction_e, + PickAction_Invalid = BadEnumValue +} PickAction_e; + + +typedef enum +{ + ContourLevelAction_Add, + ContourLevelAction_New, + ContourLevelAction_DeleteRange, + ContourLevelAction_Reset, + ContourLevelAction_ResetToNice, + ContourLevelAction_DeleteNearest, + END_ContourLevelAction_e, + ContourLevelAction_Invalid = BadEnumValue +} ContourLevelAction_e; + +typedef enum +{ + ContourLabelAction_Add, + ContourLabelAction_DeleteAll, + END_ContourLabelAction_e, + ContourLabelAction_Invalid = BadEnumValue +} ContourLabelAction_e; + +typedef enum +{ + StreamtraceAction_Add, + StreamtraceAction_DeleteAll, + StreamtraceAction_DeleteRange, + StreamtraceAction_SetTerminationLine, + StreamtraceAction_ResetDeltaTime, + END_StreamtraceAction_e, + StreamtraceAction_Invalid = BadEnumValue +} StreamtraceAction_e; + +typedef enum +{ + ColorMapControlAction_RedistributeControlPoints, + ColorMapControlAction_CopyCannedColorMap, + ColorMapControlAction_ResetToFactoryDefaults, + END_ColorMapControlAction_e, + ColorMapControlAction_Invalid = BadEnumValue +} ColorMapControlAction_e; + +typedef enum +{ + ColorMapDistribution_Continuous, + ColorMapDistribution_Banded, + END_ColorMapDistribution_e, + ColorMapDistribution_Invalid = BadEnumValue +} ColorMapDistribution_e; + +typedef enum +{ + RGBMode_SpecifyRGB, + RGBMode_SpecifyRG, + RGBMode_SpecifyRB, + RGBMode_SpecifyGB, + END_RGBMode_e, + RGBMode_Invalid = BadEnumValue +} RGBMode_e; + +typedef enum +{ + TecUtilErr_None, + TecUtilErr_Undetermined, + END_TecUtilErr_e, + TecUtilErr_Invalid = BadEnumValue +} TecUtilErr_e; + +/* BEGINREMOVEFROMADDON */ +/* deprecated type from alpha/beta v10 */ +typedef enum +{ + AxisShape_Ray, + AxisShape_LineTwoDirections, + AxisShape_LShape, + AxisShape_CrossOrBox, + END_AxisShape_e, + AxisShape_Invalid = BadEnumValue +} AxisShape_e; + +/* licensing enums : keep hidden */ +typedef enum +{ + RunMode_Demo, + RunMode_Eval, + RunMode_Full, + /**/ + END_RunMode_e, + /**/ + RunMode_Invalid = BadEnumValue +} RunMode_e; + +/* ENDREMOVEFROMADDON */ + +typedef enum /* Custom exporter error message */ +{ + ExportCustReturnCode_Ok, + ExportCustReturnCode_Failed, + ExportCustReturnCode_TecplotLocked, + ExportCustReturnCode_ExporterNotLoaded, + ExportCustReturnCode_ExportCallbackFailed, + ExportCustReturnCode_NotAnImageExporter, + ExportCustReturnCode_NotAFieldDataExporter, + END_ExportCustReturnCode_e, + ExportCustReturnCode_Invalid = BadEnumValue +} ExportCustReturnCode_e; + +/** + * COB/Zone types. + */ +typedef enum +{ + CZType_FieldDataZone, + CZType_FEBoundaryCOB, + CZType_IsoSurfaceCOB, + CZType_SliceCOB, + CZType_StreamtraceCOB, + CZType_StreamtraceMarkerCOB, + CZType_StreamtraceArrowheadCOB, + END_CZType_e, + CZType_Invalid = BadEnumValue +} CZType_e; + +/** + */ +typedef enum +{ + FaceNeighborMode_LocalOneToOne, + FaceNeighborMode_LocalOneToMany, + FaceNeighborMode_GlobalOneToOne, + FaceNeighborMode_GlobalOneToMany, + END_FaceNeighborMode_e, + FaceNeighborMode_Invalid = BadEnumValue +} FaceNeighborMode_e; + + +/** + * Page render destinations. + */ +typedef enum +{ + PageRenderDest_None, + PageRenderDest_OnScreen, + PageRenderDest_OffScreen, + END_PageRenderDest_e, + PageRenderDest_Invalid = BadEnumValue +} PageRenderDest_e; + +/* BEGINREMOVEFROMADDON */ +/* + * Destination for all internal rendering (VDI/Gr) functions. For external + * linkage we translate RenderDest_WorkArea to PageRenderDest_OnScreen, + * RenderDest_OffscreenBitmap to PageRenderDest_OffScreen and + * RenderDest_Invalid to PageRenderDest_None. + */ +typedef enum +{ + RenderDest_WorkArea, /* Do not move from start of screen entries */ + RenderDest_ExampleText, + RenderDest_ExampleLightSourcePosition, + RenderDest_ExampleColorMap, + RenderDest_ExampleBasicColor, /* Do not move from end of screen entries */ + RenderDest_OffscreenBitmap, + RenderDest_Hardcopy, + END_RenderDest_e, + RenderDest_Invalid = BadEnumValue, + /* + * These next two are optimizations to make the + * RDT_IsScreen() macro as efficient as possible. + */ + RenderDest_FirstScreenEntry = RenderDest_WorkArea, + RenderDest_LastScreenEntry = RenderDest_ExampleBasicColor +} RenderDest_e; +/* ENDREMOVEFROMADDON */ + +typedef enum +{ + Stipple_All, + Stipple_Critical, + Stipple_None, + END_Stipple_e, + Stipple_Invalid = BadEnumValue +} Stipple_e; + +typedef enum +{ + DataFileType_Full, + DataFileType_Grid, + DataFileType_Solution, + END_DataFileType_e, + DataFileType_Invalid = BadEnumValue +} DataFileType_e; + +typedef enum +{ + ConditionAwakeReason_Signaled, + ConditionAwakeReason_TimedOut, + END_ConditionAwakeReason_e, + ConditionAwakeReason_Invalid = BadEnumValue +} ConditionAwakeReason_e; + +/**************************************************************** + * * + * STRUCTURE TYPEDEFS * + * * + ****************************************************************/ + +/* + * These are defined to work with pthreads, more work for WINAPI needed + */ +typedef struct _Mutex_a* Mutex_pa; + +typedef void*(STDCALL *ThreadFunction_pf)(ArbParam_t ThreadData); + +typedef struct _Condition_a* Condition_pa; + +typedef struct _JobControl_s* JobControl_pa; + +typedef void (STDCALL *ThreadPoolJob_pf)(ArbParam_t JobData); + +/* BEGINREMOVEFROMADDON */ +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if defined USE_OOSTYLE +#endif +#endif /* TECPLOTKERNEL */ +/* ENDREMOVEFROMADDON */ + +typedef struct _StringList_s *StringList_pa; +typedef struct _Menu_s *Menu_pa; +/* BEGINREMOVEFROMADDON */ +typedef struct _ArrayList_s *ArrayList_pa; +/* ENDREMOVEFROMADDON */ + +typedef enum +{ + ImageResizeFilter_Texture, + ImageResizeFilter_Box, + ImageResizeFilter_Lanczos2, + ImageResizeFilter_Lanczos3, + ImageResizeFilter_Triangle, + ImageResizeFilter_Bell, + ImageResizeFilter_BSpline, + ImageResizeFilter_Cubic, + ImageResizeFilter_Mitchell, + ImageResizeFilter_Gaussian, + END_ImageResizeFilter_e, + ImageResizeFilter_Invalid = BadEnumValue +} ImageResizeFilter_e; + +typedef enum +{ + VarStatus_Passive, + VarStatus_Custom, + VarStatus_Map, + VarStatus_Heap, + VarStatus_NotLoaded, + END_VarStatus_e, + VarStatus_Invalid = BadEnumValue +} VarStatus_e; + + + +/* BEGINREMOVEFROMADDON */ + +/* here until GR and GRHW layer can be rearranged. */ +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# if !defined NO_ASSERTS +# endif +#endif /* TECPLOTKERNEL */ + +/* ENDREMOVEFROMADDON */ + +typedef struct _Set_a *Set_pa; + +typedef struct +{ + double X; + double Y; + double Z; +} XYZ_s; + +/* BEGINREMOVEFROMADDON */ + +typedef struct _Generic3Var_s +{ + double V1; + double V2; + double V3; +} Generic3Var_s; + +typedef struct _ThetaR_s +{ + double Theta; + double R; +} ThetaR_s; + +/* + * This union is designed to allow different plottypes + * to access the same values by different names. In + * C++ we could use member access functions, or we + * could have used macros, but instead we use this + * union. NOTE: This only works if all the structures + * have the same alignment. + */ +typedef union _AnchorPos_u +{ + Generic3Var_s Generic; + XYZ_s XYZ; + ThetaR_s ThetaR; +} AnchorPos_u; + +typedef struct _DataFileInfo_s +{ + char *PrimaryFName; + char *TempBinaryFName; + DataFileType_e FileType; + FileOffset_t DataFileOffset; + StringList_pa VarName; + EntIndex_t NumZones; + EntIndex_t NumVars; + double SolutionFileTime; + struct _DataFileInfo_s *NextFile; +} DataFileInfo_s; + +typedef struct _StylesheetIOFlags_s +{ + Boolean_t IncludePlotStyle; + Boolean_t IncludeFieldAndMapStyle; /* Only used for undo */ + Boolean_t IncludeUniqueIDs; /* Only used for undo */ + Boolean_t IncludeText; + Boolean_t IncludeGeom; + Boolean_t IncludeGeomImageData; + Boolean_t IncludeAuxData; + Boolean_t IncludeStreamPositions; + Boolean_t IncludeContourLevels; + Boolean_t IncludeFactoryDefaults; /* Only used when writing */ + Boolean_t CompressStyleCommands; /* Only used when writing */ + Boolean_t MergeStyle; /* Only used when reading */ + Boolean_t IncludeFrameSizeAndPosition; /* Only used when reading */ + Boolean_t UseRelativePaths; +} StylesheetIOFlags_s; + + +/** + */ +typedef struct +{ + Boolean_t Show; /* power switch */ + Boolean_t ShowMesh; + Boolean_t ShowContour; + Boolean_t ShowShade; + Boolean_t UseLightingEffect; + Boolean_t UseTranslucency; +} IsoSurfaceLayers_s; + +/** + */ +typedef struct +{ + Boolean_t Show; /* power switch */ + Boolean_t ShowMesh; + Boolean_t ShowContour; + Boolean_t ShowVector; + Boolean_t ShowShade; + Boolean_t ShowEdge; + Boolean_t UseLightingEffect; + Boolean_t UseTranslucency; +} SliceLayers_s; + +/** + */ +typedef struct +{ + Boolean_t Show; /* power switch */ + Boolean_t ShowPaths; + Boolean_t ShowDashes; + Boolean_t ShowArrowheads; + Boolean_t ShowMesh; + Boolean_t ShowContour; + Boolean_t ShowShade; + Boolean_t ShowMarkers; + Boolean_t UseLightingEffect; + Boolean_t UseTranslucency; +} StreamtraceLayers_s; + +/** + */ +typedef struct +{ +#if 0 /* in the future we may add a main power switch */ + Boolean_t Show; /* power switch */ +#endif + TwoDDrawOrder_e TwoDDrawOrder; + Boolean_t ShowMesh; + Boolean_t ShowContour; + Boolean_t ShowVector; + Boolean_t ShowScatter; + Boolean_t ShowShade; + Boolean_t ShowEdge; + Boolean_t UseLightingEffect; + Boolean_t UseTranslucency; +} FieldLayers_s; + +/** + * General purpose field layers structure used for low level drawing code only. + * SetupXxxx is responsible for populating this general field layers structure + * from the specific layer structures above for CZInfo. + */ +typedef struct +{ + Boolean_t ShowMesh; + Boolean_t ShowContour; + Boolean_t ShowVector; + Boolean_t ShowScatter; + Boolean_t ShowShade; + Boolean_t ShowEdge; + Boolean_t UseLightingEffect; + Boolean_t UseTranslucency; +} CZFieldLayers_s; + +/** + */ +typedef struct _LinePlotLayers_s +{ +#if 0 /* in the future we may add a main power switch */ + Boolean_t Show; /* power switch */ +#endif + Boolean_t ShowLines; + Boolean_t ShowSymbols; + Boolean_t ShowBarCharts; + Boolean_t ShowErrorBars; +} LinePlotLayers_s; + + +typedef union _InterfaceAdjust_u +{ + double ScaleFact; + LgIndex_t Shift; +} InterfaceAdjust_u; + +typedef Boolean_t (*SuffixModifier_pf)(TP_IN_OUT double* Value, + const char* Suffix); + +typedef struct _InputSpecs_s +{ + Input_e Type; + double Min; + double Max; + InterfaceAdjust_u InterfaceAdjust; + SuffixModifier_pf SuffixModifier; +} InputSpec_s; + + +typedef struct _RGB_s +{ + ColorIndex_t R; + ColorIndex_t G; + ColorIndex_t B; +} RGB_s; + + +typedef struct _ControlPoint_s +{ + double ColorMapFraction; + RGB_s LeadRGB; + RGB_s TrailRGB; +} ControlPoint_s; + + +typedef struct _ColorMapBand_s +{ + short NumControlPoints; + ControlPoint_s ControlPoint[MaxColorMapControlPoints]; +} ColorMapBand_s; + + +typedef struct _EventAction_s +{ + int I; + int J; + int LastI; + int LastJ; + int BaseI; + int BaseJ; + int ButtonOrKey; + Event_e Event; + Boolean_t IsShifted; + Boolean_t IsAlted; + Boolean_t IsControlled; + Boolean_t WasShiftedOnButtonPress; + Boolean_t WasAltedOnButtonPress; + Boolean_t WasControlledOnButtonPress; +} EventAction_s; + +typedef struct _MacroCmd_s +{ + LString_t MacroLine; + struct _MacroCmd_s *NextCmd; +} MacroCmd_s; + + +typedef struct _IntegerRect_s +{ + LgIndex_t X1; + LgIndex_t Y1; + LgIndex_t X2; + LgIndex_t Y2; +} IntegerRect_s; + + +typedef struct _Rect_s +{ + double X1; + double Y1; + double X2; + double Y2; +} Rect_s; + +typedef struct _XY_s +{ + double X; + double Y; +} XY_s; + +typedef struct _IJKSkip_s +{ + LgIndex_t I; + LgIndex_t J; + LgIndex_t K; +} IJKSkip_s; + + + +/* + * + * NOTE ON RANGES (Ent and Index) + * + * Min, Max and Skip all use the following assignment logic: + * + * 0 = First element + * -1 = mxindex value, (X[mxindex-1] in c) + * -n = mxindex-n+1 value (X[mxindex+n] in c) + * n = n+1 value (X[n] in c) + * + */ + +/* + * 2/28/95: NOTE: EntRange_s is no longer used but may be + * needed later. + */ + +typedef struct _EntRange_s +{ + EntIndex_t Min; + EntIndex_t Max; + EntIndex_t Skip; +} EntRange_s; + + +typedef struct _IndexRange_s +{ + LgIndex_t Min; + LgIndex_t Max; + LgIndex_t Skip; +} IndexRange_s; + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if defined (THREED) +#endif +#endif /* TECPLOTKERNEL */ + +typedef struct _TextShape_s +{ + Font_e Font; + double Height; + Units_e SizeUnits; +} TextShape_s; + +#define AsciiShapeFontIsGreek(S) (((S)->UseBaseFont == FALSE) && ((S)->FontOverride == Font_Greek)) +#define AsciiShapeFontIsMath(S) (((S)->UseBaseFont == FALSE) && ((S)->FontOverride == Font_Math)) +#define AsciiShapeFontIsUserDefined(S) (((S)->UseBaseFont == FALSE) && ((S)->FontOverride == Font_UserDefined)) + + +typedef struct +{ + Boolean_t UseBaseFont; /* (Default = TRUE) */ + Font_e FontOverride;/* (Default = Font_Math)*/ + SymbolChar_t Char; +} AsciiShape_s; + +typedef struct _SymbolShape_s +{ + GeomShape_e GeomShape; + Boolean_t IsAscii; + AsciiShape_s AsciiShape; +} SymbolShape_s; + +#ifdef NOT_USED +struct _AddOnList_a +{ + /* added temporarily so Windows makelibtec works */ + int dummy; +}; +#endif + +/* ENDREMOVEFROMADDON */ + +typedef struct _AddOnList_a *AddOn_pa; + +typedef struct _NodeMap_a *NodeMap_pa; + +/* BEGINREMOVEFROMADDON */ +typedef struct _StylePointState_a *StylePointState_pa; +typedef struct _DataElementState_a *DataElementState_pa; +typedef struct _StyleElementState_a *StyleElementState_pa; +typedef struct _NormalCache_a *NormalCache_pa; +/* ENDREMOVEFROMADDON */ + + +#define INVALID_INDEX (-1) + +/* used to indicate that no neighboring element or zone exists */ +#define NO_NEIGHBORING_ELEMENT (-1) +#define NO_NEIGHBORING_ZONE (-1) + +typedef struct _FaceNeighbor_a *FaceNeighbor_pa; + +/** + */ +typedef struct _FaceMap_a *FaceMap_pa; + +/** + */ +typedef struct _ElemToFaceMap_a *ElemToFaceMap_pa; + +/** + */ +typedef struct _NodeToElemMap_a *NodeToElemMap_pa; + +/* BEGINREMOVEFROMADDON */ + +/* + * Enumerates the face neighbor array members to make indexed members + * identifiable. + */ +typedef enum +{ + FaceNeighborMemberArray_CellFaceNbrs, + FaceNeighborMemberArray_BndryConnectNbrsCompObscure, + FaceNeighborMemberArray_BndryConnectFaceToCellsMap, + FaceNeighborMemberArray_BndryConnectIsPerfectNbr, + FaceNeighborMemberArray_BndryConnectCellList, + FaceNeighborMemberArray_BndryConnectZoneList, + END_FaceNeighborMemberArray_e, + FaceNeighborMemberArray_Invalid = BadEnumValue +} FaceNeighborMemberArray_e; + +int const FaceNeighborNumMemberArrays = (int)END_FaceNeighborMemberArray_e; + +/* + * Enumerates the face map's array members to make indexed members + * identifiable. + */ +typedef enum +{ + FaceMapMemberArray_FaceNodeOffsets, + FaceMapMemberArray_FaceNodes, + FaceMapMemberArray_FaceLeftElems, + FaceMapMemberArray_FaceRightElems, + FaceMapMemberArray_FaceBndryItemOffsets, + FaceMapMemberArray_FaceBndryItemElems, + FaceMapMemberArray_FaceBndryItemElemZones, + END_FaceMapMemberArray_e, + FaceMapMemberArray_Invalid = BadEnumValue +} FaceMapMemberArray_e; + +const int FaceMapNumMemberArrays = (int)END_FaceMapMemberArray_e; + +/* + * Enumerates the element to face map's array members to make indexed members + * identifiable. + */ +typedef enum +{ + ElemToFaceMapMemberArray_ElemFaceOffsets, + ElemToFaceMapMemberArray_ElemFaces, + END_ElemToFaceMapMemberArray_e, + ElemToFaceMapMemberArray_Invalid = BadEnumValue +} ElemToFaceMapMemberArray_e; + +const int ElemToFaceMapNumMemberArrays = (int)END_ElemToFaceMapMemberArray_e; + +/* + * Enumerates the element map's array members to make indexed members + * identifiable. + */ +typedef enum +{ + NodeToElemMapMemberArray_NodeElemOffsets, + NodeToElemMapMemberArray_NodeElems, + END_NodeToElemMapMemberArray_e, + NodeToElemMapMemberArray_Invalid = BadEnumValue +} NodeToElemMapMemberArray_e; + +const int NodeToElemMapNumMemberArrays = (int)END_NodeToElemMapMemberArray_e; + +/* ENDREMOVEFROMADDON */ + + +typedef struct _FieldData_a *FieldData_pa; + +/** + */ +typedef struct _AuxData_s *AuxData_pa; + + +/** + * Enumerates the data value structure of a variable in a data file. + * For all but ordered cell centered data the classic, classic padded and + * classic plus formats are identical. All values are laid out contiguously + * in the file. The number of values written depends upon the value location: + * + * - FE nodal:\n + * The number of values equals the number of data points. + * - FE cell centered:\n + * The number of values equals the number of elements. + * - Ordered nodal:\n + * The number of values equals the number of data points. + * - Ordered cell centered:\n + * There are three formats: + * -# Classic (binary version < 103):\n + * Classic is a compressed format of ordered cell centered data in + * that it does not include ghost cells. The cell index of each cell + * does not correspond to the lowest corner point index of each cell + * as it does internally in Tecplot.\n + * The number of values in the data file is calculated as follows: + * @code + * NumValues = MAX(IMax-1,1) * MAX(JMax-1,1) * MAX(KMax-1,1); + * @endcode + * Where IMax, JMax, and KMax are the maximum point dimensions of the + * zone. + * -# Classic padded (binary version < 104):\n + * Classic padded is an intermediary format that was available only + * within Tecplot, Inc. The cell centered data includes the ghost cells + * and each cell index corresponds to the lowest corner point index of + * each cell.\n + * The number of values in the data file (including ghost cells) is + * calculated as follows: + * @code + * NumValues = IMax * JMax * KMax; + * @endcode + * Where IMax, JMax, and KMax are the maximum point dimensions of the + * zone. The contents of the ghost cells is undefined and should not + * be used. + * -# Classic plus (binary version >= 104):\n + * Classic plus is similar to classic padded except that it does not + * include the ghost cells of the slowest moving index greater than + * one.\n + * The number of values in the data file (including ghost cells) is + * calculated as follows: + * @code + * FinalIMax = IMax; + * FinalJMax = JMax; + * FinalKMax = KMax; + * + * // decrement the max index of the slowest moving index greater than 1 + * if (KMax > 1) + * FinalKMax--; + * else if (JMax > 1) + * FinalJMax--; + * else if (IMax > 1) + * FinalIMax--; + * + * NumValues = FinalIMax * FinalJMax * FinalKMax; + * @endcode + * Where IMax, JMax, and KMax are the maximum point dimensions of the + * zone. The contents of the ghost cells is undefined and should not + * be used. + */ +typedef enum +{ + DataValueStructure_Classic, + DataValueStructure_ClassicPadded, + DataValueStructure_ClassicPlus, + END_DataValueStructure_e, + /* BEGINREMOVEFROMADDON */ + DataValueStructure_Latest = (END_DataValueStructure_e - 1), + /* ENDREMOVEFROMADDON */ + DataValueStructure_Invalid = BadEnumValue +} DataValueStructure_e; + +/** + * Enumerates the data node structure of a node map in a data file. The classic + * format uses 1 based nodes while the classic plus format uses zero based + * node. + */ +typedef enum +{ + DataNodeStructure_Classic, /* ones based node maps */ + DataNodeStructure_ClassicPlus, /* zero based node maps */ + END_DataNodeStructure_e, + DataNodeStructure_Invalid = BadEnumValue +} DataNodeStructure_e; + +/** + * Enumerates the variable locking modes. The \ref VarLockMode_ValueChange mode + * prevents modification of the values in a variable but permits deletion, and + * the \ref VarLockMode_Delete mode prevents deletion of a varaible but permits + * modification. + */ +typedef enum +{ + VarLockMode_ValueChange, + VarLockMode_Delete, + END_VarLockMode_e, + VarLockMode_Invalid = BadEnumValue +} VarLockMode_e; + +typedef enum +{ + FieldMapMode_UseStrandID, + FieldMapMode_UseZoneSet, + END_FieldMapMode_e, + FieldMapMode_Invalid = BadEnumValue +} FieldMapMode_e; + +typedef enum +{ + UnloadStrategy_Auto, + UnloadStrategy_NeverUnload, + UnloadStrategy_MinimizeMemoryUse, + END_UnloadStrategy_e, + UnloadStrategy_Invalid = BadEnumValue +} UnloadStrategy_e; + +/* BEGINREMOVEFROMADDON */ + + + +typedef struct +{ + ColorIndex_t PresetZoneColor; + Boolean_t IsInBlockFormat; +} ZoneLoadInfo_s; + +/* + * Note: For FE Data, NumPtsI = Number of data points. + * NumPtsJ = Number of elements. + * NumPtsK = Number of points per element. + */ + +typedef struct _ZoneSpec_s +{ + UniqueID_t UniqueID; + ZoneName_t Name; + EntIndex_t ParentZone; + Strand_t StrandID; + double SolutionTime; + LgIndex_t NumPtsI; // ...NumDataPts + LgIndex_t NumPtsJ; // ...NumElements + LgIndex_t NumPtsK; // ...NumPtsPerElem or NumFaces + LgIndex_t ICellDim; // ...currently not used + LgIndex_t JCellDim; // ...currently not used + LgIndex_t KCellDim; // ...currently not used + ZoneType_e Type; + ZoneLoadInfo_s ZoneLoadInfo; + AuxData_pa AuxData; + Boolean_t BuildZoneOptInfo; + + /* classic data only */ + FaceNeighborMode_e FNMode; + Boolean_t FNAreCellFaceNbrsSupplied; // ...meaning we don't need to update them + + /* polytope data only */ + LgIndex_t NumFaceNodes; + LgIndex_t NumFaceBndryFaces; + LgIndex_t NumFaceBndryItems; +} ZoneSpec_s; + + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ + +typedef struct _GenericImage_a *GenericImage_pa; + +typedef struct _TextBox_s +{ + TextBox_e BoxType; /* Used to be textbox */ + double Margin; /* Used to be textboxmargin */ + double LineThickness; /* Used to be textboxmargin */ + ColorIndex_t BColor; /* Used to be textboxcolor */ + ColorIndex_t FillBColor; /* Used to be textboxfillcolor */ +} TextBox_s; + + +typedef struct _Text_s +{ + UniqueID_t UniqueID; /* Not used yet */ + AnchorPos_u AnchorPos; + CoordSys_e PositionCoordSys; + EntIndex_t Zone; + Boolean_t AttachToZone; /* New */ + ColorIndex_t BColor; /* Used to be TextColor */ + TextShape_s TextShape; + TextBox_s Box; /* Box items used to be here*/ + double Angle; /* NOTE: short in v6, now in rad */ + TextAnchor_e Anchor; /* New */ + double LineSpacing; /* New */ + Scope_e Scope; + char *MacroFunctionCommand; + Clipping_e Clipping; + char *Text; + struct _Text_s *NextText; + struct _Text_s *PrevText; +} Text_s; + + +typedef struct _GenericGeomData_s +{ + FieldData_pa V1Base; + FieldData_pa V2Base; + FieldData_pa V3Base; +} GenericGeomData_s; + +typedef struct _PolarGeomData_s +{ + FieldData_pa ThetaBase; + FieldData_pa RBase; +} PolarGeomData_s; + +typedef struct _CartesianGeomData_s +{ + FieldData_pa XBase; + FieldData_pa YBase; + FieldData_pa ZBase; +} CartesianGeomData_s; + +/* + * This union is designed to allow different plottypes + * to access the same values by different names. In + * C++ we could use member access functions, or we + * could have used macros, but instead we use this + * union. NOTE: This only works if all the structures + * have the same alignment. + */ +typedef union _GeomData_u +{ + GenericGeomData_s Generic; + CartesianGeomData_s XYZ; + PolarGeomData_s ThetaR; +} GeomData_u; + +typedef struct _Geom_s +{ + UniqueID_t UniqueID; + GeomType_e GeomType; + CoordSys_e PositionCoordSys; + AnchorPos_u AnchorPos; + Boolean_t AttachToZone; + EntIndex_t Zone; + ColorIndex_t BColor; + Boolean_t IsFilled; + ColorIndex_t FillBColor; + LinePattern_e LinePattern; + double PatternLength; + double LineThickness; + Scope_e Scope; + DrawOrder_e DrawOrder; + Clipping_e Clipping; + FieldDataType_e DataType; + char *MacroFunctionCommand; + ArrowheadStyle_e ArrowheadStyle; + ArrowheadAttachment_e ArrowheadAttachment; + double ArrowheadSize; + double ArrowheadAngle; + SmInteger_t NumEllipsePts; + char *ImageFileName; + LgIndex_t ImageNumber; /* used only to locate images within .lpk files */ + Boolean_t MaintainAspectRatio; + double PixelAspectRatio; /* VerticalPixelsPerHorizontalPixel */ + SmInteger_t NumSegments; + SegPtsArray_t NumSegPts; + GeomData_u GeomData; + ImageResizeFilter_e ImageResizeFilter; + /* Internal Scratch */ + GenericImage_pa _ImageData; + struct _Geom_s *_NextGeom; + struct _Geom_s *_PrevGeom; +} Geom_s; + + +typedef struct _Text_s *Text_pa; +typedef struct _Geom_s *Geom_pa; + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if defined USE_OOSTYLE +#endif +#if defined USE_OOSTYLE +#endif +#endif /* TECPLOTKERNEL */ + +/* ENDREMOVEFROMADDON */ +/* - NO DOXYGEN COMMENT GENERATION - + * Page creation callback is responsible for creating a RenderHandler for the page and + * calling @ref TecEngPageCreateNew(ArbParam_t RenderHandle) + * + * The RenderHandler type can be anything, for example,a pointer to a class instance that will + * be responsible for handling requests from the engine to perform operations on + * a page. + * + * @param PageConstructionHints a string list of construction hints that can be used for deciding + * how the page should be displayed in an application's UI. The construction hints could have been + * restored from a saved layout file or passed to @ref TecUtilPageCreateNew function. + * + * @param RegistrationClientData + * Client data that was registered with the callback. + * + * @return TRUE if page create request was handled and TecEngPageCreateNew() returned TRUE. + * + * @sa TecEngPageCreateRegisterCallback, TecEngPageCreateNew + * + * @since + * 11.0-5-014 + */ +typedef Boolean_t (STDCALL *PageCreateCallback_pf)(StringList_pa PageConstructionHints, + ArbParam_t RegistrationClientData); + +/* - NO DOXYGEN COMMENT GENERATION - + * Page destruction callback responsible for destroying a page. + * + * @param PageClientData + * Data associated with a page that was returned from the PageCreateCallback_pf + * callback function. You will get a different value for each page. + * + * @param RegistrationClientData + * Data associated with the registration of this function. This will always return + * the value supplied in the original registration of this function. + * + * @sa TecEngPageDestroyRegisterCallback, PageCreateCallback_pf + * + * @since + * 11.0-5-014 + */ +typedef void (STDCALL *PageDestroyCallback_pf)(ArbParam_t PageClientData, + ArbParam_t RegistrationClientData); + +/* - NO DOXYGEN COMMENT GENERATION - + * Callback responsible for informing the parent application of a new current page. + * Note that this could be done via a state change monitor but a more secure method + * is needed as state changes may be shut down from time to time. + * + * @param PageClientData + * Data associated with a page that was returned from the PageCreateCallback_pf + * callback function. You will get a different value for each page. + * + * @param RegistrationClientData + * Data associated with the registration of this function. This will always return + * the value supplied in the original registration of this function. + * + * @since + * 11.0-5-017 + */ +typedef void (STDCALL *PageNewCurrentCallback_pf)(ArbParam_t PageClientData, + ArbParam_t RegistrationClientData); + +/* - NO DOXYGEN COMMENT GENERATION - + * Callback responsible for creation of an offscreen image. + * + * @param RegistrationClientData + * Data associated with the registration of this function. This will always return + * the value supplied in the original registration of this function. + * + * @param ImageHandle handle to a newly created image. This is an output parameter. + * + * @return TRUE if an offscreen image was created successfully. + * + * @since + * 11.2-0-054 + */ +typedef Boolean_t (STDCALL *OffscreenImageCreateCallback_pf)(ScreenDim_t Width, + ScreenDim_t Height, + ArbParam_t RegistrationClientData, + TP_OUT ArbParam_t* ImageHandle); + +/* - NO DOXYGEN COMMENT GENERATION - + * Callback responsible for destruction of an offscreen image. + * + * @param ImageHandle handle to an offscreen image to be destroyed. + * + * @param RegistrationClientData + * Data associated with the registration of this function. This will always return + * the value supplied in the original registration of this function. + * + * @since + * 11.2-0-054 + */ +typedef void (STDCALL *OffscreenImageDestroyCallback_pf)(ArbParam_t ImageHandle, + ArbParam_t RegistrationClientData); + +/* - NO DOXYGEN COMMENT GENERATION - + * Callback responsible for returning RGB values for a row. + * + * @param ImageHandle + * Handle to an off-screen image from which RGB values to be retrieved. + * + * @param Row + * Row for which RGB values to be retrieved. + * + * @param RedArray + * Array to receive the red byte values for the specified Row. The number of values in + * the array must equal the width of the image. The array address is maintained by the + * Tecplot Engine until the image is destroyed however it is reused for each invocation + * of this callback. + * + * @param GreenArray + * Array to receive the green byte values for the specified Row. The number of values in + * the array must equal the width of the image. The array address is maintained by the + * Tecplot Engine until the image is destroyed however it is reused for each invocation + * of this callback. + * + * @param BlueArray + * Array to receive the blue byte values for the specified Row. The number of values in + * the array must equal the width of the image. The array address is maintained by the + * Tecplot Engine until the image is destroyed however it is reused for each invocation + * of this callback. + * + * @param RegistrationClientData + * Data associated with the registration of this function. This will always return + * the value supplied in the original registration of this function. + * + * @return TRUE if successful, FALSE otherwise. + * + * @since + * 11.2-0-054 + */ +typedef Boolean_t (STDCALL *OffscreenImageGetRGBRowCallback_pf)(ArbParam_t ImageHandle, + ScreenDim_t Row, + ArbParam_t RegistrationClientData, + TP_ARRAY_OUT Byte_t* RedArray, + TP_ARRAY_OUT Byte_t* GreenArray, + TP_ARRAY_OUT Byte_t* BlueArray); + +#if defined MSWIN +/* - NO DOXYGEN COMMENT GENERATION - + * Callback responsible for printing an image on the specified printer DC + * + * @param PrintDC a device context of a printer on which the printing should be performed. + * + * @param ImageHandle handle to an image to print. + * + * @param Palette specifies if an image should be printed as a color or monochrome image. + * + * @param RegistrationClientData + * Data associated with the registration of this function. This will always return + * the value supplied in the original registration of this function. + * + * @return TRUE if the printing operation was successfull. + * + * @since + * 11.2-0-463 + */ +typedef Boolean_t (STDCALL *WinPrintImageCallback_pf)(HDC PrintDC, + ArbParam_t ImageHandle, + Palette_e Palette, + ArbParam_t RegistrationClientData); + +#endif /* MSWIN */ + +#if defined MSWIN +/* - NO DOXYGEN COMMENT GENERATION - + * Callback responsible for providing a printer context. + * + * @param RegistrationClientData + * Data associated with the registration of this function. This will always return + * the value supplied in the original registration of this function. + * + * @return HDC context of the destination printer. + * + * @since + * 11.2-0-468 + */ +typedef HDC(STDCALL *WinPrinterGetContextCallback_pf)(ArbParam_t RegistrationClientData); + +#endif /* MSWIN */ + +/* - NO DOXYGEN COMMENT GENERATION - + * Render destination callback responsible for switching the render destination + * of the OpenGL drawing state when requested by the Tecplot engine. + * + * @since + * 11.0-0-397 + * + * @param PageRenderDest + * Enumeration of page render destination of interest. + * + * @param RenderDestClientData + * Data associated with a render destination, such as returned from the PageCreateCallback_pf or + * OffscreenImageCreate_pf callback functions. + * + * @param RegistrationClientData + * Data associated with the registration of this function. This will always return + * the value supplied in the original registration of this function. + * + * @return + * TRUE if render destination was set successfully. FALSE, otherwise. + * + * @sa TecEngRenderDestRegisterCallback + */ +typedef Boolean_t (STDCALL *RenderDestCallback_pf)(PageRenderDest_e PageRenderDest, + ArbParam_t RenderDestClientData, + ArbParam_t RegistrationClientData); + +/* - NO DOXYGEN COMMENT GENERATION - + * Render query callback responsible for informing Tecplot if the page + * associated with the PageClientData should be rendered into. + * + * @since + * 11.0-5-018 + * + * @param PageClientData + * Data associated with a page that was returned from the + * PageCreateCallback_pf callback function. + * @param RegistrationClientData + * Data associated with the registration of this function. This will always + * return the value supplied in the original registration of this function. + * + * + * @return + * TRUE if Tecplot should render to the page identified by the + * PageClientData, FALSE otherwise. + * + * @sa TecEngRenderQueryRegisterCallback + */ +typedef Boolean_t (STDCALL *RenderQueryCallback_pf)(ArbParam_t PageClientData, + ArbParam_t RegistrationClientData); +/* - NO DOXYGEN COMMENT GENERATION - + * Render destination size callback responsible for returning the size of the + * specified render destination when requested by the Tecplot engine. + * + * @since + * 11.0-0-397 + * + * @param PageClientData + * Data associated with a page that was returned from the + * PageCreateCallback_pf callback function. + * @param RegistrationClientData + * Client data that was registered with the callback. + * @param Width + * Pointer who's contents should receive the width of the current render + * destination. + * @param Height + * Pointer who's contents should receive the height of the current render + * destination. + * + * @sa TecEngRenderDestSizeRegisterCallback + */ +typedef void (STDCALL *RenderDestSizeCallback_pf)(ArbParam_t PageClientData, + ArbParam_t RegistrationClientData, + TP_OUT LgIndex_t* Width, + TP_OUT LgIndex_t* Height); + +/* - NO DOXYGEN COMMENT GENERATION - + * Callback responsible for swapping the front and back buffers for the current + * OpenGL drawing state's render destination when requested by the Tecplot + * engine. + * + * @since + * 11.0-0-397 + * + * @param RegistrationClientData + * Client data that was registered with the callback. + * + * @sa TecUtilpBuffersRegisterCallback + */ +typedef void (STDCALL *SwapBuffersCallback_pf)(ArbParam_t RegistrationClientData); + + +/* - NO DOXYGEN COMMENT GENERATION - + * Callback responsible for querying of key states. + * + * @since + * 11.0-0-399 + * + * @param RegistrationClientData + * Client data that was registered with the callback. + * @param IsShiftKeyDown + * Boolean pointer. If non-NULL, set the boolean to TRUE if the Shift key is + * down or FALSE if it is up. + * @param IsAltKeyDown + * Boolean pointer. If non-NULL, set the boolean to TRUE if the Alt key is + * down or FALSE if it is up. + * @param IsCntrlKeyDown + * Boolean pointer. If non-NULL, set the boolean to TRUE if the Cntrl key is + * down or FALSE if it is up. + * + * @sa TecEngKeyStateRegisterCallback + */ +typedef void (STDCALL *KeyStateCallback_pf)(ArbParam_t RegistrationClientData, + TP_OUT Boolean_t* IsShiftKeyDown, + TP_OUT Boolean_t* IsAltKeyDown, + TP_OUT Boolean_t* IsCntrlKeyDown); + +/* - NO DOXYGEN COMMENT GENERATION - + * Callback responsible for querying of a mouse button state. + * + * @since + * 11.0-0-424 + * + * @param Button + * Mouse button number to query. Button numbers start at one. + * @param RegistrationClientData + * Client data that was registered with the callback. + * + * @return + * TRUE if the specified mouse button is down, FALSE otherwise. + * + * @sa TecEngMouseButtonStateRegisterCallback + */ +typedef Boolean_t (STDCALL *MouseButtonStateCallback_pf)(int Button, + ArbParam_t RegistrationClientData); + +/* - NO DOXYGEN COMMENT GENERATION - + * Callback responsible for setting wait cursor when requested by the kernel + * + * @since + * 11.2-0-302 + * + * @param Activate + * TRUE if the kernel is requesting that the wait cursor be activated. + * FALSE if the kernel is requesting that the wait cursor be deactivated. + * @param RegistractionClientData + * Client data that was registered with the callback. + * + * @sa TecEngWaitCursorStateRegisterCallback + */ +typedef void (STDCALL *WaitCursorStateCallback_pf)(Boolean_t Activate, + ArbParam_t RegistrationClientData); + +/* - NO DOXYGEN COMMENT GENERATION - + * Callback responsible for setting cursor style when requested by the kernel + * + * @since + * 11.2-0-302 + * + * @param CursorStyle + * The cursor style which the kernel is requesting. + * @param RenderHandle + * Handle to page where new cursor shape is being set. + * @param RegistractionClientData + * Client data that was registered with the callback. + * + * @sa TecEngBaseCursorStyleRegisterCallback + */ +typedef void (STDCALL *BaseCursorStyleCallback_pf)(CursorStyle_e CursorStyle, + ArbParam_t RenderHandle, + ArbParam_t RegistrationClientData); + +/* - NO DOXYGEN COMMENT GENERATION - + * Callback responsible for processing events when the Tecplot engine is busy + * peforming a requested operation. This callback will be called at regular + * intervals to repair the interface and if required check for interrupts. Very + * little work should be done by this function. + * + * @since + * 11.0-0-415 + * + * @param RegistrationClientData + * Client data that was registered with the callback. + * + * @sa TecEngProcessBusyEventsRegisterCallback, TecUtilInterrupt + */ +typedef void (STDCALL *ProcessBusyEventsCallback_pf)(ArbParam_t RegistrationClientData); + +/* - NO DOXYGEN COMMENT GENERATION - + * Callback responsible for launching a dialog. + * + * @since + * 11.0-0-415 + * + * @param RegistrationClientData + * Client data that was registered with this launch dialog callback. + * + * @return + * TRUE if the dialog was launched, FALSE if it could not be launched + * programmatically. + * + * @sa TecUtilDialogLaunch, TecUtilDialogDrop + */ +typedef Boolean_t (STDCALL *DialogLaunchCallback_pf)(ArbParam_t RegistrationClientData); + +/* - NO DOXYGEN COMMENT GENERATION - + * Callback responsible for dropping a dialog. + * + * @since + * 11.0-0-407 + * + * @param RegistrationClientData + * Client data that was registered with this drop dialog callback. + * + * @sa TecUtilDialogLaunch, TecUtilDialogDrop + */ +typedef void (STDCALL *DialogDropCallback_pf)(ArbParam_t RegistrationClientData); + +/* - NO DOXYGEN COMMENT GENERATION - + * Callback responsible for querying of the physical display's horizontal and + * vertical dot pitch. + * + * @since + * 11.0-0-407 + * + * @param RegistrationClientData + * Client data that was registered with the callback. + * @param IDotsPerCm + * Pointer who's contents should receive the physical display's horizontal + * dot pitch in terms of the number of dots per centimeter. + * @param JDotsPerCm + * Pointer who's contents should receive the physical display's vertical + * dot pitch in terms of the number of dots per centimeter. + * + * @sa TecEngDotPitchRegisterCallback + */ +typedef void (STDCALL *DotPitchCallback_pf)(ArbParam_t RegistrationClientData, + TP_OUT double* IDotsPerCm, + TP_OUT double* JDotsPerCm); + +/* - NO DOXYGEN COMMENT GENERATION - + * Callback responsible for querying of the physical display's width and + * height in pixels. + * + * @since + * 11.2-0-471 + * + * @param RegistrationClientData + * Client data that was registered with the callback. + * @param WidthInPixels + * Pointer who's contents should receive the physical display's width + * in pixels. NULL may be passed. + * @param HeightInPixels + * Pointer who's contents should receive the physical display's height + * in pixels. NULL may be passed. + * + * @sa TecEngScreenSizeRegisterCallback + */ +typedef void (STDCALL *ScreenSizeCallback_pf)(ArbParam_t RegistrationClientData, + TP_OUT int* WidthInPixels, + TP_OUT int* HeightInPixels); + +/* - NO DOXYGEN COMMENT GENERATION - + * Callback responsible for displaying a message box dialog and returning the + * user's response. + * + * @since + * 11.0-0-415 + * + * @param MessageString + * Message string to display in the dialog. + * @param MessageBoxType + * Type of message box to display. + * @param RegistrationClientData + * Client data that was registered with the callback. + * + * @return + * Result of user's response to the dialog. + * + * @sa TecEngDialogMessageBoxRegisterCallback + */ +typedef MessageBoxReply_e(STDCALL *DialogMessageBoxCallback_pf)(const char* MessageString, + MessageBoxType_e MessageBoxType, + ArbParam_t RegistrationClientData); + +/* - NO DOXYGEN COMMENT GENERATION - + * Callback responsible for displaying a status line + * + * @since + * 11.2-0-085 + * + * @param StatusString + * Message string to display in the dialog. + * + * @param RegistrationClientData + * Client data that was registered with the callback. + * + * @sa TecEngStatusLineRegisterCallback + */ +typedef void (STDCALL *StatusLineCallback_pf)(const char* StatusString, + ArbParam_t RegistrationClientData); + +/* - NO DOXYGEN COMMENT GENERATION - + * Callback that will be called with the updated progress status. + * + * @since 11.2-0-098 + * + * + * @param ProgressStatus + * Percentage of the progress. + * + * @param RegistrationClientData + * Client data that was registered with the callback. + * + * @sa TecEngProgressMonitorRegisterCallback + */ +typedef void (STDCALL *ProgressMonitorCallback_pf)(int ProgressStatus, + ArbParam_t RegistrationClientData); +/* - NO DOXYGEN COMMENT GENERATION - + * Callback that will be called with Tecplot Engine is about to perform a lengthy operation. + * The client that registers such the callback may present a user with a progress bar, + * if the ShowProgressBar argument is TRUE, and a stop button that would interrupt the operation by + * calling TecUtilInterrupt(). + * + * @since 11.2-0-098 + * + * @param ShowProgressBar + * Boolean indicating if the progress steps can be monitored for an operation. If TRUE, Tecplot Engine will be calling + * the registered ProgressMonitorCallback_pf function with the updated progress status. + * + * @param IsInterruptible + * Boolean indicating if the operation can be interrupted before completion. + * + * @param RegistrationClientData + * Client data that was registered with the callback. + * + * @sa TecEngProgressMonitorRegisterCallback + */ +typedef void (STDCALL *ProgressMonitorStartCallback_pf)(Boolean_t ShowProgressBar, + Boolean_t IsInterruptible, + ArbParam_t RegistrationClientData); +/* - NO DOXYGEN COMMENT GENERATION - + * Callback tht will be called with Tecplot Engine has finished performing a lengthy operation. + * At this point, client may hide progress bar that was shown during handling of ProgressMonitorStartCallback callback and + * disable or hide the stop button. + * + * @since 11.2-0-098 + * + * @param RegistrationClientData + * Client data that was registered with the callback. + * + * @sa TecEngProgressMonitorRegisterCallback + */ +typedef void (STDCALL *ProgressMonitorFinishCallback_pf)(ArbParam_t RegistrationClientData); + +/********************************************************* + * Add-on Timers + *********************************************************/ +/** + * This is called when a registered timer fires. + * + * @par Limitation: + * Unix and Linux versions of Tecplot currently do not fire timer events when + * Tecplot is running in batch mode (with the -b flag). This behavior + * limitation is subject to change. + * + * @param ClientData + * Arbitrary client data. + * + * @return + * Return TRUE if the timer should be reinstated. Return FALSE + * to stop subsequent callbacks. + * + * + * + * INTEGER*4 FUNCTION MyAddOnTimerCallback( + * & ClientDataPtr) + * POINTER (ClientDataPtr,DummyClientData) + * + */ +typedef Boolean_t (STDCALL *AddOnTimerCallback_pf)(ArbParam_t ClientData); + +/* - NO DOXYGEN COMMENT GENERATION - + * Callback that will be called when Tecplot Engine has requested an event timer to be created. + * + * @since 12.0.1.5642 + * + * @param ClientData + * ClientData that should be sent in the callback. + * + * @param TimerCallback + * Callback to fire when the timer interval has expired. + * + * @param Interval + * The time (in milliseconds) after which the timer callback should be called. + * + * @param RegistrationClientData + * Client data that was registered via TecEngTimerRegisterCallback. + * + * @return + * Return TRUE if the timer was successfully created, FALSE if not. + */ +typedef Boolean_t (STDCALL *TimerCallback_pf)(AddOnTimerCallback_pf TimerCallback, + ArbParam_t ClientData, + UInt32_t Interval, + ArbParam_t RegistrationClientData); + +/** + * This function is called when the user activates a menu item + * added via TecUtilMenuInsertOption or TecUtilMenuInsertToggle. + * + * @param RegistrationClientData + * Arbitrary client data. + */ +typedef void (STDCALL *MenuActivateCallback_pf)(ArbParam_t RegistrationClientData); + +/** + * This function is called when the a menu is deleted. + * + * @param RegistrationClientData + * Arbitrary client data. + */ +typedef void (STDCALL *MenuDeleteCallback_pf)(ArbParam_t RegistrationClientData); + +/** + * This function is called to determine the sensitivity for a menu item (option, + * toggle or submenu). + * + * @param RegistrationClientData + * Arbitrary client data. + * + * @return + * Return TRUE if the menu item should be sensitive to user input, + * or FALSE if it should be insensitive to user input (gray). + */ +typedef Boolean_t (STDCALL *MenuGetSensitivityCallback_pf)(ArbParam_t RegistrationClientData); + +/** + * This function is called to determine the checked state for a toggle menu item. + * + * @param RegistrationClientData + * Arbitrary client data. + * + * @return + * Return TRUE if the toggle should be checked, + * or FALSE if it should be unchecked. + */ +typedef Boolean_t (STDCALL *MenuGetToggleStateCallback_pf)(ArbParam_t RegistrationClientData); + + +/** + * This function is called when the user performs a probe event. + * + * @param IsNearestPoint + * This is TRUE if the previous probe event was a nearest point probe. + * This is FALSE if it was an interpolated probe. + * + * + * SUBROUTINE MyProbeDestinationCallback( + * IsNearestPoint) + * INTEGER*4 IsNearestPoint + * + */ +typedef void (STDCALL *ProbeDestination_pf)(Boolean_t IsNearestPoint); + + +/** + * This function type called when a probe callback is installed via + * TecUtilProbeInstallCallbackX. + * + * @param WasSuccessful + * This is TRUE if the previous probe event was successful. + * This is FALSE if it was the probe failed. Probe events may fail if the + * user probes in a region of the plot that contains no data. + * + * @param IsNearestPoint + * This is TRUE if the previous probe event was a nearest point probe. + * This is FALSE if it was an interpolated probe. + * + * @param ClientData + * Arbitrary client data. + * + */ +typedef void (STDCALL *ProbeDestinationX_pf)(Boolean_t WasSuccessful, + Boolean_t IsNearestPoint, + ArbParam_t ClientData); + + +/** + * DynamicMenu Functions are called upon a user selecting + * a menu item added via TecUtilMenuAddOption. + * + * + * SUBROUTINE MyDynamicMenuCallback() + * + */ +typedef void (STDCALL *DynamicMenuCallback_pf)(void); + +/** + * This callback signature is used to perform redraw events. + * + * @since + * 11.0-0-363 + * + * @param RedrawReason + * An enumerated value describing the reason for the re-draw event. + * @param ClientData + * Client data that was registered with the callback. + * + * @return + * TRUE if successfull, FALSE otherwise. + * + * + * INTEGER*4 FUNCTION DrawEventCallback( + * & RedrawReason, + * & ClientDataPtr) + * INTEGER*4 RedrawReason + * POINTER (ClientDataPtr,ClientData) + * + * + * @sa TecUtilEventAddPreDrawCallback(), TecUtilEventAddPostDrawCallback() + */ +typedef Boolean_t (STDCALL *DrawEventCallback_pf)(RedrawReason_e RedrawReason, + ArbParam_t ClientData); + + +/** + * Compares two strings from a list string. Note that either string may be NULL + * as StringLists allow for NULL elements. + * + * @param String1 + * String to compare against String2. + * @param String2 + * String to compare against String1. + * @param ClientData + * Contextual information that was passed to the 'StringListSort' function. + * + * @return + * - A value less than zero if String1 is less than String2. + * - A value of zero if String1 is equal to String2. + * - A value greater than zero if String1 is greater than String2. + */ +typedef int (STDCALL *StringListStringComparator_pf)(const char* String1, + const char* String2, + ArbParam_t ClientData); + +/** + * Gets a value at the specified point index using, if necessary, the private + * client data retrieved from the field data handle. + * + * @par Note: + * This callback is called asynchronously. This callback should NOT + * lock/unlock Tecplot. + * + * @since + * 10.0-3-128 + * + * @param FD + * Field data handle for which to set the value. This + * FieldValueGetFunction_pf must have been retrieved from this field data + * handle via TecUtilDataValueRefGetGetFunc. + * + * @param pt + * Zero-based index into the field data. + * + * @return + * Value for that index, always passed as a double precision floating-point + * value regardless of the data type of the field data handle. + * + * @sa TecUtilDataValueCustomLOD(), TecUtilDataValueGetClientData() + */ +typedef double(STDCALL *FieldValueGetFunction_pf)(const FieldData_pa FD, + LgIndex_t pt); + +/** + * Sets a value at the specified index using the private client data retrieved + * from the field data handle. + * + * @par Note: + * This callback is called asynchronously. This callback should NOT + * lock/unlock Tecplot. + * + * @since + * 10.0-3-128 + * + * @param FD + * Field data handle for which to set the value. This + * FieldValueSetFunction_pf must have been retrieved from this field data + * handle via TecUtilDataValueRefGetSetFunc. + * + * @param pt + * Zero-based index into the field data. + * + * @param val + * New value for that index, always passed as a double precision + * floating-point value regardless of the data type of the field data handle. + * + * @sa TecUtilDataValueCustomLOD(), TecUtilDataValueGetClientData() + */ +typedef void (STDCALL *FieldValueSetFunction_pf)(FieldData_pa FD, + LgIndex_t pt, + double val); + +/** + * Callback responsible for loading the specified variable for Tecplot using + * the private client data retrieved from the field data handle. + * + * @par Note: + * This callback is called asynchronously. With the exception of calls to + * modify the field data all calls back to Tecplot through the TecUtil layer + * should be limited to queries. + * + * @since + * 11.0-0-001 + * + * @param FieldData + * Field data handle of the variable load. + * + * @result + * TRUE if the variable was loaded, FALSE if unable to do so. + * + * @code + * typedef struct + * { + * char *DataFileName; + * long SeekOffset; + * LgIndex_t NumValues; + * ... other information needed to load variable data + * } MyVariableClientData_s; + * + * Boolean_t STDCALL MyVariableLoader(FieldData_pa FieldData) + * { + * REQUIRE(VALID_REF(FieldData)); + * + * MyVariableClientData_s *MyClientData = (MyVariableClientData_s *)TecUtilDataValueGetClientData(FieldData); + * + * // open the data file + * FILE *MyDataFile = fopen(MyClientData->DataFileName, "rb"); + * Boolean_t IsOk = (MyDataFile != NULL); + * + * // seek to the place in the file where the variable data is located + * IsOk = IsOk && (fseek(MyDataFile, MyClientData->SeekOffset, SEEK_SET) == 0); + * if (IsOk) + * { + * // load the data into the variable's field data + * IsOk = ReadMyDataInfoVariable(MyDataFile, MyClientData, FieldData); + * } + * + * // cleanup + * if (MyDataFile != NULL) + * fclose(MyDataFile); + * + * ENSURE(VALID_BOOLEAN(IsOk)); + * return IsOk; + * } + * @endcode + * + * @sa TecUtilDataValueCustomLOD(), TecUtilDataValueGetClientData() + */ +typedef Boolean_t (STDCALL *LoadOnDemandVarLoad_pf)(FieldData_pa FieldData); + +/** + * Callback responsible for performing private actions associated with a + * variable being unloaded using the private client data retrieved from the + * field data handle. Whenever possible the callback should honor Tecplot's + * request to unload the variable by returning TRUE. This callback is + * responsible for performing private actions associated with a variable being + * unloaded. + * + * Most add-ons should simply supply NULL for this callback thereby instructing + * Tecplot to handle the unloading (and subsequent reloading) of the variable + * without the intervention of the add-on. + * + * @par Note: + * This callback is called asynchronously. All calls back to Tecplot through + * the TecUtil layer should be limited to queries. + * + * @since + * 11.0-0-001 + * + * @param FieldData + * Field data handle of the variable Tecplot wants to unload. + * + * @code + * typedef struct + * { + * char *DataFileName; + * long SeekOffset; + * LgIndex_t NumValues; + * ... other information needed to load variable data + * } MyVariableClientData_s; + * + * Boolean_t STDCALL MyVariableUnload(FieldData_pa FieldData) + * { + * REQUIRE(VALID_REF(FieldData)); + * + * // We don't have any private data to cleanup (i.e in addition to the + * // private client data which we don't cleanup here) so all we have to do + * // is return TRUE or FALSE letting Tecplot know that it can or can not + * // unload the variable. + * Boolean_t Result = TRUE; // ...tell Tecplot to go ahead and unload the variable + * + * ENSURE(VALID_BOOLEAN(Result)); + * return Result; + * } + * @endcode + * + * @result + * TRUE if the variable can be unloaded, FALSE otherwise. The add-on should + * if at all possible honor the request to unload the variable. Most add-ons + * should return TRUE. + * + * @sa TecUtilDataValueCustomLOD(), TecUtilDataValueGetClientData() + */ +typedef Boolean_t (STDCALL *LoadOnDemandVarUnload_pf)(FieldData_pa FieldData); + +/** + * Callback responsible for performing private actions associated with a + * variable being cleaned up using the private client data retrieved from the + * field data handle. Most add-ons will need to register this callback in order + * to cleanup privately allocated client data. + * + * @par Note: + * This callback is called asynchronously. All calls back to Tecplot through + * the TecUtil layer should be limited to queries. + * + * @since + * 11.0-0-001 + * + * @param FieldData + * Field data handle of the variable being cleaned up. + * + * @code + * typedef struct + * { + * char *DataFileName; + * long SeekOffset; + * LgIndex_t NumValues; + * ... other information needed to load variable data + * } MyVariableClientData_s; + * + * void STDCALL MyVariableCleanup(FieldData_pa FieldData) + * { + * REQUIRE(VALID_REF(FieldData)); + * + * MyVariableClientData_s *MyClientData = (MyVariableClientData_s *)TecUtilDataValueGetClientData(FieldData); + * + * // cleanup privately allocated resources + * free(MyClientData->DataFileName); + * free(MyClientData); + * } + * @endcode + * + * @sa TecUtilDataValueCustomLOD(), TecUtilDataValueGetClientData() + */ +typedef void (STDCALL *LoadOnDemandVarCleanup_pf)(FieldData_pa FieldData); + +/** + * Callback responsible for loading the specified node mapping for Tecplot + * using the private client data retrieved from the node mapping handle. + * + * @par Note: + * This callback is called asynchronously. With the exception of calls to + * modify the node mapping, all calls back to Tecplot through the TecUtil + * layer should be limited to queries. + * + * @since + * 11.3-0-010 + * + * @param NodeMap + * Handle of the node mapping. + * + * @result + * TRUE if the node mapping was loaded, FALSE if unable to do so. + * + * @code + * typedef struct + * { + * char *DataFileName; + * long SeekOffset; + * ... other information needed to load node map data + * } MyNodeMapClientData_s; + * + * Boolean_t STDCALL MyNodeMapLoader(NodeMap_pa NodeMap) + * { + * REQUIRE(VALID_REF(NodeMap)); + * + * MyNodeMapClientData_s *MyClientData = + * (MyNodeMapClientData_s *)TecUtilDataNodeGetClientData(NodeMap); + * + * // open the data file + * FILE *MyDataFile = fopen(MyClientData->DataFileName, "rb"); + * Boolean_t IsOk = (MyDataFile != NULL); + * + * // seek to the place in the file where the node map data is located + * IsOk = IsOk && (fseek(MyDataFile, MyClientData->SeekOffset, SEEK_SET) == 0); + * if (IsOk) + * { + * // load the data into the zone's node map + * IsOk = ReadMyNodeMapDataIntoZone(MyDataFile, MyClientData, NodeMap); + * } + * + * // cleanup + * if (MyDataFile != NULL) + * fclose(MyDataFile); + * + * ENSURE(VALID_BOOLEAN(IsOk)); + * return IsOk; + * } + * @endcode + * + * @sa TecUtilDataNodeCustomLOD(), TecUtilDataNodeGetClientData() + */ +typedef Boolean_t (STDCALL *LoadOnDemandNodeMapLoad_pf)(NodeMap_pa NodeMap); + +/** + * Callback responsible for performing private actions associated with a + * node mapping being unloaded using the private client data retrieved from the + * node mapping handle. Whenever possible the callback should honor Tecplot's + * request to unload the node mapping by returning TRUE. + * + * Most add-ons should simply supply NULL for this callback thereby instructing + * Tecplot to handle the unloading (and subsequent reloading) of the node mapping + * without the intervention of the add-on. + * + * @par Note: + * This callback is called asynchronously. All calls back to Tecplot through + * the TecUtil layer should be limited to queries. + * + * @since + * 11.3-0-010 + * + * @param NodeMap + * Node mapping handle of the node mapping Tecplot wants to unload. + * + * @code + * Boolean_t STDCALL MyNodeMapUnload(NodeMap_pa NodeMap) + * { + * REQUIRE(VALID_REF(NodeMap)); + * + * // We don't have any private data to cleanup (i.e in addition to the + * // private client data which we don't cleanup here) so all we have to do + * // is return TRUE or FALSE letting Tecplot know that it can or can not + * // unload the variable. + * Boolean_t Result = TRUE; // ...tell Tecplot to go ahead and unload the node mapping + * + * ENSURE(VALID_BOOLEAN(Result)); + * return Result; + * } + * @endcode + * + * @result + * TRUE if the node mapping can be unloaded, FALSE otherwise. The add-on should + * if at all possible honor the request to unload the node mapping. Most add-ons + * should return TRUE. + * + * @sa TecUtilDataNodeCustomLOD(), TecUtilDataNodeGetClientData() + */ +typedef Boolean_t (STDCALL *LoadOnDemandNodeMapUnload_pf)(NodeMap_pa NodeMap); + +/** + * Callback responsible for performing private actions associated with a + * node mapping being cleaned up using the private client data retrieved from the + * node mapping handle. Most add-ons will need to register this callback in order + * to cleanup privately allocated client data. + * + * @par Note: + * This callback is called asynchronously. All calls back to Tecplot through + * the TecUtil layer should be limited to queries. + * + * @since + * 11.3-0-010 + * + * @param NodeMap + * Node Mapping data handle of the node mapping being cleaned up. + * + * @code + * typedef struct + * { + * char *DataFileName; + * long SeekOffset; + * ... other information needed to load node map data + * } MyNodeMapClientData_s; + * + * void STDCALL MyNodeMapCleanup(NodeMap_pa NodeMap) + * { + * REQUIRE(VALID_REF(NodeMap)); + * + * MyNodeMapClientData_s *MyClientData = (MyNodeMapClientData_s *)TecUtilDataNodeGetClientData(NodeMap); + * + * // cleanup privately allocated resources + * free(MyClientData->DataFileName); + * free(MyClientData); + * } + * @endcode + * + * @sa TecUtilDataNodeCustomLOD(), TecUtilDataNodeGetClientData() + */ +typedef void (STDCALL *LoadOnDemandNodeMapCleanup_pf)(NodeMap_pa NodeMap); + +/** + * Callback responsible for loading the specified face neighbor for Tecplot + * using the private client data retrieved from the face neighbor handle. + * + * @par Note: + * This callback is called asynchronously. With the exception of calls to + * modify the face neighbors, all calls back to Tecplot through the TecUtil + * layer should be limited to queries. + * + * @since + * 11.3-0-010 + * + * @param FaceNeighbor + * Handle of the face neighbors. + * + * @result + * TRUE if the face neighbors was loaded, FALSE if unable to do so. + * + * @code + * typedef struct + * { + * char *DataFileName; + * long SeekOffset; + * ...other information needed to load face neighbor data + * } MyFaceNeighborClientData_s; + * + * Boolean_t STDCALL MyFaceNeighborLoader(FaceNeighbor_pa FaceNeighbor) + * { + * REQUIRE(VALID_REF(FaceNeighbor)); + * + * MyFaceNeighborClientData_s *MyClientData = + * (MyFaceNeighborClientData_s*)TecUtilDataFaceNbrGetClientData(FaceNeighbor); + * + * // open the data file + * FILE *MyDataFile = fopen(MyClientData->DataFileName, "rb"); + * Boolean_t IsOk = (MyDataFile != NULL); + * + * // seek to the place in the file where the face neighbor data is located + * IsOk = IsOk && (fseek(MyDataFile, MyClientData->SeekOffset, SEEK_SET) == 0); + * if (IsOk) + * { + * // load the data into the zone's face neighbor + * IsOk = ReadMyFaceNeighborDataIntoZone(MyDataFile, MyClientData, FaceNeighbor); + * } + * + * // cleanup + * if (MyDataFile != NULL) + * fclose(MyDataFile); + * + * ENSURE(VALID_BOOLEAN(IsOk)); + * return IsOk; + * } + * @endcode + * + * @sa TecUtilDataFaceNbrCustomLOD(), TecUtilDataFaceNbrGetClientData() + */ +typedef Boolean_t (STDCALL *LoadOnDemandFaceNeighborLoad_pf)(FaceNeighbor_pa FaceNeighbor); + +/** + * Callback responsible for performing private actions associated with a + * face neighbors being unloaded using the private client data retrieved from + * the face neighbor handle. Whenever possible the callback should honor + * Tecplot's request to unload the face neighbors by returning TRUE. + * + * Most add-ons should simply supply NULL for this callback thereby instructing + * Tecplot to handle the unloading (and subsequent reloading) of the face + * neighbors without the intervention of the add-on. + * + * @par Note: + * This callback is called asynchronously. All calls back to Tecplot through + * the TecUtil layer should be limited to queries. + * + * @since + * 11.3-0-010 + * + * @param FaceNeighbor + * Face neighbor handle of the face neighbors Tecplot wants to unload. + * + * @code + * Boolean_t STDCALL MyFaceNeighborUnload(FaceNeighbor_pa FaceNeighbor) + * { + * REQUIRE(VALID_REF(FaceNeighbor)); + * + * // We don't have any private data to cleanup (i.e in addition to the + * // private client data which we don't cleanup here) so all we have to do + * // is return TRUE or FALSE letting Tecplot know that it can or can not + * // unload the variable. + * Boolean_t Result = TRUE; // ...tell Tecplot to go ahead and unload the face neighbors + * + * ENSURE(VALID_BOOLEAN(Result)); + * return Result; + * } + * @endcode + * + * @result + * TRUE if the face neighbors can be unloaded, FALSE otherwise. The add-on + * should if at all possible honor the request to unload the face neighbors. + * Most add-ons should return TRUE. + * + * @sa TecUtilDataFaceNbrCustomLOD(), TecUtilDataFaceNbrGetClientData() + */ +typedef Boolean_t (STDCALL *LoadOnDemandFaceNeighborUnload_pf)(FaceNeighbor_pa FaceNeighbor); + +/** + * Callback responsible for performing private actions associated with a face + * neighbors being cleaned up using the private client data retrieved from the + * face neighbor handle. Most add-ons will need to register this callback in + * order to cleanup privately allocated client data. + * + * @par Note: + * This callback is called asynchronously. All calls back to Tecplot through + * the TecUtil layer should be limited to queries. + * + * @since + * 11.3-0-010 + * + * @param FaceNeighbor + * Face neighbor data handle of the Face neighbors being cleaned up. + * + * @code + * typedef struct + * { + * char *DataFileName; + * long SeekOffset; + * ... other information needed to load face neighbor data + * } MyFaceNeighborClientData_s; + * + * void STDCALL MyFaceNeighborCleanup(FaceNeighbor_pa FaceNeighbor) + * { + * REQUIRE(VALID_REF(FaceNeighbor)); + * + * MyFaceNeighborClientData_s *MyClientData = (MyFaceNeighborClientData_s *)TecUtilDataFaceNbrGetClientData(FaceNeighbor); + * + * // cleanup privately allocated resources + * free(MyClientData->DataFileName); + * free(MyClientData); + * } + * @endcode + * + * @sa TecUtilDataFaceNbrCustomLOD(), TecUtilDataFaceNbrGetClientData() + */ +typedef void (STDCALL *LoadOnDemandFaceNeighborCleanup_pf)(FaceNeighbor_pa FaceNeighbor); + +/** + * Callback responsible for loading the specified face mapping for Tecplot + * using the private client data retrieved from the face mapping handle. + * + * @par Note: + * This callback is called asynchronously. With the exception of calls to + * modify the face mapping, all calls back to Tecplot through the TecUtil + * layer should be limited to queries. + * + * @since + * 11.2-1-0 + * + * @param FaceMap + * Handle of the face mapping. + * + * @result + * TRUE if the face mapping was loaded, FALSE if unable to do so. + * + * @code + * typedef struct + * { + * char *DataFileName; + * long SeekOffset; + * ... other information needed to load face map data + * } MyFaceMapClientData_s; + * + * Boolean_t STDCALL MyFaceMapLoader(FaceMap_pa FaceMap) + * { + * REQUIRE(VALID_REF(FaceMap)); + * + * MyFaceMapClientData_s *MyClientData = + * (MyFaceMapClientData_s *)TecUtilDataFaceMapGetClientData(FaceMap); + * + * // open the data file + * FILE *MyDataFile = fopen(MyClientData->DataFileName, "rb"); + * Boolean_t IsOk = (MyDataFile != NULL); + * + * // seek to the place in the file where the face map data is located + * IsOk = IsOk && (fseek(MyDataFile, MyClientData->SeekOffset, SEEK_SET) == 0); + * if (IsOk) + * { + * // load the data into the zone's face map + * IsOk = ReadMyFaceMapDataIntoZone(MyDataFile, MyClientData, FaceMap); + * } + * + * // cleanup + * if (MyDataFile != NULL) + * fclose(MyDataFile); + * + * ENSURE(VALID_BOOLEAN(IsOk)); + * return IsOk; + * } + * @endcode + * + * @sa TecUtilDataFaceMapCustomLOD(), TecUtilDataFaceMapGetClientData() + */ +typedef Boolean_t (STDCALL *LoadOnDemandFaceMapLoad_pf)(FaceMap_pa FaceMap); + +/** + * Callback responsible for performing private actions associated with a + * face mapping being unloaded using the private client data retrieved from the + * face mapping handle. Whenever possible the callback should honor Tecplot's + * request to unload the face mapping by returning TRUE. + * + * Most add-ons should simply supply NULL for this callback thereby instructing + * Tecplot to handle the unloading (and subsequent reloading) of the face mapping + * without the intervention of the add-on. + * + * @par Note: + * This callback is called asynchronously. All calls back to Tecplot through + * the TecUtil layer should be limited to queries. + * + * @since + * 11.2-1-0 + * + * @param FaceMap + * Face mapping handle of the face mapping Tecplot wants to unload. + * + * @code + * Boolean_t STDCALL MyFaceMapUnload(FaceMap_pa FaceMap) + * { + * REQUIRE(VALID_REF(FaceMap)); + * + * // We don't have any private data to cleanup (i.e in addition to the + * // private client data which we don't cleanup here) so all we have to do + * // is return TRUE or FALSE letting Tecplot know that it can or can not + * // unload the variable. + * Boolean_t Result = TRUE; // ...tell Tecplot to go ahead and unload the face mapping + * + * ENSURE(VALID_BOOLEAN(Result)); + * return Result; + * } + * @endcode + * + * @result + * TRUE if the face mapping can be unloaded, FALSE otherwise. The add-on should + * if at all possible honor the request to unload the face mapping. Most add-ons + * should return TRUE. + * + * @sa TecUtilDataFaceMapCustomLOD(), TecUtilDataFaceMapGetClientData() + */ +typedef Boolean_t (STDCALL *LoadOnDemandFaceMapUnload_pf)(FaceMap_pa FaceMap); + +/** + * Callback responsible for performing private actions associated with a + * face mapping being cleaned up using the private client data retrieved from the + * face mapping handle. Most add-ons will need to register this callback in order + * to cleanup privately allocated client data. + * + * @par Note: + * This callback is called asynchronously. All calls back to Tecplot through + * the TecUtil layer should be limited to queries. + * + * @since + * 11.2-1-0 + * + * @param FaceMap + * Face Mapping data handle of the face mapping being cleaned up. + * + * @code + * typedef struct + * { + * char *DataFileName; + * long SeekOffset; + * ... other information needed to load face map data + * } MyFaceMapClientData_s; + * + * void STDCALL MyFaceMapCleanup(FaceMap_pa FaceMap) + * { + * REQUIRE(VALID_REF(FaceMap)); + * + * MyFaceMapClientData_s *MyClientData = (MyFaceMapClientData_s *)TecUtilDataFaceMapGetClientData(FaceMap); + * + * // cleanup privately allocated resources + * free(MyClientData->DataFileName); + * free(MyClientData); + * } + * @endcode + * + * @sa TecUtilDataFaceMapCustomLOD(), TecUtilDataFaceMapGetClientData() + */ +typedef void (STDCALL *LoadOnDemandFaceMapCleanup_pf)(FaceMap_pa FaceMap); + + +/** + * ExtractDestination functions are called upon successful completion of an + * extract polyline or extract discrete points operation. + * + * @param NumPts + * Number of points extracted. + * + * @param XValues + * Double precision array of X-Coordinates of the extracted polyline. + * + * @param YValues + * Double precision array of Y-Coordinates of the extracted polyline. + * + * + * INTEGER*4 FUNCTION MyExtractDestinationCallback( + * & NumPts, + * & XValues, + * & YValues) + * INTEGER*4 NumPts + * REAL*8 XValues + * REAL*8 YValues + * + */ +typedef void (STDCALL *ExtractDestination_pf)(LgIndex_t NumPts, + double* XValues, + double* YValues); + + + +/** + * SelectFileOptionsCallback Functions are called when the + * "Options" button is pressed in the modal file selection + * dialog. + * + * + * SUBROUTINE MySelectFileOptionsCallback() + * + */ +typedef void (STDCALL *SelectFileOptionsCallback_pf)(void); + + + + +/** + * Post data load instruction callback for "Converter-Plus" addons. + * + * @param PreviousInstructions + * The previous set of instructions used by the converter. + * + * @param PreviousRawData + * The previous raw data associated with the instructions. + * + * @param PreviousZones + * Set of zones loaded with the previous instructions. + * + * + * SUBROUTINE MyConverterPostReadCallback( + * & PreviousInstructions, + * & PreviousRawData, + * & PreviousZones) + * CHARACTER*(*) CommandString + * CHARACTER*(*) ErrMsgString + * POINTER (PreviousZones,DummyPreviousZonesData) + * + * + */ +typedef void (STDCALL *ConverterPostReadCallback_pf)(const char* PreviousInstructions, + const char* PreviousRawData, + const Set_pa PreviousZones); + + +/** + * Callback registered by your addon to convert a foreign datafile into a + * Tecplot Binary datafile format. + * + * @return + * Return TRUE if the conversion is successful. Otherwise return FALSE. + * If FALSE is returned then *MessageString is assumed to contain an error + * message. + * + * @param DataFName + * Name of the original foreign data file to be converted. + * + * @param TempBinFName + * Name of the temporary binary datafile that is created (by your converter). + * + * @param MessageString + * Reference to a string. If an error occurs during conversion allocate space + * for an error message and copy the message string into that allocated + * space otherwise be sure to assign *MessageString to NULL. If + * *MessageString is non NULL Tecplot will release the allocated memory when + * finished. + * + * + * INTEGER*4 FUNCTION MyDataSetConverterCallback( + * & DataFName, + * & TempBinFName, + * & MessageString) + * CHARACTER*(*) DataFName + * CHARACTER*(*) TempBinFName + * CHARACTER*(*) MessageString + * + * + */ +typedef Boolean_t (STDCALL *DataSetConverter_pf)(char* DataFName, + char* TempBinFName, + TP_GIVES char** MessageString); + + + + + + + +/** + * Callback registered by your addon to process foreign loader instructions. + * When called, it must parse the supplied instructions and load the data into Tecplot. + * + * @return + * Return TRUE if the data is loaded successfully. Otherwise, FALSE. + * + * @param Instructions + * This contains all of the instructions needed to load the data. + * + * + * + * INTEGER*4 FUNCTION MyDataSetLoaderCallback( + * & Instructions) + * POINTER (Instructions,DummyInstructionsData) + * + */ +typedef Boolean_t (STDCALL *DataSetLoader_pf)(StringList_pa Instructions); + + + + + +/** + * Callback used to provide the ability to override data loader instructions + * while processing a layout. + * + * @return + * Return TRUE if the instructions are successfully replaced or left alone. + * Return FALSE if the user cancels the operation. + * + * @param Instructions + * The original instructions needed to load the data. + * + * + * INTEGER*4 FUNCTION MyDataSetLoaderInstOverCallback( + * & Instructions) + * POINTER (Instructions,DummyInstructionsData) + * + * + */ +typedef Boolean_t (STDCALL *DataSetLoaderInstructionOverride_pf)(StringList_pa Instructions); + + + +/** + * Callback used to assign extended curve settings. + * This is called when the user presses the "Curve Settings" + * button in the mapping style dialog. + * + * @param LineMapSet + * Set of line maps currently selected. + * @param SelectedLineMapSettings + * A string list of the curve settings for the Line-maps that are selected in the + * Line mappings dialog. + * + * + * SUBROUTINE MyGetCurveSettingsCallback( + * & LineMapSet, + * & SelectedLineMapSettings) + * POINTER (LineMapSet,DummyLineMapData) + * POINTER (SelectedLineMapSettings,DummyLineMapSettings) + * + */ +typedef void (STDCALL *GetCurveSettingsCallback_pf)(Set_pa LineMapSet, + StringList_pa SelectedLineMapSettings); + + + + +/** + * Callback function that returns an abbreviated version of the curve settings + * for a particular Line Map for display in the Line Mappings dialog. + * + * @param LineMap + * The map number that is currently being operated on. + * @param CurveSettings + * The string that Tecplot maintains which contains the extended curve fit + * settings for the current Line-map. This argument may be NULL indicating + * that defaults should be used. + * @param AbbreviatedSettings + * The short form of the CurveSettings that is allocated and returned from + * your function and used by Tecplot. This must be allocated by the addon + * using TecUtilStringAlloc(). + * + * + * SUBROUTINE MyGetAbrevSettingsStringCallback( + * & LineMap, + * & CurveSettings, + * & AbbreviatedSettings), + * INTEGER*4 LineMap + * CHARACTER*(*) CurveSettings + * CHARACTER*(*) AbbreviatedSettings + * + */ +typedef void (STDCALL *GetAbbreviatedSettingsStringCallback_pf)(EntIndex_t LineMap, + char* CurveSettings, + TP_GIVES char** AbbreviatedSettings); + + + + +/** + * This function returns a string (CurveInfoString) for Tecplot to display + * information about a particular curve in the curve info dialog. + * + * @param RawIndV + * The handle to the raw field data of the independent variable. + * @param RawDepV + * The handle to the raw field data of the dependent variable. + * @param IndVCoordScale + * An enumerated variable whose values are Scale_linear when the independent variable + * axis has a linear scale and Scale_log when it has a log scale. + * @param DepVCoordScale + * An enumerated variable whose values are Scale_linear when the dependent variable axis + * has a linear scale and Scale_log when it has a log scale. + * @param NumRawPts + * number of raw field data values. + * @param LineMap + * The map number that is currently being operated on. + * @param CurveSettings + * The curve settings string for the current Line-map. This argument may be + * NULL indicating that defaults should be used. + * @param CurveInfoString + * The string that is allocated and returned by your function and be + * presented in the Data/XY-Plot Curve Info dialog. The CurveInfoString must + * be allocated by the addon using TecUtilStringAlloc(). + * + * @return + * Return TRUE if the curve info string can be generated, otherwise FALSE. + * + * + * INTEGER*4 FUNCTION MyGetCurveInfoStringCallback( + * & RawIndV, + * & RawDepV, + * & IndVCoordScale, + * & DepVCoordScale, + * & NumRawPts, + * & LineMap, + * & CurveSettings, + * & CurveInfoString) + * POINTER (RawIndV,DummyRawIndVData) + * POINTER (RawDepV,DummyRawDepVData) + * INTEGER*4 IndVCoordScale + * INTEGER*4 DepVCoordScale + * INTEGER*4 NumRawPts + * INTEGER*4 LineMap + * CHARACTER*(*) CurveSettings + * CHARACTER*(*) CurveInfoString + * + */ +typedef Boolean_t (STDCALL *GetCurveInfoStringCallback_pf)(FieldData_pa RawIndV, + FieldData_pa RawDepV, + CoordScale_e IndVCoordScale, + CoordScale_e DepVCoordScale, + LgIndex_t NumRawPts, + EntIndex_t LineMap, + char* CurveSettings, + TP_GIVES char** CurveInfoString); + +/** + * Callback function used to calculate data points for an extended curve fit. + * + * @return + * Return TRUE if the curve can be calculated, otherwise FALSE. + * + * @param RawIndV + * The handle to the raw field data of the independent variable. + * @param RawDepV + * The handle to the raw field data of the dependent variable. + * @param IndVCoordScale + * An enumerated variable whose values are Scale_linear when the independent variable + * axis has a linear scale and Scale_log when it has a log scale. + * @param DepVCoordScale + * An enumerated variable whose values are Scale_linear when the dependent variable axis + * has a linear scale and Scale_log when it has a log scale. + * @param NumRawPts + * number of raw field data values. + * @param NumCurvePts + * The number of points that will construct the curve fit. + * @param LineMap + * The line map to operated on. + * @param CurveSettings + * The curve settings string for the current Line-map. This argument may be + * NULL indicating that defaults should be used. + * @param IndCurveValues + * A pre-allocated array of size NumCurvePts which the addon will populate with + * the independent values for the curve fit + * @param DepCurveValues. + * A pre-allocated array of size NumCurvePts which the add-on will populate + * with the dependent values for the curve fit. + * + * + * INTEGER*4 FUNCTION MyGetLinePlotDataPointsCallback( + * & RawIndV, + * & RawDepV, + * & IndVCoordScale, + * & DepVCoordScale, + * & NumRawPts, + * & NumCurvePts, + * & LineMap, + * & CurveSettings, + * & IndCurveValues, + * & DepCurveValues) + * POINTER (RawIndV,DummyRawIndVData) + * POINTER (RawDepV,DummyRawDepVData) + * INTEGER*4 IndVCoordScale + * INTEGER*4 DepVCoordScale + * INTEGER*4 NumRawPts + * INTEGER*4 NumCurvePts + * INTEGER*4 LineMap + * CHARACTER*(*) CurveSettings + * REAL*8 IndCurveValues() + * REAL*8 DepCurveValues() + * + */ +typedef Boolean_t (STDCALL *GetLinePlotDataPointsCallback_pf)(FieldData_pa RawIndV, + FieldData_pa RawDepV, + CoordScale_e IndVCoordScale, + CoordScale_e DepVCoordScale, + LgIndex_t NumRawPts, + LgIndex_t NumCurvePts, + EntIndex_t LineMap, + char* CurveSettings, + TP_OUT double* IndCurveValues, + TP_OUT double* DepCurveValues); +#if defined EXPORT_DEPRECATED_INTERFACES_TO_ADK_ONLY +/** + * @deprecated + * Please use \ref GetLinePlotDataPointsCallback_pf instead. + */ +typedef GetLinePlotDataPointsCallback_pf GetXYDataPointsCallback_pf; +#endif + + + + +/** + * A Callback function used to obtain an interpolated dependent value for an + * extended curve fit given an independent value. + * + * @return + * Return TRUE if it is possible to obtain the interpolated value, otherwise FALSE. + * + * @param RawIndV + * handle to the raw field data of the independent variable. + * @param RawDepV + * The handle to the raw field data of the dependent variable. + * @param IndVCoordScale + * An enumerated variable whose values are Scale_linear when the independent variable + * axis has a linear scale and Scale_log when it has a log scale. + * @param DepVCoordScale + * An enumerated variable whose values are Scale_linear when the dependent variable axis + * has a linear scale and Scale_log when it has a log scale. + * @param NumRawPts + * The number of field data values. + * @param NumCurvePts + * The number of points used to construct the curve fit. + * @param LineMapNum + * The line map number currently being operated on. + * @param CurveSettings + * The curve settings string for the current Line-map. This argument may be + * NULL indicating that defaults should be used. + * @param ProbeIndValue + * The independent value location of the probe (supplied). + * @param ProbeDepValue + * Reference to the calculated dependent value location of the probe. + * + * + * INTEGER*4 FUNCTION MyGetProbeValueCallback( + * & RawIndV, + * & RawDepV, + * & IndVCoordScale, + * & DepVCoordScale, + * & NumRawPts, + * & NumCurvePts, + * & LineMapNum, + * & CurveSettings, + * & CurveInfoString, + * & ProbeIndValue, + * & ProbeDepValue) + * POINTER (RawIndV,DummyRawIndVData) + * POINTER (RawDepV,DummyRawDepVData) + * INTEGER*4 IndVCoordScale + * INTEGER*4 DepVCoordScale + * INTEGER*4 NumRawPts + * INTEGER*4 NumCurvePts + * INTEGER*4 LineMapNum + * CHARACTER*(*) CurveSettings + * REAL*8 ProbeIndValue + * REAL*8 ProbeDepValue + * + * + */ +typedef Boolean_t (STDCALL *GetProbeValueCallback_pf)(FieldData_pa RawIndV, + FieldData_pa RawDepV, + CoordScale_e IndVCoordScale, + CoordScale_e DepVCoordScale, + LgIndex_t NumRawPts, + LgIndex_t NumCurvePts, + EntIndex_t LineMapNum, + char* CurveSettings, + double ProbeIndValue, + TP_OUT double* ProbeDepValue); + + + +#if defined MSWIN +typedef Boolean_t (STDCALL *PreTranslateMessage_pf)(MSG *pMsg); +#endif + + +/** + * Callback function pointer for providing a Dynamic Axis labels. + * @since + * 10.0-6-015 + * @param Value + * Value that corresponds to a tick label that will be drwan. + * + * @param ClientData + * Convenience storage of user client data. + * + * @param LabelString + * Output label for the tick mark. + * This must be allocated by the addon using TecUtilStringAlloc(). + * + * @return + * Returns TRUE if the LabelString has been successfully allocated. + * Otherwise, FALSE is returned. + */ +typedef Boolean_t (STDCALL *DynamicLabelCallback_pf)(double Value, + ArbParam_t ClientData, + TP_GIVES char** LabelString); + +/** + * This is called when Tecplot is idle. + * + * @par Note: + * Tecplot is never idle when running in batch mode (with the -b flag). + * + * @param ClientData + * Arbitrary client data. + * + * + * INTEGER*4 FUNCTION MyOnIdleCallback( + * & ClientDataPtr) + * POINTER (ClientDataPtr,DummyClientData) + * + * + */ +typedef void (STDCALL *OnIdleCallback_pf)(ArbParam_t ClientData); + +/** + * Callback responsible for executing the specified script file. + * + * @since + * 11.0-2-005 + * + * @param ScriptFileName + * Relative or absolute file name of the script to execute. If the path + * is relative it is relative to the current working directory. + * @param ClientData + * Client data registered with the callback. + * + * @return + * TRUE if the script executed successfully, FALSE otherwise. + * + * @sa TecUtilScriptExecRegisterCallback + */ +typedef Boolean_t (STDCALL *ScriptExecCallback_pf)(const char *ScriptFileName, + ArbParam_t ClientData); + +/* BEGINREMOVEFROMADDON */ +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if 0 /* NOTUSED */ +#endif +#if !defined NO_ASSERTS +#endif +#if defined MSWIN +#endif /* MSWIN */ +#if !defined (MSWIN) +#endif +#if defined Q_MAINMODULE +#else +#endif +#if 0 /* NOTUSED */ +#endif +#endif /* TECPLOTKERNEL */ + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ + + +/* ENDREMOVEFROMADDON */ +struct _ViewState_a; +typedef struct _ViewState_a *SavedView_pa, *ViewState_pa; + + +#endif /* _GLOBAL_H */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/INPUT.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/INPUT.h new file mode 100644 index 0000000000..d778ee5984 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/INPUT.h @@ -0,0 +1,196 @@ +/* + * 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/ + * + */ +/* +***************************************************************** +***************************************************************** +******* ******** +****** Copyright (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +***************************************************************** +***************************************************************** +*/ +#if defined EXTERN +#undef EXTERN +#endif +#if defined INITMODULE +#define EXTERN +#else +#define EXTERN extern +#endif + +/* Input Specification limits */ + +/* General */ +EXTERN InputSpec_s /*X*/ GridCoordInputSpec; +EXTERN InputSpec_s /*X*/ GridCoordFloatInputSpec; +EXTERN InputSpec_s /*X*/ XFrameCoordInputSpec; +EXTERN InputSpec_s /*X*/ YFrameCoordInputSpec; +EXTERN InputSpec_s /*X*/ XFrameCoordFloatInputSpec; +EXTERN InputSpec_s /*X*/ YFrameCoordFloatInputSpec; +EXTERN InputSpec_s /*X*/ XFrameCoordDeltaInputSpec; +EXTERN InputSpec_s /*X*/ YFrameCoordDeltaInputSpec; +EXTERN InputSpec_s /*X*/ XFrameCoordFloatDeltaInputSpec; +EXTERN InputSpec_s /*X*/ YFrameCoordFloatDeltaInputSpec; +EXTERN InputSpec_s /*X*/ FrameOffsetCoordInputSpec; +EXTERN InputSpec_s /*X*/ XPaperCoordInputSpec; +EXTERN InputSpec_s /*X*/ YPaperCoordInputSpec; +EXTERN InputSpec_s /*X*/ AxisPercentageInputSpec; +EXTERN InputSpec_s /*X*/ AngleInputSpec; +EXTERN InputSpec_s /*X*/ AngleToApproxInputSpec; +EXTERN InputSpec_s /*X*/ FieldOfViewInputSpec; +EXTERN InputSpec_s /*X*/ ZeroAndAboveLgIndexInputSpec; +EXTERN InputSpec_s /*X*/ ZeroAndAboveSmIntegerInputSpec; +EXTERN InputSpec_s /*X*/ ZeroAndAboveDoubleInputSpec; +EXTERN InputSpec_s /*X*/ AboveZeroLgIndexInputSpec; +EXTERN InputSpec_s /*X*/ AboveZeroDoubleInputSpec; +EXTERN InputSpec_s /*X*/ DoubleInputSpec; +EXTERN InputSpec_s /*X*/ EntIndexInputSpec; +EXTERN InputSpec_s /*X*/ EntRangeInputSpec; +EXTERN InputSpec_s /*X*/ IndexRangeInputSpec; +EXTERN InputSpec_s /*X*/ AboveZeroIndexRangeInputSpec; +EXTERN InputSpec_s /*X*/ ZeroToOneInputSpec; +EXTERN InputSpec_s /*X*/ PercentageInputSpec; +EXTERN InputSpec_s /*X*/ AboveZeroPercentageInputSpec; +EXTERN InputSpec_s /*X*/ SignedPercentageInputSpec; +EXTERN InputSpec_s /*X*/ RadiansInputSpec; +EXTERN InputSpec_s /*X*/ AboveZeroRadiansInputSpec; +EXTERN InputSpec_s /*X*/ TimeDateDoubleInputSpec; +EXTERN InputSpec_s /*X*/ AboveZeroTimeDateDoubleInputSpec; +EXTERN InputSpec_s /*X*/ AboveZeroElapsedTimeInputSpec; + + +/* Specific */ +#define MIN_VIEWPORT_SIZE 0.05 +EXTERN InputSpec_s /*X*/ SurfaceTranslucencyInputSpec; +EXTERN InputSpec_s /*X*/ MaxDepthBufferSizeInputSpec; +EXTERN InputSpec_s /*X*/ MaxMultiSamplesInputSpec; +EXTERN InputSpec_s /*X*/ MinBitsPerRGBPlaneInputSpec; +EXTERN InputSpec_s /*X*/ AnimationSpeedInputSpec; +EXTERN InputSpec_s /*X*/ AnimationNumStepsInputSpec; +EXTERN InputSpec_s /*X*/ MaxCustomColorsInInterfaceInputSpec; +EXTERN InputSpec_s /*X*/ MaxReducedPointsInputSpec; +EXTERN InputSpec_s /*X*/ MaxStripLengthInputSpec; +EXTERN InputSpec_s /*X*/ MaxPrimativesPerBlockInputSpec; +EXTERN InputSpec_s /*X*/ MaxTextureSizeInputSpec; +EXTERN InputSpec_s /*X*/ SuperSampleFactorInputSpec; +EXTERN InputSpec_s /*X*/ TickLengthInputSpec; +EXTERN InputSpec_s /*X*/ BorrowLicenseInputSpec; + + + + +/* I/O Related */ +EXTERN InputSpec_s /*X*/ HardcopyPaperSizeInputSpec; +EXTERN InputSpec_s /*X*/ HardcopyNumCopiesInputSpec; +EXTERN InputSpec_s /*X*/ HardcopyPrecisionInputSpec; +EXTERN InputSpec_s /*X*/ HardcopyPenSpeedInputSpec; +EXTERN InputSpec_s /*X*/ PenPlotterPenNumberInputSpec; +EXTERN InputSpec_s /*X*/ BitDumpDepthInputSpec; + + +/* Widths, physical lengths, etc. */ +EXTERN InputSpec_s /*X*/ XFrameDimensionInputSpec; +EXTERN InputSpec_s /*X*/ YFrameDimensionInputSpec; +EXTERN InputSpec_s /*X*/ LineThicknessInputSpec; +EXTERN InputSpec_s /*X*/ PatternLengthInputSpec; +EXTERN InputSpec_s /*X*/ AxisPercentageTextSizeInputSpec; +EXTERN InputSpec_s /*X*/ FrameTextSizeInputSpec; +EXTERN InputSpec_s /*X*/ GridTextSizeInputSpec; +EXTERN InputSpec_s /*X*/ PointTextSizeInputSpec; +EXTERN InputSpec_s /*X*/ TextBoxMarginInputSpec; +EXTERN InputSpec_s /*X*/ TextLineSpacingInputSpec; +EXTERN InputSpec_s /*X*/ ArrowheadSizeInputSpec; +EXTERN InputSpec_s /*X*/ AxisLabelOffsetInputSpec; +EXTERN InputSpec_s /*X*/ LegendLineSpacingInputSpec; +EXTERN InputSpec_s /*X*/ StreamStepSizeInputSpec; +EXTERN InputSpec_s /*X*/ StreamMaxStepsInputSpec; +EXTERN InputSpec_s /*X*/ ArrowheadSpacingInputSpec; +EXTERN InputSpec_s /*X*/ RulerPaddingInputSpec; +EXTERN InputSpec_s /*X*/ RulerThicknessInputSpec; +EXTERN InputSpec_s /*X*/ PickHandleWidthInputSpec; +EXTERN InputSpec_s /*X*/ ImageDimensionInputSpec; +EXTERN InputSpec_s /*X*/ ZoomScalePerFrameUnitInputSpec; +EXTERN InputSpec_s /*X*/ RGBLegendHeightInputSpec; + + + +/* Limit the number of objects or limit which object can be selected*/ +EXTERN InputSpec_s /*X*/ ColorMapGroupInputSpec; +EXTERN InputSpec_s /*X*/ SliceGroupInputSpec; +EXTERN InputSpec_s /*X*/ IsoSurfaceGroupInputSpec; +EXTERN InputSpec_s /*X*/ ContourGroupInputSpec; +EXTERN InputSpec_s /*X*/ ColorIndexInputSpec; +EXTERN InputSpec_s /*X*/ NumLightSourceShadesInputSpec; +EXTERN InputSpec_s /*X*/ NumberOfControlPointsInputSpec; +EXTERN InputSpec_s /*X*/ CustomLabelNumberInputSpec; +EXTERN InputSpec_s /*X*/ NumMinorTicksInputSpec; +EXTERN InputSpec_s /*X*/ AxisEdgeNumberInputSpec; +EXTERN InputSpec_s /*X*/ LineMapWhichXAxisInputSpec; +EXTERN InputSpec_s /*X*/ LineMapWhichYAxisInputSpec; +EXTERN InputSpec_s /*X*/ NumberOfCurvePointsInputSpec; +EXTERN InputSpec_s /*X*/ NumberOfContourLevelsInputSpec; +EXTERN InputSpec_s /*X*/ ColorMapOverrideLevelInputSpec; +EXTERN InputSpec_s /*X*/ ColorMapOverrideNumberInputSpec; +EXTERN InputSpec_s /*X*/ NumberOfColorMapCyclesInputSpec; +EXTERN InputSpec_s /*X*/ NumberOfRodPointsInputSpec; +EXTERN InputSpec_s /*X*/ NumberOfStreamtracesInputSpec; +EXTERN InputSpec_s /*X*/ NumberOfEllipsePointsInputSpec; +EXTERN InputSpec_s /*X*/ MaxPtsInALineInputSpec; +EXTERN InputSpec_s /*X*/ MaxChrsTextLabelsInputSpec; +EXTERN InputSpec_s /*X*/ MaxContourLevelsInputSpec; +EXTERN InputSpec_s /*X*/ MaxLinkGroupsInputSpec; + + +/* Ratios */ +EXTERN InputSpec_s /*X*/ DataAspectRatioLimitInputSpec; +EXTERN InputSpec_s /*X*/ DataAspectRatioResetInputSpec; +EXTERN InputSpec_s /*X*/ AxisBoxAspectRatioLimitInputSpec; +EXTERN InputSpec_s /*X*/ AxisBoxAspectRatioResetInputSpec; +EXTERN InputSpec_s /*X*/ AxisRatioInputSpec; +EXTERN InputSpec_s /*X*/ AxisBoxPaddingInputSpec; +EXTERN InputSpec_s /*X*/ ScreenDistanceRatioInputSpec; +EXTERN InputSpec_s /*X*/ LiftFractionInputSpec; +EXTERN InputSpec_s /*X*/ ZClipInputSpec; +EXTERN InputSpec_s /*X*/ VectorHeadSizeFractionInputSpec; + + +/* Misc */ +EXTERN InputSpec_s /*X*/ ValuePrecisionInputSpec; +EXTERN InputSpec_s /*X*/ PolynomialOrderInputSpec; +EXTERN InputSpec_s /*X*/ SplineSlopeInputSpec; +EXTERN InputSpec_s /*X*/ RotationStepSizeInputSpec; +EXTERN InputSpec_s /*X*/ SmoothRotationDegPerFrameUnitInputSpec; +EXTERN InputSpec_s /*X*/ TranslationStepSizeInputSpec; +EXTERN InputSpec_s /*X*/ ScaleStepSizeInputSpec; +EXTERN InputSpec_s /*X*/ SortLevelInputSpec; +EXTERN InputSpec_s /*X*/ AxisLabelSkipInputSpec; +EXTERN InputSpec_s /*X*/ TextAngleInputSpec; +EXTERN InputSpec_s /*X*/ ArrowheadAngleInputSpec; +EXTERN InputSpec_s /*X*/ MinCreaseAngleInputSpec; +EXTERN InputSpec_s /*X*/ ExponentInputSpec; +EXTERN InputSpec_s /*X*/ SmoothWeightInputSpec; +EXTERN InputSpec_s /*X*/ TriangleKeepFactorInputSpec; +EXTERN InputSpec_s /*X*/ PlotAttrColumnWidthInputSpec; +EXTERN InputSpec_s /*X*/ ImageQualityInputSpec; + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/MASTER.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/MASTER.h new file mode 100644 index 0000000000..38c495dcf8 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/MASTER.h @@ -0,0 +1,684 @@ +/* + * 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/ + * + */ +/***************************************************************** + ***************************************************************** + ******* ******** + ****** Copyright (C) 1988-2008 Tecplot, Inc. ******* + ******* ******** + ***************************************************************** + *****************************************************************/ +/* BEGINREMOVEFROMADDON */ +/* NOTE: All code contained between comments that look like + * BEGINREMOVEFROMADDON + * ENDREMOVEFROMADDON + * are pulled out to create the MASTER.h file used in addons. + */ +/* ENDREMOVEFROMADDON */ + +#ifndef _MASTER_H_ +#define _MASTER_H_ + +/* + * Annotations that specify the life cycle of objects returned from functions + * and input and output parameters sent as function parameters. The following + * table specifies the meaning in their context. The annotations provide code + * generation tools with information for building language bindings to various + * Tecplot 360 and Tecplot SDK related libraries. + * + * For purposes of this table the client is one making the call and the service + * is the recipient. + * + * +==================+=========================+=================================================================+ + * | Function Context | Annotation | Meaning | + * | Result or | | | + * | Parameter | | | + * |==================+=========================+=================================================================| + * | Result | TP_OUT | Default for a function return value that does not transfer | + * | | | ownership. Because this is the most common scenario this | + * | | | annotation is implied and never explicitly used in this | + * | | | context. | + * |------------------+-------------------------+-----------------------------------------------------------------| + * | Scalar Result | TP_GIVES | Annotates a function scalar return value as one who's ownership | + * | | | is transfered to the client. The client is responsible for | + * | | | properly disposing the value. | + * |------------------+-------------------------+-----------------------------------------------------------------| + * | Array Result | TP_ARRAY_GIVES | Annotates a function array return value as one who's ownership | + * | | | is transfered to the client. The client is responsible for | + * | | | properly disposing the value. | + * |==================+=========================+=================================================================| + * | Parameter | TP_IN | Default for a function input parameter value sent to the | + * | | | service. Because this is the most common scenario this | + * | | | annotation is implied and never explicitly used. | + * |------------------+-------------------------+-----------------------------------------------------------------| + * | Parameter | TP_ACQUIRES | Annotates a function parameter as one that sends a value to | + * | | | the service through the parameter and acquires shared | + * | | | ownership of the input value with the client. The service is | + * | | | not responsible for disposing the value however it is | + * | | | expected that a symmetric API exists that "releases" the | + * | | | library of this shared ownership. For example: | + * | | | void addListener(TP_ACQUIRES Listener& listener); | + * | | | void removeListener(TP_RELEASES Listener& listener); | + * |------------------+-------------------------+-----------------------------------------------------------------| + * | Parameter | TP_RELEASES | Annotates a function parameter as one that sends a value to | + * | | | the service through the parameter and releases previously | + * | | | shared ownership of the | + * | | | input value with the client. The service is not responsible | + * | | | for disposing the value however it is expected that a | + * | | | symmetric API exists that "releases" the library of this | + * | | | shared ownership. For example: | + * | | | void addListener(TP_ACQUIRES Listener& listener); | + * | | | void removeListener(TP_RELEASES Listener& listener); | + * |------------------+-------------------------+-----------------------------------------------------------------| + * | Scalar Parameter | TP_OUT | Annotates a function scalar parameter as one that returns a | + * | | | value to the client through the parameter but does not | + * | | | transfer ownership of the output value to the client. | + * | | | The client is not responsible for disposing the value. | + * |------------------+-------------------------+-----------------------------------------------------------------| + * | Scalar Parameter | TP_IN_OUT | Annotates a function scalar parameter as one that both sends | + * | | | a value to the service and returns a value to the client | + * | | | through the parameter. Ownership of the input value is not | + * | | | transfered to the service nor is ownership of the output value | + * | | | transfered to the client. The service is not responsible for | + * | | | disposing the input value and the client is not responsible | + * | | | for disposing the output value. | + * |------------------+-------------------------+-----------------------------------------------------------------| + * | Array Parameter | TP_ARRAY_OUT | Annotates a function array parameter as one that returns a | + * | | | value to the client through the parameter but does not | + * | | | transfer ownership of the output value to the client. | + * | | | The client is not responsible for disposing the value. | + * |------------------+-------------------------+-----------------------------------------------------------------| + * | Array Parameter | TP_ARRAY_IN_OUT | Annotates a function array parameter as one that both sends | + * | | | a value to the service and returns a value to the client | + * | | | through the parameter. Ownership of the input value is not | + * | | | transfered to the service nor is ownership of the output value | + * | | | transfered to the client. The service is not responsible for | + * | | | disposing the input value and the client is not responsible | + * | | | for disposing the output value. | + * |------------------+-------------------------+-----------------------------------------------------------------| + * | Scalar Parameter | TP_GIVES | Annotates a function scalar parameter as one that returns a | + * | | | value to the client through the parameter and transfers | + * | | | ownership of the output value to the client. The client is | + * | | | responsible for properly disposing the value. | + * |------------------+-------------------------+-----------------------------------------------------------------| + * | Scalar Parameter | TP_RECEIVES | Annotates a function scalar parameter as one that sends a value | + * | | | to the service through the parameter and transfers ownership | + * | | | of the input value to the service. The service is responsible | + * | | | for properly disposing the value. | + * |------------------+-------------------------+-----------------------------------------------------------------| + * | Scalar Parameter | TP_RECEIVES_GIVES | Annotates a function scalar parameter as one that both sends | + * | | | a value to the service and returns a value to the client | + * | | | through the parameter. Ownership of the input value is | + * | | | transfered to the service and ownership of the output value is | + * | | | transfered to the client. The service is responsible for | + * | | | properly disposing the input value and the client is | + * | | | responsible for properly disposing the output value. | + * |------------------+-------------------------+-----------------------------------------------------------------| + * | Array Parameter | TP_ARRAY_GIVES | Annotates a function array parameter as one that returns a | + * | | | value to the client through the parameter and transfers | + * | | | ownership of the output value to the client. The client is | + * | | | responsible for properly disposing the value. | + * |------------------+-------------------------+-----------------------------------------------------------------| + * | Array Parameter | TP_ARRAY_RECEIVES | Annotates a function array parameter as one that sends a value | + * | | | to the service through the parameter and transfers ownership | + * | | | of the input value to the service. The service is responsible | + * | | | for properly disposing the value. | + * |------------------+-------------------------+-----------------------------------------------------------------| + * | Array Parameter | TP_ARRAY_RECEIVES_GIVES | Annotates a function array parameter as one that both sends | + * | | | a value to the service and returns a value to the client | + * | | | through the parameter. Ownership of the input value is | + * | | | transfered to the service and ownership of the output value is | + * | | | transfered to the client. The service is responsible for | + * | | | properly disposing the input value and the client is | + * | | | responsible for properly disposing the output value. | + * |==================+===================+=======================================================================| + */ + +/* + * First check to make sure that our life-cycle keywords are not in conflict with any system defines. + */ +#if defined TP_ACQUIRES || \ + defined TP_RELEASES || \ + defined TP_OUT || \ + defined TP_IN_OUT || \ + defined TP_ARRAY_OUT || \ + defined TP_ARRAY_IN_OUT || \ + defined TP_GIVES || \ + defined TP_RECEIVES || \ + defined TP_RECEIVES_GIVES || \ + defined TP_ARRAY_GIVES || \ + defined TP_ARRAY_RECEIVES || \ + defined TP_ARRAY_RECEIVES_GIVES + #error "Tecplot's parameter life-cycle keywords are in direct conflict with other meanings." +#endif + +#if defined INCLUDE_OBJECT_LIFECYCLE_ANNOTATIONS + #define TP_ACQUIRES __attribute((gccxml("acquires","in"))) + #define TP_RELEASES __attribute((gccxml("releases","in"))) + #define TP_OUT __attribute((gccxml("out"))) + #define TP_IN_OUT __attribute((gccxml("in","out"))) + #define TP_ARRAY_OUT __attribute((gccxml("array","out"))) + #define TP_ARRAY_IN_OUT __attribute((gccxml("array","in","out"))) + #define TP_GIVES __attribute((gccxml("gives","out"))) + #define TP_RECEIVES __attribute((gccxml("receives","in"))) + #define TP_RECEIVES_GIVES __attribute((gccxml("receives","in","gives","out"))) + #define TP_ARRAY_GIVES __attribute((gccxml("array","gives","out"))) + #define TP_ARRAY_RECEIVES __attribute((gccxml("array","receives","in"))) + #define TP_ARRAY_RECEIVES_GIVES __attribute((gccxml("array","receives","in","gives","out"))) +#else + #define TP_ACQUIRES + #define TP_RELEASES + #define TP_OUT + #define TP_IN_OUT + #define TP_ARRAY_OUT + #define TP_ARRAY_IN_OUT + #define TP_GIVES + #define TP_RECEIVES + #define TP_RECEIVES_GIVES + #define TP_ARRAY_GIVES + #define TP_ARRAY_RECEIVES + #define TP_ARRAY_RECEIVES_GIVES +#endif + +/* BEGINREMOVEFROMADDON */ +#ifdef NO_ASSERTS /* obfuscate names */ +#define ShutDownLicensing FreeAllExtraMapData +#define ProcessYMapInXDirection +#endif /* NO_ASSERTS */ + + +/************************************** + * LICENSING + **************************************/ +#if defined TECPLOTKERNEL && !defined ENGINE +/* CORE SOURCE CODE REMOVED */ +#if defined FLEXLM && defined RLM +#endif +#if !defined FLEXLM && !defined RLM +#endif +#endif + +#include "stdafx.h" + +#if defined MSWIN +#include "W__BASE.h" +#endif + +#include +#include +#include +#include + +#include "TranslatedString.h" + +/* + * The following is a temporary fix for figuring out which product is + * running. In the future when Focus and 360 use the same code base, + * we will have to do this dynamically (either with flags on the compiler + * or variables within Tecplot). + */ +/* ENDREMOVEFROMADDON */ + +#if defined _WIN32 + +#if !defined TECPLOTKERNEL + +#if !defined MSWIN +#define MSWIN +#endif /* !MSWIN */ + +/* For the sake of some older add-ons, + defined _WINDOWS, WINDOWS, and WIN32 + New code should always use MSWIN */ + +#if !defined WINDOWS +#define WINDOWS +#endif /* WINDOWS */ + +#if !defined _WINDOWS +#define _WINDOWS +#endif /* !_WINDOWS */ + +#if !defined WIN32 +#define WIN32 +#endif /* !WIN32 */ + +#if defined _DEBUG +#if !defined DEBUG +#define DEBUG +#endif +#elif defined CHECKED_BUILD +#if defined NO_ASSERTS +#undef NO_ASSERTS +#endif +#if defined NDEBUG +#undef NDEBUG +#endif +#else /* RELEASE */ +#if !defined NDEBUG +#define NDEBUG +#endif +#if !defined NO_ASSERTS +#define NO_ASSERTS +#endif +#endif /* _DEBUG */ +#endif /* TECPLOTKERNEL */ + +#if _MSC_VER >= 1400 +#define VS_2005 /* Using VS2005 Compiler */ +#endif + +#if !defined TECPLOTKERNEL && defined VS_2005 +/* Suppress the warnings about the + deprecated c runtime functions. */ + +#if !defined _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE +#endif +#endif /* !TECPLOTKERNEL && VS_2005 */ + +#endif /* MSWIN */ + +#ifdef NDEBUG +# ifdef _DEBUG +# error "Both NDEBUG and _DEBUG defined" +# endif +#elif defined TECPLOTKERNEL +# ifndef _DEBUG +# define _DEBUG +# endif +#endif + +/* Now a requirement */ +#define USE_3D_HARDWARE + +#ifndef THREED +# define THREED +#endif + +#include +#include +#include + +#if defined QUICKDEMO +#define DEMO +#endif + +#if defined MicrosoftC +#define DOS +#endif + +#if defined CRAYX +#define CRAY +#endif + +#if defined IRISX +#define IRIS +#endif + +#if defined HPX +#define HPUX +#define HP +#endif + +#if defined IBMRS6000X +#define IBMRS6000 +#endif + +#if defined COMPAQALPHAX +#define COMPAQALPHA +#define COMPAQX +#define COMPAQ +#endif + +#if defined DECALPHAX +#define DECALPHA +#define DECX +#endif + +#if defined DECX +#define DEC +#endif + +#if defined SUNSOLARISX || defined SUNSOLARIS86X +#define SUNX +#endif + +#if defined SUNX +#define SUN +#endif + +#if defined IRISX || defined CRAYX || defined HPX || defined SUNX || defined CONVEXX +#define UNIXX +#define SYSV +#endif + +#if defined DECX || defined LINUX || defined IBMRS6000X || defined COMPAQX || defined DARWIN +#define UNIXX +#endif + +/* BEGINREMOVEFROMADDON */ +#include + + +/* A bit of OEM stuff */ +#define OEM_INVALID_CHECKSUM (LgIndex_t) -1 + +/* Hide the name of the checksum function */ +#if defined NDEBUG +# define DECRYPTTIMEDCODE FixupPlot +# define CHECKHASHEDCODE ExpandPlot +# define UPDATECLASSICOEMEHCKSUM ToggleQuadrants +# define UPDATEOEMCHECKSUM ComputeAngleFromQuatrant +# define InitOemSettings InitAngleQuatrantSettings +#endif + +#if defined MSWIN +#define USE_TRUETYPEFONTS +#endif +/* ENDREMOVEFROMADDON */ + +/* BEGINREMOVEFROMADDON */ + +#ifdef __cplusplus // STL + +#ifdef MSWIN + +#pragma warning(push, 1) /* warning disabling bellow doesn't actually have any effect on compiler warning. +* It appears that Microsft STL enables all the warning right back on. +* Therefore, the only way to hide them is to push existing warning level, +* lower the level for the time while STL headers are included and then restore + * previous warning level with a "pragma warning(pop)" + */ + +#pragma warning(disable: 4018) // signed/unsigned mismatch +#pragma warning(disable: 4100) // unreferenced formal parameter +#pragma warning(disable: 4146) // unary minus operator applied to unsigned type, + // result still unsigned +#pragma warning(disable: 4244) // 'conversion' conversion from 'type1' to 'type2', + // possible loss of data +#pragma warning(disable: 4245) // conversion from 'type1' to 'type2', signed/unsigned + // mismatch +#pragma warning(disable: 4511) // 'class' : copy constructor could not be generated +#pragma warning(disable: 4512) // 'class' : assignment operator could not be generated +#pragma warning(disable: 4663) // C++ language change: to explicitly specialize class + // template 'vector' +#pragma warning(disable: 4710) // 'function' : function not inlined +#pragma warning(disable: 4786) // identifier was truncated to 'number' characters + // in the debug information +#endif + +#ifdef MSWIN +#pragma warning(pop) //Restore old warning state. +#endif //MSWIN + +#endif //__cplusplus + + /* ENDREMOVEFROMADDON */ + +#ifdef MSWIN + /* BEGINREMOVEFROMADDON */ +#ifdef TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#ifdef _DEBUG +#endif +#endif /* TECPLOTKERNEL */ + /* ENDREMOVEFROMADDON */ + +#ifndef TECPLOTKERNEL +#if defined VS_2005 +#define Widget LONG_PTR /* correct for 32 & 64 bit builds */ +#else +#define Widget long +#endif +#endif + + + +#endif /* MSWIN */ + + +#if defined UNIXX && defined ENGINE + typedef void *Widget; +#endif + + +#include + +#if !defined SYSV && !defined MSWIN +#include +#endif + +#if defined (MicrosoftC) +#include +#define EXECOS +#ifndef FAR +#define FAR +#endif +#define VOID void +#endif + +#include +#include + +#if defined UNIXX +#if !defined ENGINE +#define X11 +#define MOTIF +#endif +#define FAR +#define NEAR +#include +#endif + +/* BEGINREMOVEFROMADDON */ +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if !defined THREADS_BY_PTHREADS && !defined THREADS_BY_WINAPI +#endif +#if defined THREADS_BY_PTHREADS +#endif +#endif +/* ENDREMOVEFROMADDON */ + +/* BEGINREMOVEFROMADDON */ +/* OPENGL currently a must have */ +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# if !defined ENGINE +# if defined UNIXX +# endif +# endif +#endif +/* ENDREMOVEFROMADDON */ +/* + * If not building the tecplot kernel then at least + * include the X Instrinsics. This will make most + * development for addons etc work. + */ + +/* NOTE: MOTIF not defined if ENGINE is defined */ +#if defined MOTIF +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# if XmVERSION == 1 && XmREVISION == 0 +# endif +# else +# include +# endif +#endif + +#if defined MOTIF +#define CREATE_DIALOG_PARAMS Widget W +typedef Widget ComboBoxWidget_t; +typedef Widget DropDownListWidget_t; +typedef Widget FileDialogWidget_t; +typedef Widget LabelWidget_t; +typedef Widget ListWidget_t; +typedef Widget OptionMenuWidget_t; +typedef Widget PullDownMenuWidget_t; +typedef Widget ScaleWidget_t; +typedef Widget TextFieldWidget_t; +typedef Widget ToggleWidget_t; +typedef Widget ButtonWidget_t; +typedef Widget GridWidget_t; +#endif +#if defined MSWIN +#include +#define CREATE_DIALOG_PARAMS CWnd *, LaunchDialogMode_e +typedef Widget ComboBoxWidget_t; +typedef Widget DropDownListWidget_t; +typedef Widget FileDialogWidget_t; +typedef Widget LabelWidget_t; +typedef Widget ListWidget_t; +typedef Widget OptionMenuWidget_t; +typedef Widget PullDownMenuWidget_t; +typedef Widget ScaleWidget_t; +typedef Widget TextFieldWidget_t; +typedef Widget ToggleWidget_t; +typedef Widget ButtonWidget_t; +typedef Widget GridWidget_t; +#endif + +/* BEGINREMOVEFROMADDON */ +#if defined MSWIN && defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if defined TRACE +#endif +#if defined TRACE0 +#endif +#if defined TRACE1 +#endif +#if defined TRACE2 +#endif +#if defined TRACE3 +#endif +#if defined NDEBUG +#else +#endif +#endif /* MSWIN */ + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ +/* ENDREMOVEFROMADDON */ + +/* Assume that if TRACE is not defined, then none of the TRACE macros are */ +#if !defined (TRACE) +/* TRACE is not used by non-debug builds */ +#if defined NDEBUG +#if defined MSWIN +#define TRACE __noop +#define TRACE0(s) __noop +#define TRACE1(S,a1) __noop +#define TRACE2(s,a1,a2) __noop +#define TRACE3(s,a1,a2,a3) __noop +#else +#define TRACE(str) ((void)0) +#define TRACE0(str) ((void)0) +#define TRACE1(str,a1) ((void)0) +#define TRACE2(str,a1,a2) ((void)0) +#define TRACE3(str,a1,a2,a3) ((void)0) +#endif /* MSWIN */ +#else /* DEBUG */ +#if defined MSWIN +/* If the add-on is running in debug mode but does not + * use MFC, then no TRACE macro is available. Thus, to make tracing available, + * map TRACE to the win32 OutpuDebugString() function. + */ +# define TRACE(str) do { OutputDebugStringA(str); } while (0) +# define TRACE1(str,a1) do { char s[5000]; sprintf(s,str,a1); OutputDebugStringA(s); } while (0) +# define TRACE2(str,a1,a2) do { char s[5000]; sprintf(s,str,a1,a2); OutputDebugStringA(s); } while (0) +# define TRACE3(str,a1,a2,a3) do { char s[5000]; sprintf(s,str,a1,a2,a3); OutputDebugStringA(s); } while (0) +# define TRACE0(str) TRACE(str) +#else +#define TRACE printf +#define TRACE0 printf +#define TRACE1 printf +#define TRACE2 printf +#define TRACE3 printf +#endif /* MSWIN */ +#endif /* NDEBUG */ +#endif /* !defined (TRACE) */ + + +/* + Platform independent way for add-ons to know how much space + to allocate for a filename. +*/ +#if !defined MAX_SIZEOFUTF8CHAR +#define MAX_SIZEOFUTF8CHAR 1 +#endif + +#if !defined (MaxCharsFilePath) +# if defined (MSWIN) +# define MaxCharsFilePath (_MAX_PATH*MAX_SIZEOFUTF8CHAR+1) /* Includes traling '\0' */ +# else +# define MaxCharsFilePath 2047 /* ...not really a hard limit for Linux/Unix */ +# endif /* MSWIN */ +#endif /* !MaxCharsFilePath */ + +/* BEGINREMOVEFROMADDON */ + +/* + * Under Windows, if we are doing a release build (NDEBUG) that is not a CHECKED_BUILD + * then NO_ASSERTS should be defined + */ +#if defined MSWIN && defined NDEBUG && !defined NO_ASSERTS && !defined CHECKED_BUILD +/* intentionally break the compile */ +# error "define NO_ASSERTS for release builds" +#endif + +/* + * Under Windows, if we are doing a CHECKED_BUILD then it should + * also be a release build (NDEBUG) + */ +#if defined MSWIN && defined CHECKED_BUILD && !defined NDEBUG +# error "CHECKED_BUILDS must also be release builds" +#endif + + +#if defined NO_ASSERTS +# define USE_MACROS_FOR_FUNCTIONS +#endif +/* ENDREMOVEFROMADDON */ + +/* BEGINREMOVEFROMADDON */ +/* + * Under Linux the definition of NULL has a cast that conflicts with our own + * casting causing warnings that make it tough to find real problems. + */ +#if defined LINUX && defined NULL +# undef NULL +# define NULL 0 +#endif + +/* + */ +#if !defined MSWIN && !defined ENGINE && !defined ISMESA +#define DISALLOW_OFFSCREEN_EXPORT_IN_BATCH +#endif + +/* ENDREMOVEFROMADDON */ + +#endif /* _MASTER_H_ */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Make/files b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Make/files new file mode 100644 index 0000000000..084478a07a --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Make/files @@ -0,0 +1,21 @@ +alloc.cpp +arrlist.cpp +auxdata.cpp +dataio4.cpp +dataio.cpp +dataset0.cpp +dataset.cpp +datautil.cpp +filestream.cpp +geom2.cpp +q_msg.cpp +q_unicode.cpp +set.cpp +strlist.cpp +strutil.cpp +tassert.cpp +tecxxx.cpp +TranslatedString.cpp + +LIB = $(FOAM_LIBBIN)/libtecio + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Make/options b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Make/options new file mode 100644 index 0000000000..a355d90c5e --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Make/options @@ -0,0 +1,7 @@ +#include "tecioOptions" + +EXE_INC = \ + $(TECIO_FLAGS) $(TECIO_INC) + +LIB_LIBS = \ + $(TECIO_LIBS) diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Make/tecioOptions b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Make/tecioOptions new file mode 100644 index 0000000000..f8dcf48759 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Make/tecioOptions @@ -0,0 +1,20 @@ +#if defined(linux64) + + TECIO_FLAGS = -DMAKEARCHIVE -DLINUX -DLINUX64 -DUSEENUM -DTHREED -U_WIN32 + +#elif defined(linuxIA64) + + TECIO_FLAGS = -DMAKEARCHIVE -DLINUX -DLINUXI64 -DUSEENUM -DTHREED -U_WIN32 + +#elif defined(linux) + + TECIO_FLAGS = -DMAKEARCHIVE -DLINUX -DUSEENUM -DTHREED -U_WIN32 + +#else + +# error architecture not supported for compiling tecio. + +#endif + +TECIO_INC = +TECIO_LIBS = diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Q_MSG.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Q_MSG.h new file mode 100644 index 0000000000..84f1d1af76 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Q_MSG.h @@ -0,0 +1,72 @@ +/* + * 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/ + * + */ +#ifndef Q_MSG_H +#define Q_MSG_H +/* +****************************************************************** +****************************************************************** +******* ******** +****** (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +****************************************************************** +****************************************************************** +*/ +#if defined EXTERN +#undef EXTERN +#endif +#if defined Q_MSGMODULE +#define EXTERN +#else +#define EXTERN extern +#endif + +#define MAX_STATUS_LINE_MSG_LEN 255 + +#include "TranslatedString.h" + +EXTERN Boolean_t WrapString(const char *OldString, + char **NewString); +EXTERN void Warning(tecplot::strutil::TranslatedString Format, + ...); /* zero or more arguments */ +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif +EXTERN void ErrMsg(tecplot::strutil::TranslatedString Format, + ...); /* zero or more arguments */ +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if !defined ENGINE +#endif +#if !defined ENGINE +#if defined MOTIF +#endif +#endif +#if !defined ENGINE +#endif +#if defined Q_MSGMODULE +#else +#endif +#endif // TECPLOTKERNEL + +#endif // Q_MSG_H diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Q_UNICODE.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Q_UNICODE.h new file mode 100644 index 0000000000..b91c2ca65e --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/Q_UNICODE.h @@ -0,0 +1,93 @@ +/* + * 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/ + * + */ +/* +****************************************************************** +****************************************************************** +******* ******** +****** (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +****************************************************************** +****************************************************************** +*/ + + +#if !defined Q_UNICODE_H_ +# define Q_UNICODE_H_ + +#if defined EXTERN +#undef EXTERN +#endif +#if defined Q_UNICODEMODULE +#define EXTERN +#else +#define EXTERN extern +#endif + +namespace tecplot +{ +namespace strutil +{ + +// functions +Boolean_t IsValidUtf8LeadByte(Byte_t ch); +Boolean_t IsValidUtf8ContinuingByte(Byte_t ch); +Boolean_t IsValidUtf8Byte(Byte_t ch); + +Boolean_t IsValidUtf8String(const char *str); +Boolean_t ShouldConvertWideStringToUtf8String(const wchar_t *str); +void InitTranslatedStrings(); +void CleanUpTranslatedStrings(); + +Boolean_t IsNullOrZeroLengthString(const char *S); +Boolean_t IsNullOrZeroLengthString(tecplot::strutil::TranslatedString TS); + +Boolean_t IsEmptyString(const char *S); +Boolean_t IsEmptyString(tecplot::strutil::TranslatedString S); +Boolean_t IsEmptyString(const wchar_t* S); + +#if defined MSWIN + +std::string LookUpTranslation(std::string& strEnglish); +void MsWinInitTranslatedStrings(); + +std::string WStringToString(std::wstring str); +std::wstring StringToWString(std::string str); + +std::wstring MultiByteToWideChar(const char *Utf8Str, + unsigned int CodePage); + +std::string WideCharToMultiByte(const wchar_t *WideStr, + unsigned int CodePage); + +// Conversion +std::string WideCharToUtf8(const wchar_t* str); +std::wstring Utf8ToWideChar(const char *str); +char *getenv(const char *str); + +#endif + +} +} + +#endif diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/SET.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/SET.h new file mode 100644 index 0000000000..2ab99f64a0 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/SET.h @@ -0,0 +1,283 @@ +/* + * 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/ + * + */ +#if defined EXTERN +#undef EXTERN +#endif +#if defined SETMODULE +#define EXTERN +#else +#define EXTERN extern +#endif + +#ifndef _SET_H_INCLUDED +#define _SET_H_INCLUDED + +/* +***************************************************************** +***************************************************************** +******* ******** +****** Copyright (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +***************************************************************** +***************************************************************** +*/ + +#define PadOut(X,Y) ((int)(((X)-1)/(Y)+1)*(Y)) +#define SetBitSize (8*sizeof(SetData_t)) +#define SetLastBit (((unsigned long)1)<<(SetBitSize-1)) + +#if defined _DEBUG +# define USE_FUNCTIONS_FOR_SETS +#endif + +/* * + * * NOTE: "Set_pa" is a pointer to an "abstract type", + * * hence the "_pa". Pointer here is akin to "handle". + * * Any routines dealing with the internals of Set_pa + * * or Set_a must be in the same file as these routines + * */ + +/* Set_a is intentionally not defined to further + * deter usage of this private structure */ +struct _Set_a +{ + /* * PRIVATE * */ + SetIndex_t size; + SetData_pt data; +}; + +/* + * Checks set for NULL. + */ +#define IsSetNull(Set) ((Set)==NULL) + +/** + * Indicates how many bytes are required to store the set data. + */ +inline size_t SetDataSizeInBytes(Set_pa Set) +{ + REQUIRE(VALID_REF(Set)); + return Set->size / SetBitSize * sizeof(SetData_t); +} + +/* + * Allocates a new empty set. Returns NULL if not enough memory. + */ +EXTERN Set_pa AllocSet(Boolean_t show_error_msg); + +/* + * Frees all memory associated with set "*set", and + * sets "*set" to NULL. + */ +EXTERN void DeallocSet(Set_pa *Set); + +/** + * This function adapts the DeallocSet function to work with the + * ArrayList's deallocation callback. + */ +EXTERN Boolean_t SetItemDestructor(void *ItemRef, + ArbParam_t ClientData); +/* + * Makes sure set "set" can hold at least "max_val" elements. + * Returns TRUE if successful, FALSE otherwise. A successful + * call to ExpandSet() guarentees that any calls to AddToSet() + * will be successful as long as the elements added are less + * than "max_val". + */ +EXTERN Boolean_t ExpandSet(Set_pa Set, + SetIndex_t max_val, + Boolean_t show_error_msg); + +/* + * Copies set "src" to set "dst". Returns TRUE if successful, + * FALSE if "src" contains elements it is unable to add to "dst". + */ +EXTERN Boolean_t CopySet(Set_pa dst, + Set_pa src, + Boolean_t show_error_msg); + +/* + * Appends set "src" to set "dst". Returns TRUE if successful, + * FALSE if "src" contains elements it is unable to add to "dst". + */ +EXTERN Boolean_t AppendSet(Set_pa dst, + Set_pa src, + Boolean_t show_error_msg); +/* + * Empties the set "set". + */ +EXTERN void ClearSet(Set_pa Set); + +/* + * Adds "member" to set "set". Returns TRUE if successful, + * FALSE otherwise. AddToSet() can only return FALSE if + * "member" is greater than any previous member of "set" and + * also greater that any "max_val" set with ExpandSet(). + */ +#if defined USE_FUNCTIONS_FOR_SETS +EXTERN Boolean_t AddToSet(Set_pa Set, + SetIndex_t member, + Boolean_t show_error_msg); +#else +# if defined __cplusplus +inline Boolean_t AddToSet(Set_pa Set, + SetIndex_t member, + Boolean_t show_error_msg) +{ + if (Set && + (member + 1 <= Set->size || + ExpandSet(Set, member + 1, show_error_msg))) + { + SetIndex_t word = member / SetBitSize; + SetData_t bit = (SetData_t)1 << (member % SetBitSize); + Set->data[word] |= bit; + return TRUE; + } + else + return FALSE; +} /* AddToSet() */ +# else +# define AddToSet(Set,member,show_error_msg) \ + (((Set) && \ + ((member)+1 <= (Set)->size || \ + ExpandSet((Set), (member)+1, (show_error_msg)))) \ + ? (((Set)->data[(member) / SetBitSize] |= (SetData_t)1 << ((member) % SetBitSize)), TRUE) \ + : FALSE) +# endif +#endif + +/* + * Removes "member" from set "set". + */ +EXTERN void RemoveFromSet(Set_pa Set, + SetIndex_t member); + +EXTERN void DeleteSetMember(Set_pa Set, + SetIndex_t Member); +EXTERN Boolean_t InsertSetMember(Set_pa Set, + SetIndex_t Member, + Boolean_t ShowErrMsg); +/* + * Test for membership of "member" in set "set". This is the only + * function worth making into a macro or inline function. + */ +#if defined USE_FUNCTIONS_FOR_SETS +EXTERN Boolean_t InSet(Set_pa Set, + SetIndex_t member); +#else +# if defined __cplusplus +inline Boolean_t InSet(Set_pa Set, + SetIndex_t member) +{ + if (Set && (0 <= member && member < Set->size)) + { + SetIndex_t word = member / SetBitSize; + SetData_t bit = (SetData_t)1 << (member % SetBitSize); + return (Set->data[word]&bit) != 0; + } + else + return FALSE; +} /* InSet() */ +# else +# define InSet(Set,member) ((Set && (0<=(member) && (member)<(Set)->size)) \ + ? ((Set)->data[(member)/SetBitSize]&((SetData_t)1<<((member)%SetBitSize)))!=0 \ + : FALSE) +# endif +#endif + +/* + * Returns TRUE if set "set" is empty. + */ +EXTERN Boolean_t IsEmpty(Set_pa Set); + +/* + * Returns TRUE if Set has voids. + */ +EXTERN Boolean_t HasVoids(Set_pa Set); + +/* + * Returns number of members in Set "Set". + */ +EXTERN SetIndex_t MemberCount(Set_pa Set); + +/* + * Returns the next member in set "set" after member "start_at". + * Use "start_at" of BAD_ZV_VALUE to find first member. + */ +EXTERN SetIndex_t GetNextMember(Set_pa Set, + SetIndex_t start_at); + +/* + * Returns the previous member in set "set" before member + * "start_at". Use "start_at" of BAD_ZV_VALUE to find last member. + */ +EXTERN SetIndex_t GetPrevMember(Set_pa Set, + SetIndex_t start_at); + +/* + * Returns TRUE if sets are equal (have same members). FALSE otherwise. + */ +EXTERN Boolean_t EqualSets(Set_pa set1, + Set_pa set2); + +/* + * Returns TRUE if all members of childset are contained in parentset. + */ +EXTERN Boolean_t IsSubSet(Set_pa childset, + Set_pa parentset); + +EXTERN SetIndex_t MemberOffset(Set_pa Set, + SetIndex_t Member); + +EXTERN SetIndex_t OffsetMember(Set_pa Set, + SetIndex_t Offset); + + +EXTERN Boolean_t CopySetMember(Set_pa DstSet, + SetIndex_t DstOffset, + Set_pa SrcSet, + SetIndex_t SrcOffset); + +EXTERN void ShiftSet(Set_pa Set, + SetIndex_t ShiftPos1, + SetIndex_t ShiftPos2, + SetIndex_t ShiftAmount); + + +/* + * Handy macros + */ +#define GetFirstSetMember(Set) (GetNextMember((Set), BAD_SET_VALUE)) +#define GetLastSetMember(Set) (GetPrevMember((Set), BAD_SET_VALUE)) + +#define ForAllMembersInSet(Member, Set) \ + for (Member = GetFirstSetMember((Set)); \ + Member != BAD_SET_VALUE; \ + Member = GetNextMember((Set), (Member))) +#define ForAllMembersInReversedSet(Member, Set) \ + for (Member = GetLastSetMember((Set)); \ + Member != BAD_SET_VALUE; \ + Member = GetPrevMember((Set), (Member))) + +#endif // _SET_H_INCLUDED diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/STRLIST.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/STRLIST.h new file mode 100644 index 0000000000..04d1673b11 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/STRLIST.h @@ -0,0 +1,122 @@ +/* + * 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/ + * + */ +/* +***************************************************************** +***************************************************************** +******* ******** +****** Copyright (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +***************************************************************** +***************************************************************** +*/ +#if defined EXTERN +# undef EXTERN +#endif +#if defined STRLISTMODULE +# define EXTERN +#else +# define EXTERN extern +#endif + +#if !defined ARRLIST_h +# error "Include ARRLIST.h before including STRLIST.h" +#endif + +/* + * + * For building pltview.exe under Windows, we use + * tecio.dll (which is linked to pltview). + * Since pltview.exe uses a few of the + * functions here, they need to be exported into + * the tecio.dll, thus "TECXXX.h" is included for the + * LIBFUNCTION & LIBCALL keywords. They are not + * documented with the other TECXXX() functions, + * however. + * + * If pltview requires other string functions + * in the future, they can be added to the dll + * by adding LIBFUNCTION & LIBCALL as in + * StringListDealloc(), etc. below. + * + * When building the tecplot kernal, LIBFUNCTION + * and LIBCALL are nop's. + * + */ +#include "TECXXX.h" + +EXTERN Boolean_t StringListValid(StringList_pa StringList); +EXTERN void StringListClear(StringList_pa StringList); +EXTERN void StringListRemoveStrings(StringList_pa StringList, + LgIndex_t StringOffset, + LgIndex_t Count); +EXTERN void StringListRemoveString(StringList_pa StringList, + LgIndex_t StringOffset); +LIBFUNCTION void LIBCALL StringListDealloc(StringList_pa *StringList); +EXTERN StringList_pa StringListAlloc(void); +EXTERN Boolean_t StringListAppendString(StringList_pa StringList, + const char *String); +LIBFUNCTION LgIndex_t LIBCALL StringListCount(StringList_pa StringList); +LIBFUNCTION char * LIBCALL StringListGetString(StringList_pa StringList, + LgIndex_t StringOffset); + +#if defined USE_MACROS_FOR_FUNCTIONS +# define StringListGetStringRef StringListGetStringRef_MACRO +#else +# define StringListGetStringRef StringListGetStringRef_FUNC +#endif + +#if !defined USE_MACROS_FOR_FUNCTIONS +EXTERN const char * StringListGetStringRef_FUNC(StringList_pa StringList, + LgIndex_t StringOffset); +#endif +/** + * To maintain the string list's integrity the result is cast to a + * (const char *) to minimize the risk of users passing the result + * to FREE_ARRAY. + */ +#define StringListGetStringRef_MACRO(StringList, StringOffset) \ + ((const char *)ArrayListGetCharPtr((ArrayList_pa)(StringList), StringOffset)) + +EXTERN Boolean_t StringListSetString(StringList_pa StringList, + LgIndex_t StringOffset, + const char *String); +EXTERN Boolean_t StringListInsertString(StringList_pa StringList, + LgIndex_t StringOffset, + const char *String); +EXTERN StringList_pa StringListCopy(StringList_pa StringList); +EXTERN Boolean_t StringListAppend(StringList_pa Target, + StringList_pa Source); + +EXTERN char *StringListToNLString(StringList_pa StringList); +EXTERN StringList_pa StringListFromNLString(const char *String); +EXTERN char **StringListToArray(StringList_pa StringList); +EXTERN StringList_pa StringListFromArray(const char **StringArray, + LgIndex_t Count); +EXTERN StringList_pa StringListFromCompound(const char *String); +EXTERN char *StringListToCompound(StringList_pa StringList, + char GroupJoinCharacter, + const char *CharsToEscape); +EXTERN void StringListSort(StringList_pa StringList, + StringListStringComparator_pf Comparator, + ArbParam_t ClientData); diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/STRUTIL.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/STRUTIL.h new file mode 100644 index 0000000000..c8e0c2b5a3 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/STRUTIL.h @@ -0,0 +1,218 @@ +/* + * 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/ + * + */ +/* +****************************************************************** +****************************************************************** +******* ******** +****** (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +****************************************************************** +****************************************************************** +*/ + +#if defined EXTERN +#undef EXTERN +#endif +#if defined STRUTILMODULE +#define EXTERN +#else +#define EXTERN extern +#endif + +#include + +namespace tecplot +{ +namespace strutil +{ +class Scanner; +} +} + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + + +EXTERN void FormatStringBufferCleanup(void); + +/* + * This is a helper function for FormatString or any other functions that want + * to format a string based on a format string followed by a set of arguments. + * See FormatString or ErrMsg functions for example usage. + * + * @param Format + * C format string. + * @param Arguments + * Variable argument list already fetched using va_start(). + * + * @return + * Allocated string with the formatted string or NULL if it failed. + */ +EXTERN char *vFormatString(const char *Format, + va_list Arguments); + +/** + * Formats a string using the specified C format string. + * + * @param Format + * C format string. + * @param ... + * Any arguments needed by the C format string. + * + * @return + * Allocated string with the formatted string or NULL if it failed. The + * client is responsible for deallocating the resource. + */ +EXTERN char *FormatString(tecplot::strutil::TranslatedString Format, + ...); /* 0 or more variable arguments */ + +/** + * Formats a string using the specified C format string and places the result + * in the string buffer. + * + * @param Buffer + * String buffer to receive the formatted string. + * @param Format + * C format string. + * @param ... + * Any arguments needed by the C format string. + * + * @return + * Upon successful return, these functions return the number of characters + * printed, not including the trailing '\0' used to end output to strings. If + * unsuccessful -1 is returned. + */ +EXTERN int FormatString(std::string& Buffer, + tecplot::strutil::TranslatedString Format + ...); /* 0 or more variable arguments */ +EXTERN char *DupString(tecplot::strutil::TranslatedString String); +EXTERN void CopySubString(char *Target, + const char *Source, + int Index, + int Count); + +#if !defined MSWIN + +EXTERN void ReplaceCharInString(char *S, + short OldChar, + short NewChar); +#endif + +EXTERN void MakeStringLowerCase(char *str); +EXTERN void MakeStringUpperCase(char *str); +EXTERN char *TrimLeadAndTrailSpaces(char *String); +EXTERN char *StringFlushLeft(char *String); +EXTERN char *StringTruncate(char *String, + LgIndex_t MaxLength); +EXTERN char *StringTrimAndTruncate(char *String, + LgIndex_t MaxLength); + +#ifndef MSWIN +EXTERN StringList_pa LineBreakString(const char *String, + UInt32_t WrapMargin); +#endif + +EXTERN Boolean_t MatchKey(char *StringToMatch, + char *Key); +EXTERN void RemoveSeparator(const char **CPtr); +EXTERN void SkipWhiteSpace(const char **CPtr); +EXTERN void SkipNonWhiteSpace(char **CPtr); +EXTERN const char *ustrstr(const char *s1, + const char *s2); +EXTERN int ustrncmp(const char *s1, + const char *s2, + size_t Len); +EXTERN int ustrcmp(const char *s1, + const char *s2); +/* public access */ +/* InternalResetString should not be used directly (use ResetString macro) */ +#if !defined NO_ASSERTS +EXTERN Boolean_t InternalResetString(char **SBase, + const char *NewString, + Boolean_t IssueErrMsg, + const char *FileName, + int LineNumber); +# define ResetString(SBase, NewString, IssueErrMsg) InternalResetString( \ + SBase, \ + NewString, \ + IssueErrMsg, \ + __FILE__, __LINE__) +#else +EXTERN Boolean_t InternalResetString(char **SBase, + const char *NewString, + Boolean_t IssueErrMsg); +# define ResetString(SBase, NewString, IssueErrMsg) InternalResetString( \ + SBase, \ + NewString, \ + IssueErrMsg) +#endif + +EXTERN Boolean_t ScanForString(tecplot::strutil::Scanner &scanner, + std::string &DestString, + Boolean_t GrabEntireStringIncludingDelimiters); +EXTERN Boolean_t TackOnString(char **SBase, + const char *StringToAdd, + Boolean_t DeleteStringToAdd, + Boolean_t ConvertNewlineToAscii); +EXTERN Boolean_t TackOnConstString(char **SBase, + const char *StringToAdd, + Boolean_t ConvertNewlineToAscii); +EXTERN Boolean_t TackOnChar(char **SBase, + char CharToAdd); +EXTERN Boolean_t ReplaceNewlineWithBackslashN(char **String); +EXTERN Boolean_t ReplaceBackslashNWithNewline(char **S); + +EXTERN Boolean_t EscapeOutDelimitersInString(char **S, + char Delimiter); +EXTERN Boolean_t ScanForSymbol(tecplot::strutil::Scanner &scanner, + char Symbol, + Boolean_t OnlySkipWhiteSpace); + + +/* Newline Delimited Strings */ +EXTERN char *ConvertStringToNewlineDelimitedString(const char *OriginalString); +EXTERN char *ConvertNewlineDelimitedStringToQuotedString(const char *NewlineDelimitedString, + Boolean_t SeparateInstructionsWithPlus); + + + +EXTERN char *InsertNameAtPlaceHolder(char *BaseString, + char *NameToInsert); +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if !defined NO_ASSERTS +#endif /* !NO_ASSERTS */ +#endif //TECPLOTKERNEL + +inline char* EndOfString(char* str) +{ + return str + strlen(str); +}; +inline char const* EndOfString(char const* str) +{ + return str + strlen(str); +}; diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/SYSTEM.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/SYSTEM.h new file mode 100644 index 0000000000..6e510359a5 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/SYSTEM.h @@ -0,0 +1,67 @@ +/* + * 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/ + * + */ +/* +***************************************************************** +***************************************************************** +******* ******** +****** Copyright (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +***************************************************************** +***************************************************************** +*/ +#if defined EXTERN +#undef EXTERN +#endif +#if defined SYSTEMMODULE +#define EXTERN +#else +#define EXTERN extern +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif +EXTERN int OpenFileListGetCount(void); +EXTERN char *GetLongFileName(const char *FileName); +EXTERN Boolean_t VerifyToOverwriteFile(const char *FName); +EXTERN Boolean_t IsValidDirectory(const char *FName); +EXTERN Boolean_t FileExists(const char *F, + Boolean_t ShowErr); +EXTERN Boolean_t IsOkFNameChar(unsigned char ch); +EXTERN void ErrFName(const char *FName); +EXTERN Boolean_t IsValidFileName(const char *FileName, + Boolean_t IsReading, + Boolean_t ShowError); +EXTERN Boolean_t ResizeFile(FILE *File, + Int64_t Length); +EXTERN Boolean_t Close_File(FILE **F, + Boolean_t ShowErr); +EXTERN Boolean_t Open_File(FILE **F, + const char *FName, + Boolean_t IsReading, + Boolean_t IsAppending, + Boolean_t ForceOpen, + Boolean_t ShowErr, + Boolean_t IsAscii); + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TASSERT.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TASSERT.h new file mode 100644 index 0000000000..78252294d3 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TASSERT.h @@ -0,0 +1,513 @@ +/* + * 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/ + * + */ +/* +****************************************************************** +****************************************************************** +******* ******** +****** (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +****************************************************************** +****************************************************************** +*/ +/* + * Provide four levels of assertion control. Assertions provide a mechanism + * to enforce a contract between a client and service provider. The assertions + * are listed in order of highest to lowest priority. Assertions can be turned + * off individually by defining the appropriate name (see preprossessor + * definitions below), however, lower priority assertions should be turned + * off prior to higher ones. As confidence in the code increases all assertions + * can be turned off by defining NO_ASSERTS. + * + * The assertions defined below have the following meanings: + * + * INVARIANT - Asserts that a property's state is invariant throughout the + * life of the property's scope. Stating invariant properties + * of an application provides a deeper understanding of the + * application's state. These statements are usually + * positioned just ahead of the preconditions and just after + * the postconditions. + * + * REQUIRE - Asserts that a method's preconditions are within their + * valid domains. Preconditions are conditions placed upon + * any state information relied upon for the call. These + * statements should be as close to the top of the method + * as possible (except for assertions on invariant properties). + * + * ENSURE - Asserts that a method's postconditions are within their + * valid ranges. Postconditions are conditions placed upon + * any state information modified by the call. These + * statements should be as close to the bottom of the method + * (presumably there is only one exit point) as possible + * (except for assertions on invariant properties). + * + * CHECK - Any other assertion not covered by the above assertions. + * These are often added within a method body to specify + * something that may not be immediately obvious to the reader + * or to validate your assumptions about a call to a 3rd party + * method that does not use runtime assertions for its + * preconditions or postconditions. Obviously if the 3rd party + * method uses assertions then there is no need for the CHECK. + * + * Additionally a convenience macro is available to place in code that is + * pending implementation. + * + * NOT_IMPLEMENTED - Assertion that always fails during runtime for debug + * builds and always fails at compile time for release + * builds. + */ +#if !defined TASSERT_H +#define TASSERT_H + +#if defined (MSWIN) +# include +#endif /* MSWIN */ + +#if !defined TECPLOTKERNEL && !defined STD_ASSERTS +#define STD_ASSERTS +#endif + +#if !defined (MSWIN) +# include +# if !defined ASSERT +# define ASSERT assert +# endif +#endif + +#if defined MSWIN +/* MFC .NET defines ENSURE, so we undefine it here */ +#if defined ENSURE +#undef ENSURE +#endif /* ENSURE */ +#endif /* MSWIN */ + +/* BEGINREMOVEFROMADDON */ +#define INVALID_REF ((void *)0x0000FFFF) +/* + * Chances are low the address 0x11111111 will be used, so we'll risk asserting + * against it (see unitialized assignment in newmalloc). + */ +#define UNINITIALIZED_REF ((void *)0x11111111) +#define INVALID_FN_REF ((void *)NULL) +/* ENDREMOVEFROMADDON */ + +#ifdef UNIXX +/* BEGINREMOVEFROMADDON */ +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# if defined NO_ASSERTS +# else +# endif +#endif /* TECPLOTKERNAL */ +/* ENDREMOVEFROMADDON */ + +/* BEGINREMOVEFROMADDON */ +#if !defined TECPLOTKERNEL +/* For add-ons, there is a problem with VALID_REF, so just test for non-NULL */ +/* ENDREMOVEFROMADDON */ +# define VALID_REF(p) ( (p) != NULL ) +# define VALID_FN_REF(fp) ( (fp) != NULL ) +/* BEGINREMOVEFROMADDON */ +#endif /* !defined TECPLOTKERNAL */ +/* ENDREMOVEFROMADDON */ + +/* BEGINREMOVEFROMADDON */ +/* Widgets are pointers under Motif */ +# define VALID_WIDGET(widget) VALID_REF((widget)) +/* Menu widgets are pointers too */ +# define VALID_MENU_WIDGET(widget) VALID_REF((widget)) +/* ENDREMOVEFROMADDON */ +#endif /* UNIXX */ + +#ifdef MSWIN +/* BEGINREMOVEFROMADDON */ +/* Don't use AfxIsValidAddress()! See Bug <7245>. + 1/4/08, dto. */ +/* ENDREMOVEFROMADDON */ + +#if defined NO_ASSERTS +/* release build in TecUtil layer uses these for TUASSERT */ +# define VALID_REF(p) ((p) != NULL) +# define VALID_FN_REF(pf) ((pf) != NULL) +#else +# define VALID_REF(p) ((p) != NULL && !IsBadReadPtr((const void *)(p), 1)) +# define VALID_FN_REF(pf) ((pf) != NULL && !IsBadReadPtr((const void *)(pf),(UINT_PTR)sizeof(const void*))) +#endif + +/* BEGINREMOVEFROMADDON */ +/* Widgets are numbers under Windows, so we decode it with GetWindowFromWidget */ +# if defined ENGINE +# define VALID_WIDGET(widget) ((widget) != NULL) +# else +# define VALID_WIDGET(widget) ((widget) != NULL && GetWindowFromWidget((widget))!=NULL) +# endif // ENGINE + +/* Menu widgets are numbers too, so we just check against zero */ +# define VALID_MENU_WIDGET(widget) ((widget)!=NULL) +/* ENDREMOVEFROMADDON */ +#endif /* MSWIN */ +/* BEGINREMOVEFROMADDON */ +/* handles are not pointers to memory, so the only test we can */ +/* perform is to check for 0 */ +#define VALID_HANDLE(handle) ((handle)!=0) + +#if defined FLEXLM +#define VALID_FLEX_JOB_HANDLE(handle) ((handle) != NULL) +#define VALID_FLEX_ERROR_CODE(ErrorCode)(ErrorCode <= 0) +#endif /* FLEXLM */ + +/* ENDREMOVEFROMADDON */ +/* other useful validity checks */ +#define VALID_BOOLEAN(b) ((b) == TRUE || (b) == FALSE) +#define VALID_ENUM(value, type) (0 <= (value) && \ + (value) < END_##type) + +/* Test a parameter than can be NULL or a valid pointer */ +#define VALID_REF_OR_NULL(ptr) IMPLICATION((ptr) != NULL, VALID_REF(ptr)) +#define VALID_FN_REF_OR_NULL(ptr) IMPLICATION((ptr) != NULL, VALID_FN_REF(ptr)) + +/* BEGINREMOVEFROMADDON */ +#define VALID_TRANSLATED_STRING(ts) (!(ts).isNull()) + +/** + * These macros are a little complicated but it allows one to + * write a simple assertion regardless of the zone type or + * selected plane: + * + * REQUIRE(VALID_CELL_INDEX(CZData, CellIndex, Plane))); + * + * Prior to using the macros a call to SetupXxx, + * or at a minimum SetupCZData, must be called to setup + * the globals defining the dataset structure. + */ +#define VALID_FE_CELL_INDEX(CZData, CellIndex) \ + (/* CellIndex range test */ \ + 0 <= (CellIndex) && \ + (CellIndex) < (CZData)->NumElements) + +#define VALID_IPLANE_CELL_INDEX(CZData,CellIndex) \ + (/* CellIndex range test */ \ + (CellIndex) >= 0 && \ + IINDEX((CZData),CellIndex) <= MAX((CZData)->NumIPtsM1,1) && \ + JINDEX((CZData),CellIndex) < MAX((CZData)->NumJPtsM1,1) && \ + KINDEX((CZData),CellIndex) < MAX((CZData)->NumKPtsM1,1)) + +#define VALID_JPLANE_CELL_INDEX(CZData,CellIndex) \ + (/* CellIndex range test */ \ + (CellIndex) >= 0 && \ + IINDEX((CZData),CellIndex) < MAX((CZData)->NumIPtsM1,1) && \ + JINDEX((CZData),CellIndex) <= MAX((CZData)->NumJPtsM1,1) && \ + KINDEX((CZData),CellIndex) < MAX((CZData)->NumKPtsM1,1)) + +#define VALID_KPLANE_CELL_INDEX(CZData,CellIndex) \ + (/* CellIndex range test */ \ + (CellIndex) >= 0 && \ + IINDEX((CZData),CellIndex) < MAX((CZData)->NumIPtsM1,1) && \ + JINDEX((CZData),CellIndex) < MAX((CZData)->NumJPtsM1,1) && \ + KINDEX((CZData),CellIndex) <= MAX((CZData)->NumKPtsM1,1)) + +#define VALID_ORDERED_CELL_INDEX(CZData, CellIndex, Plane) \ + (/* macro preconditions */ \ + ((IJKPlanes_e)(Plane) == IJKPlanes_I || \ + (IJKPlanes_e)(Plane) == IJKPlanes_J || \ + (IJKPlanes_e)(Plane) == IJKPlanes_K || \ + (IJKPlanes_e)(Plane) == IJKPlanes_Volume) && \ +\ + /* CellIndex range test */ \ + (IMPLICATION(((IJKPlanes_e)(Plane) == IJKPlanes_I || \ + (IJKPlanes_e)(Plane) == IJKPlanes_Volume), \ + VALID_IPLANE_CELL_INDEX((CZData),CellIndex)) && \ + IMPLICATION(((IJKPlanes_e)(Plane) == IJKPlanes_J || \ + (IJKPlanes_e)(Plane) == IJKPlanes_Volume), \ + VALID_JPLANE_CELL_INDEX((CZData),CellIndex)) && \ + IMPLICATION(((IJKPlanes_e)(Plane) == IJKPlanes_K || \ + (IJKPlanes_e)(Plane) == IJKPlanes_Volume), \ + VALID_KPLANE_CELL_INDEX((CZData),CellIndex)))) + +#define VALID_CELL_INDEX(CZData, CellIndex, Plane) \ + (((CZData)->NM != NULL || (CZData)->FM != NULL) ? \ + VALID_FE_CELL_INDEX((CZData), (CellIndex)) : \ + VALID_ORDERED_CELL_INDEX((CZData), (CellIndex), (Plane))) + +#define VALID_DATASET(dataSet,checkNumZones) (((dataSet) != NULL) && \ + IMPLICATION((checkNumZones),(dataSet)->NumZones >= 1)) + + + +#ifdef MSWIN +/* Here is a more specific check in Windows for a valid + pointer to an MFC Window object. + Note that GetSafeHwnd() works even if pWnd is NULL, because + it checks the 'this' pointer first */ +# define VALID_WND(pWnd) (::IsWindow((pWnd)->GetSafeHwnd())) + +#else /* !MSWIN */ +# define VALID_WND(pWnd) /* Should not be used in Motif */ +#endif /* MSWIN */ +/* ENDREMOVEFROMADDON */ + +/* Check for a non-zero length string */ +#if defined MSWIN +# if defined NO_ASSERTS +# define VALID_NON_ZERO_LEN_STR(str) (VALID_REF(str) && !ISEMPTYSTRING(str)) +# else +# define VALID_NON_ZERO_LEN_STR(str) \ + (VALID_REF(str) && \ + !IsBadReadPtr((const void*)(str),(UINT_PTR)(1+strlen((const char*)(str)))) && \ + !ISEMPTYSTRING(str)) +# endif +#else +# define VALID_NON_ZERO_LEN_STR(str) (VALID_REF(str) && !ISEMPTYSTRING(str)) +#endif + +#define VALID_SET_INDEX(setIndex) (((SetIndex_t)setIndex)>=(SetIndex_t)1) + +/* Check for valid stdio file handle */ +#define VALID_FILE_HANDLE(stream) ((stream) != NULL) + +/* To check colors and pen numbers */ +/* BEGINREMOVEFROMADDON */ +#define VALID_BASIC_COLOR(BColor) \ + (FirstBasicColor<=(BColor) && (BColor)<=LastBasicColor) +#define VALID_CONTOUR_COLOR(Color) \ + (ContourColorOffset<=(Color) && \ + (Color) +#include +#include + +class AssertionLog +{ +public: + static void initializeAssertLog(const std::string &fileName); + static bool isLoggingAssertions(); + static void addAssertion(const std::string &message); +private: + static void writeOutAssertion(const std::string &message); +private: + static bool logAssertions; + static std::string logFileName; + static std::vector assertList; +}; + +extern void TWinCheckedFailedLine(const char *Expr, + const char *FileName, + int LineNum); + +#define TASSERT(EXPR)\ + do { if (!(EXPR)) { TWinCheckedFailedLine(#EXPR,__FILE__,__LINE__); } } while (0) +#else +#define TASSERT(EXPR) ASSERT(EXPR) /* MFC assert. +Works in both release & debug builds */ +#endif /* CHECKED_BUILD */ +#else +#define TASSERT(EXPR) (void)((EXPR) || (TAssert(#EXPR, __FILE__, __LINE__), 0)) +#endif + +# if defined NO_INVARIANTS +# define INVARIANT(EXPR) +# else +# define INVARIANT(EXPR) TASSERT(EXPR) +# endif + +# if defined NO_PRECONDITIONS +# define REQUIRE(EXPR) +# else +# define REQUIRE(EXPR) TASSERT(EXPR) +# endif + +# if defined NO_POSTCONDITIONS +# define ENSURE(EXPR) +# else +# define ENSURE(EXPR) TASSERT(EXPR) +# endif + +# if defined VERIFY +# undef VERIFY +# endif + +# if defined NO_CHECKS +# define CHECK(EXPR) +# define VERIFY(EXPR) ((void)(EXPR)) +# else +# define CHECK(EXPR) TASSERT(EXPR) +# if defined NDEBUG +# define VERIFY(EXPR) ((void)(EXPR)) +# else +# define VERIFY(EXPR) TASSERT(EXPR) +# endif +# endif + +# if defined NICE_NOT_IMPLEMENTED +# define NOT_IMPLEMENTED() NiceNotImplemented() +# else +# define NOT_IMPLEMENTED() TASSERT(!("Not Implemented")) +# endif +/* ENDREMOVEFROMADDON */ +#endif +/* BEGINREMOVEFROMADDON */ +#if !defined STD_ASSERTS +extern void TecplotMopupOnAssert(void); +#endif /* !STD_ASSERTS */ + +#if defined NICE_NOT_IMPLEMENTED +extern void NiceNotImplemented(void); +#endif +/* ENDREMOVEFROMADDON */ + +/* convenience macros for implication, P -> Q, and equivalence, P <-> Q. */ +#define IMPLICATION(P,Q) (!(P) || (Q)) +#define EQUIVALENCE(P,Q) ((P) == (Q)) + +/* BEGINREMOVEFROMADDON */ +#if defined RLM +#define VALID_RLM_HANDLE(h) ((h) != NULL) +#endif /* RLM */ +/* ENDREMOVEFROMADDON */ + + +#endif /* TASSERT_H */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TECIO.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TECIO.h new file mode 100644 index 0000000000..fabb1344b0 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TECIO.h @@ -0,0 +1,24 @@ +/* + * 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 "TECXXX.h" diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TECXXX.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TECXXX.h new file mode 100644 index 0000000000..a61539e90b --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TECXXX.h @@ -0,0 +1,698 @@ +/* + * 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/ + * + */ +/* + * TECXXX.h: Copyright (C) 1988-2008 Tecplot, Inc. + */ + +#if !defined TECXXX_H_ +#define TECXXX_H_ + +#if !defined CRAY +# define TECFOREIGN112 tecforeign112 +# define TECINI112 tecini112 +# define TECZNE112 teczne112 +# define TECDAT112 tecdat112 +# define TECNOD112 tecnod112 +# define TECGEO112 tecgeo112 +# define TECTXT112 tectxt112 +# define TECLAB112 teclab112 +# define TECFIL112 tecfil112 +# define TECEND112 tecend112 +# define TECUSR112 tecusr112 +# define TECAUXSTR112 tecauxstr112 +# define TECZAUXSTR112 teczauxstr112 +# define TECVAUXSTR112 tecvauxstr112 +# define TECFACE112 tecface112 +# define TECPOLY112 tecpoly112 + +# define TECFOREIGN111 tecforeign111 +# define TECINI111 tecini111 +# define TECZNE111 teczne111 +# define TECDAT111 tecdat111 +# define TECNOD111 tecnod111 +# define TECGEO111 tecgeo111 +# define TECTXT111 tectxt111 +# define TECLAB111 teclab111 +# define TECFIL111 tecfil111 +# define TECEND111 tecend111 +# define TECUSR111 tecusr111 +# define TECAUXSTR111 tecauxstr111 +# define TECZAUXSTR111 teczauxstr111 +# define TECVAUXSTR111 tecvauxstr111 +# define TECFACE111 tecface111 +# define TECPOLY111 tecpoly111 + +# define TECFOREIGN110 tecforeign110 +# define TECINI110 tecini110 +# define TECZNE110 teczne110 +# define TECDAT110 tecdat110 +# define TECNOD110 tecnod110 +# define TECGEO110 tecgeo110 +# define TECTXT110 tectxt110 +# define TECLAB110 teclab110 +# define TECFIL110 tecfil110 +# define TECEND110 tecend110 +# define TECUSR110 tecusr110 +# define TECAUXSTR110 tecauxstr110 +# define TECZAUXSTR110 teczauxstr110 +# define TECVAUXSTR110 tecvauxstr110 +# define TECFACE110 tecface110 + +# define TECFOREIGN100 tecforeign100 +# define TECINI100 tecini100 +# define TECZNE100 teczne100 +# define TECDAT100 tecdat100 +# define TECNOD100 tecnod100 +# define TECGEO100 tecgeo100 +# define TECTXT100 tectxt100 +# define TECLAB100 teclab100 +# define TECFIL100 tecfil100 +# define TECEND100 tecend100 +# define TECUSR100 tecusr100 +# define TECAUXSTR100 tecauxstr100 +# define TECZAUXSTR100 teczauxstr100 +# define TECVAUXSTR100 tecvauxstr100 +# define TECFACE100 tecface100 + +# define TECINI tecini +# define TECZNE teczne +# define TECDAT tecdat +# define TECNOD tecnod +# define TECGEO tecgeo +# define TECTXT tectxt +# define TECLAB teclab +# define TECFIL tecfil +# define TECEND tecend +# define TECUSR tecusr +#endif + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#else +#define INTEGER4 int +#define INTEGER2 short +#endif + +#if defined _WIN32 +#if !defined MSWIN +#define MSWIN /* MSWIN */ +#endif +#endif /* _WIN32 */ + +#if !defined (EXTERNC) +# if defined (__cplusplus) +# define EXTERNC extern "C" +# else +# define EXTERNC +# endif /* __cplusplus */ +#endif /* EXTERN_C */ + +#if !defined (STDCALL) +# if defined MSWIN +# define STDCALL __stdcall +# else /* !MSWIN */ +# define STDCALL +# endif /* MSWIN */ +#endif /* STDCALL */ + +#if !defined (DLLEXPORT) +# if defined (MSWIN) +# define DLLEXPORT _declspec (dllexport) +# else +# define DLLEXPORT +# endif /* MSWIN */ +#endif /* DLLEXPORT */ + +#if !defined (DLLIMPORT) +# if defined (MSWIN) +# define DLLIMPORT _declspec (dllimport) +# else +# define DLLIMPORT +# endif /* MSWIN */ +#endif /* DLLIMPORT */ + + +#if defined (TECPLOTKERNEL) +/* CORE SOURCE CODE REMOVED */ +#else /* !TECPLOTKERNAL && !MAKEARCHIVE */ +# define LIBCALL STDCALL +# define LIBFUNCTION EXTERNC DLLIMPORT +#endif + +/* + * V11.3 tecio functions + */ + +LIBFUNCTION void LIBCALL TECFOREIGN112(INTEGER4 *OutputForeignByteOrder); + +LIBFUNCTION INTEGER4 LIBCALL TECINI112(char *Title, + char *Variables, + char *FName, + char *ScratchDir, + INTEGER4 *FileType, + INTEGER4 *Debug, + INTEGER4 *VIsDouble); + +LIBFUNCTION INTEGER4 LIBCALL TECZNE112(char *ZoneTitle, + INTEGER4 *ZoneType, + INTEGER4 *IMxOrNumPts, + INTEGER4 *JMxOrNumElements, + INTEGER4 *KMxOrNumFaces, + INTEGER4 *ICellMx, + INTEGER4 *JCellMx, + INTEGER4 *KCellMx, + double *SolutionTime, + INTEGER4 *StrandID, + INTEGER4 *ParentZone, + INTEGER4 *IsBlock, + INTEGER4 *NumFaceConnections, + INTEGER4 *FaceNeighborMode, + INTEGER4 *TotalNumFaceNodes, + INTEGER4 *NumConnectedBoundaryFaces, + INTEGER4 *TotalNumBoundaryConnections, + INTEGER4 *PassiveVarList, + INTEGER4 *ValueLocation, + INTEGER4 *ShareVarFromZone, + INTEGER4 *ShareConnectivityFromZone); + +LIBFUNCTION INTEGER4 LIBCALL TECDAT112(INTEGER4 *N, + void *FieldData, + INTEGER4 *IsDouble); + +LIBFUNCTION INTEGER4 LIBCALL TECNOD112(INTEGER4 *NData); + +LIBFUNCTION INTEGER4 LIBCALL TECEND112(void); + +LIBFUNCTION INTEGER4 LIBCALL TECLAB112(char *S); + +LIBFUNCTION INTEGER4 LIBCALL TECUSR112(char *S); + +LIBFUNCTION INTEGER4 LIBCALL TECGEO112(double *XPos, + double *YPos, + double *ZPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *Color, + INTEGER4 *FillColor, + INTEGER4 *IsFilled, + INTEGER4 *GeomType, + INTEGER4 *LinePattern, + double *PatternLength, + double *LineThickness, + INTEGER4 *NumEllipsePts, + INTEGER4 *ArrowheadStyle, + INTEGER4 *ArrowheadAttachment, + double *ArrowheadSize, + double *ArrowheadAngle, + INTEGER4 *Scope, + INTEGER4 *Clipping, + INTEGER4 *NumSegments, + INTEGER4 *NumSegPts, + float *XGeomData, + float *YGeomData, + float *ZGeomData, + char *mfc); + +LIBFUNCTION INTEGER4 LIBCALL TECTXT112(double *XOrThetaPos, + double *YOrRPos, + double *ZOrUnusedPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *BFont, + INTEGER4 *FontHeightUnits, + double *FontHeight, + INTEGER4 *BoxType, + double *BoxMargin, + double *BoxLineThickness, + INTEGER4 *BoxColor, + INTEGER4 *BoxFillColor, + double *Angle, + INTEGER4 *Anchor, + double *LineSpacing, + INTEGER4 *TextColor, + INTEGER4 *Scope, + INTEGER4 *Clipping, + char *String, + char *mfc); + +LIBFUNCTION INTEGER4 LIBCALL TECFIL112(INTEGER4 *F); + +LIBFUNCTION INTEGER4 LIBCALL TECAUXSTR112(char *Name, + char *Value); + +LIBFUNCTION INTEGER4 LIBCALL TECZAUXSTR112(char *Name, + char *Value); + +LIBFUNCTION INTEGER4 LIBCALL TECVAUXSTR112(INTEGER4 *Var, + char *Name, + char *Value); + +LIBFUNCTION INTEGER4 LIBCALL TECFACE112(INTEGER4 *FaceConnections); + +LIBFUNCTION INTEGER4 LIBCALL TECPOLY112(INTEGER4 *FaceNodeCounts, + INTEGER4 *FaceNodes, + INTEGER4 *FaceLeftElems, + INTEGER4 *FaceRightElems, + INTEGER4 *FaceBndryConnectionCounts, + INTEGER4 *FaceBndryConnectionElems, + INTEGER4 *FaceBndryConnectionZones); + +/* + * V11.1 tecio functions TODO (JN): Tecplot's version is still in flux so the .1 may change + */ + +LIBFUNCTION void LIBCALL TECFOREIGN111(INTEGER4 *OutputForeignByteOrder); + +LIBFUNCTION INTEGER4 LIBCALL TECINI111(char *Title, + char *Variables, + char *FName, + char *ScratchDir, + INTEGER4 *FileType, + INTEGER4 *Debug, + INTEGER4 *VIsDouble); + +LIBFUNCTION INTEGER4 LIBCALL TECZNE111(char *ZoneTitle, + INTEGER4 *ZoneType, + INTEGER4 *IMxOrNumPts, + INTEGER4 *JMxOrNumElements, + INTEGER4 *KMxOrNumFaces, + INTEGER4 *ICellMx, + INTEGER4 *JCellMx, + INTEGER4 *KCellMx, + double *SolutionTime, + INTEGER4 *StrandID, + INTEGER4 *ParentZone, + INTEGER4 *IsBlock, + INTEGER4 *NumFaceConnections, + INTEGER4 *FaceNeighborMode, + INTEGER4 *TotalNumFaceNodes, + INTEGER4 *NumConnectedBoundaryFaces, + INTEGER4 *TotalNumBoundaryConnections, + INTEGER4 *PassiveVarList, + INTEGER4 *ValueLocation, + INTEGER4 *ShareVarFromZone, + INTEGER4 *ShareConnectivityFromZone); + +LIBFUNCTION INTEGER4 LIBCALL TECDAT111(INTEGER4 *N, + void *FieldData, + INTEGER4 *IsDouble); + +LIBFUNCTION INTEGER4 LIBCALL TECNOD111(INTEGER4 *NData); + +LIBFUNCTION INTEGER4 LIBCALL TECEND111(void); + +LIBFUNCTION INTEGER4 LIBCALL TECLAB111(char *S); + +LIBFUNCTION INTEGER4 LIBCALL TECUSR111(char *S); + +LIBFUNCTION INTEGER4 LIBCALL TECGEO111(double *XPos, + double *YPos, + double *ZPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *Color, + INTEGER4 *FillColor, + INTEGER4 *IsFilled, + INTEGER4 *GeomType, + INTEGER4 *LinePattern, + double *PatternLength, + double *LineThickness, + INTEGER4 *NumEllipsePts, + INTEGER4 *ArrowheadStyle, + INTEGER4 *ArrowheadAttachment, + double *ArrowheadSize, + double *ArrowheadAngle, + INTEGER4 *Scope, + INTEGER4 *Clipping, + INTEGER4 *NumSegments, + INTEGER4 *NumSegPts, + float *XGeomData, + float *YGeomData, + float *ZGeomData, + char *mfc); + +LIBFUNCTION INTEGER4 LIBCALL TECTXT111(double *XOrThetaPos, + double *YOrRPos, + double *ZOrUnusedPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *BFont, + INTEGER4 *FontHeightUnits, + double *FontHeight, + INTEGER4 *BoxType, + double *BoxMargin, + double *BoxLineThickness, + INTEGER4 *BoxColor, + INTEGER4 *BoxFillColor, + double *Angle, + INTEGER4 *Anchor, + double *LineSpacing, + INTEGER4 *TextColor, + INTEGER4 *Scope, + INTEGER4 *Clipping, + char *String, + char *mfc); + +LIBFUNCTION INTEGER4 LIBCALL TECFIL111(INTEGER4 *F); + +LIBFUNCTION INTEGER4 LIBCALL TECAUXSTR111(char *Name, + char *Value); + +LIBFUNCTION INTEGER4 LIBCALL TECZAUXSTR111(char *Name, + char *Value); + +LIBFUNCTION INTEGER4 LIBCALL TECVAUXSTR111(INTEGER4 *Var, + char *Name, + char *Value); + +LIBFUNCTION INTEGER4 LIBCALL TECFACE111(INTEGER4 *FaceConnections); + +LIBFUNCTION INTEGER4 LIBCALL TECPOLY111(INTEGER4 *FaceNodeCounts, + INTEGER4 *FaceNodes, + INTEGER4 *FaceLeftElems, + INTEGER4 *FaceRightElems, + INTEGER4 *FaceBndryConnectionCounts, + INTEGER4 *FaceBndryConnectionElems, + INTEGER2 *FaceBndryConnectionZones); + + +/* + * V11 tecio functions + */ + +LIBFUNCTION void LIBCALL TECFOREIGN110(INTEGER4 *OutputForeignByteOrder); + +LIBFUNCTION INTEGER4 LIBCALL TECINI110(char *Title, + char *Variables, + char *FName, + char *ScratchDir, + INTEGER4 *Debug, + INTEGER4 *VIsDouble); + +LIBFUNCTION INTEGER4 LIBCALL TECZNE110(char *ZoneTitle, + INTEGER4 *ZoneType, + INTEGER4 *IMxOrNumPts, + INTEGER4 *JMxOrNumElements, + INTEGER4 *KMxOrNumFaces, + INTEGER4 *ICellMx, + INTEGER4 *JCellMx, + INTEGER4 *KCellMx, + double *SolutionTime, + INTEGER4 *StrandID, + INTEGER4 *ParentZone, + INTEGER4 *IsBlock, + INTEGER4 *NumFaceConnections, + INTEGER4 *FaceNeighborMode, + INTEGER4 *PassiveVarList, + INTEGER4 *ValueLocation, + INTEGER4 *ShareVarFromZone, + INTEGER4 *ShareConnectivityFromZone); + +LIBFUNCTION INTEGER4 LIBCALL TECDAT110(INTEGER4 *N, + void *FieldData, + INTEGER4 *IsDouble); + +LIBFUNCTION INTEGER4 LIBCALL TECNOD110(INTEGER4 *NData); + +LIBFUNCTION INTEGER4 LIBCALL TECEND110(void); + +LIBFUNCTION INTEGER4 LIBCALL TECLAB110(char *S); + +LIBFUNCTION INTEGER4 LIBCALL TECUSR110(char *S); + +LIBFUNCTION INTEGER4 LIBCALL TECGEO110(double *XPos, + double *YPos, + double *ZPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *Color, + INTEGER4 *FillColor, + INTEGER4 *IsFilled, + INTEGER4 *GeomType, + INTEGER4 *LinePattern, + double *PatternLength, + double *LineThickness, + INTEGER4 *NumEllipsePts, + INTEGER4 *ArrowheadStyle, + INTEGER4 *ArrowheadAttachment, + double *ArrowheadSize, + double *ArrowheadAngle, + INTEGER4 *Scope, + INTEGER4 *Clipping, + INTEGER4 *NumSegments, + INTEGER4 *NumSegPts, + float *XGeomData, + float *YGeomData, + float *ZGeomData, + char *mfc); + +LIBFUNCTION INTEGER4 LIBCALL TECTXT110(double *XOrThetaPos, + double *YOrRPos, + double *ZOrUnusedPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *BFont, + INTEGER4 *FontHeightUnits, + double *FontHeight, + INTEGER4 *BoxType, + double *BoxMargin, + double *BoxLineThickness, + INTEGER4 *BoxColor, + INTEGER4 *BoxFillColor, + double *Angle, + INTEGER4 *Anchor, + double *LineSpacing, + INTEGER4 *TextColor, + INTEGER4 *Scope, + INTEGER4 *Clipping, + char *String, + char *mfc); + +LIBFUNCTION INTEGER4 LIBCALL TECFIL110(INTEGER4 *F); + +LIBFUNCTION INTEGER4 LIBCALL TECAUXSTR110(char *Name, + char *Value); + +LIBFUNCTION INTEGER4 LIBCALL TECZAUXSTR110(char *Name, + char *Value); + +LIBFUNCTION INTEGER4 LIBCALL TECVAUXSTR110(INTEGER4 *Var, + char *Name, + char *Value); + +LIBFUNCTION INTEGER4 LIBCALL TECFACE110(INTEGER4 *FaceConnections); + + +/* + * V10 tecio functions kept for backward compatability. + */ + +LIBFUNCTION void LIBCALL TECFOREIGN100(INTEGER4 *OutputForeignByteOrder); + +LIBFUNCTION INTEGER4 LIBCALL TECINI100(char *Title, + char *Variables, + char *FName, + char *ScratchDir, + INTEGER4 *Debug, + INTEGER4 *VIsDouble); + +LIBFUNCTION INTEGER4 LIBCALL TECZNE100(char *ZoneTitle, + INTEGER4 *ZoneType, + INTEGER4 *IMxOrNumPts, + INTEGER4 *JMxOrNumElements, + INTEGER4 *KMxOrNumFaces, + INTEGER4 *ICellMx, + INTEGER4 *JCellMx, + INTEGER4 *KCellMx, + INTEGER4 *IsBlock, + INTEGER4 *NumFaceConnections, + INTEGER4 *FaceNeighborMode, + INTEGER4 *ValueLocation, + INTEGER4 *ShareVarFromZone, + INTEGER4 *ShareConnectivityFromZone); + +LIBFUNCTION INTEGER4 LIBCALL TECDAT100(INTEGER4 *N, + void *FieldData, + INTEGER4 *IsDouble); + +LIBFUNCTION INTEGER4 LIBCALL TECNOD100(INTEGER4 *NData); + +LIBFUNCTION INTEGER4 LIBCALL TECEND100(void); + +LIBFUNCTION INTEGER4 LIBCALL TECLAB100(char *S); + +LIBFUNCTION INTEGER4 LIBCALL TECUSR100(char *S); + +LIBFUNCTION INTEGER4 LIBCALL TECGEO100(double *XPos, + double *YPos, + double *ZPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *Color, + INTEGER4 *FillColor, + INTEGER4 *IsFilled, + INTEGER4 *GeomType, + INTEGER4 *LinePattern, + double *PatternLength, + double *LineThickness, + INTEGER4 *NumEllipsePts, + INTEGER4 *ArrowheadStyle, + INTEGER4 *ArrowheadAttachment, + double *ArrowheadSize, + double *ArrowheadAngle, + INTEGER4 *Scope, + INTEGER4 *Clipping, + INTEGER4 *NumSegments, + INTEGER4 *NumSegPts, + float *XGeomData, + float *YGeomData, + float *ZGeomData, + char *mfc); + +LIBFUNCTION INTEGER4 LIBCALL TECTXT100(double *XOrThetaPos, + double *YOrRPos, + double *ZOrUnusedPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *BFont, + INTEGER4 *FontHeightUnits, + double *FontHeight, + INTEGER4 *BoxType, + double *BoxMargin, + double *BoxLineThickness, + INTEGER4 *BoxColor, + INTEGER4 *BoxFillColor, + double *Angle, + INTEGER4 *Anchor, + double *LineSpacing, + INTEGER4 *TextColor, + INTEGER4 *Scope, + INTEGER4 *Clipping, + char *String, + char *mfc); + +LIBFUNCTION INTEGER4 LIBCALL TECFIL100(INTEGER4 *F); + +LIBFUNCTION INTEGER4 LIBCALL TECAUXSTR100(char *Name, + char *Value); + +LIBFUNCTION INTEGER4 LIBCALL TECZAUXSTR100(char *Name, + char *Value); + +LIBFUNCTION INTEGER4 LIBCALL TECVAUXSTR100(INTEGER4 *Var, + char *Name, + char *Value); + +LIBFUNCTION INTEGER4 LIBCALL TECFACE100(INTEGER4 *FaceConnections); + +/* Old V9 functions retained for backward compatibility */ + +LIBFUNCTION INTEGER4 LIBCALL TECINI(char *Title, + char *Variables, + char *FName, + char *ScratchDir, + INTEGER4 *Debug, + INTEGER4 *VIsDouble); + +LIBFUNCTION INTEGER4 LIBCALL TECZNE(char *ZoneTitle, + INTEGER4 *IMx, + INTEGER4 *JMx, + INTEGER4 *KMx, + char *ZFormat, + char *DupList); + +LIBFUNCTION INTEGER4 LIBCALL TECDAT(INTEGER4 *N, + void *FieldData, + INTEGER4 *IsDouble); + +LIBFUNCTION INTEGER4 LIBCALL TECNOD(INTEGER4 *NData); + +LIBFUNCTION INTEGER4 LIBCALL TECEND(void); + +LIBFUNCTION INTEGER4 LIBCALL TECLAB(char *S); + +LIBFUNCTION INTEGER4 LIBCALL TECUSR(char *S); + +LIBFUNCTION INTEGER4 LIBCALL TECGEO(double *XPos, + double *YPos, + double *ZPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *Color, + INTEGER4 *FillColor, + INTEGER4 *IsFilled, + INTEGER4 *GeomType, + INTEGER4 *LinePattern, + double *PatternLength, + double *LineThickness, + INTEGER4 *NumEllipsePts, + INTEGER4 *ArrowheadStyle, + INTEGER4 *ArrowheadAttachment, + double *ArrowheadSize, + double *ArrowheadAngle, + INTEGER4 *Scope, + INTEGER4 *NumSegments, + INTEGER4 *NumSegPts, + float *XGeomData, + float *YGeomData, + float *ZGeomData, + char *mfc); + +LIBFUNCTION INTEGER4 LIBCALL TECTXT(double *XPos, + double *YPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *BFont, + INTEGER4 *FontHeightUnits, + double *FontHeight, + INTEGER4 *BoxType, + double *BoxMargin, + double *BoxLineThickness, + INTEGER4 *BoxColor, + INTEGER4 *BoxFillColor, + double *Angle, + INTEGER4 *Anchor, + double *LineSpacing, + INTEGER4 *TextColor, + INTEGER4 *Scope, + char *Text, + char *mfc); + +LIBFUNCTION INTEGER4 LIBCALL TECFIL(INTEGER4 *F); + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif +#endif /* TECXXX_H_ */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TEXT.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TEXT.h new file mode 100644 index 0000000000..06887c923b --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TEXT.h @@ -0,0 +1,62 @@ +/* + * 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/ + * + */ +/* +****************************************************************** +****************************************************************** +******* ******** +****** (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +****************************************************************** +****************************************************************** +*/ + +#if defined EXTERN +#undef EXTERN +#endif +#if defined TEXTMODULE +#define EXTERN +#else +#define EXTERN extern +#endif + +#define _TEXT_H_INCLUDED + +/* These macros for checking CoordSys_e and Units of text objects (i.e., those associated with the text tool). */ +#define VALID_TEXT_COORDSYS(sys) (((sys)==CoordSys_Frame)||((sys)==CoordSys_Grid)||((sys)==CoordSys_Grid3D)) +#define VALID_TEXT_UNITS(units) (((units)==Units_Grid)||((units)==Units_Frame)||((units)==Units_Point)) +#define VALID_TEXT_COORDSYS_AND_UNITS(pos_sys, size_units) \ + ( VALID_TEXT_COORDSYS((pos_sys)) && \ + VALID_TEXT_UNITS((size_units)) && \ + ! ((pos_sys) == CoordSys_Frame && (size_units) == Units_Grid) ) + +/* This is for any type of font in Tecplot. */ +#define VALID_FONT_SIZEUNITS(units) (((units)==Units_Grid)||((units)==Units_Frame)||((units)==Units_Point)||(units)==Units_AxisPercentage) + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if 0 /* contract template */ +#endif +#if 0 /* contract template */ +#endif +#endif /* TECPLOTKERNEL */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TranslatedString.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TranslatedString.cpp new file mode 100644 index 0000000000..5ae0cb73a0 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TranslatedString.cpp @@ -0,0 +1,362 @@ +/* + * 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 +/* +***************************************************************** +***************************************************************** +******* ******** +****** Copyright (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +***************************************************************** +***************************************************************** +*/ + +#include "GLOBAL.h" +#include "TASSERT.h" +#include "Q_UNICODE.h" + + +using namespace std; + +namespace tecplot +{ +namespace strutil +{ + +#if defined MSWIN && !defined TECPLOTKERNEL +/** + * Stub function for non-TECPLOTKERNEL + */ +string LookUpTranslation(string& str) +{ + return string(str); +} +#endif + +/** + * Convenience function for creating Utf8 string translations. + * + * @param str + * String to translate. + * + * @return + * A new Utf8 translated string. + */ +static inline string* createUtf8StringTranslation(string& str) +{ +#if defined MSWIN + string *result = new string(LookUpTranslation(str)); +#else + string *result = new string(str); +#endif + ENSURE(VALID_REF(result)); + return result; +} + +#if defined MSWIN +/** + * Convenience function for creating wide string translations. + * + * @param str + * String to translate. + * + * @return + * A new wide translated string. + */ +static inline wstring* createWideStringTranslation(string& str) +{ + wstring *result = new wstring; + *result = StringToWString(LookUpTranslation(str)); + + ENSURE(VALID_REF(result)); + return result; +} +#endif + +#if defined MSWIN +/** + * Convenience function for creating wide string with the given mode. + * + * @param mode + * Indicates if this string is to be translated or not. + * @param str + * String to translate. + * + * @return + * A new wide translated string. + */ +static inline wstring* createWideString(TranslatedString::Mode mode, + string& str) +{ + REQUIRE(mode == TranslatedString::DoTranslate || mode == TranslatedString::DontTranslate); + + wstring* result; + if (mode == TranslatedString::DoTranslate) + result = createWideStringTranslation(str); + else + result = new wstring(StringToWString(str)); + + return result; +} +#endif + +/** + */ +void TranslatedString::init(TranslatedString::Mode mode, + const char* str, + const char* translatorNotes) +{ + REQUIRE(mode == DoTranslate || mode == DontTranslate); + REQUIRE(VALID_REF_OR_NULL(str)); + REQUIRE(VALID_REF_OR_NULL(translatorNotes)); + + m_mode = mode; + m_isNull = (str == NULL); + if (!m_isNull) + m_string = str; + m_utf8String = NULL; // ...on demand resource +#if defined MSWIN + m_wideString = NULL; // ...on demand resource +#endif +} + +/** + */ +TranslatedString::TranslatedString() +{ + init(DontTranslate, (const char*)NULL, (const char*)NULL); + ENSURE(this->isValid()); +} + +/** + */ +TranslatedString TranslatedString::null() +{ + return dontTranslate(NULL); +} + +/** + */ +TranslatedString::TranslatedString(TranslatedString::Mode mode, + const char* str, + const char* translatorNotes) +{ + + REQUIRE(mode == DoTranslate || mode == DontTranslate); + REQUIRE(VALID_REF_OR_NULL(str)); + REQUIRE(VALID_REF_OR_NULL(translatorNotes)); + + init(mode, str, translatorNotes); + ENSURE(this->isValid()); +} + +/** + */ +TranslatedString::~TranslatedString() +{ + delete m_utf8String; +#if defined MSWIN + delete m_wideString; +#endif +} + +#if !defined NO_ASSERTS +/** + */ +bool TranslatedString::isValid() const +{ + CHECK(IMPLICATION(m_isNull, m_string.length() == 0)); +#if 0 + /* TODO(DTO/RMS/CAM): 11/2/2007 + * Code currently exists in Tecplot where we call translate() on a + * variable. This seems wrong and at times (PleaseWait() in + * particular) the variable passed is a NULL pointer which causes + * this assertion to fail. There is not enough time before v11.2 + * release to remove all translate() calls to non-literal strings so + * we'll have to do this as a post release cleanup. For now just + * deactivate this assertion. + */ + CHECK(IMPLICATION(m_isNull, m_mode == DontTranslate)); +#endif + + return true; +} +#endif + +/** + */ +bool TranslatedString::isNull() const +{ + INVARIANT(this->isValid()); + return m_isNull; +} + +/** + */ +bool TranslatedString::isNullOrZeroLength() const +{ + INVARIANT(this->isValid()); + return m_isNull || m_string.length() == 0; +} + +/** + */ +const char* TranslatedString::c_str() +{ + INVARIANT(this->isValid()); + + const char* result = NULL; + if (!isNull()) + { + if (m_mode == DoTranslate) + { + if (m_utf8String == NULL) + m_utf8String = createUtf8StringTranslation(m_string); + result = m_utf8String->c_str(); + } + else // ...if we aren't translating don't bother creating another Utf8 copy just use m_string + result = m_string.c_str(); + } + + ENSURE(result == NULL || VALID_REF(result)); + return result; +} + +#if defined MSWIN +/** + */ +const wchar_t *TranslatedString::c_wstr() +{ + INVARIANT(this->isValid()); + + const wchar_t *result = NULL; + if (!isNull()) + { + if (m_wideString == NULL) + m_wideString = createWideString(m_mode, m_string); + result = m_wideString->c_str(); + } + + ENSURE(result == NULL || VALID_REF(result)); + return result; +} +#endif + +/** + */ +TranslatedString::operator string() +{ + INVARIANT(this->isValid()); + REQUIRE(!isNull()); + + string* result; + if (m_mode == DoTranslate) + { + if (m_utf8String == NULL) + m_utf8String = createUtf8StringTranslation(m_string); + result = m_utf8String; + } + else // ...if we aren't translating don't bother creating another Utf8 copy just use m_string + result = &m_string; + + return *result; +} + +#if defined MSWIN +/** + */ +TranslatedString::operator wstring() +{ + INVARIANT(this->isValid()); + REQUIRE(!isNull()); + + if (m_wideString == NULL) + m_wideString = createWideString(m_mode, m_string); + + return *m_wideString; +} +#endif + +/** + */ +TranslatedString& TranslatedString::operator =(const TranslatedString& other) +{ + REQUIRE(other.isValid()); + + if (this != &other) // ...only perform if not self assignment + { + m_mode = other.m_mode; + m_isNull = other.m_isNull; + m_string = other.m_string; + m_utf8String = (other.m_utf8String != NULL ? new string(*other.m_utf8String) : NULL); +#if defined MSWIN + m_wideString = (other.m_wideString != NULL ? new wstring(*other.m_wideString) : NULL); +#endif + } + + ENSURE(this->isValid()); + return *this; +} + +/** + */ +TranslatedString::TranslatedString(const TranslatedString& other) +{ + REQUIRE(other.isValid()); + + m_mode = other.m_mode; + m_isNull = other.m_isNull; + m_string = other.m_string; + m_utf8String = (other.m_utf8String != NULL ? new string(*other.m_utf8String) : NULL); +#if defined MSWIN + m_wideString = (other.m_wideString != NULL ? new wstring(*other.m_wideString) : NULL); +#endif + + ENSURE(this->isValid()); +} + +/** + */ +TranslatedString TranslatedString::translate(const char* str, + const char* translatorNotes) +{ + REQUIRE(VALID_REF_OR_NULL(str)); + REQUIRE(VALID_REF_OR_NULL(translatorNotes)); + + return TranslatedString(DoTranslate, str, translatorNotes); +} + +/** + */ +TranslatedString TranslatedString::dontTranslate(const char* str) +{ + REQUIRE(VALID_REF_OR_NULL(str)); + + return TranslatedString(DontTranslate, str, NULL); +} + +} +} diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TranslatedString.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TranslatedString.h new file mode 100644 index 0000000000..9e3311a2e3 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/TranslatedString.h @@ -0,0 +1,293 @@ +/* + * 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/ + * + */ +/* +***************************************************************** +***************************************************************** +******* ******** +****** Copyright (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +***************************************************************** +***************************************************************** +*/ + +#ifndef TECPLOT_STRUTIL_TRANSLATEDSTRING +#define TECPLOT_STRUTIL_TRANSLATEDSTRING + +#if defined MSWIN +#pragma warning(disable : 4181) +#endif + +namespace tecplot +{ +namespace strutil +{ + +/** + * Class responsible for translating strings for internationalization. This + * class is used both to perform the translation and to identify which strings + * are/aren't in need of translation. + * + * With the exception of the empty constructor all translated strings are + * created via static methods or inline helper functions named translate() and + * dontTranslate(). Translated strings created with a call to translate() are + * flagged as needing human translation and return the translated value at + * runtime. Translated strings created with a call to dontTranslate() are + * flagged as not needing human translation and return the non-translated value + * at runtime. Examples: + * + * ErrMsg(translate("Can I have %d cookies?", numCookies); + * ErrMsg(dontTranslate("%s"), errMsgString); + * + * Conversion methods exists for std::string so that they operate well + * together. Therefore you can pass translated strings to methods or functions + * that receive std::string or std::string references. Additionally you can + * perform std::string operations by casting the translated string to a + * std::string. For example: + * + * if (string(dialogTitle).size() != 0) + * ...do something useful + * + * We have intentionally not provided conversion methods for "const char*" (an + * internal representation of the object's string) because of the risk of the + * client using the pointer after the translated string object goes out of + * scope. + * + * @author David Ossorio + */ +class TranslatedString +{ +public: + /** + * Enumeration describing available translation modes. + */ + typedef enum { DontTranslate, DoTranslate } Mode; + + /** + * Constructs an empty translated string. It is equivalent to calling + * TranslatedString::null(). + */ + TranslatedString(); + + /** + * Convenience function for creating a NULL translated string. + * + * @return + * NULL translated string. + */ + static TranslatedString null(); + + /** + * Creates a translated string object and marks it as a string needing + * translation. + * + * @param str + * Character string to translate. + * @param translatorNotes + * Optional notes for the human translator describing the meaning + * of the string. + */ + static TranslatedString translate(const char* str, + const char* translatorNotes = NULL); + + /** + * Creates a translated string object and marks it as a string not needing + * translation. + * + * @param str + * Character string to translate. The str parameter can be a NULL + * pointer. + */ + static TranslatedString dontTranslate(const char* str); + + /** + * Destructor. + */ + virtual ~TranslatedString(); + + /** + * Indicates if the object's string is NULL. + * + * @return + * true if the object's string is NULL, false otherwise. + */ + virtual bool isNull() const; + + /** + * Indicates if the object's string is NULL or zero length. + * + * @return + * true if the object's string is NULL or zero length, false otherwise. + */ + virtual bool isNullOrZeroLength() const; + + /** + * Returns the internal representation of the object's string. Use this + * result carefully. When this object goes out of scope so does this + * references. + * + * @return + * Pointer to the internal representation of the object's string. + */ + virtual const char* c_str(); + +#if defined MSWIN + /** + * Returns the internal representation of the wide character version of the + * object's string. Use this result carefully. When this object goes out of + * scope so does this references. + * + * @return + * Pointer to the internal representation of the object's string. + */ + virtual const wchar_t* c_wstr(); +#endif + + /** + * Returns a copy of the object's string by this object. The result is + * translated or not depending on the platform and how it was created. + * + * @return + * Copy of the object's string. + */ + virtual operator std::string(); + +#if defined MSWIN + /** + * Returns a copy of the wide character version of the object's string. + * The result is translated or not depending on the platform and how it was + * created. + * + * @return + * Copy of the wide character version of the object's string. + */ + virtual operator std::wstring(); +#endif + + /** + * Assignment operator. + */ + virtual TranslatedString& operator =(const TranslatedString& other); + + /** + * Copy constructor. + */ + TranslatedString(const TranslatedString& other); + +#if !defined NO_ASSERTS + /** + * Used only for assertions. + */ + virtual bool isValid() const; +#endif /* !NO_ASSERTS */ + +private: + /** + * Constructs a translated string. This is declared private to make sure + * clients use translate() or dontTranslate() so that Tecplot's translation + * parser can easily extract strings from the source code. + * + * @param mode + * Indicates if this string is to be translated or not at runtime. + * @param str + * Character string to translate. + * @param translatorNotes + * Optional notes for the human translator describing the meaning + * of the string. + */ + TranslatedString(TranslatedString::Mode mode, + const char* str, + const char* translatorNotes); + + /** + * Convenience method for initialize a translated string. + * + * @param mode + * Indicates if this string is to be translated or not at runtime. + * @param str + * Character string to translate. + * @param translatorNotes + * Optional notes for the human translator describing the meaning + * of the string. + */ + void init(TranslatedString::Mode mode, + const char* str, + const char* translatorNotes); + + /** + * Private instance data. + */ + TranslatedString::Mode m_mode; + bool m_isNull; + std::string m_string; + std::string *m_utf8String; +#if defined MSWIN + std::wstring *m_wideString; +#endif +}; + +/** + * Convenience function for creating a translated string object and marking it + * as a string needing translation. + * + * @param str + * Character string to translate. + * @param translatorNotes + * Optional notes for the human translator describing the meaning + * of the string. + */ +inline TranslatedString translate(const char* str, + const char* translatorNotes = NULL) +{ + return TranslatedString::translate(str, translatorNotes); +} + +/** + * Convenience function for creating a translated string object and marking it + * as a string not needing translation. + * + * @param str + * Character string to translate. The str parameter can be a NULL + * pointer. + */ +inline TranslatedString dontTranslate(const char* str) +{ + return TranslatedString::dontTranslate(str); +} + +/** + * Convenience function for creating a translated string object and marks it as + * a string not needing translation. + * + * @param str + * String to translate. + */ +inline TranslatedString dontTranslate(const std::string& str) +{ + return TranslatedString::dontTranslate(str.c_str()); +} + +} +} + +#endif diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/VERSION.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/VERSION.h new file mode 100644 index 0000000000..a6528cf9de --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/VERSION.h @@ -0,0 +1,23 @@ +/* + * 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/ + * + */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/alloc.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/alloc.cpp new file mode 100644 index 0000000000..be5a0b0127 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/alloc.cpp @@ -0,0 +1,161 @@ +/* + * 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 ALLOCMODULE +#include "GLOBAL.h" +#include "ALLOC.h" +#include "TASSERT.h" +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TRACK_MEMORY_USAGE +static size_t memInUse = 0; +static size_t memTotalHighMark = 0; +static size_t memCurrentHighMark = 0; +static size_t memSavedHighMark = 0; +Mutex_pa memMutex; + +void initMemoryUsageTracking(void) +{ + REQUIRE(!Thread_ThreadingIsInitialized()); + Thread_InitMutex(&memMutex); +} + +void cleanUpMemoryUsageTracking(void) +{ + REQUIRE(!Thread_ThreadingIsInitialized()); + Thread_FreeMutex(&memMutex); +} + +void trackMemoryClearHighMark(void) +{ + memCurrentHighMark = memInUse; +} + +void trackMemorySaveHighMark(void) +{ + memSavedHighMark = memCurrentHighMark; +} + +void trackMemoryAlloc(size_t size) +{ + REQUIRE(memInUse >= 0); + + if (Thread_ThreadingIsInitialized()) + Thread_LockMutex(memMutex); + + memInUse += size; + if (memInUse > memTotalHighMark) + memTotalHighMark = memInUse; + if (memInUse > memCurrentHighMark) + memCurrentHighMark = memInUse; + + if (Thread_ThreadingIsInitialized()) + Thread_UnlockMutex(memMutex); +} + +void trackMemoryFree(size_t size) +{ + if (Thread_ThreadingIsInitialized()) + Thread_LockMutex(memMutex); + + memInUse -= size; + + if (Thread_ThreadingIsInitialized()) + Thread_UnlockMutex(memMutex); + + ENSURE(memInUse >= 0); +} + +void getMemoryUsage(size_t* memoryInUse, + size_t* memoryCurrentHighMark, + size_t* memorySavedHighMark, + size_t* memoryTotalHighMark) +{ + REQUIRE(VALID_REF_OR_NULL(memoryInUse)); + REQUIRE(VALID_REF_OR_NULL(memoryCurrentHighMark)); + REQUIRE(VALID_REF_OR_NULL(memorySavedHighMark)); + REQUIRE(VALID_REF_OR_NULL(memoryTotalHighMark)); + if (memoryInUse != NULL) + *memoryInUse = memInUse; + if (memoryCurrentHighMark != NULL) + *memoryCurrentHighMark = memCurrentHighMark; + if (memorySavedHighMark != NULL) + *memorySavedHighMark = memSavedHighMark; + if (memoryTotalHighMark != NULL) + *memoryTotalHighMark = memTotalHighMark; +} +#endif + +#if defined MSWIN && defined ALLOC_HEAP +#define HEAPMIN 512 +#endif + +#if defined MSWIN && defined ALLOC_HEAP +/** + */ +void *MSWinAlloc(DWORD nSize) +{ + long *pMem = NULL; + if (nSize < HEAPMIN) + pMem = (long *)malloc(sizeof(long) + nSize); + else + pMem = (long *)HeapAlloc(GetProcessHeap(), NULL, sizeof(long) + nSize); + if (pMem) + pMem[0] = nSize; + return (void *)&(pMem[1]); +} +#endif + +#if defined MSWIN && defined ALLOC_HEAP +/** + */ +void MSWinFree(void *pMem) +{ + REQUIRE(VALID_REF(pMem)); + if (pMem) + { + long *pMemLong = &(((long *)pMem)[-1]); + if (pMemLong[0] < HEAPMIN) + free((void *)pMemLong); + else + HeapFree(GetProcessHeap(), NULL, (void *)pMemLong); + } +} +#endif diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/arrlist.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/arrlist.cpp new file mode 100644 index 0000000000..c4955817ee --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/arrlist.cpp @@ -0,0 +1,1671 @@ +/* + * 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 + +/* + ***************************************************************** + ***************************************************************** + ******* ******** + ****** Copyright (C) 1988-2008 Tecplot, Inc. ******** + ******* All Rights Reserved. ******** + ******* ******** + ***************************************************************** + ***************************************************************** + */ + +#define ARRLISTMODULE +#include "GLOBAL.h" +#include "TASSERT.h" +#include "ALLOC.h" +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif +#include "ARRLIST.h" + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +/* + * ABSTRACT: + * + * This general purpose list uses an array implementation. The high use member + * functions have macro covers to make the implementation both efficient with + * respect to speed without compromising the internal representation. The + * internal array is allocated to fit the requested type's item size. Most + * intrinsic 'C' and Tecplot types are available. + */ + + +/** + * Copies the private array items from the specified source to the target + * location. The buffers may overlap. + * + * note + * Originally this function was a macro that called memmove + * directly: + * + * #define CopyArrayItems(TargetArray, TargetOffset, \ + * SourceArray, SourceOffset, \ + * Count, ItemSize) \ + * (memmove(&((TargetArray)[(TargetOffset)*ItemSize]), \ + * &((SourceArray)[(SourceOffset)*ItemSize]), \ + * Count*ItemSize)) + * + * This however proved troublesome as some machines replaced the memmove + * with a call to memcpy in the linker. The memcpy function does not support + * overlapping moves so I could not use it. This function should be just + * about as fast however so it is no big deal. + * + * param TargetArray + * Base address of the target array to receive the items. + * param TargetOffset + * Target offset of the first item. + * param SourceArray + * Base address of the source array supplying the items. + * param SourceOffset + * Source offset of the first item. + * param Count + * Number of items to copy. + * param ItemSize + * Item size in bytes. + */ +static void CopyArrayItems(char *TargetArray, + LgIndex_t TargetOffset, + char *SourceArray, + LgIndex_t SourceOffset, + LgIndex_t Count, + SmInteger_t ItemSize) +{ + REQUIRE(VALID_REF(TargetArray)); + REQUIRE(TargetOffset >= 0); + REQUIRE(VALID_REF(SourceArray)); + REQUIRE(SourceOffset >= 0); + REQUIRE(&TargetArray[TargetOffset] != &SourceArray[SourceOffset]); + REQUIRE(Count >= 1); + REQUIRE(1 <= ItemSize && ItemSize <= (SmInteger_t)sizeof(ArrayListItem_u)); + + void* TargetPtr = &TargetArray[TargetOffset * ItemSize]; + void* SourcePtr = &SourceArray[SourceOffset * ItemSize]; + memmove(TargetPtr, SourcePtr, ((size_t)Count) * ItemSize); +} + + +/** + * Adjusts the capacity request as necessary to minimize memory reallocations + * for large lists. Unless the request exceeds the maximum the adjusted + * capacity will be at least as big as requested however it may be larger if it + * is determined that the space requirement is growing faster. If the maximum + * is exceeded zero should be returned. + * + * param ArrayList + * Array list requesting the change in capacity. + * param CurrentCapacity + * Current capacity of the array list. + * param RequestedCapacity + * Capacity request or zero for default size. + * param ClientData + * Any client data needed for the adjustment. + * + * return + * Adjusted capacity that is at least as large as the request or zero if + * unable to satisfy the requested capacity. + */ +static LgIndex_t AdjustCapacityRequest(ArrayList_pa ArrayList, + LgIndex_t CurrentCapacity, + LgIndex_t RequestedCapacity, + ArbParam_t ClientData) +{ + LgIndex_t Result; + + REQUIRE(ArrayListIsValid(ArrayList)); + REQUIRE((RequestedCapacity == 0 && CurrentCapacity == 0) || + RequestedCapacity > CurrentCapacity); + + if (RequestedCapacity != 0 && CurrentCapacity == 0) + { + /* first allocation; assume the request is the desired capacityy */ + Result = RequestedCapacity; + } + else + { + const LgIndex_t DEFAULT_CAPACITY = 32; + LgIndex_t BlockSize = MAX(DEFAULT_CAPACITY, CurrentCapacity / 2); + if (RequestedCapacity == 0) + Result = DEFAULT_CAPACITY; + else + Result = ((RequestedCapacity - 1) / BlockSize + 1) * BlockSize; + } + + ENSURE(Result == 0 || Result >= RequestedCapacity); + return Result; +} + + +/** + * Gets the size of an individual element. + * + * param Type + * Array list element type. + * + * return + * Element size corresponding to the type. + */ +static SmInteger_t GetElementSize(ArrayListType_e Type) +{ + SmInteger_t Result; + + REQUIRE(VALID_ENUM(Type, ArrayListType_e)); + + switch (Type) + { + case ArrayListType_UnsignedChar: + Result = (SmInteger_t)sizeof(unsigned char); + break; + case ArrayListType_UnsignedShort: + Result = (SmInteger_t)sizeof(unsigned short); + break; + case ArrayListType_UnsignedInt: + Result = (SmInteger_t)sizeof(unsigned int); + break; + case ArrayListType_UnsignedLong: + Result = (SmInteger_t)sizeof(unsigned long); + break; + case ArrayListType_Int64: + Result = (SmInteger_t)sizeof(Int64_t); + break; + case ArrayListType_Char: + Result = (SmInteger_t)sizeof(char); + break; + case ArrayListType_Short: + Result = (SmInteger_t)sizeof(short); + break; + case ArrayListType_Int: + Result = (SmInteger_t)sizeof(int); + break; + case ArrayListType_Long: + Result = (SmInteger_t)sizeof(long); + break; + case ArrayListType_Float: + Result = (SmInteger_t)sizeof(float); + break; + case ArrayListType_Double: + Result = (SmInteger_t)sizeof(double); + break; + case ArrayListType_LgIndex: + Result = (SmInteger_t)sizeof(LgIndex_t); + break; + case ArrayListType_EntIndex: + Result = (SmInteger_t)sizeof(EntIndex_t); + break; + case ArrayListType_SmInteger: + Result = (SmInteger_t)sizeof(SmInteger_t); + break; + case ArrayListType_Boolean: + Result = (SmInteger_t)sizeof(Boolean_t); + break; + case ArrayListType_ArbParam: + Result = (SmInteger_t)sizeof(ArbParam_t); + break; + + case ArrayListType_UnsignedCharPtr: + Result = (SmInteger_t)sizeof(unsigned char *); + break; + case ArrayListType_UnsignedShortPtr: + Result = (SmInteger_t)sizeof(unsigned short *); + break; + case ArrayListType_UnsignedIntPtr: + Result = (SmInteger_t)sizeof(unsigned int *); + break; + case ArrayListType_UnsignedLongPtr: + Result = (SmInteger_t)sizeof(unsigned long *); + break; + case ArrayListType_Int64Ptr: + Result = (SmInteger_t)sizeof(Int64_t *); + break; + case ArrayListType_CharPtr: + Result = (SmInteger_t)sizeof(char *); + break; + case ArrayListType_ShortPtr: + Result = (SmInteger_t)sizeof(short *); + break; + case ArrayListType_IntPtr: + Result = (SmInteger_t)sizeof(int *); + break; + case ArrayListType_LongPtr: + Result = (SmInteger_t)sizeof(long *); + break; + case ArrayListType_FloatPtr: + Result = (SmInteger_t)sizeof(float *); + break; + case ArrayListType_DoublePtr: + Result = (SmInteger_t)sizeof(double *); + break; + case ArrayListType_LgIndexPtr: + Result = (SmInteger_t)sizeof(LgIndex_t *); + break; + case ArrayListType_EntIndexPtr: + Result = (SmInteger_t)sizeof(EntIndex_t *); + break; + case ArrayListType_SmIntegerPtr: + Result = (SmInteger_t)sizeof(SmInteger_t *); + break; + case ArrayListType_BooleanPtr: + Result = (SmInteger_t)sizeof(Boolean_t *); + break; + case ArrayListType_ArbParamPtr: + Result = (SmInteger_t)sizeof(ArbParam_t *); + break; + + case ArrayListType_VoidPtr: + Result = (SmInteger_t)sizeof(void *); + break; + case ArrayListType_FunctionPtr: + Result = (SmInteger_t)sizeof(void (*)()); + break; + case ArrayListType_Any: /* allows a mixed bag of items */ + Result = (SmInteger_t)sizeof(ArrayListItem_u); + break; + + default: + Result = 0; /* make some compilers happy. */ + CHECK(FALSE); + break; + } + + ENSURE(1 <= Result && Result <= (SmInteger_t)sizeof(ArrayListItem_u)); + return Result; +} + + +/** + * Calls the item destructor for each item specified. + * + * param ArrayList + * Array list needing its items destroyed. + * param ItemOffset + * Offset to the first item to destroy in the list. + * param ItemSize + * Size of each array list item. + * param Count + * Number of items to destroy. + * param ItemDestructor + * Function called for each array list item. + * param CientData + * Any client data needed for the destructor. + */ +static void DestroyItems(ArrayList_pa ArrayList, + LgIndex_t ItemOffset, + SmInteger_t ItemSize, + LgIndex_t Count, + ArrayListItemDestructor_pf ItemDestructor, + ArbParam_t ClientData) +{ + LgIndex_t Index; + + REQUIRE(ArrayListIsValid(ArrayList)); + REQUIRE(0 <= ItemOffset && ItemOffset <= ArrayList->Count - 1); + REQUIRE(1 <= Count && ItemOffset + Count <= ArrayList->Count); + REQUIRE(VALID_FN_REF(ItemDestructor)); + + for (Index = 0; + Index < Count; + Index++) + { + LgIndex_t ItemIndex = (Index + ItemOffset) * ItemSize; +#if !defined NO_ASSERTS + Boolean_t DoContinue = ItemDestructor((void *) & ArrayList->Array[ItemIndex], ClientData); + CHECK(DoContinue); /* this is a requirement of ArrayListItemDestructor_pf */ +#else + ItemDestructor((void *)&ArrayList->Array[ItemIndex], ClientData); +#endif + } +} + + +/** + * Calls the item duplicator for each item specified. + * + * param TargetArray + * Target array needing its items duplicated. + * param TargetItemOffset + * Target offset to the first duplicated item. + * param SourceArray + * Source array needing its items duplicated. + * param SourceItemOffset + * Source offset to the first item to duplicate in the list. + * param ItemSize + * Size of each array list item. + * param Count + * Number of items to duplicate. + * param ItemDuplicator + * Function called for each array list item. + * param CientData + * Any client data needed for the destructor. + * + * return + * TRUE if the duplication was a success + * FALSE otherwise + */ +static Boolean_t DuplicateItems(char *TargetArray, + LgIndex_t TargetItemOffset, + char *SourceArray, + LgIndex_t SourceItemOffset, + SmInteger_t ItemSize, + LgIndex_t Count, + ArrayListItemDuplicator_pf ItemDuplicator, + ArbParam_t ClientData) +{ + Boolean_t IsOk = TRUE; + LgIndex_t Index; + + REQUIRE(VALID_REF(TargetArray)); + REQUIRE(TargetItemOffset >= 0); + REQUIRE(VALID_REF(SourceArray)); + REQUIRE(SourceItemOffset >= 0); + REQUIRE(1 <= ItemSize && + ItemSize <= (SmInteger_t)sizeof(ArrayListItem_u)); + REQUIRE(Count >= 1); + REQUIRE(VALID_FN_REF(ItemDuplicator)); + + for (Index = 0; + Index < Count && IsOk; + Index++) + { + LgIndex_t TargetItemIndex = (Index + TargetItemOffset) * ItemSize; + LgIndex_t SourceItemIndex = (Index + SourceItemOffset) * ItemSize; + IsOk = ItemDuplicator((void *) & TargetArray[TargetItemIndex], + (void *) & SourceArray[SourceItemIndex], + ClientData); + } + + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + + +/** + * Determine if the list handle is sane. + * + * param ArrayList + * Array list in question. + * + * return + * TRUE if the array list is valid, otherwise FALSE. + */ +Boolean_t ArrayListIsValid(ArrayList_pa ArrayList) +{ + Boolean_t IsValid; + + /* this just makes sure that the NULL item global was initialized */ + INVARIANT(ArrayListNullItem.Double == 0.0); + + IsValid = (VALID_REF(ArrayList) && + VALID_ENUM(ArrayList->Type, ArrayListType_e) && + (1 <= ArrayList->ItemSize && + ArrayList->ItemSize <= (SmInteger_t)sizeof(ArrayListItem_u)) && + (0 <= ArrayList->Count && + ArrayList->Count <= ArrayList->Capacity)); + + ENSURE(VALID_BOOLEAN(IsValid)); + return IsValid; +} + + +/** + * Gets the specified array list's type. + * + * param ArrayList + * Array list of which the type is desired. + * + * return + * Array list type. + */ +ArrayListType_e ArrayListGetType(ArrayList_pa ArrayList) +{ + ArrayListType_e Result; + + REQUIRE(ArrayListIsValid(ArrayList)); + + Result = ArrayList->Type; + + ENSURE(VALID_ENUM(Result, ArrayListType_e)); + return Result; +} + + +/** + * Enlarge the list capacity to accommodate, at a minimum, the requested + * capacity (number of items). The enlarged section is initialized with zeros. + * This function can be called by clients who want to ensure that calls to + * the ArrayListSetXxx class of functions will never fail for offsets within + * the RequestedCapacity. + * + * param ArrayList + * Current capacity used as a helpful hint for the adjustment algorythm. + * param RequestedCapacity + * Capacity (number ot items) request or zero for default size. + * + * return + * TRUE if the list could be enlarged (or was large enough), + * otherwise FALSE. + */ +Boolean_t ArrayListEnlargeCapacity(ArrayList_pa ArrayList, + LgIndex_t RequestedCapacity) +{ + Boolean_t IsOk; + LgIndex_t AdjustedCapacity; + char *EnlargedArray; + + REQUIRE(ArrayListIsValid(ArrayList)); + REQUIRE(IMPLICATION(RequestedCapacity == 0, ArrayList->Capacity == 0)); + + if (RequestedCapacity == 0 || + RequestedCapacity > ArrayList->Capacity) + { + AdjustedCapacity = + ArrayList->CapacityRequestAdjuster(ArrayList, + ArrayList->Capacity, + RequestedCapacity, + ArrayList->CapacityRequestAdjusterClientData); + CHECK(AdjustedCapacity == 0 || + AdjustedCapacity >= RequestedCapacity); + + IsOk = (AdjustedCapacity != 0); /* ...were we able to meet the request? */ + if (IsOk) + { + EnlargedArray = ALLOC_ARRAY(AdjustedCapacity * ArrayList->ItemSize, + char, "array list"); + if (EnlargedArray == NULL) + { + /* try again with minimum capacity request */ + if (RequestedCapacity != 0) + AdjustedCapacity = RequestedCapacity; + else + AdjustedCapacity = 1; /* can't get smaller than this */ + EnlargedArray = ALLOC_ARRAY(AdjustedCapacity * ArrayList->ItemSize, + char, "array list"); + } + IsOk = (EnlargedArray != NULL); + } + + if (IsOk) + { + /* + * Initialize the expanded section of the array with zeros. This default + * value of zero is necessary for many other array list operations. + */ + memset(&EnlargedArray[ArrayList->Count*ArrayList->ItemSize], 0, + (AdjustedCapacity - ArrayList->Count)*ArrayList->ItemSize); + + if (ArrayList->Array != NULL) + { + if (ArrayList->Count != 0) + CopyArrayItems(EnlargedArray, 0, + ArrayList->Array, 0, + ArrayList->Count, + ArrayList->ItemSize); + FREE_ARRAY(ArrayList->Array, "array list"); + } + + ArrayList->Array = EnlargedArray; + ArrayList->Capacity = AdjustedCapacity; + } + } + else + { + IsOk = TRUE; + } + + ENSURE(ArrayListIsValid(ArrayList)); + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + + +/** + * Allocates an array list handle with the estimated capacity + * or a suitable default if an estimate is unavailable. + * + * param EstimatedCapacity + * Clients best guess at the estimated capacity (number of items) needed. + * If an estimate is not available zero the zero should be used to get the + * default capacity. + * param Type + * Type of array list being allocated. + * param CapacityRequestAdjuster + * Function to use to adjust any capacity change requests or + * NULL if the default adjuster is good enough. + * param CapacityRequestAdjusterClientData + * Any client data needed for the capacity adjustment. + * + * return + * Array list handle if sufficient memory was available, + * otherwise a handle to NULL. + */ +ArrayList_pa ArrayListAlloc(LgIndex_t EstimatedCapacity, + ArrayListType_e Type, + ArrayListCapacityRequestAdjuster_pf CapacityRequestAdjuster, + ArbParam_t CapacityRequestAdjusterClientData) +{ + ArrayList_pa Result; + + REQUIRE(EstimatedCapacity >= 0); + REQUIRE(VALID_ENUM(Type, ArrayListType_e)); + + Result = ALLOC_ITEM(ArrayList_s, "ArrayList structure"); + if (Result != NULL) + { + Result->Array = NULL; + Result->Type = Type; + Result->ItemSize = GetElementSize(Type); + Result->Count = 0; + Result->Capacity = 0; + Result->IsVisitingItems = FALSE; + if (CapacityRequestAdjuster != NULL) + { + /* install the client's capacity request adjuster */ + Result->CapacityRequestAdjuster = CapacityRequestAdjuster; + Result->CapacityRequestAdjusterClientData = CapacityRequestAdjusterClientData; + } + else + { + /* install the default capacity request adjuster */ + Result->CapacityRequestAdjuster = AdjustCapacityRequest; + Result->CapacityRequestAdjusterClientData = 0; + } + + /* enalarge the list to the estimated capacity */ + if (!ArrayListEnlargeCapacity(Result, EstimatedCapacity)) + ArrayListDealloc(&Result, NULL, 0); + } + + ENSURE(ArrayListIsValid(Result) || Result == NULL); + ENSURE(IMPLICATION(Result != NULL, Result->Capacity >= EstimatedCapacity)); + return Result; +} + + +/** + * Deallocates the list handle and set the handle to NULL. + * + * param ArrayList + * Reference to an array list handle. + * param ItemDestructor + * Destructor responsible for array list item cleanup or + * NULL if no item cleanup is desired. + * param ClientData + * Any client data needed for cleanup. + */ +void ArrayListDealloc(ArrayList_pa *ArrayList, + ArrayListItemDestructor_pf ItemDestructor, + ArbParam_t ClientData) +{ + REQUIRE(VALID_REF(ArrayList)); + REQUIRE(ArrayListIsValid(*ArrayList) || *ArrayList == NULL); + REQUIRE(VALID_FN_REF(ItemDestructor) || ItemDestructor == NULL); + + if (*ArrayList != NULL) + { + /* request item cleanup if a destructor was supplied */ + if (ItemDestructor != NULL && (*ArrayList)->Count != 0) + DestroyItems(*ArrayList, 0, (*ArrayList)->ItemSize, (*ArrayList)->Count, + ItemDestructor, ClientData); + + /* release the list */ + if ((*ArrayList)->Capacity != 0) + FREE_ARRAY((*ArrayList)->Array, "array list"); + + /* release the list structure itself */ + FREE_ITEM(*ArrayList, "ArrayList structure"); + *ArrayList = NULL; + } + + ENSURE(*ArrayList == NULL); +} + + +#if !defined USE_MACROS_FOR_FUNCTIONS +/** + * Gets the number of items currently maintained by the list. + * + * param + * Array list in question. + * + * return + * Number of items maintained by the list. + */ +LgIndex_t ArrayListGetCount_FUNC(ArrayList_pa ArrayList) +{ + LgIndex_t Result; + + REQUIRE(ArrayListIsValid(ArrayList)); + + Result = ArrayListGetCount_MACRO(ArrayList); + + ENSURE(Result >= 0); + return Result; +} +#endif + + +/** + * Empties the array list of all items. + * + * param ArrayList + * Array list from which to delete all items. + * param ItemDestructor + * Destructor responsible for array list item cleanup or + * NULL if no item cleanup is desired. + * param ClientData + * Any client data needed for cleanup. + */ +void ArrayListDeleteAllItems(ArrayList_pa ArrayList, + ArrayListItemDestructor_pf ItemDestructor, + ArbParam_t ClientData) +{ + REQUIRE(ArrayListIsValid(ArrayList)); + REQUIRE(VALID_FN_REF(ItemDestructor) || ItemDestructor == NULL); + REQUIRE(!ArrayList->IsVisitingItems); + + /* request item cleanup if a destructor was supplied */ + if (ItemDestructor != NULL && ArrayList->Count != 0) + DestroyItems(ArrayList, 0, ArrayList->ItemSize, ArrayList->Count, + ItemDestructor, ClientData); + + /* + * Fill the vacated items with zeros. This default value of zero is necessary + * for many other array list operations. + */ + if (ArrayList->Count != 0) + memset(&ArrayList->Array[0], 0, ArrayList->Count*ArrayList->ItemSize); + + ArrayList->Count = 0; + + ENSURE(ArrayListIsValid(ArrayList) && ArrayList->Count == 0); +} + + +/** + * Deletes 'Count' items from the array list. The members following the + * items deleted are shifted down accordingly to fill the vacated space. + * + * param ArrayList + * Array list containing the items to delete. + * param ItemOffset + * Offset to the first item to delete in the list. + * param Count + * Number of items to delete. + * param ItemDestructor + * Destructor responsible for array list item cleanup or + * NULL if no item cleanup is desired. + * param ClientData + * Any client data needed for cleanup. + */ +void ArrayListDeleteItems(ArrayList_pa ArrayList, + LgIndex_t ItemOffset, + LgIndex_t Count, + ArrayListItemDestructor_pf ItemDestructor, + ArbParam_t ClientData) +{ + REQUIRE(ArrayListIsValid(ArrayList)); + REQUIRE(0 <= ItemOffset && ItemOffset <= ArrayList->Count - 1); + REQUIRE(1 <= Count && ItemOffset + Count <= ArrayList->Count); + REQUIRE(VALID_FN_REF(ItemDestructor) || ItemDestructor == NULL); + REQUIRE(!ArrayList->IsVisitingItems); + + /* release the items if a destructor is installed */ + if (ItemDestructor != NULL) + DestroyItems(ArrayList, ItemOffset, ArrayList->ItemSize, Count, + ItemDestructor, ClientData); + + /* if we deleted the items from the middle of the array then */ + /* shift the end items down by 'Count' to fill the vacated space */ + if (ItemOffset + Count < ArrayList->Count) + CopyArrayItems(ArrayList->Array, ItemOffset, + ArrayList->Array, ItemOffset + Count, + ArrayList->Count - (ItemOffset + Count), + ArrayList->ItemSize); + /* + * Fill the vacated items with zeros. This default value of zero is necessary + * for many other array list operations. + */ + memset(&ArrayList->Array[(ArrayList->Count - Count)*ArrayList->ItemSize], + 0, Count*ArrayList->ItemSize); + + /* update the count but leave the capacity alone */ + ArrayList->Count -= Count; + + ENSURE(ArrayListIsValid(ArrayList)); +} + + +/** + * Deletes an item from the array list. The members following the item + * deleted are shifted down accordingly to fill the vacated space. + * + * param ArrayList + * Array list containing the item to delete. + * param ItemOffset + * Offset to the item in the list. + * param ItemDestructor + * Destructor responsible for array list item cleanup or + * NULL if no item cleanup is desired. + * param ClientData + * Any client data needed for cleanup. + */ +void ArrayListDeleteItem(ArrayList_pa ArrayList, + LgIndex_t ItemOffset, + ArrayListItemDestructor_pf ItemDestructor, + ArbParam_t ClientData) +{ + REQUIRE(ArrayListIsValid(ArrayList)); + REQUIRE(0 <= ItemOffset && ItemOffset <= ArrayList->Count - 1); + REQUIRE(VALID_FN_REF(ItemDestructor) || ItemDestructor == NULL); + + ArrayListDeleteItems(ArrayList, ItemOffset, 1, ItemDestructor, ClientData); + + ENSURE(ArrayListIsValid(ArrayList)); +} + + +/** + * Removes 'Count' items from the array list beginning at the specified + * item offset. The members following the items removed are shifted down + * accordingly to fill the vacated space. + * + * param ArrayList + * Array list containing the items to remove. + * param ItemOffset + * Offset to the first item to remove in the list. + * param Count + * Number of items to remove. + * + * return + * Array list handle referring to the removed items if sufficient + * memory was available, otherwise a handle to NULL. + */ +ArrayList_pa ArrayListRemoveItems(ArrayList_pa ArrayList, + LgIndex_t ItemOffset, + LgIndex_t Count) +{ + ArrayList_pa Result; + + REQUIRE(ArrayListIsValid(ArrayList)); + REQUIRE(0 <= ItemOffset && ItemOffset <= ArrayList->Count - 1); + REQUIRE(1 <= Count && ItemOffset + Count <= ArrayList->Count); + REQUIRE(!ArrayList->IsVisitingItems); + + /* get a copy of the items and delete them from the source */ + Result = ArrayListGetItems(ArrayList, ItemOffset, Count); + if (Result != NULL) + ArrayListDeleteItems(ArrayList, ItemOffset, Count, NULL, 0); + + ENSURE(ArrayListIsValid(ArrayList)); + ENSURE(ArrayListIsValid(Result) || Result == NULL); + return Result; +} + + +/** + * Removes an item from the array list. The members following the item + * removed are shifted down accordingly to fill the vacated space. + * + * param ArrayList + * Array list containing the item to remove. + * param ItemOffset + * Offset to the item in the list. + * + * return + * Item removed from the array list. + */ +ArrayListItem_u ArrayListRemoveItem(ArrayList_pa ArrayList, + LgIndex_t ItemOffset) +{ + ArrayListItem_u Result; + + REQUIRE(ArrayListIsValid(ArrayList)); + REQUIRE(0 <= ItemOffset && ItemOffset <= ArrayList->Count - 1); + REQUIRE(!ArrayList->IsVisitingItems); + + /* record the original item */ + CopyArrayItems((char *)&Result, 0, + ArrayList->Array, ItemOffset, + 1, ArrayList->ItemSize); + + /* delete the item from the array */ + ArrayListDeleteItems(ArrayList, ItemOffset, 1, NULL, 0); + + ENSURE(ArrayListIsValid(ArrayList)); + return Result; +} + + +/** + * Inserts copies of the items from the source list to the target list at + * the specified offset. The target list will expand to accommodate the + * additional items. The source list remains unchanged. + * + * param Target + * Array list receiving the source items. + * param ItemOffset + * Offset at which to insert the source list items. + * param Source + * Array list supplying the source items. + * + * return + * TRUE if sufficient memory permitted the operation, otherwise FALSE. + */ +Boolean_t ArrayListInsert(ArrayList_pa Target, + LgIndex_t ItemOffset, + ArrayList_pa Source) +{ + Boolean_t IsOk = TRUE; + + REQUIRE(ArrayListIsValid(Target)); + REQUIRE(ItemOffset >= 0); + REQUIRE(ArrayListIsValid(Source)); + REQUIRE(Target != Source); + REQUIRE(Target->Type == Source->Type); + REQUIRE(!Target->IsVisitingItems); + + if (Source->Count != 0) + { + LgIndex_t NeededCapacity; + + /* if necessary enlarge the target list to accommodate the request */ + if (ItemOffset > Target->Count) + NeededCapacity = ItemOffset + Source->Count; + else + NeededCapacity = Target->Count + Source->Count; + if (NeededCapacity > Target->Capacity) + IsOk = ArrayListEnlargeCapacity(Target, NeededCapacity); + + if (IsOk) + { + if (ItemOffset < Target->Count) + { + /* shift all items in the target list ahead of the */ + /* insert position up by the number of items in the */ + /* source list to make room for the new items */ + CopyArrayItems(Target->Array, ItemOffset + Source->Count, + Target->Array, ItemOffset, + Target->Count - ItemOffset, + Target->ItemSize); + Target->Count += Source->Count; + } + else + { + /* no shifting to do, just update the count */ + if (ItemOffset > Target->Count) + Target->Count = ItemOffset + Source->Count; + else + Target->Count += Source->Count; + } + + /* insert the items and update the count */ + CopyArrayItems(Target->Array, ItemOffset, + Source->Array, 0, + Source->Count, Source->ItemSize); + } + } + + ENSURE(ArrayListIsValid(Target)); + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + + +/** + * Inserts the item into the array list at the specified offset. The list will + * be expanded to accommodate the additional item. If the offset is beyond the + * end of the list it is sized accordingly and the intervening items between + * the last item of the original state and the last item of the new state are + * guaranteed to be 0. + * + * param ArrayList + * Array list target in which to insert the item. + * param ItemOffset + * Offset at which to insert the item. + * param Item + * Item to insert at the specified offset. + * + * return + * TRUE if sufficient memory permitted the operation, otherwise FALSE. + */ +Boolean_t ArrayListInsertItem(ArrayList_pa ArrayList, + LgIndex_t ItemOffset, + ArrayListItem_u Item) +{ + Boolean_t IsOk = TRUE; + LgIndex_t NeededCapacity; + + REQUIRE(ArrayListIsValid(ArrayList)); + REQUIRE(ItemOffset >= 0); + REQUIRE(!ArrayList->IsVisitingItems); + + /* if necessary enlarge the list to accommodate the request */ + if (ItemOffset > ArrayList->Count) + NeededCapacity = ItemOffset + 1; + else + NeededCapacity = ArrayList->Count + 1; + if (NeededCapacity > ArrayList->Capacity) + IsOk = ArrayListEnlargeCapacity(ArrayList, NeededCapacity); + + if (IsOk) + { + if (ItemOffset < ArrayList->Count) + { + /* shift all items in the target list ahead of the insert */ + /* position up by one to make room for the new item */ + CopyArrayItems(ArrayList->Array, ItemOffset + 1, + ArrayList->Array, ItemOffset, + ArrayList->Count - ItemOffset, + ArrayList->ItemSize); + ArrayList->Count++; + } + else + { + /* no shifting to do, just update the count */ + if (ItemOffset > ArrayList->Count) + ArrayList->Count = ItemOffset + 1; + else + ArrayList->Count++; + } + + /* insert the item */ + CopyArrayItems(ArrayList->Array, ItemOffset, + (char *)&Item, 0, + 1, ArrayList->ItemSize); + } + + ENSURE(ArrayListIsValid(ArrayList)); + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + + +/** + * Visits array list items calling the item visitor for each item. + * + * param ArrayList + * Array list needing its items destroyed. + * param ItemOffset + * Offset to the first item to visit from the list. + * param Count + * Number of items to visit. + * param ItemVisitor + * Function called for each array list item. + * param CientData + * Any client data needed for the visitor. + * + * return + * TRUE if the all element were visited, otherwise + * FALSE if the visitation was terminated early + */ +Boolean_t ArrayListVisitItems(ArrayList_pa ArrayList, + LgIndex_t ItemOffset, + LgIndex_t Count, + ArrayListItemVisitor_pf ItemVisitor, + ArbParam_t ClientData) +{ + Boolean_t DoContinue = TRUE; + Boolean_t IsVisitingItems; + SmInteger_t ItemSize; + LgIndex_t Index; + + REQUIRE(ArrayListIsValid(ArrayList)); + REQUIRE(VALID_FN_REF(ItemVisitor)); + + IsVisitingItems = ArrayList->IsVisitingItems; + ArrayList->IsVisitingItems = TRUE; /* guards against structure changes */ + + for (Index = 0, ItemSize = ArrayList->ItemSize; + Index < Count && DoContinue; + Index++) + { + LgIndex_t ItemIndex = (Index + ItemOffset) * ItemSize; + DoContinue = ItemVisitor((void *) & ArrayList->Array[ItemIndex], ClientData); + } + + ArrayList->IsVisitingItems = IsVisitingItems; + + ENSURE(ArrayList->IsVisitingItems == IsVisitingItems); + ENSURE(VALID_BOOLEAN(DoContinue)); + return DoContinue; +} + + +/** + * Gets copies of 'Count' items from the array list beginning at the + * specified item offset. Note that if the items are pointer types + * the copies are of the pointers and not the pointees. + * + * param ArrayList + * Array list containing the items to copy. + * param ItemOffset + * Offset to the first item to copy from the list. + * param Count + * Number of items to copy. + * + * return + * Array list handle referring to the copied items if sufficient + * memory was available, otherwise a handle to NULL. + */ +ArrayList_pa ArrayListGetItems(ArrayList_pa ArrayList, + LgIndex_t ItemOffset, + LgIndex_t Count) +{ + ArrayList_pa Result; + + REQUIRE(ArrayListIsValid(ArrayList)); + REQUIRE(0 <= ItemOffset && ItemOffset <= ArrayList->Count - 1); + REQUIRE(1 <= Count && ItemOffset + Count <= ArrayList->Count); + + Result = ArrayListAlloc(Count, ArrayList->Type, + ArrayList->CapacityRequestAdjuster, + ArrayList->CapacityRequestAdjusterClientData); + if (Result != NULL) + { + /* copy the original items into the result */ + CopyArrayItems(Result->Array, 0, + ArrayList->Array, ItemOffset, + Count, ArrayList->ItemSize); + Result->Count = Count; + } + + ENSURE(ArrayListIsValid(ArrayList)); + ENSURE(ArrayListIsValid(Result) || Result == NULL); + return Result; +} + + +/** + * Gets the item at the specified offset in the list. + * + * param ArrayList + * Array list containing the desired item. + * param ItemOffset + * Offset to the item in the list. + * + * return + * The requested item. + */ +ArrayListItem_u ArrayListGetItem(ArrayList_pa ArrayList, + LgIndex_t ItemOffset) +{ + ArrayListItem_u Result; + + REQUIRE(ArrayListIsValid(ArrayList)); + REQUIRE(0 <= ItemOffset && ItemOffset <= ArrayList->Count - 1); + + CopyArrayItems((char *)&Result, 0, + ArrayList->Array, ItemOffset, + 1, ArrayList->ItemSize); + + return Result; +} + + +#if !defined USE_MACROS_FOR_FUNCTIONS +/** + * Gets the item's internal reference at the specified offset in the list. + * + * WARNING: + * Some array list functions modify the internal buffer. + * This will invalidate this reference however it is + * the client's responsibility not to make further use + * of it. In addition, this reference should never be + * deallocated directly as the array list assumes the + * responsible for the cleanup. + * + * param ArrayList + * Array list containing the desired item. + * param ItemOffset + * Offset to the item in the list. + * + * return + * The internal reference to the requested item. + */ +const void *ArrayListGetItemInternalRef_FUNC(ArrayList_pa ArrayList, + LgIndex_t ItemOffset) +{ + REQUIRE(ArrayListIsValid(ArrayList)); + REQUIRE(0 <= ItemOffset && ItemOffset <= ArrayList->Count - 1); + + const void *Result = ArrayListGetItemInternalRef_MACRO(ArrayList, ItemOffset); + ENSURE(Result == NULL || VALID_REF(Result)); + return Result; +} +#endif + + +/** + * Places the item at the specified offset. If the offset is beyond the + * end of the list it is sized accordingly and the intervening items + * between the last item of the original state and the last item of the + * new state are guaranteed to be 0. + * + * param ArrayList + * Array list target in which to set the item. + * param ItemOffset + * Offset of the item. + * param Item + * Item to set at the specified offset. + * param ItemDestructor + * Destructor responsible for array list item cleanup or + * NULL if no item cleanup is desired. + * param ClientData + * Any client data needed for cleanup. + * + * return + * TRUE if sufficient memory permitted the operation, otherwise FALSE. + */ +Boolean_t ArrayListSetItem(ArrayList_pa ArrayList, + LgIndex_t ItemOffset, + ArrayListItem_u Item, + ArrayListItemDestructor_pf ItemDestructor, + ArbParam_t ClientData) +{ + Boolean_t IsOk = TRUE; + + REQUIRE(ArrayListIsValid(ArrayList)); + REQUIRE(ItemOffset >= 0); + REQUIRE(VALID_FN_REF(ItemDestructor) || ItemDestructor == NULL); + REQUIRE(IMPLICATION(ItemOffset + 1 > ArrayList->Count, + !ArrayList->IsVisitingItems)); + + /* release the item if a destructor is installed */ + if (ItemDestructor != NULL && ItemOffset < ArrayList->Count) + DestroyItems(ArrayList, ItemOffset, ArrayList->ItemSize, 1, + ItemDestructor, ClientData); + + /* if necessary enlarge the list to accommodate the request */ + if (ItemOffset + 1 > ArrayList->Capacity) + IsOk = ArrayListEnlargeCapacity(ArrayList, ItemOffset + 1); + + if (IsOk) + { + if (ItemOffset + 1 > ArrayList->Count) + ArrayList->Count = ItemOffset + 1; + CopyArrayItems(ArrayList->Array, ItemOffset, + (char *)&Item, 0, + 1, ArrayList->ItemSize); + } + + ENSURE(ArrayListIsValid(ArrayList)); + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + + +/** + * Appends the item to the list. The list will be expanded + * to accommodate the additional item. + * + * param ArrayList + * Array list target to which the item is to be appended. + * param Item + * Item to append to the array list. + * + * return + * TRUE if sufficient memory permitted the operation, otherwise FALSE. + */ +Boolean_t ArrayListAppendItem(ArrayList_pa ArrayList, + ArrayListItem_u Item) +{ + Boolean_t IsOk; + + REQUIRE(ArrayListIsValid(ArrayList)); + REQUIRE(!ArrayList->IsVisitingItems); + + IsOk = ArrayListInsertItem(ArrayList, ArrayList->Count, Item); + + ENSURE(ArrayListIsValid(ArrayList)); + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + + +/** + * Appends copies of the items from the source list to the target list. + * The source list remains unchanged. + * + * param Target + * Array list receiving the source items. + * param Source + * Array list supplying the source items. + * + * return + * TRUE if sufficient memory permitted the operation, otherwise FALSE. + */ +Boolean_t ArrayListAppend(ArrayList_pa Target, + ArrayList_pa Source) +{ + Boolean_t IsOk; + + REQUIRE(ArrayListIsValid(Target)); + REQUIRE(ArrayListIsValid(Source)); + REQUIRE(Target != Source); + REQUIRE(Target->Type == Source->Type); + REQUIRE(!Target->IsVisitingItems); + + IsOk = ArrayListInsert(Target, Target->Count, Source); + + ENSURE(ArrayListIsValid(Target)); + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + + +/** + * Copies the items of the array list. + * + * param ArrayList + * Array list to copy. + * param ItemDuplicator + * Duplicator responsible for array list item duplication or + * NULL if an exact item copy is desired. In other words for + * pointer types the effect is copy by reference. + * param ClientData + * Any client data needed for duplication. + * + * return + * Handle to a duplicate of the specified array list if sufficient + * memory permitted the operation, otherwise NULL. + */ +ArrayList_pa ArrayListCopy(ArrayList_pa ArrayList, + ArrayListItemDuplicator_pf ItemDuplicator, + ArbParam_t ClientData) +{ + ArrayList_pa Result; + + REQUIRE(ArrayListIsValid(ArrayList)); + REQUIRE(VALID_FN_REF(ItemDuplicator) || ItemDuplicator == NULL); + + Result = ArrayListAlloc(ArrayList->Count, ArrayList->Type, + ArrayList->CapacityRequestAdjuster, + ArrayList->CapacityRequestAdjusterClientData); + if (Result != NULL && ArrayList->Count != 0) + { + Boolean_t IsOk = TRUE; + if (ItemDuplicator != NULL) + /* client defines how the item duplication is performed */ + IsOk = DuplicateItems(Result->Array, 0, + ArrayList->Array, 0, + ArrayList->ItemSize, ArrayList->Count, + ItemDuplicator, ClientData); + else + /* copy the original items into the result */ + CopyArrayItems(Result->Array, 0, + ArrayList->Array, 0, + ArrayList->Count, + ArrayList->ItemSize); + if (IsOk) + Result->Count = ArrayList->Count; + else + ArrayListDealloc(&Result, NULL, 0); + } + + ENSURE(Result == NULL || + (ArrayListIsValid(Result) && Result->Count == ArrayList->Count)); + return Result; +} + + +/** + * Creates a native 'C' array containing copies of the items held in the + * source array list. + * + * param Source + * Array list containing the items of interest. + * param ItemDuplicator + * Duplicator responsible for array list item duplication or + * NULL if an exact item copy is desired. In other words for + * pointer types the effect is copy by reference. + * param ClientData + * Any client data needed for duplication. + * + * return + * Allocated array populated with copies of the members of the array list + * or NULL if there are no items in the list or if the allocation was + * not successful. The caller is responsible for deallocation of the + * array (but not the individual members unless a item duplication function + * was supplied) when it is no longer needed. + */ +void *ArrayListToArray(ArrayList_pa Source, + ArrayListItemDuplicator_pf ItemDuplicator, + ArbParam_t ClientData) +{ + void *Result; + + REQUIRE(ArrayListIsValid(Source)); + REQUIRE(VALID_FN_REF(ItemDuplicator) || ItemDuplicator == NULL); + + if (Source->Count != 0) + Result = (void *)ALLOC_ARRAY(Source->Count * Source->ItemSize, + char, "native array"); + else + Result = NULL; + + if (Result != NULL) + { + Boolean_t IsOk = TRUE; + if (ItemDuplicator != NULL) + /* client defines how the item duplication is performed */ + IsOk = DuplicateItems((char*)Result, 0, + Source->Array, 0, + Source->ItemSize, Source->Count, + ItemDuplicator, ClientData); + else + /* copy the original items into the result */ + CopyArrayItems((char *)Result, 0, + Source->Array, 0, + Source->Count, + Source->ItemSize); + if (!IsOk) + { + /* Hack to remove delete warning... */ + char *Tmp = (char *)Result; + FREE_ARRAY(Tmp, "native array"); + } + } + + ENSURE(VALID_REF(Result) || Result == NULL); + return Result; +} + + +/** + * Creates an array list containing copies of the items held in the + * native 'C' array. + * + * param Source + * Native 'C' array containing the items of interest. + * param Count + * Number of items contained in the native 'C' array. + * param Type + * Type of items contained in the native 'C' array. + * param ItemDuplicator + * Duplicator responsible for array list item duplication or + * NULL if an exact item copy is desired. In other words for + * pointer types the effect is copy by reference. + * param ClientData + * Any client data needed for duplication. + * + * return + * Array list handle containing copies of the items held in the + * native 'C' array if sufficient memory was available, otherwise + * a handle to NULL. + */ +ArrayList_pa ArrayListFromArray(void *Source, + LgIndex_t Count, + ArrayListType_e Type, + ArrayListItemDuplicator_pf ItemDuplicator, + ArbParam_t ClientData) +{ + ArrayList_pa Result; + + REQUIRE(VALID_REF(Source)); + REQUIRE(Count >= 0); + REQUIRE(VALID_ENUM(Type, ArrayListType_e)); + REQUIRE(VALID_FN_REF(ItemDuplicator) || ItemDuplicator == NULL); + + Result = ArrayListAlloc(Count, Type, NULL, 0); + if (Result != NULL && Count != 0) + { + Boolean_t IsOk = TRUE; + if (ItemDuplicator != NULL) + /* client defines how the item duplication is performed */ + IsOk = DuplicateItems(Result->Array, 0, + (char*)Source, 0, + Result->ItemSize, Count, + ItemDuplicator, ClientData); + else + /* copy the original items into the result */ + CopyArrayItems(Result->Array, 0, + (char *)Source, 0, + Count, Result->ItemSize); + if (IsOk) + Result->Count = Count; + else + ArrayListDealloc(&Result, NULL, 0); + } + + ENSURE(ArrayListIsValid(Result) || Result == NULL); + return Result; +} + + +/** + * Holds the comparator function pointer for sorting. + */ +static ArrayListItemComparator_pf ComparatorFunction = NULL; + + +/** + * Holds the context for comparisons. This information is forwarded to + * the item comparator function for sorting. + */ +static ArbParam_t ComparatorClientData = 0; + + +/** + * Holds the item size of the individual array components for sorting. + */ +static SmInteger_t ComparatorItemSize = 0; + + +/** + * Forwards the comparison test to the 'Comparator' supplied to the + * 'ArrayListQSort' function. + * + * param Item1Ref + * Reference to base address of Item1. + * param Item2Ref + * Reference to base address of Item2. + * + * return + * - A value less than zero if Item1 is less than Item2. + * - A value of zero if Item1 is equal to Item2. + * - A value greater than zero if Item1 is greater than Item2. + */ +static int QSortCompareItemsAdapter(const void *Item1Ref, + const void *Item2Ref) +{ + int Result; + ArrayListItem_u Item1; + ArrayListItem_u Item2; + + REQUIRE(Item1Ref != NULL); + REQUIRE(Item2Ref != NULL); + + /* collect up the items */ + CopyArrayItems((char *)&Item1, 0, + (char *)Item1Ref, 0, + 1, ComparatorItemSize); + CopyArrayItems((char *)&Item2, 0, + (char *)Item2Ref, 0, + 1, ComparatorItemSize); + + /* forward the call */ + Result = ComparatorFunction(Item1, Item2, ComparatorClientData); + + ENSURE(Result == -1 || Result == 0 || Result == 1); + return Result; +} + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +/** + * Sorts the array list using the qsort algorithm. + * + * param ArrayList + * Array list to sort. + * param Comparator + * Function called to compare two array list elements. + * param ClientData + * Contextual information that is passed along to the comparator function. + */ +void ArrayListQSort(ArrayList_pa ArrayList, + ArrayListItemComparator_pf Comparator, + ArbParam_t ClientData) +{ + ArrayListItemComparator_pf CurComparatorFunction; + ArbParam_t CurComparatorClientData; + SmInteger_t CurComparatorItemSize; + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + REQUIRE(ArrayListIsValid(ArrayList)); + REQUIRE(VALID_FN_REF(Comparator)); + + /* to support sort recursion we need to save off the current values */ + CurComparatorFunction = ComparatorFunction; + CurComparatorClientData = ComparatorClientData; + CurComparatorItemSize = ComparatorItemSize; + + /* set up for comparison proxy */ + ComparatorFunction = Comparator; + ComparatorClientData = ClientData; + ComparatorItemSize = ArrayList->ItemSize; + + /* sort the array */ + qsort(ArrayList->Array, ArrayList->Count, + ArrayList->ItemSize, QSortCompareItemsAdapter); + + /* cleanup */ + ComparatorFunction = CurComparatorFunction; + ComparatorClientData = CurComparatorClientData; + ComparatorItemSize = CurComparatorItemSize; + + ENSURE(ArrayListIsValid(ArrayList)); +} + +/** + * Binary searches a sorted array looking for a match using the supplied + * comparator function. If a match is found the resulting item index refers to + * the location otherwise it refers to the location where the item could be + * inserted in sorted order. + * + * param ArrayList + * Array list to sort. + * param Item + * The item for which to search. + * param Comparator + * Function called to compare the Item to the array list elements. + * param ClientData + * Contextual information that is passed along to the comparator function. + * param ItemIndex + * Pointer to the resulting position where the item was found or where the + * item could be inserted in sorted order. If the pointer is NULL the + * result position is not returned. + * + * result + * TRUE if the item was found in the list, FALSE otherwise. + */ +Boolean_t ArrayListBSearch(ArrayList_pa ArrayList, + ArrayListItem_u Item, + ArrayListItemComparator_pf Comparator, + ArbParam_t ClientData, + LgIndex_t *ItemIndex) +{ + REQUIRE(ArrayListIsValid(ArrayList)); + REQUIRE(VALID_FN_REF(Comparator)); + REQUIRE(ItemIndex == NULL || VALID_REF(ItemIndex)); + + LgIndex_t MiddleItemIndex = 0; + LgIndex_t FirstItemIndex = 0; + LgIndex_t NumItems = ArrayListGetCount(ArrayList); + LgIndex_t LastItemIndex = NumItems - 1; + Boolean_t Found = FALSE; + while (FirstItemIndex <= LastItemIndex && !Found) + { + /* calculate the middle item index for current sub-range */ + MiddleItemIndex = (FirstItemIndex + LastItemIndex) / 2; + + int CompareResult = Comparator(ArrayListGetItem(ArrayList, MiddleItemIndex), Item, ClientData); + if (CompareResult > 0) + LastItemIndex = MiddleItemIndex - 1; + else if (CompareResult < 0) + FirstItemIndex = MiddleItemIndex + 1; + else + Found = TRUE; + } + + if (ItemIndex != NULL) + { + if (Found || NumItems == 0 || FirstItemIndex < NumItems) + *ItemIndex = MiddleItemIndex; + else + *ItemIndex = NumItems; /* ...in other words it goes on the end */ + } + + ENSURE(IMPLICATION(ItemIndex != NULL, + 0 <= *ItemIndex && *ItemIndex <= ArrayListGetCount(ArrayList))); + ENSURE(VALID_BOOLEAN(Found)); + return Found; +} + +#if !defined USE_MACROS_FOR_FUNCTIONS +/** + * Gets the array list's internal buffer representation. + * + * WARNING: + * Some array list functions modify the internal buffer. + * This will invalidate this reference however it is + * the client's responsibility not to make further use + * of it. In addition, this reference should never be + * deallocated directly as the array list assumes the + * responsible for the cleanup. + * + * param ArrayList + * Array list for which a reference to the internal + * buffer is desired. + * + * return + * Reference to the array list's internal buffer. + */ +const void *ArrayListGetInternalRef_FUNC(ArrayList_pa ArrayList) +{ + REQUIRE(ArrayListIsValid(ArrayList)); + + const void *Result = ArrayListGetInternalRef_MACRO(ArrayList); + ENSURE(Result == NULL || VALID_REF(Result)); + return Result; +} +#endif diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/auxdata.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/auxdata.cpp new file mode 100644 index 0000000000..c42b222046 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/auxdata.cpp @@ -0,0 +1,809 @@ +/* + * 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 + +/* + ***************************************************************** + ***************************************************************** + ******* ******** + ****** Copyright (C) 1988-2008 Tecplot, Inc. ******** + ******* All Rights Reserved. ******** + ******* ******** + ***************************************************************** + ***************************************************************** + */ + +#define AUXDATAMODULE +#include "GLOBAL.h" +#include "TASSERT.h" +#include "Q_UNICODE.h" +#include "ALLOC.h" +#include "STRUTIL.h" +#include "ARRLIST.h" +#include "DATASET.h" +#include "STRLIST.h" +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif +#include "SET.h" +#include "AUXDATA.h" + +using namespace tecplot::strutil; + +/** + * Private auxiliary data item structure. + */ +typedef struct +{ + const char *Name; + ArbParam_t Value; + AuxDataType_e Type; + Boolean_t Retain; +} AuxDataItem_s; + +/** + * Private auxiliary data item container structure. + */ +typedef struct _AuxData_s +{ + /* invariant: ItemList is case-insensitive sorted by AuxDataItem->Name */ + ArrayList_pa ItemList; /* [dynamic] */ +} AuxData_s; + +static Mutex_pa AuxDataMutex = NULL; + + +/** + * A valid auxiliary data name character must begin with a '_' or alpha + * character and may be followed by one or more '_', '.', alpha or digit + * characters. + */ +Boolean_t AuxDataIsValidNameChar(char Char, + Boolean_t IsLeadChar) +{ + Boolean_t IsValidNameChar; + + REQUIRE("Char can be any value"); + REQUIRE(VALID_BOOLEAN(IsLeadChar)); + + IsValidNameChar = (Char == '_' || + isalpha(Char)); + if (!IsLeadChar) + IsValidNameChar = (IsValidNameChar || + Char == '.' || + isdigit(Char)); + + ENSURE(VALID_BOOLEAN(IsValidNameChar)); + return IsValidNameChar; +} + +/** + * Indicates if the auxiliary data name is valid. A valid auxiliary data name + * must begin with a '_' or alpha character and may be followed by one or + * more '_', '.', alpha or digit characters. + */ +Boolean_t AuxDataIsValidName(const char *Name) +{ + Boolean_t IsValidName; + const char *NPtr; + REQUIRE(VALID_REF(Name)); + + for (NPtr = Name, IsValidName = AuxDataIsValidNameChar(*NPtr, TRUE); + IsValidName && *NPtr != '\0'; + NPtr++) + { + IsValidName = AuxDataIsValidNameChar(*NPtr, FALSE); + } + + ENSURE(VALID_BOOLEAN(IsValidName)); + return IsValidName; +} + +/** + * Deallocates an auxiliary data item and its contents and sets the target to + * NULL. + * + * param AuxDataItem + * Reference to an auxiliary data item. + */ +static void AuxDataItemDealloc(AuxDataItem_s **AuxDataItem) +{ + REQUIRE(VALID_REF(AuxDataItem)); + REQUIRE(VALID_REF(*AuxDataItem) || *AuxDataItem == NULL); + + if (*AuxDataItem != NULL) + { + char *Name = (char *)(*AuxDataItem)->Name; + if (Name != NULL) + FREE_ARRAY(Name, "auxiliary name"); + + if ((*AuxDataItem)->Type == AuxDataType_String) + { + char *Value = (char *)(*AuxDataItem)->Value; + if (Value != NULL) + FREE_ARRAY(Value, "auxiliary value"); + } + else + CHECK(FALSE); + + FREE_ITEM(*AuxDataItem, "auxiliary data item"); + *AuxDataItem = NULL; + } + + ENSURE(*AuxDataItem == NULL); +} + +/** + * Allocates an auxiliary data item. + * + * NOTE: Copies are made of the name and value. + * + * param Name + * Auxiliary data item's name (case insenstive). + * param Value + * Auxiliary data item's value. + * param Type + * Auxiliary data item's value type. + * param Retain + * Indicates if the auxiliary data item should persist. In other words + * copied, saved, etc. + * + * return + * A new auxiliary data item or NULL if sufficient memory was not + * available. + */ +static AuxDataItem_s *AuxDataItemAlloc(const char *Name, + ArbParam_t Value, + AuxDataType_e Type, + Boolean_t Retain) +{ + AuxDataItem_s *Result; + + REQUIRE(VALID_REF(Name) && AuxDataIsValidName(Name)); + REQUIRE(IMPLICATION(Type == AuxDataType_String, + (VALID_REF((char *)Value) || + (char *)Value == NULL))); + REQUIRE(VALID_ENUM(Type, AuxDataType_e)); + REQUIRE(VALID_BOOLEAN(Retain)); + + Result = ALLOC_ITEM(AuxDataItem_s, "auxiliary data item"); + if (Result != NULL) + { + Boolean_t IsOk; + Result->Type = Type; + Result->Retain = Retain; + Result->Name = DupString(dontTranslate(Name)); + IsOk = (Result->Name != NULL); + Result->Value = 0; /* to satisfy some compilers' uninitialized warnings */ + if (IsOk && Type == AuxDataType_String) + { + char *strValue = (char *)Value; + if (strValue != NULL) + { + char *strCopy = DupString(dontTranslate(strValue)); + Result->Value = (ArbParam_t)strCopy; + IsOk = (strCopy != NULL); + } + else + Result->Value = (ArbParam_t)NULL; + } + else + CHECK(FALSE); + + if (!IsOk) + AuxDataItemDealloc(&Result); + } + + ENSURE(VALID_REF(Result) || Result == NULL); + return Result; +} + +/** + * Destroys an auxiliary data item list item. This is an item destructor + * callback for ArrayList's private data. + * + * param ItemRef + * Reference to the auxiliary data item to cleanup. + * param ClientData + * Not used. + * + * return + * TRUE is a requirement + */ +static Boolean_t AuxDataItemListItemDestructor(void *ItemRef, + ArbParam_t ClientData) +{ + AuxDataItem_s **AuxDataItemRef = (AuxDataItem_s **)ItemRef; + + REQUIRE(VALID_REF(AuxDataItemRef)); + REQUIRE(VALID_REF(*AuxDataItemRef) || *AuxDataItemRef == NULL); + + if (*AuxDataItemRef != NULL) + AuxDataItemDealloc(AuxDataItemRef); + + ENSURE(*AuxDataItemRef == NULL); + return TRUE; +} + +/** + * Destroys an auxiliary data item. This is an item destructor + * callback for ArrayList's private data. + * + * param ItemRef + * Reference to the auxiliary data to cleanup. + * param ClientData + * Not used. + * + * return + * TRUE is a requirement + */ +Boolean_t AuxDataItemDestructor(void *ItemRef, + ArbParam_t ClientData) +{ + AuxData_pa *AuxDataRef = (AuxData_pa *)ItemRef; + + REQUIRE(VALID_REF(AuxDataRef)); + REQUIRE(VALID_REF(*AuxDataRef) || *AuxDataRef == NULL); + + if (*AuxDataRef != NULL) + AuxDataDealloc(AuxDataRef); + + ENSURE(*AuxDataRef == NULL); + return TRUE; +} + + +/** + * Duplicates an auxiliary data item if its Retain flag is TRUE or if directed + * by the callback data. This is an item duplicator callback for ArrayList. + * + * param TargetItemRef + * Reference to the auxiliary data item to receive duplicate. + * param SourceItemRef + * Reference to the auxiliary data item to duplicate. + * param ClientData + * Boolean indicating if the Retain flag should be considered. + * + * return + * TRUE if the duplication was a success + * FALSE otherwise. + */ +static Boolean_t AuxDataItemDuplicator(void *TargetItemRef, + void *SourceItemRef, + ArbParam_t ClientData) +{ + Boolean_t IsOk = TRUE; + AuxDataItem_s **TargetAuxDataItemRef = (AuxDataItem_s **)TargetItemRef; + AuxDataItem_s **SourceAuxDataItemRef = (AuxDataItem_s **)SourceItemRef; + Boolean_t ConsiderRetain; + + REQUIRE(VALID_REF(TargetAuxDataItemRef)); + REQUIRE(VALID_REF(SourceAuxDataItemRef)); + REQUIRE(VALID_REF(*SourceAuxDataItemRef) || *SourceAuxDataItemRef == NULL); + REQUIRE(VALID_BOOLEAN((Boolean_t)ClientData)); + + ConsiderRetain = (Boolean_t)ClientData; + + /* duplicate the item */ + if (*SourceAuxDataItemRef != NULL && + (!ConsiderRetain || (*SourceAuxDataItemRef)->Retain)) + { + *TargetAuxDataItemRef = AuxDataItemAlloc((*SourceAuxDataItemRef)->Name, + (*SourceAuxDataItemRef)->Value, + (*SourceAuxDataItemRef)->Type, + (*SourceAuxDataItemRef)->Retain); + IsOk = (*TargetAuxDataItemRef != NULL); + } + else + *TargetAuxDataItemRef = NULL; + + ENSURE(VALID_REF(*TargetAuxDataItemRef) || *TargetAuxDataItemRef == NULL); + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + +/** + * Deallocates an auxiliary data handle and sets the handle to NULL. + * + * param AuxData + * Reference to an auxiliary data handle or reference to NULL. + */ +void AuxDataDealloc(AuxData_pa *AuxData) +{ + REQUIRE(VALID_REF(AuxData)); + REQUIRE(VALID_REF(*AuxData) || *AuxData == NULL); + + if (*AuxData != NULL) + { + ArrayListDealloc(&(*AuxData)->ItemList, AuxDataItemListItemDestructor, 0); + FREE_ITEM(*AuxData, "auxiliary data container"); + *AuxData = NULL; + } + + ENSURE(*AuxData == NULL); +} + +/** + * Allocates an auxiliary data handle. + * + * return + * Auxiliary data handle or NULL if sufficient memory was not available. + */ +AuxData_pa AuxDataAlloc(void) +{ + AuxData_pa Result = ALLOC_ITEM(AuxData_s, "auxiliary data container"); + if (Result != NULL) + { + Result->ItemList = ArrayListAlloc(0, ArrayListType_VoidPtr, NULL, 0); + if (Result->ItemList == NULL) + AuxDataDealloc(&Result); + } + + ENSURE(VALID_REF(Result) || Result == NULL); + return Result; +} + +/** + * Copies the auxiliary data and all its members who's Retain flag is TRUE + * if the ConsiderRetain flag is TRUE otherwise it copies everything. + */ +AuxData_pa AuxDataCopy(AuxData_pa AuxData, + Boolean_t ConsiderRetain) +{ + AuxData_pa Result; + + REQUIRE(VALID_REF(AuxData)); + REQUIRE(VALID_BOOLEAN(ConsiderRetain)); + + Result = ALLOC_ITEM(AuxData_s, "auxiliary data container"); + if (Result != NULL) + { + Result->ItemList = ArrayListCopy(AuxData->ItemList, + AuxDataItemDuplicator, + ConsiderRetain); + if (Result->ItemList != NULL) + { + if (ConsiderRetain) + { + /* + * Now pass through the array cleaning up the holes left by those + * auxiliary data item member who's Retain flag was FALSE and + * therefore left a VOID pointer because it was not copied. + */ + LgIndex_t ItemOffset = 0; + LgIndex_t ItemCount = ArrayListGetCount(Result->ItemList); + while (ItemOffset < ItemCount) + { + /* if there is more than one in a row remove them all at once */ + if (ArrayListGetVoidPtr(Result->ItemList, ItemOffset) == NULL) + { + LgIndex_t BaseOffsetToRemove = ItemOffset; + LgIndex_t NumItemsToRemove = 1; + while (BaseOffsetToRemove + NumItemsToRemove < ItemCount && + ArrayListGetVoidPtr(Result->ItemList, + BaseOffsetToRemove + NumItemsToRemove) == NULL) + NumItemsToRemove++; + + /* delete the NULL items */ + ArrayListDeleteItems(Result->ItemList, + BaseOffsetToRemove, + NumItemsToRemove, + NULL, 0); + + /* + * Update ItemCount but leave ItemOffset alone as it is now + * indexing the next item to examine. + */ + ItemCount = ArrayListGetCount(Result->ItemList); + } + else + ItemOffset++; + } + } + } + else + AuxDataDealloc(&Result); + } + + ENSURE(VALID_REF(Result) || Result == NULL); + return Result; +} + +/** + * Gets the current number of auxiliary data items maintained by the auxiliary. + * + * param AuxData + * Handle to auxiliary data. + * + * return + * Number of items maintained by the auxiliary data. + */ +LgIndex_t AuxDataGetNumItems(AuxData_pa AuxData) +{ + LgIndex_t NumItems; + + REQUIRE(VALID_REF(AuxData)); + + NumItems = ArrayListGetCount(AuxData->ItemList); + + ENSURE(NumItems >= 0); + return NumItems; +} + +/** + * Gets the item index of the name if found or if not found the index where an + * auxiliary data item could be inserted. + * + * param AuxData + * Handle to auxiliary data. + * param Name + * Name used for the search (case insensitive). + * param ItemIndex + * Address to hold the index of the found item or the index where an + * auxiliary data item could be inserted. + * + * return + * TRUE if the named item was found, + * FALSE otherwise. + */ +Boolean_t AuxDataGetItemIndex(AuxData_pa AuxData, + const char *Name, + LgIndex_t *ItemIndex) +{ + Boolean_t FoundItem = FALSE; + LgIndex_t Index; + LgIndex_t NumItems; + + REQUIRE(VALID_REF(AuxData)); + INVARIANT("AuxData->ItemList is case-insensitive sorted by AuxDataItem->Name"); + REQUIRE(VALID_REF(Name) && AuxDataIsValidName(Name)); + REQUIRE(VALID_REF(ItemIndex)); + + /* + * Note that the current implementation just does a linear search + * though the array looking for the index of the item or if not + * found the index of the insertion point. This should be replaced + * with a binary search. + */ + NumItems = AuxDataGetNumItems(AuxData); + +# if defined DO_LINEAR_SEARCH + { + for (Index = 0; Index < NumItems; Index++) + { + AuxDataItem_s *AuxDataItem = + (AuxDataItem_s *)ArrayListGetVoidPtr(AuxData->ItemList, Index); + int CompareResult = ustrcmp(AuxDataItem->Name, Name); + if (CompareResult >= 0) + { + FoundItem = (CompareResult == 0); + break; + } + } + } +# else + { + int low, high; + low = 0; + high = NumItems - 1; + Index = 0; + while (low <= high) + { + AuxDataItem_s *AuxDataItem; + int CompareResult; + Index = (low + high) / 2; + AuxDataItem = (AuxDataItem_s *)ArrayListGetVoidPtr(AuxData->ItemList, Index); + CompareResult = ustrcmp(Name, AuxDataItem->Name); + if (CompareResult < 0) + high = Index - 1; /* If the new name is "less" than the one we're comparing to, + don't change Index since Index is already in the right spot */ + else if (CompareResult > 0) + low = ++Index; /* If the new name it "greater" than the one we're comparing + against, we want to make sure its Index is greater than + the current name's index as well, that's why we increment Index here. */ + else + { + FoundItem = TRUE; + break; + } + } + } +# endif + + *ItemIndex = Index; + + ENSURE(VALID_BOOLEAN(FoundItem)); + ENSURE(0 <= *ItemIndex && + ((FoundItem && *ItemIndex < NumItems) || + (!FoundItem && *ItemIndex <= NumItems))); + return FoundItem; +} + +/** + * Gets the auxiliary data item at the specified index. + * + * NOTE: The name and value are a references, NOT copies. + * + * param AuxData + * Handle to auxiliary data. + * param Index + * Index of the auxiliary data item of interest. + * param Name + * Address to hold the auxiliary data item name. + * param Value + * Address to hold the auxiliary data item value. + * param Type + * Address to hold the auxiliary data item type. + * param Retain + * Address to hold the auxiliary data item retain flag. + */ +void AuxDataGetItemByIndex(AuxData_pa AuxData, + LgIndex_t Index, + const char **Name, + ArbParam_t *Value, + AuxDataType_e *Type, + Boolean_t *Retain) +{ + AuxDataItem_s *AuxDataItem; + + REQUIRE(VALID_REF(AuxData)); + INVARIANT("AuxData->ItemList is case-insensitive sorted by AuxDataItem->Name"); + REQUIRE(0 <= Index && Index < ArrayListGetCount(AuxData->ItemList)); + REQUIRE(VALID_REF(Name)); + REQUIRE(VALID_REF(Value)); + REQUIRE(VALID_REF(Type)); + REQUIRE(VALID_REF(Retain)); + + AuxDataItem = (AuxDataItem_s *)ArrayListGetVoidPtr(AuxData->ItemList, Index); + *Name = AuxDataItem->Name; + *Value = AuxDataItem->Value; + *Type = AuxDataItem->Type; + *Retain = AuxDataItem->Retain; + + ENSURE(VALID_REF(*Name) && AuxDataIsValidName(*Name)); + ENSURE(IMPLICATION(*Type == AuxDataType_String, + (VALID_REF((char *)(*Value)) || + (char *)(*Value) == NULL))); + ENSURE(VALID_ENUM(*Type, AuxDataType_e)); + ENSURE(VALID_BOOLEAN(*Retain)); +} + +/** + * Gets the auxiliary data item by the specified name if it exists. + * + * NOTE: The name and value are a references, NOT copies. + * + * param AuxData + * Handle to auxiliary data. + * param Name + * Name used for the search (case insensitive). + * param Value + * Address to hold the auxiliary data item value. + * param Type + * Address to hold the auxiliary data item type. + * param Retain + * Address to hold the auxiliary data item retain flag. + * + * return + * TRUE if the an auxilary data item by the specified name was found, + * FALSE otherwise. + */ +Boolean_t AuxDataGetItemByName(AuxData_pa AuxData, + const char *Name, + ArbParam_t *Value, + AuxDataType_e *Type, + Boolean_t *Retain) +{ + Boolean_t FoundItem; + LgIndex_t ItemIndex; + + REQUIRE(VALID_REF(AuxData)); + INVARIANT("AuxData->ItemList is case-insensitive sorted by AuxDataItem->Name"); + REQUIRE(VALID_REF(Name) && AuxDataIsValidName(Name)); + REQUIRE(VALID_REF(Value)); + REQUIRE(VALID_REF(Type)); + REQUIRE(VALID_REF(Retain)); + + FoundItem = AuxDataGetItemIndex(AuxData, Name, &ItemIndex); + if (FoundItem) + { + const char *SameName; + AuxDataGetItemByIndex(AuxData, ItemIndex, &SameName, + Value, Type, Retain); + CHECK(ustrcmp(Name, SameName) == 0); + } + + ENSURE(VALID_BOOLEAN(FoundItem)); + ENSURE(IMPLICATION(FoundItem, + IMPLICATION(*Type == AuxDataType_String, + (VALID_REF((char *)(*Value)) || + (char *)(*Value) == NULL)))); + ENSURE(IMPLICATION(FoundItem, + VALID_ENUM(*Type, AuxDataType_e))); + ENSURE(IMPLICATION(FoundItem, + VALID_BOOLEAN(*Retain))); + return FoundItem; +} + + +/** + * Get a string value from AuxData and convert it to a boolean. + */ +Boolean_t AuxDataGetBooleanItemByName(AuxData_pa AuxData, /* IN */ + const char *Name, /* IN */ + Boolean_t *Value, /* OUT */ + AuxDataType_e *Type, /* OUT */ + Boolean_t *Retain) /* OUT */ +{ + Boolean_t FoundItem; + + REQUIRE(VALID_REF(AuxData)); + INVARIANT("AuxData->ItemList is case-insensitive sorted by AuxDataItem->Name"); + REQUIRE(VALID_REF(Name) && AuxDataIsValidName(Name)); + REQUIRE(VALID_REF(Value)); + REQUIRE(VALID_REF(Type)); + REQUIRE(VALID_REF(Retain)); + + ArbParam_t strValue; + FoundItem = AuxDataGetItemByName(AuxData, + Name, + &strValue, + Type, + Retain); + + if (FoundItem && + (ustrcmp((char *)strValue, "YES") == 0 || + ustrcmp((char *)strValue, "YEP") == 0 || + ustrcmp((char *)strValue, "Y") == 0 || + ustrcmp((char *)strValue, "TRUE") == 0 || + ustrcmp((char *)strValue, "T") == 0 || + ustrcmp((char *)strValue, "ON") == 0 || + ustrcmp((char *)strValue, "1") == 0)) + { + *Value = TRUE; + } + else + { + *Value = FALSE; + } + + ENSURE(VALID_BOOLEAN(FoundItem)); + ENSURE(VALID_BOOLEAN(*Value)); + return FoundItem; +} + + +/** + * Adds the auxiliary data item to the auxiliary data or replaces it if one + * already exists by the same name. + * + * NOTE: The auxiliary data makes copies of the name and value. + * + * param AuxData + * Auxiliary data handle. + * param Name + * Auxiliary data item's name (case insenstive). + * param Value + * Auxiliary data item's value. + * param Type + * Auxiliary data item's value type. + * param Retain + * Indicates if the auxiliary data item should persist. + * + * return + * TRUE if the item was added to the auxiliary data. + */ +Boolean_t AuxDataSetItem(AuxData_pa AuxData, + const char *Name, + ArbParam_t Value, + AuxDataType_e Type, + Boolean_t Retain) +{ + Boolean_t IsOk; + AuxDataItem_s *AuxDataItem; + + REQUIRE(VALID_REF(AuxData)); + INVARIANT("AuxData->ItemList is case-insensitive sorted by AuxDataItem->Name"); + REQUIRE(VALID_REF(Name) && AuxDataIsValidName(Name)); + REQUIRE(IMPLICATION(Type == AuxDataType_String, + (VALID_REF((char *)Value) || + (char *)Value == NULL))); + REQUIRE(VALID_ENUM(Type, AuxDataType_e)); + REQUIRE(VALID_BOOLEAN(Retain)); + + AuxDataItem = AuxDataItemAlloc(Name, Value, Type, Retain); + IsOk = (AuxDataItem != NULL); + if (IsOk) + { + LgIndex_t ItemIndex; + ArrayListItem_u ListItem; + + /* add or replace the item to the list */ + ListItem.VoidPtr = (void *)AuxDataItem; + if (!AuxDataGetItemIndex(AuxData, Name, &ItemIndex)) + IsOk = ArrayListInsertItem(AuxData->ItemList, ItemIndex, ListItem); + else + IsOk = ArrayListSetItem(AuxData->ItemList, ItemIndex, ListItem, + AuxDataItemListItemDestructor, 0); + + if (!IsOk) + AuxDataItemDealloc(&AuxDataItem); + } + + ENSURE(VALID_BOOLEAN(IsOk)); + INVARIANT("AuxData->ItemList is case-insensitive sorted by AuxDataItem->Name"); + return IsOk; +} + +/** + * Deletes the auxiliary data item at the specified index. + * + * param AuxData + * Auxiliary data handle. + * param Index + * Index of the auxiliary data item of interest. + */ +void AuxDataDeleteItemByIndex(AuxData_pa AuxData, + LgIndex_t Index) +{ + REQUIRE(VALID_REF(AuxData)); + REQUIRE(0 <= Index && Index < ArrayListGetCount(AuxData->ItemList)); + + ArrayListDeleteItem(AuxData->ItemList, Index, AuxDataItemListItemDestructor, 0); +} + +/** + * Deletes the auxiliary data item by the specified name if it exists. + * + * param AuxData + * Auxiliary data handle. + * param Name + * Name used for the search (case insensitive). + * + * return + * TRUE if the an auxilary data item by the specified name was found, + * FALSE otherwise. + */ +Boolean_t AuxDataDeleteItemByName(AuxData_pa AuxData, + const char *Name) +{ + Boolean_t FoundItem; + LgIndex_t ItemIndex; + + REQUIRE(VALID_REF(AuxData)); + REQUIRE(VALID_REF(Name) && AuxDataIsValidName(Name)); + + FoundItem = AuxDataGetItemIndex(AuxData, Name, &ItemIndex); + if (FoundItem) + AuxDataDeleteItemByIndex(AuxData, ItemIndex); + + ENSURE(VALID_BOOLEAN(FoundItem)); + return FoundItem; +} + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/dataio.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/dataio.cpp new file mode 100644 index 0000000000..a88c7c1f43 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/dataio.cpp @@ -0,0 +1,695 @@ +/* + * 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, /*[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 */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/dataio4.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/dataio4.cpp new file mode 100644 index 0000000000..18374dfe7b --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/dataio4.cpp @@ -0,0 +1,3357 @@ +/* + * 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 DATAIO4MODULE +#include "GLOBAL.h" +#include "TASSERT.h" +#include "Q_UNICODE.h" +#include "ALLOC.h" + +#include "AUXDATA.h" +#include "DATASET.h" +#include "FILESTREAM.h" + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#include "GEOM2.h" +#include "GEOM.h" +#include "INPUT.h" +#include "SET.h" +#include "TEXT.h" +#include "DATAIO4.h" +#include "DATASET0.h" + +#include "STRUTIL.h" +#include "ARRLIST.h" +#include "STRLIST.h" +#include "Q_MSG.h" + +#if defined IRIS +#include +#endif + +using namespace tecplot::strutil; + +#if !defined(TECPLOTKERNEL) && defined(MSWIN) +# pragma warning(disable : 4244) +#endif + +/*END HEADER*/ + +/* + * This module contains mostly low level i/o functions. + */ + +#if defined DECALPHA || defined COMPAQALPHA +#define _IEEE_FP_INEXACT +#define _IEEE_FP +#endif + +#if defined SUN41 +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +/********************************************************************** + ********************************************************************** + ********************** INPUT ************************** + ********************************************************************** + **********************************************************************/ + +static char FilterFloatChar(float X) +{ + char C; + if (((X >= 32.0) && (X <= 127.0)) || + ((X >= 160.0) && (X <= 255.0)) || + (X == 0.0)) + C = (char)X; + else + C = '?'; + return (C); +} + + +double GetNextValue(FileStream_s *FileStream, + FieldDataType_e FieldDataType, + double VMin, + double VMax, + Boolean_t *IsOk) +{ + double X = 0.0; + + REQUIRE(VALID_REF(IsOk) && VALID_BOOLEAN(*IsOk)); + REQUIRE(!(*IsOk) || VALID_FIELD_DATA_TYPE(FieldDataType)); + REQUIRE(!(*IsOk) || VALID_REF(FileStream)); + + if (*IsOk) + { + switch (FieldDataType) + { + case FieldDataType_Float : + { + float XX; + + *IsOk = (TP_FREAD(&XX, 4, 1, FileStream->File) == 1); + + if (!FileStream->IsByteOrderNative) + REVERSE_4_BYTES(&XX); + + if (*IsOk) + X = XX; + else + X = 0.0; + } break; + case FieldDataType_Double : + { + double XX; + + *IsOk = (TP_FREAD(&XX, sizeof(double), 1, FileStream->File) == 1); + if (!FileStream->IsByteOrderNative) + REVERSE_8_BYTES(&XX); + + if (*IsOk) + X = XX; + else + X = 0.0; + } break; + case FieldDataType_Int32 : + { + Int32_t L; + *IsOk = (TP_FREAD(&L, sizeof(Int32_t), 1, FileStream->File) == 1); + if (!FileStream->IsByteOrderNative) + REVERSE_4_BYTES(&L); + if (*IsOk) + X = (double)L; + } break; + case FieldDataType_Int16 : + { + Int16_t S; + *IsOk = (TP_FREAD(&S, sizeof(Int16_t), 1, FileStream->File) == 1); + if (!FileStream->IsByteOrderNative) + REVERSE_2_BYTES(&S); + if (*IsOk) + X = (double)S; + } break; + case FieldDataType_Byte : + { + Byte_t B; + *IsOk = (TP_FREAD(&B, sizeof(Byte_t), 1, FileStream->File) == 1); + if (*IsOk) + X = (double)B; + } break; + case FieldDataType_Bit : + { + /* + * Important note: + * Reading bit data a value at a time is only valid for a + * single bit value. If the file contains a block of more than + * one bit value and you attempt to read it a bit at a time it + * will not work as Tecplot does not buffer the read. In order + * to read a block of bits you must perform a block read. + */ + Byte_t B; + *IsOk = (TP_FREAD(&B, sizeof(Byte_t), 1, FileStream->File) == 1); + if (*IsOk) + X = (double)(B & (Byte_t)01); + } break; + default: CHECK(FALSE); break; + } + + if (*IsOk) + { + if ((X < VMin) || (X > VMax)) + { + *IsOk = FALSE; + } + } + } + + return X; +} + + +LgIndex_t GetNextI(FileStream_s *FileStream, + Boolean_t *IsOk) +{ + LgIndex_t I = 0; + + REQUIRE(VALID_REF(IsOk) && VALID_BOOLEAN(*IsOk)); + REQUIRE(!(*IsOk) || (VALID_REF(FileStream) && VALID_REF(FileStream->File))); + + if (*IsOk) + { + Int32_t Int32Val; + *IsOk = (TP_FREAD((void *) & Int32Val, 4, 1, FileStream->File) == 1); + if (!FileStream->IsByteOrderNative) + REVERSE_4_BYTES(&Int32Val); + + I = Int32Val; + } + return I; +} + + +LgIndex_t GetIoFileInt(FileStream_s *FileStream, + short Version, + LgIndex_t IMin, + LgIndex_t IMax, + Boolean_t *IsOk) +{ + LgIndex_t I = 0; + + REQUIRE(VALID_REF(IsOk) && VALID_BOOLEAN(*IsOk)); + REQUIRE(!(*IsOk) || (0 < Version && Version <= TecplotBinaryFileVersion)); + REQUIRE(!(*IsOk) || (VALID_REF(FileStream) && VALID_REF(FileStream->File))); + REQUIRE(!(*IsOk) || IMin <= IMax); + + if (!(*IsOk)) + return (0); + + if (Version <= 63) + { + float X; + if (*IsOk) + { + X = (float)GetNextValue(FileStream, FieldDataType_Float, + (double)IMin - 1.0e-10, + (double)IMax + 1.0e-10, IsOk); + if (*IsOk) + { + if (ABS(X) < (float)MAXINDEX) + I = (LgIndex_t)X; + else + *IsOk = FALSE; + } + else + *IsOk = FALSE; + } + } + else + { + I = GetNextI(FileStream, IsOk); + } + + if ((I < IMin) || (I > IMax)) + *IsOk = FALSE; + + return (I); +} + +/** + * Basically this is "realloc" but apparently "realloc" doesn't behave reliably + * on all platforms. + */ +static Boolean_t ReallocString(char **String, + LgIndex_t NewLength) +{ + Boolean_t IsOk; + char *NewString; + + REQUIRE(VALID_REF(String)); + REQUIRE(*String == NULL || VALID_REF(*String)); + REQUIRE((*String != NULL && NewLength >= (LgIndex_t)strlen(*String)) || + (*String == NULL && NewLength >= 0)); + + NewString = ALLOC_ARRAY(NewLength + 1, char, "reallocated string"); + IsOk = (NewString != NULL); + if (IsOk) + { + if (*String == NULL) + { + NewString[0] = '\0'; + } + else + { + strcpy(NewString, *String); + FREE_ARRAY(*String, "old string"); + } + *String = NewString; + } + + ENSURE(VALID_BOOLEAN(IsOk)); + ENSURE(IMPLICATION(IsOk, VALID_REF(*String))); + return IsOk; +} + + +/** + * Reads a string from all versions of a binary plt file. + * + * param FileStream + * Open file stream positioned at the string to read. + * param IVersion + * Binary file version number. + * param MaxCharacters + * IVersion < 63 + * This value is exactly the number of characters (actually floats, each + * one representing a character's ordinal value) to read from the file. + * IVersion >= 63 and ProcessData == TRUE + * If non-zero, this value represents the largest string to be returned. + * In other words, larger strings are read from the file but an allocated + * string of up to MaxCharacters is returned. A zero value indicates that + * the string size is unlimited and determined only by the actual length + * of the string in the file. + * param TargetStr + * Pointer to hold the allocated string if ProcessData == TRUE. + * param ProcessData + * Indicates if the read string should be retrieved. + * + * return + * TRUE if the read was successful with an allocated string *TargetStr + * containing the string read (no larger than requested or necessary), + * FALSE otherwise. + */ +Boolean_t ReadInString(FileStream_s *FileStream, + short IVersion, + int MaxCharacters, + char **TargetStr, + Boolean_t ProcessData) +{ + Boolean_t IsOk = TRUE; + + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE(0 < IVersion && IVersion <= TecplotBinaryFileVersion); + REQUIRE(IMPLICATION(IVersion < 63 || ProcessData, MaxCharacters >= 0)); + REQUIRE(IMPLICATION(ProcessData, VALID_REF(TargetStr))); + REQUIRE(VALID_BOOLEAN(ProcessData)); + + if (IVersion < 63) + { + /* + * One word per character. Read Exactly "MaxCharacters" number of words. + */ + float X; + + if (ProcessData) + { + *TargetStr = ALLOC_ARRAY(MaxCharacters + 1, char, "target string"); + IsOk = (*TargetStr != NULL); + } + + if (IsOk) + { + LgIndex_t I; + for (I = 0; IsOk && I < MaxCharacters; I++) + { + X = (float)GetNextValue(FileStream, FieldDataType_Float, 0.0, 127.0, &IsOk); + if (!IsOk) + break; + if (ProcessData) + (*TargetStr)[I] = FilterFloatChar(X); + } + if (ProcessData) + (*TargetStr)[I] = '\0'; + } + else + { + ErrMsg(translate("Cannot allocate memory for string during read", + "'string' meaning the computer science data type")); + } + } + else + { +#define MAX_STRBUFFER_LEN 4095 + static char StrBuffer[MAX_STRBUFFER_LEN+1]; + LgIndex_t StrBufferLen = 0; + LgIndex_t TargetStrLen = 0; + LgIndex_t I = 0; + LgIndex_t CharValue = 0; + + if (ProcessData) + *TargetStr = NULL; + + do + { + CharValue = GetIoFileInt(FileStream, IVersion, 0, 255, &IsOk); + if (IsOk && ProcessData) + { + /* massage the character if necessary */ + if ((CharValue < 32 && CharValue != '\0' && CharValue != '\n') || + (CharValue >= 128 && CharValue < 160)) + CharValue = ' '; + + /* + * if the limit is not exceded, stuff the + * character into the buffer + */ + if (CharValue != '\0' && + (I < MaxCharacters || MaxCharacters == 0)) + { + StrBuffer[StrBufferLen] = (char)CharValue; + StrBufferLen++; + } + + if (CharValue == '\0' || + StrBufferLen == MAX_STRBUFFER_LEN) + { + if (StrBufferLen != 0 || *TargetStr == NULL) + { + StrBuffer[StrBufferLen] = '\0'; + TargetStrLen += StrBufferLen; + IsOk = ReallocString(TargetStr, TargetStrLen); + if (IsOk) + strcat(*TargetStr, StrBuffer); + StrBufferLen = 0; /* reset the string buffer */ + } + } + } + + I++; + } + while (IsOk && (char)CharValue != '\0'); + + /* if we failed cleanup if necessary */ + if (!IsOk && + ProcessData && + *TargetStr != NULL) + { + FREE_ARRAY(*TargetStr, "failed read string"); + *TargetStr = NULL; + } + } + + ENSURE(IMPLICATION(ProcessData, + (VALID_REF(*TargetStr) || *TargetStr == NULL))); + ENSURE(VALID_BOOLEAN(IsOk)); + return (IsOk); +} + +/** + */ +static void ReadDoubleBlock(FileStream_s *FileStream, + Boolean_t DoRead, + double *Buffer, + LgIndex_t StartIndex, + LgIndex_t NumValues, + Boolean_t *IsOk) +{ + if (DoRead) + { + double *DPtr = Buffer + StartIndex; + *IsOk = (TP_FREAD(DPtr, sizeof(double), NumValues, FileStream->File) == (size_t)NumValues); + if (!FileStream->IsByteOrderNative && *IsOk) + { + LgIndex_t N; + for (N = 0; N < NumValues; N++) + REVERSE_8_BYTES(&DPtr[N]); + } + } + else + *IsOk = (TP_FSEEK(FileStream->File, NumValues * sizeof(double), SEEK_CUR) == 0); +} + +/** + */ +static void ReadFloatBlock(FileStream_s *FileStream, + Boolean_t DoRead, + float *Buffer, + LgIndex_t StartIndex, + LgIndex_t NumValues, + Boolean_t *IsOk) +{ + if (DoRead) + { + float *FPtr = Buffer + StartIndex; + *IsOk = (TP_FREAD(FPtr, sizeof(float), NumValues, FileStream->File) == (size_t)NumValues); + if (!FileStream->IsByteOrderNative && *IsOk) + { + LgIndex_t N; + for (N = 0; N < NumValues; N++) + REVERSE_4_BYTES(&FPtr[N]); + } + } + else + *IsOk = (TP_FSEEK(FileStream->File, NumValues * sizeof(float), SEEK_CUR) == 0); +} + + +/** + */ +static void ReadBitBlock(FileStream_s *FileStream, + Boolean_t DoRead, + Byte_t *Buffer, + LgIndex_t NumValues, + Boolean_t *IsOk) +{ + /* + * Do not allow reading of bit values if startindex is not 0. + * (This means geometries cannot use bit data. + */ + LgIndex_t NumBytes = (NumValues + 7) / 8; + if (DoRead) + { + *IsOk = (TP_FREAD(Buffer, + sizeof(Byte_t), + NumBytes, + FileStream->File) == (size_t)NumBytes); + } + else + *IsOk = (TP_FSEEK(FileStream->File, NumBytes * sizeof(Byte_t), SEEK_CUR) == 0); +} + +/** + */ +void ReadByteBlock(FileStream_s *FileStream, + Boolean_t DoRead, + Byte_t *Buffer, + HgIndex_t StartIndex, + HgIndex_t NumValues, + Boolean_t *IsOk) +{ + if (DoRead) + { + *IsOk = (TP_FREAD(Buffer + StartIndex, + sizeof(Byte_t), + NumValues, + FileStream->File) == (size_t)NumValues); + } + else + *IsOk = (TP_FSEEK(FileStream->File, NumValues * sizeof(Byte_t), SEEK_CUR) == 0); +} + + +/** + */ +void ReadInt16Block(FileStream_s *FileStream, + Boolean_t DoRead, + Int16_t *Buffer, + HgIndex_t StartIndex, + HgIndex_t NumValues, + Boolean_t *IsOk) +{ + if (DoRead) + { + Int16_t *IntPtr = Buffer + StartIndex; + *IsOk = (TP_FREAD(IntPtr, + sizeof(Int16_t), + NumValues, + FileStream->File) == (size_t)NumValues); + + if (!FileStream->IsByteOrderNative && *IsOk) + { + LgIndex_t N; + for (N = 0; N < NumValues; N++) + REVERSE_2_BYTES(&IntPtr[N]); + } + } + else + *IsOk = (TP_FSEEK(FileStream->File, NumValues * sizeof(Int16_t), SEEK_CUR) == 0); +} + +/** + */ +void ReadInt16BlockToInt32(FileStream_s *FileStream, + Boolean_t DoRead, + Int32_t *Buffer, + HgIndex_t StartIndex, + HgIndex_t NumValues, + Boolean_t *IsOk) +{ + REQUIRE(VALID_REF(FileStream)); + REQUIRE(VALID_BOOLEAN(DoRead)); + REQUIRE(VALID_REF(Buffer)); + REQUIRE(StartIndex >= 0); + REQUIRE(NumValues >= 0); + REQUIRE(VALID_REF(IsOk) && VALID_BOOLEAN(*IsOk)); + + if (DoRead) + { + HgIndex_t EndIndex = StartIndex + NumValues; + for (HgIndex_t ValueIndex = StartIndex; *IsOk && ValueIndex < EndIndex; ValueIndex++) + { + Int16_t Value; + *IsOk = (TP_FREAD(&Value, sizeof(Int16_t), 1, FileStream->File) == 1); + if (!FileStream->IsByteOrderNative && *IsOk) + REVERSE_2_BYTES(&Value); + Buffer[ValueIndex] = (Int32_t)Value; + } + } + else + *IsOk = (TP_FSEEK(FileStream->File, NumValues * sizeof(Int16_t), SEEK_CUR) == 0); +} + +/** + */ +void ReadInt32Block(FileStream_s *FileStream, + Boolean_t DoRead, + Int32_t *Buffer, + HgIndex_t StartIndex, + HgIndex_t NumValues, + Boolean_t *IsOk) +{ + if (DoRead) + { + Int32_t *IntPtr = Buffer + StartIndex; + *IsOk = (TP_FREAD(IntPtr, + sizeof(Int32_t), + NumValues, + FileStream->File) == (size_t)NumValues); + + if (!FileStream->IsByteOrderNative && *IsOk) + { + LgIndex_t N; + for (N = 0; N < NumValues; N++) + REVERSE_4_BYTES(&IntPtr[N]); + } + } + else + *IsOk = (TP_FSEEK(FileStream->File, NumValues * sizeof(Int32_t), SEEK_CUR) == 0); +} + +/** + */ +void ReadPureBlock(FileStream_s *FileStream, + Boolean_t DoRead, + void *Buffer, + FieldDataType_e FieldDataType, + HgIndex_t StartIndex, + HgIndex_t NumValues, + Boolean_t *IsOk) +{ + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE(VALID_BOOLEAN(DoRead)); + REQUIRE(!DoRead || VALID_REF(Buffer)); + REQUIRE(VALID_FIELD_DATA_TYPE(FieldDataType)); + REQUIRE(StartIndex >= 0); + REQUIRE(NumValues >= 0); + REQUIRE(VALID_REF(IsOk) && VALID_BOOLEAN(*IsOk)); + + switch (FieldDataType) + { + case FieldDataType_Float : + { + ReadFloatBlock(FileStream, + DoRead, + (float *)Buffer, + StartIndex, + NumValues, + IsOk); + } break; + case FieldDataType_Double : + { + ReadDoubleBlock(FileStream, + DoRead, + (double *)Buffer, + StartIndex, + NumValues, + IsOk); + } break; + case FieldDataType_Bit : + { + if (StartIndex != 0) + { + ErrMsg(translate("Internal Error: Attempt to read bit data at non-zero offset", + "see Tecplot User's manual for a definition of 'bit' data")); + *IsOk = FALSE; + } + else + ReadBitBlock(FileStream, + DoRead, + (Byte_t *)Buffer, + NumValues, + IsOk); + } break; + case FieldDataType_Byte : + { + ReadByteBlock(FileStream, + DoRead, + (Byte_t *)Buffer, + StartIndex, + NumValues, + IsOk); + } break; + case FieldDataType_Int16 : + { + ReadInt16Block(FileStream, + DoRead, + (Int16_t *)Buffer, + StartIndex, + NumValues, + IsOk); + } break; + case FieldDataType_Int32 : + { + ReadInt32Block(FileStream, + DoRead, + (Int32_t *)Buffer, + StartIndex, + NumValues, + IsOk); + } break; + case FieldDataType_IJKFunction : /* Not used yet */ + case FieldDataType_Int64 : /* Not used yet */ + default: CHECK(FALSE); break; + } + ENSURE(VALID_BOOLEAN(*IsOk)); +} + +/** + */ +void ReadBlock(FileStream_s *FileStream, + FieldData_pa FieldData, + Boolean_t DoRead, + FieldDataType_e FieldDataTypeInFile, + HgIndex_t StartIndex, + HgIndex_t EndIndex, + Boolean_t *IsOk) +{ + REQUIRE(VALID_REF(IsOk) && VALID_BOOLEAN(*IsOk)); + REQUIRE(IMPLICATION(IsOk, VALID_REF(FileStream))); + REQUIRE(IMPLICATION(IsOk, VALID_FIELD_DATA_TYPE(FieldDataTypeInFile))); + REQUIRE(VALID_BOOLEAN(DoRead)); + REQUIRE(IMPLICATION(DoRead, VALID_REF(FieldData))); + + /* + * Bit data is packed into bytes. Since Tecplot doesn't buffer reads it can + * not perform bit by bit value reads and therefore must only perform block + * reads of bit data. + */ + Boolean_t ReadByBlock = IMPLICATION(DoRead, GetFieldDataType(FieldData) == FieldDataTypeInFile); + REQUIRE(ReadByBlock || (FieldDataTypeInFile != FieldDataType_Bit)); + + if (*IsOk) + { + LgIndex_t NumValues = EndIndex - StartIndex + 1; + if (ReadByBlock) + { + void *data_array; + if (DoRead) + data_array = GetFieldDataVoidPtr(FieldData); + else + data_array = NULL; + ReadPureBlock(FileStream, + DoRead, + data_array, + FieldDataTypeInFile, + StartIndex, + NumValues, + IsOk); + } + else + { + LgIndex_t N; + for (N = 0; *IsOk && (N < NumValues); N++) + { + double D = GetNextValue(FileStream, FieldDataTypeInFile, -LARGEDOUBLE, LARGEDOUBLE, IsOk); + if (DoRead) + SetFieldValue(FieldData, N + StartIndex, D); + } + } + } +} + +/** + */ +void ReadClassicOrderedCCBlock(FileStream_s *DataFileStream, + FieldData_pa FieldData, + FieldDataType_e FieldDataTypeInFile, + LgIndex_t NumIPtsInFile, + LgIndex_t NumJPtsInFile, + LgIndex_t NumKPtsInFile, + Boolean_t *IsOk) +{ + REQUIRE(IMPLICATION(*IsOk, VALID_REF(DataFileStream))); + REQUIRE(IMPLICATION(*IsOk, VALID_FIELD_DATA_TYPE(FieldDataTypeInFile))); + REQUIRE(VALID_REF(FieldData)); + REQUIRE(NumIPtsInFile >= 0); + REQUIRE(NumJPtsInFile >= 0); + REQUIRE(NumKPtsInFile >= 0); + REQUIRE(VALID_REF(IsOk) && VALID_BOOLEAN(*IsOk)); + + if (*IsOk) + { + LgIndex_t J, K; + LgIndex_t NumIJPts = NumIPtsInFile * NumJPtsInFile; + LgIndex_t IEnd = MAX(NumIPtsInFile - 1, 1); + LgIndex_t JEnd = MAX(NumJPtsInFile - 1, 1); + LgIndex_t KEnd = MAX(NumKPtsInFile - 1, 1); + LgIndex_t NumValues = (IEnd * JEnd * KEnd); + Boolean_t IsLinear = ((NumJPtsInFile == 1 && NumKPtsInFile == 1) || + (NumIPtsInFile == 1 && NumKPtsInFile == 1) || + (NumIPtsInFile == 1 && NumJPtsInFile == 1)); + if (IsLinear) + ReadBlock(DataFileStream, FieldData, TRUE, FieldDataTypeInFile, + 0, NumValues - 1, IsOk); + else + for (K = 0; K < KEnd && IsOk; K++) + for (J = 0; J < JEnd && IsOk; J++) + { + LgIndex_t CellIndex = 0 + (J * NumIPtsInFile) + (K * NumIJPts); + ReadBlock(DataFileStream, FieldData, TRUE, FieldDataTypeInFile, + CellIndex, CellIndex + IEnd - 1, IsOk); + } + } + + ENSURE(VALID_BOOLEAN(*IsOk)); +} + +/** + */ +static void AdjustCustomColor(short IVersion, + ColorIndex_t *BColor) +{ + REQUIRE(0 < IVersion && IVersion <= TecplotBinaryFileVersion); + REQUIRE(VALID_REF(BColor)); + + if ((IVersion < 70) && (*BColor >= 15) && (*BColor <= 22)) + *BColor -= 7; +} + + +/* + * ReadInDataFileTypeTitleAndVarNames replaces ReadInDataFileTitleAndVarNames + * and reads in the filetype as well in files with version >= 109. + */ +Boolean_t ReadInDataFileTypeTitleAndVarNames(FileStream_s *FileStream, + short IVersion, + char **DataSetTitle, + DataFileType_e *FileType, + int *NumVars, + StringList_pa *VarNames) +{ + EntIndex_t CurVar; + Boolean_t IsOk = TRUE; + + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE(0 < IVersion && IVersion <= TecplotBinaryFileVersion); + REQUIRE(VALID_REF(DataSetTitle) || (DataSetTitle == NULL)); + REQUIRE(VALID_REF(FileType) || (FileType == NULL)); + REQUIRE(VALID_REF(NumVars)); + REQUIRE(VALID_REF(VarNames) || (VarNames == NULL)); + + *NumVars = 0; + if (DataSetTitle) + *DataSetTitle = NULL; + if (IVersion >= 109) + { + if (FileType) + *FileType = (DataFileType_e)GetIoFileInt(FileStream, + IVersion, + 0, + DataFileType_Solution, + &IsOk); + else + GetIoFileInt(FileStream, + IVersion, + 0, + DataFileType_Solution, + &IsOk); + } + if (ReadInString(FileStream, + IVersion, + ((IVersion < 63) ? 80 : MaxChrsDatasetTitle), + DataSetTitle, + (Boolean_t)(DataSetTitle != NULL))) + { + if (DataSetTitle) + TrimLeadAndTrailSpaces(*DataSetTitle); + *NumVars = GetIoFileInt(FileStream, IVersion, 0, MAXZONEMAP, &IsOk); + } + else + IsOk = FALSE; + + if (IsOk && (*NumVars > MaxNumZonesOrVars)) + { + ErrMsg(translate("Too many variables")); + IsOk = FALSE; + } + + if (IsOk && VarNames) + { + if (*NumVars > 0) + { + /* allocate a string list filled with NULL's */ + *VarNames = StringListAlloc(); + IsOk = (*VarNames != NULL); + if (IsOk) + IsOk = StringListSetString(*VarNames, *NumVars - 1, NULL); + + if (!IsOk) + { + if (*VarNames != NULL) + StringListDealloc(VarNames); + ErrMsg(translate("Out of space while allocating var names")); + } + } + } + + for (CurVar = 0; IsOk && (CurVar < *NumVars); CurVar++) + { + char *VName = NULL; + + IsOk = ReadInString(FileStream, + IVersion, + ((IVersion < 63) ? 5 : MaxChrsVarName), + VarNames ? &VName : NULL, + (Boolean_t)(VarNames != NULL)); + if (IsOk && VarNames) + { + if (VName == NULL) + { + /* NULL variable names are converted to empty names */ + VName = ALLOC_ARRAY(1, char, "empty variable name"); + strcpy(VName, ""); + } + TrimLeadAndTrailSpaces(VName); + + /* + * variables are not allowed to have litteral new line characters + * within them but they can sneek in from ASCII data files so + * convert any to their appropriate two character representation + */ + IsOk = ReplaceNewlineWithBackslashN(&VName); + + IsOk = IsOk && StringListSetString(*VarNames, CurVar, VName); + if (VName != NULL) + FREE_ARRAY(VName, "variable name"); + } + + if (!IsOk) + { + if (VarNames && *VarNames) + StringListDealloc(VarNames); + ErrMsg(translate("Out of space while allocating variable names")); + } + } + ENSURE(VALID_BOOLEAN(IsOk)); + return (IsOk); +} + + + + +/** + */ +static Boolean_t ReadInPresetZoneColor(FileStream_s *FileStream, + short IVersion, + ZoneSpec_s *ZoneSpec) +{ + Boolean_t IsOk = TRUE; + LgIndex_t ZoneColor; + + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE(0 < IVersion && IVersion <= TecplotBinaryFileVersion); + REQUIRE(VALID_REF(ZoneSpec)); + + ZoneColor = GetIoFileInt(FileStream, IVersion, -1, LastBasicColor, &IsOk); + if (IsOk) + { + if (VALID_BASIC_COLOR(ZoneColor)) + { + ZoneSpec->ZoneLoadInfo.PresetZoneColor = (EntIndex_t)ZoneColor; + AdjustCustomColor(IVersion, &ZoneSpec->ZoneLoadInfo.PresetZoneColor); + } + else if (ZoneColor != -1) + IsOk = FALSE; + } + + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + +/** + */ +static void ConvertCommonTimeToSolutionTime(ZoneSpec_s *ZoneSpec) +{ + REQUIRE(VALID_REF(ZoneSpec)); + REQUIRE(ZoneSpec->AuxData == NULL || VALID_REF(ZoneSpec->AuxData)); + + LgIndex_t ItemIndex; + if (ZoneSpec->AuxData != NULL && + AuxDataGetItemIndex(ZoneSpec->AuxData, AuxData_Common_Time, &ItemIndex)) + { + const char *SameName; + ArbParam_t Value; + AuxDataType_e Type; + Boolean_t Retain; + + AuxDataGetItemByIndex(ZoneSpec->AuxData, ItemIndex, + &SameName, &Value, &Type, &Retain); + CHECK(ustrcmp(AuxData_Common_Time, SameName) == 0); + CHECK(Type == AuxDataType_String); + + char *EndPtr = NULL; + double SolutionTime = strtod((const char *)Value, &EndPtr); + if (EndPtr != (char *)Value) + { + /* we only allow white space to trail a value */ + while (isspace(*EndPtr)) + EndPtr++; + } + if (EndPtr != (char *)Value && *EndPtr == '\0') + { + ZoneSpec->SolutionTime = SolutionTime; + ZoneSpec->StrandID = STRAND_ID_PENDING; + AuxDataDeleteItemByIndex(ZoneSpec->AuxData, ItemIndex); + } + } +} + +/* + * Pass1 for a zone reads in and initializes the zone structures. + * These structures are released later if the user elects to not read them + * in. + */ +Boolean_t ReadInZoneHeader(FileStream_s *FileStream, + short IVersion, + ZoneSpec_s *ZoneSpec, + Set_pa IsVarCellCentered, + EntIndex_t NumVars, + Boolean_t *IsRawFNAvailable, + LgIndex_t *FNNumBndryConns) +{ + EntIndex_t Var; + Boolean_t IsOk = TRUE; + LgIndex_t I1; + + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE(0 < IVersion && IVersion <= TecplotBinaryFileVersion); + REQUIRE(VALID_REF(ZoneSpec)); + REQUIRE(IsVarCellCentered == NULL || VALID_REF(IsVarCellCentered)); + REQUIRE(NumVars >= 0); + REQUIRE(VALID_REF(IsRawFNAvailable)); + REQUIRE(VALID_REF(FNNumBndryConns)); + + SetZoneSpecDefaults(ZoneSpec); + + if (IsVarCellCentered != NULL) + { + /* assign default variable value location: nodal */ + ClearSet(IsVarCellCentered); + IsOk = ExpandSet(IsVarCellCentered, NumVars, FALSE); + } + + if (IsOk) + IsOk = ReadInString(FileStream, IVersion, + ((IVersion < 63) ? 10 : MaxChrsZnTitle), + &ZoneSpec->Name, + TRUE); + + if (IsOk && ZoneSpec->Name == NULL) + { + /* NULL zone names are converted to empty names */ + ZoneSpec->Name = ALLOC_ARRAY(1, char, "empty zone name"); + IsOk = (ZoneSpec->Name != NULL); + if (IsOk) + strcpy(ZoneSpec->Name, ""); + } + + if (IsOk) + TrimLeadAndTrailSpaces(ZoneSpec->Name); + + if (IVersion < 101) + { + Boolean_t IsZoneFinite; + DataFormat_e ZoneDataFormat; + + I1 = GetIoFileInt(FileStream, IVersion, 0, 3, &IsOk); + + if ((I1 < 0) || (I1 > 3)) + { + return (FALSE); + } + + ZoneDataFormat = (DataFormat_e)I1; + + IsZoneFinite = (ZoneDataFormat == DataFormat_FEPoint || + ZoneDataFormat == DataFormat_FEBlock); + + ZoneSpec->ZoneLoadInfo.IsInBlockFormat = (ZoneDataFormat == DataFormat_IJKBlock || + ZoneDataFormat == DataFormat_FEBlock); + + if (IVersion > 62) + IsOk = ReadInPresetZoneColor(FileStream, IVersion, ZoneSpec); + + if (IVersion < 60) + GetNextValue(FileStream, FieldDataType_Float, -LARGEDOUBLE, LARGEDOUBLE, &IsOk); /* Old ZPlane Value */ + + if (IsOk) + { + ZoneSpec->NumPtsI = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk); + ZoneSpec->NumPtsJ = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk); + if (IVersion >= 60) + ZoneSpec->NumPtsK = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk); + else + ZoneSpec->NumPtsK = 1; + } + + if (IsOk) + { + /* If IMax,JMax, & KMax are all zero then this zone was "zombied" by + a partial read to make layout files align. */ + + if (!((ZoneSpec->NumPtsI == 0) && + (ZoneSpec->NumPtsJ == 0) && + (ZoneSpec->NumPtsK == 0)) && + ((ZoneSpec->NumPtsI <= 0) || + (ZoneSpec->NumPtsJ <= 0) || + (ZoneSpec->NumPtsK < 0) || + ((!IsZoneFinite && (ZoneSpec->NumPtsK == 0))))) + { + ErrMsg(translate("Datafile is corrupted")); + IsOk = FALSE; + } + + if (IsZoneFinite) + { + if (IVersion >= 61) + { + ZoneSpec->Type = (ZoneType_e)(ZoneSpec->NumPtsK + 1); + switch (ZoneSpec->Type) + { + case ZoneType_FETriangle: ZoneSpec->NumPtsK = 3; break; + case ZoneType_FEQuad: ZoneSpec->NumPtsK = 4; break; + case ZoneType_FETetra: ZoneSpec->NumPtsK = 4; break; + case ZoneType_FEBrick: ZoneSpec->NumPtsK = 8; break; + case ZoneType_FELineSeg: ZoneSpec->NumPtsK = 2; break; + default: + { + ErrMsg(translate("Datafile corrupted: Invalid element type for FE DataSet")); + IsOk = FALSE; + } + } + } + else + { + ZoneSpec->Type = ZoneType_FEQuad; + ZoneSpec->NumPtsK = 4; + } + } + else + { + ZoneSpec->Type = ZoneType_Ordered; + + ZoneSpec->ICellDim = ZoneSpec->NumPtsI - 1; + ZoneSpec->JCellDim = ZoneSpec->NumPtsJ - 1; + ZoneSpec->KCellDim = ZoneSpec->NumPtsK - 1; + } + } + + /* + * Raw and user defined boundary face neighbors connections were not in + * this or previous versions of the binary data files. + */ + *IsRawFNAvailable = FALSE; + *FNNumBndryConns = 0; + } + else + { + if (IsOk && (IVersion >= 107)) + { + ZoneSpec->ParentZone = GetIoFileInt(FileStream, IVersion, -1, MAXZONEMAP - 1, &IsOk); + if (!IsOk) + ErrMsg(translate("Invalid datafile: parent zone assignment must be to an existing zone within the same datafile.")); + } + + if (IsOk && (IVersion >= 106)) + { + /* Strand ID and solution time. Strand ID's of STRAND_ID_PENDING, -2, instruct Tecplot to generate strand ID's */ + ZoneSpec->StrandID = GetIoFileInt(FileStream, IVersion, -2, MAXZONEMAP - 1, &IsOk); + ZoneSpec->SolutionTime = GetNextValue(FileStream, FieldDataType_Double, -LARGEDOUBLE, LARGEDOUBLE, &IsOk); + if (!IsOk) + ErrMsg(translate("Invalid datafile: bad StrandID or SolutionTime")); + } + + /* preset zone color */ + IsOk = IsOk && ReadInPresetZoneColor(FileStream, IVersion, ZoneSpec); + + /* ZoneType */ + I1 = (ZoneType_e)GetIoFileInt(FileStream, IVersion, 0, 7, &IsOk); + switch (I1) + { + case 0: ZoneSpec->Type = ZoneType_Ordered; break; + case 1: ZoneSpec->Type = ZoneType_FELineSeg; break; + case 2: ZoneSpec->Type = ZoneType_FETriangle; break; + case 3: ZoneSpec->Type = ZoneType_FEQuad; break; + case 4: ZoneSpec->Type = ZoneType_FETetra; break; + case 5: ZoneSpec->Type = ZoneType_FEBrick; break; + case 6: ZoneSpec->Type = ZoneType_FEPolygon; break; + case 7: ZoneSpec->Type = ZoneType_FEPolyhedron; break; + default: + { + ErrMsg(translate("Invalid datafile: unknown zone type.")); + IsOk = FALSE; + } break; + } + + /* DataPacking (Always BLOCK starting with file version 112 so removed from binary format) */ + if (IVersion < 112) + ZoneSpec->ZoneLoadInfo.IsInBlockFormat = + ((DataPacking_e)GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk) == DataPacking_Block); + else + ZoneSpec->ZoneLoadInfo.IsInBlockFormat = TRUE; + + /* is the variable value location specified? */ + if ((Boolean_t)GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk) && IsOk) + { + /* Variable Value Location foreach Var */ + for (Var = 0; Var < NumVars && IsOk; Var++) + { + if ((Boolean_t)GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk) && IsOk && + IsVarCellCentered != NULL) + { + IsOk = (ZoneSpec->ZoneLoadInfo.IsInBlockFormat); + if (IsOk) + IsOk = AddToSet(IsVarCellCentered, Var, FALSE); + else + ErrMsg(translate("Invalid datafile: cell centered " + "variable must be in block format.", + "See the Tecplot User's Manual for a definition of 'block format'")); + } + } + } + + /* are raw face neighbors supplied in the data section? */ + if (IVersion >= 108 && IsOk) + { + *IsRawFNAvailable = GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk); + if (*IsRawFNAvailable && + (ZoneSpec->Type == ZoneType_Ordered || + ZoneSpec->Type == ZoneType_FELineSeg)) + { + IsOk = FALSE; + ErrMsg(translate("Invalid datafile: raw face neighbors may not be " + "supplied for ordered or FE line segment zones.")); + } + } + else + *IsRawFNAvailable = FALSE; + + /* + * If raw face neighbors are available in the datafile then Tecplot + * should not auto-assign the neighbors after the load. + */ + ZoneSpec->FNAreCellFaceNbrsSupplied = *IsRawFNAvailable; + + /* miscellaneous face neighbor info */ + *FNNumBndryConns = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk); + if (*FNNumBndryConns != 0) + ZoneSpec->FNMode = (FaceNeighborMode_e)GetIoFileInt(FileStream, IVersion, 0, 3, &IsOk); + + if (IVersion >= 108 && IsOk) + { + Boolean_t FaceNeighborsComplete = FALSE; + if (*FNNumBndryConns != 0 && + ZoneSpec->Type != ZoneType_Ordered) + FaceNeighborsComplete = (Boolean_t)GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk); + + /* + * If the user defined face neighbors completely specify all the + * face neighbors then we don't want to auto-assign the cell face + * neighbors after loading. If they are not complete then leave the + * setting (as set above) dependent on the availability of the raw + * face neighbors. + * + * NOTE: + * This is a rather inefficient way to specify face neighbors. + */ + if (FaceNeighborsComplete) + ZoneSpec->FNAreCellFaceNbrsSupplied = TRUE; + } + + if (ZoneSpec->Type == ZoneType_Ordered) + { + /* IMax, JMax, KMax */ + ZoneSpec->NumPtsI = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk); + ZoneSpec->NumPtsJ = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk); + ZoneSpec->NumPtsK = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk); + /* + * if not a zombie zone (zombie zone: points in all dimensions are + * zero) then points in each direction must be specified + */ + if (IsOk && + !(ZoneSpec->NumPtsI == 0 && + ZoneSpec->NumPtsJ == 0 && + ZoneSpec->NumPtsK == 0) && + (ZoneSpec->NumPtsI == 0 || + ZoneSpec->NumPtsJ == 0 || + ZoneSpec->NumPtsK == 0)) + { + ErrMsg(translate("Invalid data file: incorrect specification of " + "I, J, or K points for ordered data set.")); + IsOk = FALSE; + } + } + else + { + ZoneSpec->NumPtsI = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk); + if (ZoneSpec->Type == ZoneType_FEPolygon || ZoneSpec->Type == ZoneType_FEPolyhedron) + { + ZoneSpec->NumPtsK = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk); // ...NumFaces + if (IVersion >= 111) + { + ZoneSpec->NumFaceNodes = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk); + ZoneSpec->NumFaceBndryFaces = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk); + ZoneSpec->NumFaceBndryItems = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk); + } + } + else + { + switch (ZoneSpec->Type) + { + case ZoneType_FETriangle: ZoneSpec->NumPtsK = 3; break; + case ZoneType_FEQuad: ZoneSpec->NumPtsK = 4; break; + case ZoneType_FETetra: ZoneSpec->NumPtsK = 4; break; + case ZoneType_FEBrick: ZoneSpec->NumPtsK = 8; break; + case ZoneType_FELineSeg: ZoneSpec->NumPtsK = 2; break; + default : + { + ErrMsg(translate("Invalid data file: invalid element type for FE data set.")); + IsOk = FALSE; + } + } + } + ZoneSpec->NumPtsJ = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk); + + ZoneSpec->ICellDim = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk); + ZoneSpec->JCellDim = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk); + ZoneSpec->KCellDim = GetIoFileInt(FileStream, IVersion, 0, MAXINDEX, &IsOk); + } + + /* Zone Auxiliary Data indicator followed by Zone Auxiliary Data */ + for (I1 = GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk); + IsOk && I1 != 0; + I1 = GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk)) + { + if (ZoneSpec->AuxData == NULL) + ZoneSpec->AuxData = AuxDataAlloc(); + IsOk = (ZoneSpec->AuxData != NULL); + if (IsOk) + IsOk = ReadInAuxData(FileStream, IVersion, ZoneSpec->AuxData); + } + } + + /* + * Convert AuxZone's Common.Time from non-time aware data files to zone + * solution time if it exists. + */ + if (IVersion < 106 && IsOk) + ConvertCommonTimeToSolutionTime(ZoneSpec); + + ENSURE(VALID_BOOLEAN(IsOk)); + return (IsOk); +} + + + + +/* + * Pass1 for Custom labels simply acknowledges that a custom label was + * parsed and skips over the labels. + */ + +Boolean_t ReadInCustomLabels(FileStream_s *FileStream, + short IVersion, + Boolean_t OkToLoad, + StringList_pa *CustomLabelBase) +{ + LgIndex_t NumLabels; + short I; + Boolean_t IsOk = TRUE; + + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE(IVersion > 0); + REQUIRE(VALID_BOOLEAN(OkToLoad)); + REQUIRE(!(OkToLoad) || VALID_REF(CustomLabelBase)); + + NumLabels = (short)GetIoFileInt(FileStream, IVersion, 1, MAXINDEX, &IsOk); + if (IsOk && NumLabels != 0 && OkToLoad) + { + *CustomLabelBase = StringListAlloc(); + IsOk = (*CustomLabelBase != NULL); + if (!IsOk) + ErrMsg(translate("Cannot allocate memory for Custom Labels.")); + } + + for (I = 0; IsOk && (I < NumLabels); I++) + { + char *TLabel = NULL; + + IsOk = ReadInString(FileStream, IVersion, + 1024, + &TLabel, + OkToLoad); + TrimLeadAndTrailSpaces(TLabel); + + if (IsOk && OkToLoad) + { +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + IsOk = StringListAppendString(*CustomLabelBase, TLabel); + if (TLabel != NULL) + FREE_ARRAY(TLabel, "custom label"); + if (!IsOk) + ErrMsg(translate("Cannot allocate memory for Custom Label.")); + } + } + if (!IsOk) + ErrMsg(translate("Invalid custom axis label record in binary datafile")); + + ENSURE(VALID_BOOLEAN(IsOk)); + ENSURE(!(IsOk && NumLabels != 0 && OkToLoad) || + StringListValid(*CustomLabelBase)); + return IsOk; +} + + +Boolean_t ReadInUserRec(FileStream_s *FileStream, + short IVersion, + int MaxCharactersAllowed, + char **UserRec) /* NULL if to ignore */ +{ + if (!ReadInString(FileStream, IVersion, + MaxCharactersAllowed, + UserRec, + (Boolean_t)(UserRec != NULL))) + { + ErrMsg(translate("Invalid USERREC record in binary datafile")); + return (FALSE); + } + return (TRUE); +} + + +/** + */ +Boolean_t ReadInAuxData(FileStream_s *FileStream, + short IVersion, + AuxData_pa AuxData) +{ + Boolean_t IsOk; + Boolean_t DoCollectData; + char *AuxName = NULL; + LgIndex_t AuxValueType; + char *AuxValue = NULL; + + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE(0 < IVersion && IVersion <= TecplotBinaryFileVersion); + REQUIRE(AuxData == NULL || VALID_REF(AuxData)); + + DoCollectData = (AuxData != NULL); + IsOk = ReadInString(FileStream, + IVersion, + MaxChrsVarName, /* ... seems reasonable */ + &AuxName, + DoCollectData); + if (IsOk && DoCollectData && !AuxDataIsValidName(AuxName)) + { + ErrMsg(translate("Invalid auxiliary data name.")); + IsOk = FALSE; + } + + /* + * currently only one value type is supported + * 0: AuxiliaryValueFormat_String + */ + if (IsOk) + { + AuxValueType = GetIoFileInt(FileStream, IVersion, 0, 0, &IsOk); + if (IsOk && (AuxValueType != (LgIndex_t)AuxDataType_String)) + { + ErrMsg(translate("Unsupported auxiliary data type")); + IsOk = FALSE; + } + } + + if (IsOk) + IsOk = ReadInString(FileStream, + IVersion, + MaxChrsAuxValueString, + &AuxValue, + DoCollectData); + if (IsOk && DoCollectData) + IsOk = AuxDataSetItem(AuxData, + AuxName, (ArbParam_t)AuxValue, + AuxDataType_String, + TRUE); /* Retain */ + + /* cleanup: auxiliary data made a copy of the name and value */ + if (AuxName != NULL) + FREE_ARRAY(AuxName, "data set auxiliary data item name"); + if (AuxValue != NULL) + FREE_ARRAY(AuxValue, "data set auxiliary data item value"); + + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + + +static void GetZoneAttachment(FileStream_s *FileStream, + short IVersion, + EntIndex_t *Z, + Boolean_t *IsAttached, + Boolean_t *IsOk) +{ + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE(VALID_REF(Z)); + REQUIRE(VALID_REF(IsAttached)); + REQUIRE(VALID_REF(IsOk) && VALID_BOOLEAN(*IsOk)); + + if (IVersion >= 47) + *Z = (EntIndex_t)GetIoFileInt(FileStream, IVersion, -1, MAXZONEMAP, IsOk); + else + *Z = 0; + + if (IVersion < 70) + (*Z)--; + + if (*Z == -1) + { + *Z = 0; + *IsAttached = FALSE; + } + else + *IsAttached = TRUE; + + ENSURE(VALID_BOOLEAN(*IsAttached)); + ENSURE(VALID_BOOLEAN(*IsOk)); + ENSURE(*Z >= 0); +} + + +static Boolean_t ReadMacroFunctionCommand(FileStream_s *FileStream, + short IVersion, + Boolean_t OkToLoad, + char **MacroFunctionCommand) +{ + Boolean_t Result = FALSE; + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE(IVersion > 0); + REQUIRE(VALID_BOOLEAN(OkToLoad)); + REQUIRE(VALID_REF(MacroFunctionCommand)); + + Result = ReadInString(FileStream, IVersion, 0, MacroFunctionCommand, OkToLoad); + + ENSURE(VALID_BOOLEAN(Result)); + return (Result); +} + + +/* + * Pass1 for Geometries simply acknowledges that a geometry was + * parsed and skips over the geometry. + */ +Boolean_t ReadInGeometry(FileStream_s *FileStream, + short IVersion, + Boolean_t OkToLoad, + Geom_s *Geom, + LgIndex_t MaxDataPts) +{ + LgIndex_t I; + LgIndex_t S; + FieldDataType_e FFT; + Boolean_t IsOk = TRUE; + TranslatedString ErrMsgString = translate("Invalid geometry record"); + + REQUIRE(VALID_REF(Geom)); + + if (IVersion < 70) + FFT = FieldDataType_Float; + else + FFT = FieldDataType_Double; + + if (IVersion < 101) + I = GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk); + else + I = GetIoFileInt(FileStream, IVersion, 0, 4, &IsOk); + + if (I == 0) + Geom->PositionCoordSys = CoordSys_Grid; + else if (I == 1) + Geom->PositionCoordSys = CoordSys_Frame; + /* + * I == 2 is for CoordSys_FrameOffset and is not used currently + * + * I == 3 is for the old window coordinate system + */ + else if (I == 4) + Geom->PositionCoordSys = CoordSys_Grid3D; + else + { + ErrMsgString = translate("Invalid geometry coordinate system"); + IsOk = FALSE; + } + + Geom->Scope = (Scope_e)GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk); + if (IVersion >= 102) + Geom->DrawOrder = (DrawOrder_e)GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk); + Geom->AnchorPos.Generic.V1 = GetNextValue(FileStream, FFT, -LARGEDOUBLE, LARGEDOUBLE, &IsOk); + Geom->AnchorPos.Generic.V2 = GetNextValue(FileStream, FFT, -LARGEDOUBLE, LARGEDOUBLE, &IsOk); + if (IVersion >= 45) + Geom->AnchorPos.Generic.V3 = GetNextValue(FileStream, FFT, -LARGEDOUBLE, LARGEDOUBLE, &IsOk); + else + Geom->AnchorPos.Generic.V3 = 0.0; + + GetZoneAttachment(FileStream, IVersion, &Geom->Zone, &Geom->AttachToZone, &IsOk); + + Geom->BColor = (SmInteger_t)GetIoFileInt(FileStream, IVersion, 0, 255, &IsOk); + + AdjustCustomColor(IVersion, &Geom->BColor); + + if (IVersion > 47) + { + Geom->FillBColor = (SmInteger_t)GetIoFileInt(FileStream, IVersion, 0, 255, &IsOk); + Geom->IsFilled = (Boolean_t)GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk); + AdjustCustomColor(IVersion, &Geom->FillBColor); + } + else + { + Geom->FillBColor = Geom->BColor; + Geom->IsFilled = FALSE; + } + + if (IVersion < 101) + { + Geom->GeomType = (GeomType_e)GetIoFileInt(FileStream, IVersion, 0, 5, &IsOk); + if (Geom->GeomType == GeomType_LineSegs3D) + { + /* + * GeomType_LineSegs3D is deprecated, converter to GeomType_LineSegs + * with CoordSys_Grid3D instead + */ + Geom->GeomType = GeomType_LineSegs; + Geom->PositionCoordSys = CoordSys_Grid3D; /*...should have been anyway */ + } + } + else + { + Geom->GeomType = (GeomType_e)GetIoFileInt(FileStream, IVersion, 0, 4, &IsOk); + } + + /* + * Check geom coord sys versus geom type + */ + if (Geom->PositionCoordSys == CoordSys_Grid3D && + Geom->GeomType != GeomType_LineSegs) + { + ErrMsgString = translate("Mismatch between geometry coordinate system and geometry type"); + IsOk = FALSE; + } + + if (IVersion > 41) + { + Geom->LinePattern = (LinePattern_e)GetIoFileInt(FileStream, IVersion, 0, (LgIndex_t)LinePattern_DashDotDot, &IsOk); + } + else + { + Geom->LinePattern = (LinePattern_e)((int)Geom->GeomType % 2); + Geom->GeomType = (GeomType_e)((int)Geom->GeomType / 10); + } + + if ((IVersion < 49) && ((short)(Geom->GeomType) == 2)) + { + Geom->GeomType = GeomType_Rectangle; + Geom->IsFilled = TRUE; + } + + if ((IVersion < 70) && ((short)(Geom->GeomType) > 1)) + Geom->GeomType = (GeomType_e)((short)Geom->GeomType + 1); + + ResetString(&Geom->MacroFunctionCommand, NULL, TRUE); + + Geom->ImageResizeFilter = ImageResizeFilter_Texture; + + if (IVersion >= 70) + { + Geom->PatternLength = GetNextValue(FileStream, FFT, + PatternLengthInputSpec.Min, + PatternLengthInputSpec.Max, + &IsOk); + Geom->LineThickness = GetNextValue(FileStream, FFT, + LineThicknessInputSpec.Min, + LineThicknessInputSpec.Max, + &IsOk); + Geom->NumEllipsePts = (SmInteger_t)GetIoFileInt(FileStream, IVersion, 2, MaxPtsCircleOrEllipse, &IsOk); + Geom->ArrowheadStyle = (ArrowheadStyle_e)GetIoFileInt(FileStream, IVersion, 0, (LgIndex_t)ArrowheadStyle_Hollow, &IsOk); + Geom->ArrowheadAttachment = (ArrowheadAttachment_e)GetIoFileInt(FileStream, IVersion, + 0, + (LgIndex_t)ArrowheadAttachment_AtBothEnds, + &IsOk); + + Geom->ArrowheadSize = GetNextValue(FileStream, FFT, + ArrowheadSizeInputSpec.Min, + ArrowheadSizeInputSpec.Max, + &IsOk); + Geom->ArrowheadAngle = GetNextValue(FileStream, FFT, + ArrowheadAngleInputSpec.Min, + ArrowheadAngleInputSpec.Max, + &IsOk); + + if (IVersion >= 75) + { + IsOk = ReadMacroFunctionCommand(FileStream, + IVersion, + OkToLoad, + &Geom->MacroFunctionCommand); + } /* version >= 75 */ + } /* version >= 70 */ + else + { + Geom->LineThickness = 0.001; + Geom->PatternLength = 0.02; + Geom->ArrowheadStyle = ArrowheadStyle_Plain; + Geom->ArrowheadAttachment = ArrowheadAttachment_None; + Geom->ArrowheadSize = 0.05; + Geom->ArrowheadAngle = 12.0 / DEGPERRADIANS; + } + + if (IVersion < 41) + { + GetNextValue(FileStream, FieldDataType_Float, -LARGEDOUBLE, LARGEDOUBLE, &IsOk); + GetNextValue(FileStream, FieldDataType_Float, -LARGEDOUBLE, LARGEDOUBLE, &IsOk); + GetNextValue(FileStream, FieldDataType_Float, -LARGEDOUBLE, LARGEDOUBLE, &IsOk); + } + + if (IVersion < 70) + Geom->DataType = FieldDataType_Float; + else + Geom->DataType = (FieldDataType_e)GetIoFileInt(FileStream, IVersion, 1, 2, &IsOk); + CHECK(VALID_GEOM_FIELD_DATA_TYPE(Geom->DataType)); + + Geom->Clipping = Clipping_ClipToViewport; /* default value for pre 101 versions */ + if (IVersion >= 101) + { + Geom->Clipping = (Clipping_e)GetIoFileInt(FileStream, IVersion, 0, 2, &IsOk); + /* + * The second clipping value was deprecated during v10 development and thus removed. + * This moved Clipping_ClipToFrame to the 2nd position from the 3rd, so we convert + * value 2 to ClipToFrame to support files made during v10 developement. + */ + if (Geom->Clipping == (Clipping_e)2) + Geom->Clipping = Clipping_ClipToFrame; + } + + if (IVersion < 50 || + Geom->GeomType == GeomType_LineSegs) + { + Geom->NumSegments = (SmInteger_t)GetIoFileInt(FileStream, IVersion, 1, MaxGeoSegments, &IsOk); +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + S = -1; + I = 0; + while ((S + 1 < Geom->NumSegments) && + !feof(FileStream->File) && IsOk) + { + S++; + Geom->NumSegPts[S] = GetIoFileInt(FileStream, IVersion, 1, MAXINDEX, &IsOk); + if ((I + Geom->NumSegPts[S] > MaxDataPts) && OkToLoad) + { + ErrMsgString = translate("Geometry is too big"); + IsOk = FALSE; + } + else + { + ReadBlock(FileStream, Geom->GeomData.Generic.V1Base, OkToLoad, Geom->DataType, I, I + Geom->NumSegPts[S] - 1, &IsOk); + ReadBlock(FileStream, Geom->GeomData.Generic.V2Base, OkToLoad, Geom->DataType, I, I + Geom->NumSegPts[S] - 1, &IsOk); + if (Geom->PositionCoordSys == CoordSys_Grid3D) + ReadBlock(FileStream, Geom->GeomData.Generic.V3Base, OkToLoad, Geom->DataType, I, I + Geom->NumSegPts[S] - 1, &IsOk); + I += Geom->NumSegPts[S]; + } + } + if (IsOk && (Geom->GeomType == GeomType_Rectangle)) /* IVersion < 50 */ + { + if (OkToLoad) + { + CopyFieldValue(Geom->GeomData.Generic.V1Base, 0, Geom->GeomData.Generic.V1Base, 2); + CopyFieldValue(Geom->GeomData.Generic.V2Base, 0, Geom->GeomData.Generic.V2Base, 2); + } + } + } + else if (Geom->GeomType == GeomType_Rectangle || + Geom->GeomType == GeomType_Ellipse) + { + double XX, YY; + XX = GetNextValue(FileStream, Geom->DataType, -LARGEDOUBLE, LARGEDOUBLE, &IsOk); + YY = GetNextValue(FileStream, Geom->DataType, -LARGEDOUBLE, LARGEDOUBLE, &IsOk); + if (OkToLoad) + { + SetFieldValue(Geom->GeomData.XYZ.XBase, 0, XX); + SetFieldValue(Geom->GeomData.XYZ.YBase, 0, YY); + } + Geom->NumSegments = 1; + Geom->NumSegPts[0] = 1; + } + else + { + double XX; + CHECK((Geom->GeomType == GeomType_Square) || + (Geom->GeomType == GeomType_Circle)); + XX = GetNextValue(FileStream, Geom->DataType, -LARGEDOUBLE, LARGEDOUBLE, &IsOk); + if (OkToLoad) + { + SetFieldValue(Geom->GeomData.XYZ.XBase, 0, XX); + } + Geom->NumSegments = 1; + Geom->NumSegPts[0] = 1; + } + + if (!IsOk) + ErrMsg(ErrMsgString); + + return (IsOk); +} + +/* + * Pass1 for text simply acknowledges that a text was + * parsed and skips over the text. + */ +Boolean_t ReadInText(FileStream_s *FileStream, + short IVersion, + Boolean_t OkToLoad, + Text_s *Text, + LgIndex_t MaxTextLen) +{ + LgIndex_t I; + FieldDataType_e FFT; + SmInteger_t TextLength = 0; + Boolean_t IsOk = TRUE; + TranslatedString ErrMsgString = translate("Invalid text record"); + + REQUIRE(VALID_REF(Text)); + + if (IVersion < 70) + FFT = FieldDataType_Float; + else + FFT = FieldDataType_Double; + + if (IVersion < 101) + I = GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk); + else + I = GetIoFileInt(FileStream, IVersion, 0, 4, &IsOk); + + if (I == 0) + Text->PositionCoordSys = CoordSys_Grid; + else if (I == 1) + Text->PositionCoordSys = CoordSys_Frame; + /* + * I == 2 is for CoordSys_FrameOffset and is not used currently + * + * I == 3 is for the old window coordinate system + */ + else if (I == 4) + Text->PositionCoordSys = CoordSys_Grid3D; + else + { + ErrMsgString = translate("Invalid text coordinate system."); + IsOk = FALSE; + } + + Text->Scope = (Scope_e)GetIoFileInt(FileStream, IVersion, 0, 1, &IsOk); + Text->AnchorPos.Generic.V1 = GetNextValue(FileStream, FFT, -LARGEDOUBLE, LARGEDOUBLE, &IsOk); + Text->AnchorPos.Generic.V2 = GetNextValue(FileStream, FFT, -LARGEDOUBLE, LARGEDOUBLE, &IsOk); + if (IVersion >= 101) + Text->AnchorPos.Generic.V3 = GetNextValue(FileStream, FFT, -LARGEDOUBLE, LARGEDOUBLE, &IsOk); + else + Text->AnchorPos.Generic.V3 = 0.0; /* default value for pre 101 versions */ + + if (IVersion > 40) + Text->TextShape.Font = (Font_e)GetIoFileInt(FileStream, IVersion, 0, (LgIndex_t)Font_CourierBold, &IsOk); + else + Text->TextShape.Font = Font_Helvetica; + if (IVersion < 43) + GetNextValue(FileStream, FFT, -LARGEDOUBLE, LARGEDOUBLE, &IsOk); + if (IVersion < 70) + { + if (Text->PositionCoordSys == CoordSys_Grid) + Text->TextShape.SizeUnits = Units_Grid; + else + Text->TextShape.SizeUnits = Units_Frame; + } + else + Text->TextShape.SizeUnits = (Units_e)GetIoFileInt(FileStream, IVersion, 0, (LgIndex_t)Units_Point, &IsOk); + + Text->TextShape.Height = GetNextValue(FileStream, FFT, -LARGEDOUBLE, LARGEDOUBLE, &IsOk); + if (IVersion > 47) + { + Text->Box.BoxType = (TextBox_e)GetIoFileInt(FileStream, IVersion, 0, (LgIndex_t)TextBox_Hollow, &IsOk); + if (IVersion < 70) + { + if (Text->Box.BoxType == TextBox_Hollow) + Text->Box.BoxType = TextBox_Filled; + else if (Text->Box.BoxType == TextBox_Filled) + Text->Box.BoxType = TextBox_Hollow; + } + Text->Box.Margin = GetNextValue(FileStream, FFT, + TextBoxMarginInputSpec.Min, + TextBoxMarginInputSpec.Max, + &IsOk); + if (IVersion >= 70) + Text->Box.LineThickness = GetNextValue(FileStream, FFT, + LineThicknessInputSpec.Min, + LineThicknessInputSpec.Max, + &IsOk); + else + Text->Box.LineThickness = 0.01; + Text->Box.BColor = (ColorIndex_t)GetIoFileInt(FileStream, IVersion, 0, 255, &IsOk); + Text->Box.FillBColor = (ColorIndex_t)GetIoFileInt(FileStream, IVersion, 0, 255, &IsOk); + AdjustCustomColor(IVersion, &Text->Box.BColor); + AdjustCustomColor(IVersion, &Text->Box.FillBColor); + } + else + { + Text->Box.BoxType = TextBox_None; + Text->Box.Margin = 0.0; + Text->Box.BColor = White_C; + Text->Box.FillBColor = Black_C; + } + if (IVersion < 70) + { + Text->Angle = GetIoFileInt(FileStream, IVersion, -720, 720, &IsOk) / DEGPERRADIANS; + Text->LineSpacing = 1; + Text->Anchor = TextAnchor_Left; + } + else + { + Text->Angle = GetNextValue(FileStream, FFT, + TextAngleInputSpec.Min, + TextAngleInputSpec.Max, + &IsOk); + Text->LineSpacing = GetNextValue(FileStream, FFT, + TextLineSpacingInputSpec.Min, + TextLineSpacingInputSpec.Max, + &IsOk); + Text->Anchor = (TextAnchor_e)GetIoFileInt(FileStream, IVersion, 0, (LgIndex_t)TextAnchor_HeadRight, &IsOk); + } + + GetZoneAttachment(FileStream, IVersion, &Text->Zone, &Text->AttachToZone, &IsOk); + + Text->BColor = (ColorIndex_t)GetIoFileInt(FileStream, IVersion, 0, 255, &IsOk); + AdjustCustomColor(IVersion, &Text->BColor); + if (IVersion < 70) + TextLength = (short)GetIoFileInt(FileStream, IVersion, 0, 5000, &IsOk); + + ResetString(&Text->MacroFunctionCommand, NULL, TRUE); + + Text->Clipping = Clipping_ClipToViewport; /* default value for pre 101 versions */ + + if (IVersion < 70) + { + short I, S; + for (I = 0; I < TextLength; I++) + { + S = (short)GetIoFileInt(FileStream, IVersion, 0, 1000, &IsOk); + if (OkToLoad && (I <= MaxTextLen)) + Text->Text[I] = (char)S; + } + if (OkToLoad) + Text->Text[MIN(TextLength, MaxTextLen)] = '\0'; + } + else + { + char *S = NULL; + + if (IVersion >= 75) + { + IsOk = ReadMacroFunctionCommand(FileStream, + IVersion, + OkToLoad, + &Text->MacroFunctionCommand); + } /* IVersion >= 75 */ + + if (IVersion >= 101) + { + /* + * The second clipping value was deprecated during v10 development and thus removed. + * This moved Clipping_ClipToFrame to the 2nd position from the 3rd, so we convert + * value 2 to ClipToFrame to support files made during v10 developement. + */ + Text->Clipping = (Clipping_e)GetIoFileInt(FileStream, IVersion, 0, 2, &IsOk); + if (Text->Clipping == (Clipping_e)2) + Text->Clipping = Clipping_ClipToFrame; + } + + if (ReadInString(FileStream, + IVersion, + MaxTextLen, + &S, + OkToLoad)) + { + REQUIRE(!(S || OkToLoad) || VALID_REF(Text->Text)); + if (S) + { +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ + if (IsOk) + { + strcpy(Text->Text, S); + } + FREE_ARRAY(S, "Release temp string for new text label"); + } + else if (OkToLoad) + Text->Text[0] = '\0'; + } + else + IsOk = FALSE; + } + + if (!IsOk) + ErrMsg(ErrMsgString); + + return (IsOk); +} + + +static Boolean_t CompareVersion(float Version, + char *VersionString, + Boolean_t IsByteOrderNative) +{ + char *VersionBuf = (char *) & Version; + + REQUIRE(VALID_REF(VersionString)); + + if (IsByteOrderNative) + return ((VersionString[0] == VersionBuf[0]) && + (VersionString[1] == VersionBuf[1]) && + (VersionString[2] == VersionBuf[2]) && + (VersionString[3] == VersionBuf[3])); + else + return ((VersionString[3] == VersionBuf[0]) && + (VersionString[2] == VersionBuf[1]) && + (VersionString[1] == VersionBuf[2]) && + (VersionString[0] == VersionBuf[3])); +} + +static float ValidVersions[] = {7.0F, + 6.3F, 6.2F, 6.1F, 6.0F, + 5.0F, + 4.7F, 4.6F, 4.5F, 4.4F, 4.3F, 4.2F, 4.1F, 4.0F + }; +#define NUMVALIDVERSIONS ((int)(sizeof(ValidVersions)/sizeof(ValidVersions[0]))) + + +/* + * Extra caution taken here in case value read is invalid float + */ +static Boolean_t GetDoubleVersion(char *VersionString, + float *FInputVersion, + Boolean_t IsByteOrderNative) +{ + int I; + REQUIRE(VALID_REF(FInputVersion)); + + for (I = 0; I < NUMVALIDVERSIONS; I++) + if (CompareVersion(ValidVersions[I], VersionString, IsByteOrderNative)) + { + *FInputVersion = ValidVersions[I]; + return (TRUE); + } + return (FALSE); +} + + +static short GetNewInputVersion(FileStream_s *FileStream) +{ + /* + * + */ + char Buf[4]; + short IVersion = 0; + short I; + LgIndex_t OneValue; + Boolean_t IsOk = TRUE; + + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE(FileStream->IsByteOrderNative); + + if (TP_FREAD(Buf, 4, 1, FileStream->File) != 1) + return (0); + + if (strncmp(Buf, "#!TD", 4)) + return (0); + + if (TP_FREAD(Buf, 4, 1, FileStream->File) != 1) + return (0); + + if (Buf[0] != 'V') + return (0); + + I = 1; + while ((I < 4) && isdigit(Buf[I])) + IVersion = IVersion * 10 + Buf[I++] - '0'; + + if (IVersion < 70) + return (0); + else if (IVersion > TecplotBinaryFileVersion) + { + ErrMsg(translate("Binary file version newer than Tecplot version. " + "Upgrade Tecplot or use an older Preplot to produce " + "the datafile.")); + return (IVersion); + } + + /* + * Determine Byte Order. + */ + + OneValue = GetIoFileInt(FileStream, + IVersion, + -MAXINDEX, + MAXINDEX, + &IsOk); + + if (!IsOk) + return (0); + + FileStream->IsByteOrderNative = (OneValue == 1); + + return (IVersion); +} + +/** + * Return value of zero is to be considered as an invalid + * tecplot binary datafile header. Actually binary files + * older than version 4.0 (return value of 40) are not supported + * (See notes in preplot.c). + */ +short GetInputVersion(FileStream_s *FileStream) +{ + Boolean_t IsOk = TRUE; + float FInputVersion; + short IVersion; + char VersionString[4]; + FileOffset_t StartOffset = 0; + + /* + * First check to see if file uses new + * input version format. + */ + + /* keep track of our start offset */ + StartOffset = TP_FTELL(FileStream->File); + + IVersion = GetNewInputVersion(FileStream); + + if (IVersion > TecplotBinaryFileVersion) + return IVersion; /* unsupported version */ + else if (IVersion == 0) + { + /* rewind to clear any errors and seek to the start offset */ + rewind(FileStream->File); + IsOk = (TP_FSEEK(FileStream->File, StartOffset, SEEK_SET) == 0); + + if (IsOk && TP_FREAD(VersionString, 4, 1, FileStream->File) == 1) + { + /* try both native and foreign versions numbers */ + if (!GetDoubleVersion(VersionString, &FInputVersion, FileStream->IsByteOrderNative)) + { + FileStream->IsByteOrderNative = !FileStream->IsByteOrderNative; /* ...reverse the byte order */ + IsOk = GetDoubleVersion(VersionString, &FInputVersion, FileStream->IsByteOrderNative); + } + if (IsOk) + IVersion = ROUNDS(FInputVersion * 10); + } + } + + if (IsOk) + return (IVersion); + else + return ((short)0); +} + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if !defined ENGINE /* TODO(RMS)-H 12/12/2005: ENGINE: refactor to use just the Interrupted flag as-is */ +#else +#endif +#endif + + + +/********************************************************************** + ********************************************************************** + ********************** OUTPUT ************************** + ********************************************************************** + **********************************************************************/ + + +/** + * Byte blocks cannot be unaligned or reversed in bytes + */ +Boolean_t WriteBinaryByteBlock(FileStream_s *FileStream, + const Byte_t *ByteValues, + const HgIndex_t NumValues) +{ + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE(VALID_REF(ByteValues)); + REQUIRE(NumValues >= 0); + + Boolean_t IsOk = TP_FWRITE(ByteValues, + sizeof(Byte_t), + (size_t)NumValues, + FileStream->File) == (size_t)NumValues; + + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + +/** + * Type Byte_t cannot be unaligned or reversed in byte order + */ +static inline Boolean_t WriteBinaryByte(FileStream_s *FileStream, + Byte_t ByteValue) +{ + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + Boolean_t IsOk = WriteBinaryByteBlock(FileStream, &ByteValue, 1); + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + +/** + */ +template +void CopyAndReverseUnalignedBytes(T *DstBuffer, + const Byte_t *SrcBuffer) +{ + REQUIRE(VALID_REF(DstBuffer)); + REQUIRE(VALID_REF(SrcBuffer)); + size_t typeSize = sizeof(T); + for (size_t ii = 0; ii < typeSize; ii++) + ((Byte_t *)(DstBuffer))[ii] = ((Byte_t *)(SrcBuffer))[typeSize-1-ii]; +} + +/** + */ +template +void CopyUnalignedBytes(T *DstBuffer, + const Byte_t *SrcBuffer) +{ + REQUIRE(VALID_REF(DstBuffer)); + REQUIRE(VALID_REF(SrcBuffer)); + for (size_t ii = 0; ii < sizeof(T); ii++) + ((Byte_t *)(DstBuffer))[ii] = ((Byte_t *)(SrcBuffer))[ii]; +} + +/** + */ +template +Boolean_t WriteBinaryDataUnaligned(FileStream_s *FileStream, + const Byte_t *ValueBuffer, + const Boolean_t ValueInNativeOrder) +{ + REQUIRE(VALID_REF(FileStream) && VALID_FILE_HANDLE(FileStream->File)); + REQUIRE(VALID_REF(ValueBuffer)); + REQUIRE(VALID_BOOLEAN(ValueInNativeOrder)); + + T DataValue; + if (ValueInNativeOrder != FileStream->IsByteOrderNative) + CopyAndReverseUnalignedBytes(&DataValue, ValueBuffer); + else + CopyUnalignedBytes(&DataValue, ValueBuffer); + + Boolean_t IsOk = TP_FWRITE(&DataValue, sizeof(T), 1, FileStream->File) == 1; + + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + + +/** + * This is used in many places and requires the value be in proper order. + */ +Boolean_t WriteBinaryInt16(FileStream_s *FileStream, + Int16_t Value) +{ + Boolean_t IsOk; + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE("Value can be any Int16_t"); + IsOk = WriteBinaryDataUnaligned(FileStream, (Byte_t *) & Value, TRUE/*ValueInNativeOrder*/); + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + +/** + * This is used in many places and requires the value be in proper order. + */ +Boolean_t WriteBinaryInt32(FileStream_s *FileStream, + Int32_t Value) +{ + Boolean_t IsOk; + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE("Value can be any Int32_t"); + IsOk = WriteBinaryDataUnaligned(FileStream, (Byte_t *) & Value, TRUE/*ValueInNativeOrder*/); + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + +/** + */ +template +Boolean_t WriteBinaryBlockUnaligned(FileStream_s *FileStream, + const Byte_t *Values, + const HgIndex_t NumValues, + const Boolean_t ValuesInNativeOrdering) +{ + Boolean_t IsOk = TRUE; + Boolean_t WriteEachValueSeparately; + + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE(VALID_REF(Values)); + REQUIRE(NumValues >= 0); + REQUIRE(VALID_BOOLEAN(ValuesInNativeOrdering)); + + WriteEachValueSeparately = (ValuesInNativeOrdering != FileStream->IsByteOrderNative); + + if (WriteEachValueSeparately) + { + for (HgIndex_t NIndex = 0; IsOk && NIndex < NumValues; NIndex++) + { + IsOk = WriteBinaryDataUnaligned(FileStream, Values + NIndex * sizeof(T), ValuesInNativeOrdering); + } + } + else + { +#if 1 + size_t NumBytesToWrite = NumValues * sizeof(T); + size_t NumBytesWritten = TP_FWRITE(Values, sizeof(Byte_t), NumBytesToWrite, FileStream->File); + IsOk = NumBytesToWrite == NumBytesWritten; +#else + IsOk = WriteBinaryByteBlock(FileStream, Values, NumValues * sizeof(T)); +#endif + } + + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + + +/** + * Use Byte_t instead of Int16_t to support unaligned values + */ +Boolean_t WriteBinaryInt16BlockUnaligned(FileStream_s *FileStream, + Byte_t *Int16Values, + HgIndex_t NumValues, + Boolean_t ValuesInNativeOrdering) +{ + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE(VALID_REF(Int16Values)); + REQUIRE(NumValues >= 0); + REQUIRE(VALID_BOOLEAN(ValuesInNativeOrdering)); + + Boolean_t IsOk = WriteBinaryBlockUnaligned(FileStream, + Int16Values, + NumValues, + ValuesInNativeOrdering); + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + + +/** + * Use Byte_t instead of Int32_t to support unaligned values + */ +Boolean_t WriteBinaryInt32BlockUnaligned(FileStream_s *FileStream, + Byte_t *Int32Values, + HgIndex_t NumValues, + Boolean_t ValuesInNativeOrdering) +{ + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE(VALID_REF(Int32Values)); + REQUIRE(NumValues >= 0); + REQUIRE(VALID_BOOLEAN(ValuesInNativeOrdering)); + + Boolean_t IsOk = WriteBinaryBlockUnaligned(FileStream, + Int32Values, + NumValues, + ValuesInNativeOrdering); + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + + + +/** + */ +Boolean_t WriteBinaryReal(FileStream_s *FileStream, + double RR, + FieldDataType_e FieldDataType) +{ + Boolean_t IsOk = FALSE; /* ...quite compiler */ + + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE((FieldDataType == FieldDataType_Float) || + (FieldDataType == FieldDataType_Double) || + (FieldDataType == FieldDataType_Byte)); + + switch (FieldDataType) + { + case FieldDataType_Float : + { + float FloatVal = CONVERT_DOUBLE_TO_FLOAT(RR); + IsOk = WriteBinaryDataUnaligned(FileStream, (Byte_t *) & FloatVal, TRUE/*NativeOrdering*/); + } break; + case FieldDataType_Double : + { + double DoubleVal = CLAMP_DOUBLE(RR); + IsOk = WriteBinaryDataUnaligned(FileStream, (Byte_t *) & DoubleVal, TRUE/*NativeOrdering*/); + } break; + case FieldDataType_Byte : + { + /* Note: type Byte cannot be unaligned or reversed in bytes */ + Byte_t B; + if (RR > 255) + B = 255; + else if (RR < 0) + B = 0; + else + B = (Byte_t)RR; + IsOk = WriteBinaryByte(FileStream, B); + } break; + default: CHECK(FALSE); break; + } + + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + + +Boolean_t WriteFieldDataType(FileStream_s *FileStream, + FieldDataType_e FDT, + Boolean_t WriteBinary) +{ + if (WriteBinary) + return (WriteBinaryInt32(FileStream, (LgIndex_t)FDT)); + else + { + short S = 0; + switch (FDT) + { + case FieldDataType_Float : S = fprintf(FileStream->File, "SINGLE "); break; + case FieldDataType_Double : S = fprintf(FileStream->File, "DOUBLE "); break; + case FieldDataType_Int32 : S = fprintf(FileStream->File, "LONGINT "); break; + case FieldDataType_Int16 : S = fprintf(FileStream->File, "SHORTINT "); break; + case FieldDataType_Byte : S = fprintf(FileStream->File, "BYTE "); break; + case FieldDataType_Bit : S = fprintf(FileStream->File, "BIT "); break; + default: CHECK(FALSE); + } + return (FPRINTFOK(S)); + } +} + +/** + */ +template +Boolean_t WriteBinaryChecksumByteValues(FileStream_s *FileStream, + const Byte_t *ByteValues, + const HgIndex_t NumValues) +{ + REQUIRE(VALID_REF(FileStream) && VALID_FILE_HANDLE(FileStream->File)); + REQUIRE(VALID_REF(ByteValues)); + REQUIRE(NumValues >= 1); + + Boolean_t IsOk; + if (NumValues == 1) + IsOk = WriteBinaryDataUnaligned(FileStream, ByteValues, TRUE); + else + IsOk = WriteBinaryBlockUnaligned(FileStream, ByteValues, NumValues, TRUE); + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + +/** + * For FieldData of Type Bit, use WriteBinaryFieldDataBlockOfTypeBit instead. + */ +template +Boolean_t WriteBinaryFieldDataBlockOfType(FileStream_s *FileStream, + const FieldData_pa FieldData, + const LgIndex_t StartOffset, + const LgIndex_t NumValues) +{ +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + Boolean_t IsOk = FALSE; + if (IsFieldDataDirectAccessAllowed(FieldData)) + { + Byte_t *ByteArray = GetFieldDataBytePtr(FieldData) + StartOffset * sizeof(T); + IsOk = WriteBinaryChecksumByteValues(FileStream, ByteArray, (HgIndex_t)NumValues); + } + else + { + for (LgIndex_t Offset = StartOffset; Offset < NumValues; Offset++) + { + T ValueBuffer = (T)GetFieldValue(FieldData, Offset); + Byte_t *ByteValue = (Byte_t *) & ValueBuffer; + IsOk = WriteBinaryChecksumByteValues(FileStream, ByteValue, 1); + } + } + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + +static Boolean_t WriteBinaryFieldDataBlockOfTypeBit(FileStream_s *FileStream, + const FieldData_pa FieldData, + const LgIndex_t StartOffset, /* Not used */ + const LgIndex_t NumValues) +{ +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + Boolean_t IsOk = FALSE; + size_t NumBytes = 1 + (NumValues - 1) / 8; + if (IsFieldDataDirectAccessAllowed(FieldData)) + { + Byte_t *ByteArray = GetFieldDataBytePtr(FieldData); + IsOk = WriteBinaryChecksumByteValues(FileStream, ByteArray, (HgIndex_t)NumBytes); + } + else + { + // Bits are written out a Byte at a time and since we only come in here every 8th + // bit, make sure to assemble a Byte value from the next 8 bits. + for (LgIndex_t Offset = 0; Offset < NumValues; Offset += 8) + { + Byte_t ValueBuffer = 0; + for (int ii = 0; ii < 8; ii++) + { + Byte_t CurBit = (Byte_t)GetFieldValue(FieldData, Offset + ii); + ValueBuffer |= (CurBit << ii); + } + IsOk = WriteBinaryChecksumByteValues(FileStream, &ValueBuffer, 1); + } + } + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + +/* + */ +Boolean_t WriteBinaryFieldDataBlock(FileStream_s *FileStream, + FieldData_pa FieldData, + LgIndex_t StartOffset, + LgIndex_t NumValues) +{ +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + Boolean_t IsOk = FALSE; + switch (GetFieldDataType(FieldData)) + { + case FieldDataType_Float : IsOk = WriteBinaryFieldDataBlockOfType(FileStream, FieldData, StartOffset, NumValues); break; + case FieldDataType_Double : IsOk = WriteBinaryFieldDataBlockOfType(FileStream, FieldData, StartOffset, NumValues); break; + case FieldDataType_Int32 : IsOk = WriteBinaryFieldDataBlockOfType(FileStream, FieldData, StartOffset, NumValues); break; + case FieldDataType_Int16 : IsOk = WriteBinaryFieldDataBlockOfType(FileStream, FieldData, StartOffset, NumValues); break; + case FieldDataType_Byte : IsOk = WriteBinaryFieldDataBlockOfType(FileStream, FieldData, StartOffset, NumValues); break; + case FieldDataType_Bit : IsOk = WriteBinaryFieldDataBlockOfTypeBit(FileStream, FieldData, StartOffset, NumValues); break; + default: CHECK(FALSE); break; + } + + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + + +static Boolean_t WriteASCIIFieldDataValue(FileStream_s *FileStream, + FieldData_pa FieldData, + LgIndex_t Offset, + SmInteger_t AsciiPrecision) +{ + Boolean_t IsOk = FALSE; /* ...quiet compiler */ + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + double V = 0.0; + char buffer[100*MAX_SIZEOFUTF8CHAR]; + char *AsciiValue = buffer; + +#ifdef TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + V = GetFieldValue(FieldData, Offset); + + switch (GetFieldDataType(FieldData)) + { + case FieldDataType_Float : + case FieldDataType_Double : + /*IsOk = FPRINTFOK(fprintf(FileStream->File," %.*E",(int)AsciiPrecision,V)); */ + sprintf(buffer, " %.*E", (int)AsciiPrecision, V); + break; + case FieldDataType_Int32 : + /* IsOk = FPRINTFOK(fprintf(FileStream->File," %*d",(int)AsciiPrecision,ROUNDL(V))); */ + sprintf(buffer, " %*d", (int)AsciiPrecision, ROUNDL(V)); + break; + case FieldDataType_Int16 : + /* IsOk = FPRINTFOK(fprintf(FileStream->File," %6d",ROUND2(V))); */ + sprintf(buffer, " %6d", ROUND2(V)); + break; + case FieldDataType_Byte : + /* IsOk = FPRINTFOK(fprintf(FileStream->File," %3d",ROUNDS(V))); */ + sprintf(buffer, " %3d", ROUNDS(V)); + break; + case FieldDataType_Bit : + /* IsOk = FPRINTFOK(fprintf(FileStream->File," %c",((V == 0) ? '0' : '1'))); */ + sprintf(buffer, " %c", ((V == 0) ? '0' : '1')); + break; + default: CHECK(FALSE); break; + } + IsOk = FPRINTFOK(fprintf(FileStream->File, buffer)); +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + ENSURE(VALID_BOOLEAN(IsOk)); + return (IsOk); +} + + +/** + */ +Boolean_t WriteCCFieldDataBlock(FileStream_s *FileStream, + FieldData_pa FieldData, + Boolean_t IsOrderedData, + LgIndex_t NumIPts, + LgIndex_t NumJPts, + LgIndex_t NumKPts, + Boolean_t WriteBinary, + SmInteger_t AsciiPrecision) +{ + Boolean_t IsOk = TRUE; + LgIndex_t NumValues; + LgIndex_t I, J, K; + LgIndex_t NumIJPts = -1; + LgIndex_t IEnd = -1; + LgIndex_t JEnd = -1; + LgIndex_t KEnd = -1; + Boolean_t IsLinear = -1; + + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE(VALID_REF(FieldData)); + REQUIRE(VALID_BOOLEAN(IsOrderedData)); + REQUIRE(NumIPts >= 0); + REQUIRE(NumJPts >= 0); + REQUIRE(NumKPts >= 0); + REQUIRE(VALID_BOOLEAN(WriteBinary)); + REQUIRE(IMPLICATION(!WriteBinary, AsciiPrecision >= 0)); + + /* + * As of version 103 Tecplot writes binary data files so that ordered cell + * centered field data includes the ghost cells. This makes it much easier + * for Tecplot to map the data when reading by simply writing out + * FieldData->NumValues. As of version 104 the ghost cells of the slowest + * moving index are not included but that does effect the output as it is + * still FieldData->NumValues. + */ + if (IsOrderedData && !WriteBinary) + { + /* + * Ordered ASCII output is always layed out using + * DataValueStructure_Classic format. + */ + NumIJPts = NumIPts * NumJPts; + IEnd = MAX(NumIPts - 1, 1); + JEnd = MAX(NumJPts - 1, 1); + KEnd = MAX(NumKPts - 1, 1); + NumValues = (IEnd * JEnd * KEnd); + IsLinear = ((NumJPts == 1 && NumKPts == 1) || + (NumIPts == 1 && NumKPts == 1) || + (NumIPts == 1 && NumJPts == 1)); + } + else + { + NumValues = GetFieldDataNumValues(FieldData); + } + + if (WriteBinary) + { + IsOk = WriteBinaryFieldDataBlock(FileStream, FieldData, 0, NumValues); + } + else + { + LgIndex_t NumValuesPerLine = 80 / (AsciiPrecision + 5); + if (IsOrderedData && !IsLinear) + { + LgIndex_t ValueIndex = 0; + for (K = 0; K < KEnd && IsOk; K++) + for (J = 0; J < JEnd && IsOk; J++) + for (I = 0; I < IEnd && IsOk; I++) + { + LgIndex_t CellIndex = I + (J * NumIPts) + (K * NumIJPts); + IsOk = WriteASCIIFieldDataValue(FileStream, + FieldData, + CellIndex, + AsciiPrecision); + if ((ValueIndex + 1) % NumValuesPerLine == 0 || ValueIndex == NumValues - 1) + IsOk = (fputc('\n', FileStream->File) != EOF); + ValueIndex++; + } + } + else + { + for (I = 0; I < NumValues && IsOk; I++) + { + IsOk = WriteASCIIFieldDataValue(FileStream, + FieldData, + I, + AsciiPrecision); + if ((I + 1) % NumValuesPerLine == 0 || I == NumValues - 1) + IsOk = (fputc('\n', FileStream->File) != EOF); + } + } + } + + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + + +Boolean_t DumpDatafileString(FileStream_s *FileStream, + const char *S, + Boolean_t WriteBinary) +{ + Boolean_t IsOk = TRUE; + const char *CPtr = S; + if (WriteBinary) + { + const char *CPtr = S; + while (IsOk && CPtr && *CPtr) + IsOk = WriteBinaryInt32(FileStream, (LgIndex_t)(unsigned char) * CPtr++); + if (IsOk) + IsOk = WriteBinaryInt32(FileStream, 0); + } + else + { + fputc('"', FileStream->File); + while (CPtr && *CPtr) + { + if (*CPtr == '\n') + { + CPtr++; + fputc('\\', FileStream->File); + fputc('\\', FileStream->File); + fputc('n', FileStream->File); + } + else + { + if ((*CPtr == '"') || (*CPtr == '\\')) + fputc('\\', FileStream->File); + fputc(*CPtr++, FileStream->File); + } + } + fputc('"', FileStream->File); + IsOk = (fputc('\n', FileStream->File) != EOF); + } + return (IsOk); +} + + +static void WriteAsciiColor(FILE *File, + ColorIndex_t Color) +{ + if (Color >= FirstCustomColor && Color <= LastCustomColor) + fprintf(File, "CUST%1d ", Color - FirstCustomColor + 1); + else + { + switch (Color) + { + case Black_C : fprintf(File, "BLACK "); break; + case Red_C : fprintf(File, "RED "); break; + case Green_C : fprintf(File, "GREEN "); break; + case Blue_C : fprintf(File, "BLUE "); break; + case Cyan_C : fprintf(File, "CYAN "); break; + case Yellow_C : fprintf(File, "YELLOW "); break; + case Purple_C : fprintf(File, "PURPLE "); break; + case White_C : fprintf(File, "WHITE "); break; + } + } +} + +static void WriteAsciiTextGeomBasics(FILE* File, + CoordSys_e CoordSys, + Boolean_t AttachToZone, + EntIndex_t Zone, + ColorIndex_t Color, + Scope_e Scope, + Boolean_t IncludeZ, + Boolean_t WriteGridDataAsPolar, + AnchorPos_u const* AnchorPos, + double ScaleFact) +{ + REQUIRE(VALID_REF(File)); + REQUIRE(VALID_TEXT_COORDSYS(CoordSys) || VALID_GEOM_COORDSYS(CoordSys)); + REQUIRE(VALID_BOOLEAN(AttachToZone)); + REQUIRE(IMPLICATION(AttachToZone, Zone >= 0)); + REQUIRE(VALID_ENUM(Scope, Scope_e)); + REQUIRE(VALID_BOOLEAN(IncludeZ)); + REQUIRE(VALID_BOOLEAN(WriteGridDataAsPolar)); + REQUIRE(VALID_REF(AnchorPos)); + + fprintf(File, "CS="); + if (CoordSys == CoordSys_Frame) + fprintf(File, "FRAME"); + else if (CoordSys == CoordSys_Grid) + fprintf(File, "GRID"); + /* + * Not currently used + * + else if (CoordSys == CoordSys_FrameOffset) + fprintf(File,"FRAMEOFFSET"); + */ + else if (CoordSys == CoordSys_Grid3D) + fprintf(File, "GRID3D"); + else + CHECK(FALSE); + + if (CoordSys == CoordSys_Grid && !IncludeZ && WriteGridDataAsPolar) + { + fprintf(File, "\nTHETA=%.12G,R=%.12G", + ScaleFact*AnchorPos->ThetaR.Theta, + ScaleFact*AnchorPos->ThetaR.R); + CHECK(!IncludeZ); + } + else + { + fprintf(File, "\nX=%.12G,Y=%.12G", + ScaleFact*AnchorPos->XYZ.X, + ScaleFact*AnchorPos->XYZ.Y); + if (IncludeZ) + fprintf(File, ",Z=%.12G", ScaleFact*AnchorPos->XYZ.Z); + } + + if (AttachToZone) + fprintf(File, "\nZN=%d", Zone + 1); + + fprintf(File, "\nC="); + WriteAsciiColor(File, Color); + + fprintf(File, "\nS="); + if (Scope == Scope_Global) + fprintf(File, "GLOBAL"); + else if (Scope == Scope_Local) + fprintf(File, "LOCAL"); + else + CHECK(FALSE); + + fputc('\n', File); +} + + +bool DumpGeometry(FileStream_s* FileStream, + Geom_s const* Geom, + Boolean_t WriteBinary, + Boolean_t WriteGridDataAsPolar) +{ + LgIndex_t I, Index; + LgIndex_t SegIndex; + bool IsOk = TRUE; + FieldDataType_e FDT; + + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE(VALID_REF(Geom)); + REQUIRE(Geom->GeomType != GeomType_Image); + + if (WriteBinary) + { + WriteBinaryReal(FileStream, GeomMarker, FieldDataType_Float); + if (Geom->PositionCoordSys == CoordSys_Grid) + WriteBinaryInt32(FileStream, 0); + else if (Geom->PositionCoordSys == CoordSys_Frame) + WriteBinaryInt32(FileStream, 1); +#if 0 /* + * Not currently used + */ + else if (Geom->PositionCoordSys == CoordSys_FrameOffset) + WriteBinaryInt32(FileStream, 2); +#endif + /* + * PositionCoordSys == 3 is for old window coordinate system + */ + else if (Geom->PositionCoordSys == CoordSys_Grid3D) + WriteBinaryInt32(FileStream, 4); + else + CHECK(FALSE); + + WriteBinaryInt32(FileStream, (LgIndex_t)Geom->Scope); + WriteBinaryInt32(FileStream, (LgIndex_t)Geom->DrawOrder); + WriteBinaryReal(FileStream, Geom->AnchorPos.Generic.V1, FieldDataType_Double); + WriteBinaryReal(FileStream, Geom->AnchorPos.Generic.V2, FieldDataType_Double); + WriteBinaryReal(FileStream, Geom->AnchorPos.Generic.V3, FieldDataType_Double); + if (Geom->AttachToZone) + WriteBinaryInt32(FileStream, (LgIndex_t)Geom->Zone); + else + WriteBinaryInt32(FileStream, (LgIndex_t) - 1); + WriteBinaryInt32(FileStream, (LgIndex_t)Geom->BColor); + WriteBinaryInt32(FileStream, (LgIndex_t)Geom->FillBColor); + WriteBinaryInt32(FileStream, (LgIndex_t)Geom->IsFilled); + CHECK(Geom->GeomType != GeomType_LineSegs3D); /* deprecated */ + WriteBinaryInt32(FileStream, (LgIndex_t)Geom->GeomType); + WriteBinaryInt32(FileStream, (LgIndex_t)Geom->LinePattern); + WriteBinaryReal(FileStream, Geom->PatternLength, FieldDataType_Double); + WriteBinaryReal(FileStream, Geom->LineThickness, FieldDataType_Double); + WriteBinaryInt32(FileStream, (LgIndex_t)Geom->NumEllipsePts); + WriteBinaryInt32(FileStream, (LgIndex_t)Geom->ArrowheadStyle); + WriteBinaryInt32(FileStream, (LgIndex_t)Geom->ArrowheadAttachment); + WriteBinaryReal(FileStream, Geom->ArrowheadSize, FieldDataType_Double); + + WriteBinaryReal(FileStream, Geom->ArrowheadAngle, FieldDataType_Double); + + /* MACRO FUNCTION COMMAND */ + DumpDatafileString(FileStream, Geom->MacroFunctionCommand, TRUE); + + /* + * Assume geometry has X,Y (and Z) all using same field + * data type. + */ + FDT = GetGeomFieldDataType(Geom); + WriteFieldDataType(FileStream, FDT, TRUE); + WriteBinaryInt32(FileStream, (LgIndex_t)Geom->Clipping); + + if (Geom->GeomType == GeomType_LineSegs) + { + short S; + WriteBinaryInt32(FileStream, Geom->NumSegments); + I = 0; + for (S = 0; IsOk && (S < Geom->NumSegments); S++) + { + WriteBinaryInt32(FileStream, Geom->NumSegPts[S]); + WriteBinaryFieldDataBlock(FileStream, Geom->GeomData.Generic.V1Base, I, Geom->NumSegPts[S]); + IsOk = WriteBinaryFieldDataBlock(FileStream, Geom->GeomData.Generic.V2Base, I, Geom->NumSegPts[S]) == TRUE; + if (Geom->PositionCoordSys == CoordSys_Grid3D) + IsOk = WriteBinaryFieldDataBlock(FileStream, Geom->GeomData.Generic.V3Base, I, Geom->NumSegPts[S]) == TRUE; + I += Geom->NumSegPts[S]; + } + } + else if (Geom->GeomType == GeomType_Rectangle || + Geom->GeomType == GeomType_Ellipse) + { + WriteBinaryReal(FileStream, GetFieldValue(Geom->GeomData.XYZ.XBase, 0), FDT); + IsOk = WriteBinaryReal(FileStream, GetFieldValue(Geom->GeomData.XYZ.YBase, 0), FDT) == TRUE; + } + else + { + CHECK((Geom->GeomType == GeomType_Square) || + (Geom->GeomType == GeomType_Circle)); + IsOk = WriteBinaryReal(FileStream, GetFieldValue(Geom->GeomData.XYZ.XBase, 0), FDT) == TRUE; + } + + } + else + { + double ScaleFact; + if (Geom->PositionCoordSys == CoordSys_Frame) + ScaleFact = 100.0; + else + ScaleFact = 1.0; + + fprintf(FileStream->File, "GEOMETRY\nF=POINT\n"); + WriteAsciiTextGeomBasics(FileStream->File, + Geom->PositionCoordSys, + Geom->AttachToZone, + Geom->Zone, + Geom->BColor, + Geom->Scope, + TRUE, + WriteGridDataAsPolar, + &Geom->AnchorPos, + ScaleFact); + + switch (Geom->LinePattern) + { + case LinePattern_Solid : fprintf(FileStream->File, "L=SOLID\n"); break; + case LinePattern_Dashed : fprintf(FileStream->File, "L=DASHED\n"); break; + case LinePattern_DashDot : fprintf(FileStream->File, "L=DASHDOT\n"); break; + case LinePattern_Dotted : fprintf(FileStream->File, "L=DOTTED\n"); break; + case LinePattern_LongDash : fprintf(FileStream->File, "L=LONGDASH\n"); break; + case LinePattern_DashDotDot : fprintf(FileStream->File, "L=DASHDOTDOT\n"); break; + default: CHECK(FALSE); break; + } + fprintf(FileStream->File, "PL=%.12G\n", + Geom->PatternLength*PatternLengthInputSpec.InterfaceAdjust.ScaleFact); + fprintf(FileStream->File, "LT=%.12G\n", + Geom->LineThickness*LineThicknessInputSpec.InterfaceAdjust.ScaleFact); + + if (Geom->IsFilled) + { + fprintf(FileStream->File, "FC="); + WriteAsciiColor(FileStream->File, Geom->FillBColor); + } + + if (Geom->Clipping == Clipping_ClipToViewport) + fprintf(FileStream->File, "CLIPPING=CLIPTOVIEWPORT\n"); + else if (Geom->Clipping == Clipping_ClipToFrame) + fprintf(FileStream->File, "CLIPPING=CLIPTOFRAME\n"); + else + CHECK(FALSE); + + if (Geom->DrawOrder == DrawOrder_AfterData) + fprintf(FileStream->File, "DRAWORDER=AFTERDATA\n"); + else if (Geom->DrawOrder == DrawOrder_BeforeData) + fprintf(FileStream->File, "DRAWORDER=BEFOREDATA\n"); + else + CHECK(FALSE); + + /* Macro function command */ + fprintf(FileStream->File, "MFC="); + DumpDatafileString(FileStream, Geom->MacroFunctionCommand, FALSE); + + if ((Geom->GeomType == GeomType_Circle) || (Geom->GeomType == GeomType_Ellipse)) + fprintf(FileStream->File, "EP=%ld\n", (long)Geom->NumEllipsePts); + + if (Geom->GeomType == GeomType_LineSegs && Geom->PositionCoordSys != CoordSys_Grid3D) + { + switch (Geom->ArrowheadStyle) + { + case ArrowheadStyle_Plain : fprintf(FileStream->File, "AST=PLAIN\n"); break; + case ArrowheadStyle_Filled : fprintf(FileStream->File, "AST=FILLED\n"); break; + case ArrowheadStyle_Hollow : fprintf(FileStream->File, "AST=HOLLOW\n"); break; + default: CHECK(FALSE); break; + } + + switch (Geom->ArrowheadAttachment) + { + case ArrowheadAttachment_None : break; + case ArrowheadAttachment_AtBeginning : fprintf(FileStream->File, "AAT=BEGINNING\n"); break; + case ArrowheadAttachment_AtEnd : fprintf(FileStream->File, "AAT=END\n"); break; + case ArrowheadAttachment_AtBothEnds : fprintf(FileStream->File, "AAT=BOTH\n"); break; + default: CHECK(FALSE); break; + } + if (Geom->ArrowheadAttachment != ArrowheadAttachment_None) + { + fprintf(FileStream->File, "ASZ=%.12G\n", + Geom->ArrowheadSize*ArrowheadSizeInputSpec.InterfaceAdjust.ScaleFact); + fprintf(FileStream->File, "AAN=%.12G\n", + Geom->ArrowheadAngle*ArrowheadAngleInputSpec.InterfaceAdjust.ScaleFact); + } + } + + switch (Geom->GeomType) + { + case GeomType_LineSegs : + { + fprintf(FileStream->File, "T=LINE\n"); + fprintf(FileStream->File, "DT="); + WriteFieldDataType(FileStream, GetFieldDataType(Geom->GeomData.Generic.V1Base), FALSE); + fputc('\n', FileStream->File); + fprintf(FileStream->File, "%d\n", (int)Geom->NumSegments); + SegIndex = 0; + for (I = 0; IsOk && (I < Geom->NumSegments); I++) + { + fprintf(FileStream->File, "%ld\n", (long)Geom->NumSegPts[I]); + for (Index = 0; Index < Geom->NumSegPts[I]; Index++) + { + fprintf(FileStream->File, "%.12G ", GetFieldValue(Geom->GeomData.Generic.V1Base, SegIndex + Index)*ScaleFact); + fprintf(FileStream->File, "%.12G", GetFieldValue(Geom->GeomData.Generic.V2Base, SegIndex + Index)*ScaleFact); + if (Geom->PositionCoordSys == CoordSys_Grid3D) + IsOk = FPRINTFOK(fprintf(FileStream->File, " %.12G\n", GetFieldValue(Geom->GeomData.Generic.V3Base, SegIndex + Index))); + else + IsOk = (Boolean_t)(fputc('\n', FileStream->File) != EOF); + } + SegIndex += Geom->NumSegPts[I]; + } + } break; + case GeomType_Rectangle : + { + fprintf(FileStream->File, "T=RECTANGLE %.12G %.12G\n", + GetFieldValue(Geom->GeomData.XYZ.XBase, 0)*ScaleFact, + GetFieldValue(Geom->GeomData.XYZ.YBase, 0)*ScaleFact); + } break; + case GeomType_Square : + { + fprintf(FileStream->File, "T=SQUARE %.12G\n", + GetFieldValue(Geom->GeomData.XYZ.XBase, 0)*ScaleFact); + } break; + case GeomType_Circle : + { + fprintf(FileStream->File, "T=CIRCLE %.12G\n", + GetFieldValue(Geom->GeomData.XYZ.XBase, 0)*ScaleFact); + } break; + case GeomType_Ellipse : + { + fprintf(FileStream->File, "T=ELLIPSE %.12G %.12G\n", + GetFieldValue(Geom->GeomData.XYZ.XBase, 0)*ScaleFact, + GetFieldValue(Geom->GeomData.XYZ.YBase, 0)*ScaleFact); + } break; + default: CHECK(FALSE); + } + } + return IsOk; +} + +/** + */ +bool DumpText(FileStream_s* FileStream, + Text_s const* Text, + Boolean_t WriteBinary, + Boolean_t WriteGridDataAsPolar) +{ + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE(VALID_REF(Text)); + REQUIRE(VALID_BOOLEAN(WriteBinary)); + REQUIRE(VALID_BOOLEAN(WriteGridDataAsPolar)); + + if (WriteBinary) + { + WriteBinaryReal(FileStream, TextMarker, FieldDataType_Float); + if (Text->PositionCoordSys == CoordSys_Grid) + WriteBinaryInt32(FileStream, 0); + else if (Text->PositionCoordSys == CoordSys_Frame) + WriteBinaryInt32(FileStream, 1); +#if 0 /* + * Not currently used + */ + else if (Geom->PositionCoordSys == CoordSys_FrameOffset) + WriteBinaryInt32(FileStream, 2); +#endif + /* + * 3 is used for old window coordinate system + */ + else if (Text->PositionCoordSys == CoordSys_Grid3D) + WriteBinaryInt32(FileStream, 4); + else + CHECK(FALSE); + + WriteBinaryInt32(FileStream, (LgIndex_t)Text->Scope); + WriteBinaryReal(FileStream, Text->AnchorPos.Generic.V1, FieldDataType_Double); + WriteBinaryReal(FileStream, Text->AnchorPos.Generic.V2, FieldDataType_Double); + WriteBinaryReal(FileStream, Text->AnchorPos.Generic.V3, FieldDataType_Double); + WriteBinaryInt32(FileStream, (LgIndex_t)Text->TextShape.Font); + WriteBinaryInt32(FileStream, (LgIndex_t)Text->TextShape.SizeUnits); + WriteBinaryReal(FileStream, Text->TextShape.Height, FieldDataType_Double); + WriteBinaryInt32(FileStream, (LgIndex_t)Text->Box.BoxType); + WriteBinaryReal(FileStream, Text->Box.Margin, FieldDataType_Double); + WriteBinaryReal(FileStream, Text->Box.LineThickness, FieldDataType_Double); + WriteBinaryInt32(FileStream, (LgIndex_t)Text->Box.BColor); + WriteBinaryInt32(FileStream, (LgIndex_t)Text->Box.FillBColor); + WriteBinaryReal(FileStream, Text->Angle, FieldDataType_Double); + WriteBinaryReal(FileStream, Text->LineSpacing, FieldDataType_Double); + WriteBinaryInt32(FileStream, (LgIndex_t)Text->Anchor); + if (Text->AttachToZone) + WriteBinaryInt32(FileStream, (LgIndex_t)Text->Zone); + else + WriteBinaryInt32(FileStream, (LgIndex_t) - 1); + WriteBinaryInt32(FileStream, (LgIndex_t)Text->BColor); + } + else + { + double ScaleFact; + Boolean_t IncludeZ = Text->PositionCoordSys == CoordSys_Grid3D; + if (Text->PositionCoordSys == CoordSys_Frame) + ScaleFact = 100.0; + else + ScaleFact = 1.0; + fprintf(FileStream->File, "TEXT\n"); + WriteAsciiTextGeomBasics(FileStream->File, + Text->PositionCoordSys, + Text->AttachToZone, + Text->Zone, + Text->BColor, + Text->Scope, + IncludeZ, + WriteGridDataAsPolar, + &Text->AnchorPos, + ScaleFact); + fprintf(FileStream->File, "HU="); + switch (Text->TextShape.SizeUnits) + { + case Units_Grid : fprintf(FileStream->File, "GRID\n"); break; + case Units_Frame : fprintf(FileStream->File, "FRAME\n"); break; + case Units_Point : fprintf(FileStream->File, "POINT\n"); break; + case Units_AxisPercentage : /* Not allowed */ + default: CHECK(FALSE); break; + } + + fprintf(FileStream->File, "LS=%.4G ", Text->LineSpacing); + + fprintf(FileStream->File, "AN="); + switch (Text->Anchor) + { + case TextAnchor_Left : fprintf(FileStream->File, "LEFT\n"); break; + case TextAnchor_Center : fprintf(FileStream->File, "CENTER\n"); break; + case TextAnchor_Right : fprintf(FileStream->File, "RIGHT\n"); break; + case TextAnchor_MidLeft : fprintf(FileStream->File, "MIDLEFT\n"); break; + case TextAnchor_MidCenter : fprintf(FileStream->File, "MIDCENTER\n"); break; + case TextAnchor_MidRight : fprintf(FileStream->File, "MIDRIGHT\n"); break; + case TextAnchor_HeadLeft : fprintf(FileStream->File, "HEADLEFT\n"); break; + case TextAnchor_HeadCenter : fprintf(FileStream->File, "HEADCENTER\n"); break; + case TextAnchor_HeadRight : fprintf(FileStream->File, "HEADRIGHT\n"); break; + default: CHECK(FALSE); break; + } + + switch (Text->Box.BoxType) + { + case TextBox_Hollow : fprintf(FileStream->File, "BX=Hollow "); break; + case TextBox_Filled : fprintf(FileStream->File, "BX=Filled "); break; + default :; + } + fprintf(FileStream->File, "BXM=%.4G ", Text->Box.Margin*100); + fprintf(FileStream->File, "LT=%.4G ", Text->Box.LineThickness*100.0); + fprintf(FileStream->File, "BXO="); WriteAsciiColor(FileStream->File, Text->Box.BColor); + fprintf(FileStream->File, "BXF="); WriteAsciiColor(FileStream->File, Text->Box.FillBColor); + + fprintf(FileStream->File, "\nF="); + switch (Text->TextShape.Font) + { + case Font_Helvetica : fprintf(FileStream->File, "HELV"); break; + case Font_HelveticaBold : fprintf(FileStream->File, "HELV-BOLD"); break; + case Font_Times : fprintf(FileStream->File, "TIMES"); break; + case Font_TimesBold: fprintf(FileStream->File, "TIMES-BOLD"); break; + case Font_TimesItalic : fprintf(FileStream->File, "TIMES-ITALIC"); break; + case Font_TimesItalicBold : fprintf(FileStream->File, "TIMES-ITALIC-BOLD"); break; + case Font_Courier : fprintf(FileStream->File, "COURIER"); break; + case Font_CourierBold : fprintf(FileStream->File, "COURIER-BOLD"); break; + case Font_Greek : fprintf(FileStream->File, "GREEK"); break; + case Font_Math : fprintf(FileStream->File, "MATH"); break; + case Font_UserDefined : fprintf(FileStream->File, "USER-DEF"); break; + default: CHECK(FALSE); break; + } + if (Text->TextShape.SizeUnits == Units_Frame) + ScaleFact = 100.0; + else + ScaleFact = 1.0; + fprintf(FileStream->File, "\nH=%.12G A=%.12G", + Text->TextShape.Height*ScaleFact, + Text->Angle*DEGPERRADIANS); + } + + + if (!WriteBinary) + fprintf(FileStream->File, "\nMFC="); + + DumpDatafileString(FileStream, Text->MacroFunctionCommand, WriteBinary); + + if (!WriteBinary) + { + if (Text->Clipping == Clipping_ClipToViewport) + fprintf(FileStream->File, "CLIPPING=CLIPTOVIEWPORT\n"); + else if (Text->Clipping == Clipping_ClipToFrame) + fprintf(FileStream->File, "CLIPPING=CLIPTOFRAME\n"); + else + CHECK(FALSE); + } + else + { + WriteBinaryInt32(FileStream, (LgIndex_t)Text->Clipping); + } + + if (!WriteBinary) + fprintf(FileStream->File, "T="); + + return DumpDatafileString(FileStream, Text->Text, WriteBinary) == TRUE; +} + +Boolean_t DumpCustomAxisLabels(FileStream_s *FileStream, + Boolean_t WriteBinary, + StringList_pa LabelBase) +{ + Boolean_t IsOk = TRUE; + LgIndex_t Index = 0; + LgIndex_t Count = 0; + + REQUIRE(VALID_REF(FileStream) && VALID_REF(FileStream->File)); + REQUIRE(VALID_BOOLEAN(WriteBinary)); + REQUIRE(StringListValid(LabelBase)); + + Count = StringListCount(LabelBase); + if (WriteBinary) + { + WriteBinaryReal(FileStream, CustomLabelMarker, FieldDataType_Float); + WriteBinaryInt32(FileStream, Count); + } + else + { + fprintf(FileStream->File, " CUSTOMLABELS = \n"); + } + + for (Index = 0, IsOk = TRUE; Index < Count && IsOk; Index++) + { + const char *CurLabel = StringListGetStringRef(LabelBase, Index); + IsOk = DumpDatafileString(FileStream, CurLabel, WriteBinary); + } + + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + +/** + */ +Boolean_t WriteBinaryMagic(FileStream_s *FileStream) +{ + /* + * Write an integer value of 1 to the file. This is used + * by the reader to determine byte order of the file. + */ + return (WriteBinaryInt32(FileStream, 1)); +} + +/** + */ +bool writeBinaryVersionNumber(FileStream_s& fileStream, + int versionNumber) +{ + char buffer[5]; + sprintf(buffer, + "V%-3d", + versionNumber); + CHECK(strlen(buffer) == 4); + return fprintf(fileStream.File, + "#!TD%s", + buffer) > 0; +} + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if !defined SUN +#else +#endif +#if !defined NO_ASSERTS +#endif +#if defined ALLOW_USERDEF_NO_NEIGHBORING_ELEMENT +#else +#endif +#if 0 /* not used yet */ +#endif +#if defined TECPLOTKERNEL +#endif +#if defined TECPLOTKERNEL +#endif +#endif diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/dataset.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/dataset.cpp new file mode 100644 index 0000000000..fd35a87dcf --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/dataset.cpp @@ -0,0 +1,283 @@ +/* + * 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 DATASETMODULE +#include "GLOBAL.h" +#include "TASSERT.h" +#include "Q_UNICODE.h" +#include "STRUTIL.h" +#include "AUXDATA.h" +#include "ARRLIST.h" +#include "STRLIST.h" +#include "ALLOC.h" +#include "SET.h" +#include "DATASET.h" +#include "FILESTREAM.h" + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif +#include "DATASET0.h" + + +#include + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if !defined ENGINE /* TODO(RMS)-H 12/12/2005: ENGINE: refactor to use just the Interrupted flag as-is */ +#else +#endif +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if !defined USE_MACROS_FOR_FUNCTIONS +#endif +#if !defined USE_MACROS_FOR_FUNCTIONS +#endif +#endif /* TECPLOTKERNEL */ + +/** + * Cleanout the contents of the zone spec item but leaves the zone spec item. + * This effectively leaves the zone spec structure in the same state as calling + * ZoneSpecAlloc initially. + * + * param ZoneSpec + * Zone spec item to cleanup. + */ +void CleanoutZoneSpec(ZoneSpec_s *ZoneSpec) +{ + REQUIRE(VALID_REF(ZoneSpec)); + + if (ZoneSpec->Name != NULL) + FREE_ARRAY(ZoneSpec->Name, "ZoneSpec name"); + if (ZoneSpec->AuxData != NULL) + AuxDataDealloc(&ZoneSpec->AuxData); + SetZoneSpecDefaults(ZoneSpec); +} + + +/** + */ +void ZoneSpecDealloc(ZoneSpec_s **ZoneSpec) +{ + REQUIRE(VALID_REF(ZoneSpec)); + REQUIRE(VALID_REF(*ZoneSpec) || *ZoneSpec == NULL); + + if (*ZoneSpec != NULL) + { + CleanoutZoneSpec(*ZoneSpec); + + FREE_ITEM(*ZoneSpec, "ZoneSpec structure"); + *ZoneSpec = NULL; + } + + ENSURE(*ZoneSpec == NULL); +} + +/** + */ +Boolean_t ZoneSpecItemDestructor(void *ItemRef, + ArbParam_t ClientData) +{ + ZoneSpec_s **ZoneSpecRef = (ZoneSpec_s **)ItemRef; + + REQUIRE(VALID_REF(ZoneSpecRef)); + REQUIRE(VALID_REF(*ZoneSpecRef) || *ZoneSpecRef == NULL); + + if (*ZoneSpecRef != NULL) + ZoneSpecDealloc(ZoneSpecRef); + + ENSURE(*ZoneSpecRef == NULL); + return TRUE; +} + +/** + */ +void SetZoneSpecDefaults(ZoneSpec_s *ZoneSpec) +{ + REQUIRE(VALID_REF(ZoneSpec)); + ZoneSpec->Name = NULL; + ZoneSpec->UniqueID = INVALID_UNIQUE_ID; + ZoneSpec->ParentZone = BAD_SET_VALUE; + ZoneSpec->StrandID = STRAND_ID_STATIC; + ZoneSpec->SolutionTime = 0.0; + ZoneSpec->NumPtsI = 0; + ZoneSpec->NumPtsJ = 0; + ZoneSpec->NumPtsK = 0; + ZoneSpec->ICellDim = 0; // ...currently not used + ZoneSpec->JCellDim = 0; // ...currently not used + ZoneSpec->KCellDim = 0; // ...currently not used + ZoneSpec->Type = ZoneType_Ordered; + ZoneSpec->ZoneLoadInfo.PresetZoneColor = NoColor_C; + ZoneSpec->ZoneLoadInfo.IsInBlockFormat = TRUE; + ZoneSpec->AuxData = NULL; + ZoneSpec->BuildZoneOptInfo = TRUE; + + /* classic data only */ + ZoneSpec->FNMode = FaceNeighborMode_LocalOneToOne; + ZoneSpec->FNAreCellFaceNbrsSupplied = FALSE; + + /* polytope data only */ + ZoneSpec->NumFaceNodes = 0; + ZoneSpec->NumFaceBndryFaces = 0; + ZoneSpec->NumFaceBndryItems = 0; +} + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ + +/** + */ +void ZoneSpecExcludeBndryConnsFromMetrics(ZoneSpec_s* ZoneSpec) +{ + REQUIRE(VALID_REF(ZoneSpec)); + + /* classic data face connectivity fixup (leave FNMode as-is) */ + ZoneSpec->FNAreCellFaceNbrsSupplied = FALSE; // ...if we invalidate boundary connections CellFaceNbrs must now be auto-generated + + /* polytope data face connectivity fixup */ + ZoneSpec->NumFaceBndryFaces = 0; + ZoneSpec->NumFaceBndryItems = 0; +} + +/** + */ +ZoneSpec_s *ZoneSpecAlloc(void) +{ + ZoneSpec_s *Result; + + Result = (ZoneSpec_s *)ALLOC_ITEM(ZoneSpec_s, "ZoneSpec structure"); + if (Result != NULL) + SetZoneSpecDefaults(Result); + + ENSURE(Result == NULL || VALID_REF(Result)); + return Result; +} + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +/** + * Adjusts the capacity request as necessary to minimize memory reallocations + * for large lists. The adjusted capacity will be at least as big as requested + * however it may be larger if it is determined that the space requirement is + * growing faster. + * + * param ZoneOrVarArrayList + * Array list requesting the change in capacity. + * param CurrentCapacity + * Current capacity of the array list. + * param RequestedCapacity + * Capacity request or zero for default size. + * param ClientData + * Any client data needed for the adjustment. + * + * return + * Adjusted capacity that is at least as large as the request or zero if + * unable to satisfy the requested capacity. + */ +LgIndex_t ZoneOrVarListAdjustCapacityRequest(ArrayList_pa ZoneOrVarArrayList, + LgIndex_t CurrentCapacity, + LgIndex_t RequestedCapacity, + ArbParam_t ClientData) +{ + LgIndex_t Result; + + REQUIRE(ArrayListIsValid(ZoneOrVarArrayList)); + REQUIRE((RequestedCapacity == 0 && CurrentCapacity == 0) || + RequestedCapacity > CurrentCapacity); + REQUIRE(CurrentCapacity <= MaxNumZonesOrVars); + + if (RequestedCapacity <= MaxNumZonesOrVars) + { + if (RequestedCapacity != 0 && CurrentCapacity == 0) + { + /* first allocation; assume the request is the desired capacityy */ + Result = RequestedCapacity; + } + else + { + const LgIndex_t DEFAULT_CAPACITY = 32; + LgIndex_t BlockSize = MAX(DEFAULT_CAPACITY, CurrentCapacity / 2); + if (RequestedCapacity == 0) + Result = DEFAULT_CAPACITY; + else + Result = ((RequestedCapacity - 1) / BlockSize + 1) * BlockSize; + + /* put a cap on the maximum */ + if (Result > MaxNumZonesOrVars) + Result = MaxNumZonesOrVars; + } + } + else + Result = 0; /* request exceeded maximum; unable to satisfy request */ + + ENSURE(Result == 0 || Result >= RequestedCapacity); + ENSURE(Result <= MaxNumZonesOrVars); + return Result; +} + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if !defined USE_MACROS_FOR_FUNCTIONS +#endif +# if defined DEBUGUNIQUE +# endif +#endif /* TECPLOTKERNEL */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/dataset0.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/dataset0.cpp new file mode 100644 index 0000000000..c18ca539d9 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/dataset0.cpp @@ -0,0 +1,1668 @@ +/* + * 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 DATASET0MODULE +#include "GLOBAL.h" +#include "TASSERT.h" +#include "Q_UNICODE.h" +#include "ALLOC.h" +#include "ARRLIST.h" +#include "DATASET.h" +#include "SET.h" +#include "DATASHR.h" +#include "FILESTREAM.h" +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif +#include "Q_MSG.h" +#include "DATASET0.h" + +using namespace tecplot::strutil; +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +/* + * Low level dataset functions. No references to zones, vars or + * the DataSet_s master structure here. + */ + + +/* + */ +void OutOfMemoryMsg(void) +{ + ErrMsg(translate("Cannot allocate enough memory for this operation.")); +} /* OutOfMemoryMsg() */ + + +/** + */ +FieldData_pa FieldDataAlloc(void) +{ + FieldData_pa Result; + + Result = (FieldData_pa)ALLOC_ITEM(struct _FieldData_a, "FieldDataPtr"); + if (Result != NULL) + { + Result->Data = NULL; + +# if defined TECPLOTKERNEL /* TecIO doesn't require these features yet */ +/* CORE SOURCE CODE REMOVED */ +# else /* ...for TecIO only */ + Result->GetValueCallback[0] = NULL; + Result->SetValueCallback[0] = NULL; +# endif + +# if defined TECPLOTKERNEL /* TecIO doesn't require these features yet */ +/* CORE SOURCE CODE REMOVED */ +# endif + + Result->Type = FieldDataType_Invalid; + Result->ValueLocation = ValueLocation_Invalid; + Result->RefCount = 1; /* self */ + Result->VarShareRefCount = 1; /* self */ + Result->NumValues = 0; +# if defined TECPLOTKERNEL /* TecIO doesn't require these features yet */ +/* CORE SOURCE CODE REMOVED */ +# endif + } + + ENSURE(VALID_REF(Result) || Result == NULL); + return Result; +} + +/** + * Most clients should not call this function but FieldDataCleanup() instead. + * An exception to this would be Tecplot's own storable load-on-demand + * functions. + */ +void FieldDataDeallocData(FieldData_pa FieldData) +{ + REQUIRE(VALID_REF(FieldData)); + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + if (FieldData->Data != NULL) + { + /* Hack to remove 'deleting void* is undefined' warning... */ + char *Tmp = (char *)FieldData->Data; + FREE_ARRAY(Tmp, "FieldData _Data"); + FieldData->Data = NULL; + } + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + ENSURE(FieldData->Data == NULL); +} + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +/** + */ +void FieldDataCleanup(FieldData_pa FieldData) +{ + REQUIRE(VALID_REF(FieldData)); + +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# else + FieldDataDeallocData(FieldData); +# endif +} + +/** + */ +void FieldDataDealloc(FieldData_pa *FieldData, + Boolean_t DoTrackVarSharing) +{ + REQUIRE(VALID_REF(FieldData)); + REQUIRE(VALID_REF(*FieldData) || *FieldData == NULL); + REQUIRE(IMPLICATION(*FieldData != NULL, + IsStructureReferenced(*FieldData))); + REQUIRE(IMPLICATION(*FieldData != NULL && DoTrackVarSharing, + IsVarStructureReferenced(*FieldData))); + REQUIRE(VALID_BOOLEAN(DoTrackVarSharing)); + REQUIRE(IMPLICATION(*FieldData != NULL, + (*FieldData)->RefCount >= (*FieldData)->VarShareRefCount)); + + if (*FieldData != NULL) + { + if (DoTrackVarSharing) + DecVarStructureReference(*FieldData); + DecStructureReference(*FieldData); + if (!IsStructureReferenced(*FieldData)) + { + FieldDataCleanup(*FieldData); + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + FREE_ITEM(*FieldData, "field data"); + } + *FieldData = NULL; + } + + ENSURE(*FieldData == NULL); +} + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if !defined NDEBUG || defined CHECKED_BUILD +#endif +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if !defined NDEBUG || defined CHECKED_BUILD +#endif +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +template +static void copyTypedValueArray(void* DstArray, + LgIndex_t DstStart, + void* SrcArray, + LgIndex_t SrcStart, + LgIndex_t SrcEnd) +{ + T* SrcPtr = ((T*)SrcArray) + SrcStart; + T* DstPtr = ((T*)DstArray) + DstStart; + size_t numBytes = sizeof(T) * (SrcEnd - SrcStart + 1); + memcpy(DstPtr, SrcPtr, numBytes); +} +/** + * DstArray and SrcArray are aligned on proper word boundaries. + */ +void CopyTypedValueArray(FieldDataType_e ValueType, + void *DstArray, + LgIndex_t DstStart, + void *SrcArray, + LgIndex_t SrcStart, + LgIndex_t SrcEnd) +{ + REQUIRE(VALID_FIELD_DATA_TYPE(ValueType) && + ValueType != FieldDataType_Bit); + REQUIRE(VALID_REF(DstArray)); + REQUIRE(DstStart >= 0); + REQUIRE(VALID_REF(SrcArray)); + REQUIRE(0 <= SrcStart && SrcStart <= SrcEnd); + REQUIRE(DstArray != SrcArray); + + switch (ValueType) + { + case FieldDataType_Int64 : CHECK(FALSE); /* Future work: remove check */ + case FieldDataType_Double : + { + CHECK(sizeof(UInt64_t) == 8 && sizeof(double) == 8); + copyTypedValueArray(DstArray, + DstStart, + SrcArray, + SrcStart, + SrcEnd); + } break; + case FieldDataType_Float : + case FieldDataType_Int32 : + { + CHECK(sizeof(UInt32_t) == 4 && sizeof(float) == 4); + copyTypedValueArray(DstArray, + DstStart, + SrcArray, + SrcStart, + SrcEnd); + } break; + case FieldDataType_Int16 : + { + CHECK(sizeof(UInt16_t) == 2); + copyTypedValueArray(DstArray, + DstStart, + SrcArray, + SrcStart, + SrcEnd); + } break; + case FieldDataType_Byte : + { + copyTypedValueArray(DstArray, + DstStart, + SrcArray, + SrcStart, + SrcEnd); + } break; + default : CHECK(FALSE); + } +} + +/** + * SrcArray is aligned on proper word boundaries. + */ +void SwapBytesInTypedValueArray(FieldDataType_e ValueType, + void *SrcArray, + LgIndex_t SrcStart, + LgIndex_t SrcEnd, + LgIndex_t SrcSkip) +{ + REQUIRE(VALID_FIELD_DATA_TYPE(ValueType) && + ValueType != FieldDataType_Bit); + REQUIRE(VALID_REF(SrcArray)); + REQUIRE(0 <= SrcStart && SrcStart <= SrcEnd); + REQUIRE(SrcSkip > 0); + + switch (ValueType) + { + case FieldDataType_Int64: CHECK(FALSE); /* Future work: remove CHECK */ + case FieldDataType_Double: + { + /* swap 8 bytes blocks */ + UInt64_t *SrcPtr = ((UInt64_t *)SrcArray) + SrcStart; + UInt64_t *SrcPtrEnd = ((UInt64_t *)SrcArray) + SrcEnd; + CHECK(sizeof(UInt64_t) == 8 && sizeof(double) == 8); + while (SrcPtr <= SrcPtrEnd) + { + REVERSE_8_BYTES(SrcPtr); + SrcPtr += SrcSkip; + } + } break; + case FieldDataType_Float: + case FieldDataType_Int32: + { + /* swap 4 bytes blocks */ + UInt32_t *SrcPtr = ((UInt32_t *)SrcArray) + SrcStart; + UInt32_t *SrcPtrEnd = ((UInt32_t *)SrcArray) + SrcEnd; + CHECK(sizeof(UInt32_t) == 4 && sizeof(float) == 4); + while (SrcPtr <= SrcPtrEnd) + { + REVERSE_4_BYTES(SrcPtr); + SrcPtr += SrcSkip; + } + } break; + case FieldDataType_Int16: + { + /* swap 4 bytes blocks */ + UInt16_t *SrcPtr = ((UInt16_t *)SrcArray) + SrcStart; + UInt16_t *SrcPtrEnd = ((UInt16_t *)SrcArray) + SrcEnd; + CHECK(sizeof(UInt16_t) == 2); + while (SrcPtr <= SrcPtrEnd) + { + REVERSE_2_BYTES(SrcPtr); + SrcPtr += SrcSkip; + } + } break; + case FieldDataType_Byte: + case FieldDataType_Bit: + { + /* nothing to do */ + } break; + default: CHECK(FALSE); + } +} + +/** + * Same as SwapBytesInTypedValueArray, but does extra work. Doesn't assume + * DstArray and SrcArray are aligned on proper word boundaries. + */ +void SwapBytesInUnalignedTypedValueArray(FieldDataType_e ValueType, + void *SrcArray, + LgIndex_t SrcStart, + LgIndex_t SrcEnd, + LgIndex_t SrcSkip) +{ + REQUIRE(VALID_FIELD_DATA_TYPE(ValueType) && + ValueType != FieldDataType_Bit); + REQUIRE(VALID_REF(SrcArray)); + REQUIRE(0 <= SrcStart && SrcStart <= SrcEnd); + REQUIRE(SrcSkip > 0); + + switch (ValueType) + { + case FieldDataType_Int64: CHECK(FALSE); /* Future work: remove CHECK */ + case FieldDataType_Double: + { + /* swap 8-byte blocks */ + Byte_t *SrcPtr = ((Byte_t *)SrcArray) + SrcStart * sizeof(UInt64_t); + Byte_t *SrcPtrEnd = ((Byte_t *)SrcArray) + SrcEnd * sizeof(UInt64_t); + size_t byte_skip = SrcSkip * sizeof(UInt64_t); + CHECK(sizeof(UInt64_t) == 8 && sizeof(double) == 8); + while (SrcPtr <= SrcPtrEnd) + { + REVERSE_8_BYTES_1_AT_A_TIME(SrcPtr); + SrcPtr += byte_skip; + } + } break; + case FieldDataType_Float: + case FieldDataType_Int32: + { + /* swap 4-byte blocks */ + Byte_t *SrcPtr = ((Byte_t *)SrcArray) + SrcStart * sizeof(UInt32_t); + Byte_t *SrcPtrEnd = ((Byte_t *)SrcArray) + SrcEnd * sizeof(UInt32_t); + size_t byte_skip = SrcSkip * sizeof(UInt32_t); + CHECK(sizeof(UInt32_t) == 4 && sizeof(float) == 4); + while (SrcPtr <= SrcPtrEnd) + { + REVERSE_4_BYTES_1_AT_A_TIME(SrcPtr); + SrcPtr += byte_skip; + } + } break; + case FieldDataType_Int16: + { + /* swap 2-byte blocks */ + Byte_t *SrcPtr = ((Byte_t *)SrcArray) + SrcStart * sizeof(UInt16_t); + Byte_t *SrcPtrEnd = ((Byte_t *)SrcArray) + SrcEnd * sizeof(UInt16_t); + size_t byte_skip = SrcSkip * sizeof(UInt16_t); + CHECK(sizeof(UInt16_t) == 2); + while (SrcPtr <= SrcPtrEnd) + { + REVERSE_2_BYTES_1_AT_A_TIME(SrcPtr); + SrcPtr += byte_skip; + } + } break; + case FieldDataType_Byte: + case FieldDataType_Bit: + { + /* No swapping required. */ + } break; + default: CHECK(FALSE); + } +} + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined DEBUG_FIELDVALUES +# define DEBUG_FIELDVALUES_BAD_VALUE 0x11 +static unsigned char BadValueStr[] = +{ + DEBUG_FIELDVALUES_BAD_VALUE, + DEBUG_FIELDVALUES_BAD_VALUE, + DEBUG_FIELDVALUES_BAD_VALUE, + DEBUG_FIELDVALUES_BAD_VALUE, + DEBUG_FIELDVALUES_BAD_VALUE, + DEBUG_FIELDVALUES_BAD_VALUE, + DEBUG_FIELDVALUES_BAD_VALUE, + DEBUG_FIELDVALUES_BAD_VALUE +}; +/** + * If Tecplot is responsible for managing (allocating and deallocating) the + * raw data then + */ +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# else +# define FIELD_DATA_VALUE_IS_INITIALIZED(fd, pt, type) \ + ((sizeof(type) < 4) /* cannot make reliably test with less than four bytes */ || \ + memcmp(BadValueStr,((char *)((fd)->Data))+sizeof(type)*(pt), sizeof(type)) != 0) +# endif +#else +# define FIELD_DATA_VALUE_IS_INITIALIZED(fd, pt, type) TRUE +#endif + + + +/** + * Used in macros, thus not static + */ +double STDCALL GetFieldValueForFloat(const FieldData_pa fd, + LgIndex_t pt) +{ + REQUIRE(VALID_REF(fd)); +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# endif + REQUIRE(0 <= pt && pt < GetFieldDataNumValues(fd)); + REQUIRE(FIELD_DATA_VALUE_IS_INITIALIZED(fd, pt, float)); + + double Result = (double)GetFieldDataFloatPtr(fd)[pt]; + + return Result; +} + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + +/** + * Used in macros, thus not static + */ +double STDCALL GetFieldValueForDouble(const FieldData_pa fd, + LgIndex_t pt) +{ + REQUIRE(VALID_REF(fd)); +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# endif + REQUIRE(0 <= pt && pt < GetFieldDataNumValues(fd)); + REQUIRE(FIELD_DATA_VALUE_IS_INITIALIZED(fd, pt, double)); + + double Result = GetFieldDataDoublePtr(fd)[pt]; + + return Result; +} + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + +/** + */ +double STDCALL GetFieldValueForInt32(const FieldData_pa fd, + LgIndex_t pt) +{ + REQUIRE(VALID_REF(fd)); +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# endif + REQUIRE(0 <= pt && pt < GetFieldDataNumValues(fd)); + REQUIRE(FIELD_DATA_VALUE_IS_INITIALIZED(fd, pt, Int32_t)); + + double Result = (double)GetFieldDataInt32Ptr(fd)[pt]; + + return Result; +} + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + +/** + */ +double STDCALL GetFieldValueForInt16(const FieldData_pa fd, + LgIndex_t pt) +{ + REQUIRE(VALID_REF(fd)); +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# endif + REQUIRE(0 <= pt && pt < GetFieldDataNumValues(fd)); + REQUIRE(FIELD_DATA_VALUE_IS_INITIALIZED(fd, pt, Int16_t)); + + double Result = (double)GetFieldDataInt16Ptr(fd)[pt]; + + return Result; +} + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + +/** + */ +double STDCALL GetFieldValueForByte(const FieldData_pa fd, + LgIndex_t pt) +{ + REQUIRE(VALID_REF(fd)); +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# endif + REQUIRE(fd->Type == FieldDataType_Byte); + REQUIRE(0 <= pt && pt < GetFieldDataNumValues(fd)); + REQUIRE(FIELD_DATA_VALUE_IS_INITIALIZED(fd, pt, Byte_t)); + + double Result = (double)GetFieldDataBytePtr(fd)[pt]; + + return Result; +} + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + +/** + */ +double STDCALL GetFieldValueForBit(const FieldData_pa fd, + LgIndex_t pt) +{ + REQUIRE(VALID_REF(fd)); +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# endif + REQUIRE(fd->Type == FieldDataType_Bit); + REQUIRE(0 <= pt && pt < GetFieldDataNumValues(fd)); + REQUIRE(FIELD_DATA_VALUE_IS_INITIALIZED(fd, pt / 8, Byte_t)); + + LgIndex_t ByteOffset = pt / 8; + Byte_t BitMask = (01 << (pt % 8)); + + Byte_t *byte_array = GetFieldDataBytePtr(fd); + double Result = (byte_array[ByteOffset] & BitMask) ? 1.0 : 0.0; + + return Result; +} + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + +/** + */ +FieldValueGetFunction_pf DetermineFieldDataGetFunction(FieldDataType_e DataType, + Boolean_t IsFragmented) +{ + FieldValueGetFunction_pf Result; + + REQUIRE(VALID_FIELD_DATA_TYPE(DataType)); + REQUIRE(VALID_BOOLEAN(IsFragmented)); + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + { + switch (DataType) + { + case FieldDataType_Float : + { + Result = GetFieldValueForFloat; + } break; + case FieldDataType_Double : + { + Result = GetFieldValueForDouble; + } break; + case FieldDataType_Int32 : + { + Result = GetFieldValueForInt32; + } break; + case FieldDataType_Int16 : + { + Result = GetFieldValueForInt16; + } break; + case FieldDataType_Byte : + { + Result = GetFieldValueForByte; + } break; + case FieldDataType_Bit : + { + Result = GetFieldValueForBit; + } break; + default : + { + CHECK(FALSE); + Result = NULL; /* satisfy compiler */ + } break; + } + } + return (Result); +} + +/** + */ +static void STDCALL SetFieldValueForFloat(FieldData_pa fd, + LgIndex_t pt, + double val) +{ + REQUIRE(VALID_REF(fd)); +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# endif + REQUIRE(0 <= pt && pt < GetFieldDataNumValues(fd)); + REQUIRE("val can have any value"); + + GetFieldDataFloatPtr(fd)[pt] = CONVERT_DOUBLE_TO_FLOAT(val); + + ENSURE(FIELD_DATA_VALUE_IS_INITIALIZED(fd, pt, float)); +} + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + +/** + */ +static void STDCALL SetFieldValueForDouble(FieldData_pa fd, + LgIndex_t pt, + double val) +{ + REQUIRE(VALID_REF(fd)); +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# endif + REQUIRE(0 <= pt && pt < GetFieldDataNumValues(fd)); + REQUIRE("val can have any value"); + + GetFieldDataDoublePtr(fd)[pt] = CLAMP_DOUBLE(val); + + ENSURE(FIELD_DATA_VALUE_IS_INITIALIZED(fd, pt, double)); +} + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + +/** + */ +static void STDCALL SetFieldValueForInt32(FieldData_pa fd, + LgIndex_t pt, + double val) +{ + REQUIRE(VALID_REF(fd)); +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# endif + REQUIRE(0 <= pt && pt < GetFieldDataNumValues(fd)); + REQUIRE("val can have any value"); + + GetFieldDataInt32Ptr(fd)[pt] = CONVERT_DOUBLE_TO_INT32(val); + + ENSURE(FIELD_DATA_VALUE_IS_INITIALIZED(fd, pt, Int32_t)); +} + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + +/** + */ +static void STDCALL SetFieldValueForInt16(FieldData_pa fd, + LgIndex_t pt, + double val) +{ + REQUIRE(VALID_REF(fd)); +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# endif + REQUIRE(0 <= pt && pt < GetFieldDataNumValues(fd)); + REQUIRE("val can have any value"); + + GetFieldDataInt16Ptr(fd)[pt] = CONVERT_DOUBLE_TO_INT16(val); + + ENSURE(FIELD_DATA_VALUE_IS_INITIALIZED(fd, pt, Int16_t)); +} + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + +/** + */ +static void STDCALL SetFieldValueForByte(FieldData_pa fd, + LgIndex_t pt, + double val) +{ + REQUIRE(VALID_REF(fd)); +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# endif + REQUIRE(fd->Type == FieldDataType_Byte); + REQUIRE(0 <= pt && pt < GetFieldDataNumValues(fd)); + REQUIRE("val can have any value"); + + if (val < 1.0) + GetFieldDataBytePtr(fd)[pt] = 0; + else if (val > 255.0) + GetFieldDataBytePtr(fd)[pt] = 255; + else + GetFieldDataBytePtr(fd)[pt] = (Byte_t)val; + + ENSURE(FIELD_DATA_VALUE_IS_INITIALIZED(fd, pt, Byte_t)); +} + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + +/** + */ +static void STDCALL SetFieldValueForBit(FieldData_pa fd, + LgIndex_t pt, + double val) +{ + REQUIRE(VALID_REF(fd)); +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# endif + REQUIRE(fd->Type == FieldDataType_Bit); + REQUIRE(0 <= pt && pt < GetFieldDataNumValues(fd)); + REQUIRE("val can have any value"); + + LgIndex_t ByteOffset = pt / 8; + Byte_t BitMask = (01 << (pt % 8)); + + if (val < 1.0) + GetFieldDataBytePtr(fd)[ByteOffset] &= ~BitMask; + else + GetFieldDataBytePtr(fd)[ByteOffset] |= BitMask; + + ENSURE(FIELD_DATA_VALUE_IS_INITIALIZED(fd, pt / 8, Byte_t)); +} + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + +/** + */ +FieldValueSetFunction_pf DetermineFieldDataSetFunction(FieldDataType_e DataType, + Boolean_t IsFragmented) +{ + FieldValueSetFunction_pf Result; + + REQUIRE(VALID_FIELD_DATA_TYPE(DataType)); + REQUIRE(VALID_BOOLEAN(IsFragmented)); + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + { + switch (DataType) + { + case FieldDataType_Float : + { + Result = SetFieldValueForFloat; + } break; + case FieldDataType_Double : + { + Result = SetFieldValueForDouble; + } break; + case FieldDataType_Int32 : + { + Result = SetFieldValueForInt32; + } break; + case FieldDataType_Int16 : + { + Result = SetFieldValueForInt16; + } break; + case FieldDataType_Byte : + { + Result = SetFieldValueForByte; + } break; + case FieldDataType_Bit : + { + Result = SetFieldValueForBit; + } break; + default : + { + CHECK(FALSE); + Result = NULL; /* satisfy compiler */ + } break; + } + } + return (Result); +} + + +/** + */ +Int64_t FieldDataGetBytesNeeded(LgIndex_t NumValues, + FieldDataType_e DataType) +{ + Int64_t Result = 0; /* ...quite compiler */ + + REQUIRE(NumValues >= 0); + REQUIRE(VALID_FIELD_DATA_TYPE(DataType)); + + switch (DataType) + { + case FieldDataType_Float: Result = ((Int64_t)NumValues)*sizeof(float); break; + case FieldDataType_Double: Result = ((Int64_t)NumValues)*sizeof(double); break; + case FieldDataType_Int32: Result = ((Int64_t)NumValues)*sizeof(LgIndex_t); break; + case FieldDataType_Int16: Result = ((Int64_t)NumValues)*sizeof(SmInteger_t); break; + case FieldDataType_Byte: Result = ((Int64_t)NumValues)*sizeof(Byte_t); break; + case FieldDataType_Bit: Result = ((Int64_t)(NumValues+7)/8)*sizeof(Byte_t); break; + default: CHECK(FALSE); break; + } + + ENSURE(Result >= 0); + return Result; +} + +/** + * On the SGI, HP, and Sun machines 64 bit objects such as doubles must be 8 + * byte aligned while on all other machines 32 bit alignment suffices. Some + * allow 1 byte alignment but we won't bother with that. + */ +#if defined IRISX || defined HPUX || defined SUNX +# define SIZEOF_LARGEST_OBJECT_TO_ALIGN sizeof(Int64_t) +#else +# define SIZEOF_LARGEST_OBJECT_TO_ALIGN sizeof(Int32_t) +#endif + +/** + */ +Boolean_t IsOffsetAlignedForFieldDataType(FieldDataType_e FieldDataType, + Int64_t Offset) +{ + REQUIRE(VALID_FIELD_DATA_TYPE(FieldDataType)); + REQUIRE(Offset >= 0); + + Int64_t SizeOfType = FieldDataGetBytesNeeded(1, FieldDataType); + if (SizeOfType > (Int64_t)SIZEOF_LARGEST_OBJECT_TO_ALIGN) + SizeOfType = SIZEOF_LARGEST_OBJECT_TO_ALIGN; + + Boolean_t HasValidAlignment = (Offset % SizeOfType == 0); + + ENSURE(VALID_BOOLEAN(HasValidAlignment)); + return HasValidAlignment; +} + +/** + */ +Int64_t GetAlignedOffsetForFieldDataType(FieldDataType_e FieldDataType, + Int64_t Offset) +{ + REQUIRE(VALID_FIELD_DATA_TYPE(FieldDataType)); + REQUIRE(Offset >= 0); + + Int64_t SizeOfType = FieldDataGetBytesNeeded(1, FieldDataType); + if (SizeOfType > (Int64_t)SIZEOF_LARGEST_OBJECT_TO_ALIGN) + SizeOfType = SIZEOF_LARGEST_OBJECT_TO_ALIGN; + + Int64_t NumBytesPastAlignment = (Offset % SizeOfType); + Int64_t Result = Offset - NumBytesPastAlignment; + + ENSURE(0 <= Result && Result <= Offset); + ENSURE(IsOffsetAlignedForFieldDataType(FieldDataType, Result)); + return Result; +} + +/** + */ +void FieldDataDefineData(FieldData_pa FieldData, + LgIndex_t NumValues, + FieldDataType_e DataType, + ValueLocation_e ValueLocation) +{ + REQUIRE(VALID_REF(FieldData)); + REQUIRE(NumValues >= 0); + REQUIRE(VALID_FIELD_DATA_TYPE(DataType)); + REQUIRE(VALID_ENUM(ValueLocation, ValueLocation_e)); + + /* + * Remove any old data (transformed UVW is one example that calls this + * function with a non-null data pointer when switching the value location + * when style changes the value location and therefore the amount of data + * allocated.) + */ + FieldDataCleanup(FieldData); + + /* + * The reference count is not modified here. This function only allocates the + * structure and makes adjustments to the some of the members. The reference + * count was initialized when the structure was initially created and the + * structure may be shared before the data portion is even allocated. + */ + FieldData->NumValues = NumValues; + FieldData->Type = DataType; + FieldData->ValueLocation = ValueLocation; +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# else /* ...for TecIO only */ + FieldData->GetValueCallback[0] = (void *)DetermineFieldDataGetFunction(DataType, FALSE); + FieldData->SetValueCallback[0] = (void *)DetermineFieldDataSetFunction(DataType, FALSE); +#endif + + ENSURE(FieldData->Data == NULL); +} + +/** + */ +Boolean_t FieldDataAllocData(FieldData_pa FieldData, + Boolean_t ShowErrMsg) +{ + REQUIRE(VALID_REF(FieldData)); + REQUIRE(FieldData->Type != FieldDataType_Invalid); /* ...must call FieldDataDefineData first */ + REQUIRE(FieldData->Data == NULL); + REQUIRE(VALID_BOOLEAN(ShowErrMsg)); + + /* + * The size of size_t may be smaller than our unsigned 64 bit integer value + * so we might have to squeeze it down possibly loosing precision. + */ + Int64_t ActualBytesNeeded = FieldDataGetBytesNeeded(FieldData->NumValues, FieldData->Type); + size_t BytesToAllocate = (size_t)ActualBytesNeeded; + + /* + * 64 bit architectures are effectively unlimited in their allocation size + * while 32 architectures are limited to 4GB (some may limit further to 2GB + * which will be borne out by the call to malloc). + */ + CHECK(sizeof(size_t) == 4 || sizeof(size_t) == 8); + Boolean_t IsOk = (FieldData->NumValues <= MAXINDEX && + IMPLICATION(sizeof(size_t) == 4, + ActualBytesNeeded <= (Int64_t)0xffffffff)); + if (IsOk) + { + if (FieldData->NumValues > 0) + { + FieldData->Data = (void *)ALLOC_ARRAY(BytesToAllocate, char, "FieldData's Data"); + #if defined DEBUG_FIELDVALUES + { + if (FieldData->Data != NULL) + memset(FieldData->Data, DEBUG_FIELDVALUES_BAD_VALUE, BytesToAllocate); + } + #endif + /* + * For bit type data zero the last byte in the data array. We do + * this because NumValues is probably not a multiple of 8 bits and + * thus the valid bit values will not occupy all bits of the last + * byte. By zeroing the unused bits at the end of the array we + * produce consistent data files when written to disk. + */ + if (FieldData->Type == FieldDataType_Bit) + ((char*)FieldData->Data)[BytesToAllocate-1] = '\0'; + } + IsOk = (FieldData->NumValues == 0 || + FieldData->Data != NULL); + if (!IsOk && ShowErrMsg) + OutOfMemoryMsg(); + } + else if (ShowErrMsg) + ErrMsg(translate("Storage limit (%ld) exceeded for a single variable."), (long)MAXINDEX); + +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# endif + + ENSURE(VALID_REF(FieldData->Data) || FieldData->Data == NULL); + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if !defined NO_ASSERTS +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +/** + * Allocates a field data pointer with space for "num_pts" of field data type + * "field_data_type" nodal values. + * + * IMPORTANT: + * This field data may NOT be used for zones but only for things like + * geometries or other temporary field data that will never be placed + * into a COB or zone. + */ +FieldData_pa AllocScratchNodalFieldDataPtr(LgIndex_t NumValues, + FieldDataType_e Type, + Boolean_t ShowErrMsg) +{ + REQUIRE(NumValues >= 0); + REQUIRE(VALID_FIELD_DATA_TYPE(Type)); + REQUIRE(VALID_BOOLEAN(ShowErrMsg)); + + FieldData_pa Result = FieldDataAlloc(); + if (Result != NULL) + { + FieldDataDefineData(Result, NumValues, Type, ValueLocation_Nodal); + if (!FieldDataAllocData(Result, ShowErrMsg)) + FieldDataDealloc(&Result, FALSE); + } + else if (ShowErrMsg) + OutOfMemoryMsg(); + + ENSURE(VALID_REF(Result) || Result == NULL); +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# endif + ENSURE(IMPLICATION(Result != NULL, + (Result->NumValues >= 0 && + IMPLICATION(Result->NumValues != 0, + VALID_REF(Result->Data)) && + VALID_FIELD_DATA_TYPE(Result->Type)))); + + return Result; +} + + +/** + * Frees memory allocated with AllocScratchNodalFieldDataPtr(). + * + * @param ScratchFieldData + * Scratch field data pointer to deallocate. This should NEVER be a field + * data from a zone or COB. See note in AllocScratchNodalFieldDataPtr(). + */ +void DeallocScratchNodalFieldDataPtr(FieldData_pa *FieldDataRef) +{ + FieldDataDealloc(FieldDataRef, + FALSE); /* DoTrackVarSharing */ +} + + +#if !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +/** + */ +FieldDataType_e GetFieldDataType_FUNC(FieldData_pa FieldData) +{ + REQUIRE(VALID_REF(FieldData)); + + FieldDataType_e Result = GetFieldDataType_MACRO(FieldData); + + ENSURE(VALID_FIELD_DATA_TYPE(Result)); + return Result; +} +#endif /* !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS */ + + +#if !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +/** + */ +FieldValueGetFunction_pf GetFieldDataGetFunction_FUNC(FieldData_pa FieldData) +{ + REQUIRE(VALID_REF(FieldData)); + + FieldValueGetFunction_pf Result = GetFieldDataGetFunction_MACRO(FieldData); + + ENSURE(VALID_FN_REF(Result)); + return Result; +} +#endif /* !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS */ + + +#if !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +/** + */ +FieldValueSetFunction_pf GetFieldDataSetFunction_FUNC(FieldData_pa FieldData) +{ + REQUIRE(VALID_REF(FieldData)); + + FieldValueSetFunction_pf Result = GetFieldDataSetFunction_MACRO(FieldData); + + ENSURE(VALID_FN_REF(Result)); + return Result; +} +#endif /* !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS */ + + +#if !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +/** + */ +LgIndex_t GetFieldDataNumValues_FUNC(FieldData_pa FieldData) +{ + REQUIRE(VALID_REF(FieldData)); + + LgIndex_t Result = GetFieldDataNumValues_MACRO(FieldData); + + ENSURE(Result >= 0); + return Result; +} +#endif /* !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS */ + + +#if !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +/** + */ +ValueLocation_e GetFieldDataValueLocation_FUNC(FieldData_pa FieldData) +{ + REQUIRE(VALID_REF(FieldData)); + + ValueLocation_e Result = GetFieldDataValueLocation_MACRO(FieldData); + + ENSURE(Result == ValueLocation_Invalid || /* i.e. pending assignment */ + VALID_ENUM(Result, ValueLocation_e)); + return Result; +} +#endif /* !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS */ + + +#if !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +/** + */ +Boolean_t IsFieldDataDirectAccessAllowed_FUNC(FieldData_pa FieldData) +{ + REQUIRE(VALID_REF(FieldData)); + + Boolean_t Result = IsFieldDataDirectAccessAllowed_MACRO(FieldData); + + ENSURE(VALID_BOOLEAN(Result)); + return Result; +} +#endif + + +#if !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +/** + */ +float *GetFieldDataFloatPtr_FUNC(FieldData_pa fd) +{ + REQUIRE(VALID_REF(fd)); + + float *Result = GetFieldDataFloatPtr_MACRO(fd); + + ENSURE(VALID_REF(Result)); + return Result; +} +#endif + + +#if !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +/** + */ +double *GetFieldDataDoublePtr_FUNC(FieldData_pa fd) +{ + REQUIRE(VALID_REF(fd)); + + double *Result = GetFieldDataDoublePtr_MACRO(fd); + + ENSURE(VALID_REF(Result)); + return Result; +} +#endif + + +#if !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +/** + */ +Int64_t *GetFieldDataInt64Ptr_FUNC(FieldData_pa fd) +{ + REQUIRE(VALID_REF(fd)); + + Int64_t *Result = GetFieldDataInt64Ptr_MACRO(fd); + + ENSURE(VALID_REF(Result)); + return Result; +} +#endif + + +#if !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +/** + */ +Int32_t *GetFieldDataInt32Ptr_FUNC(FieldData_pa fd) +{ + REQUIRE(VALID_REF(fd)); + + Int32_t *Result = GetFieldDataInt32Ptr_MACRO(fd); + + ENSURE(VALID_REF(Result)); + return Result; +} +#endif + + +#if !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +/** + */ +Int16_t *GetFieldDataInt16Ptr_FUNC(FieldData_pa fd) +{ + REQUIRE(VALID_REF(fd)); + + Int16_t *Result = GetFieldDataInt16Ptr_MACRO(fd); + + ENSURE(VALID_REF(Result)); + return Result; +} +#endif + + +#if !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +/* + * No byte ordering or alignment issues with single bytes (which are also used with the "Bit" type) + */ +Byte_t *GetFieldDataBytePtr_FUNC(FieldData_pa fd) +{ + /* + * This function gets called for Byte and Bit types, but we cannot REQUIRE + * those types because it is also used for non-aligned values. We can't + * check for non-aligned because we might be copying aligned bytes to a + * non-aligned location. + */ + REQUIRE(VALID_REF(fd)); + + Byte_t *Result = GetFieldDataBytePtr_MACRO(fd); + + ENSURE(VALID_REF(Result)); + return Result; +} +#endif + + +#if !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +/** + * Gets a ptr to 2-byte blocks regardless of byte ordering, but still has to + * worry about byte alignment + */ +UInt16_t *GetFieldData2BytePtr_FUNC(FieldData_pa fd) +{ + REQUIRE(VALID_REF(fd)); + REQUIRE(fd->Type == FieldDataType_Int16); + + UInt16_t *Result = GetFieldData2BytePtr_MACRO(fd); + + ENSURE(VALID_REF(Result)); + return Result; +} +#endif + + +#if !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +/* + * Gets a ptr to 4-byte blocks regardless of byte ordering, but still has to + * worry about byte alignment + */ +UInt32_t *GetFieldData4BytePtr_FUNC(FieldData_pa fd) +{ + REQUIRE(VALID_REF(fd)); + REQUIRE(fd->Type == FieldDataType_Int32 || fd->Type == FieldDataType_Float); + + UInt32_t *Result = GetFieldData4BytePtr_MACRO(fd); + + ENSURE(VALID_REF(Result)); + return Result; +} +#endif + + +#if !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +/* + * Gets a ptr to 8-byte blocks regardless of byte ordering, but still has to + * worry about byte alignment + */ +UInt64_t *GetFieldData8BytePtr_FUNC(FieldData_pa fd) +{ + REQUIRE(VALID_REF(fd)); + REQUIRE(fd->Type == FieldDataType_Int64 || fd->Type == FieldDataType_Double); + + UInt64_t *Result = GetFieldData8BytePtr_MACRO(fd); + + ENSURE(VALID_REF(Result)); + return Result; +} +#endif + + +#if !defined USE_MACROS_FOR_FIELD_DATA_FUNCTIONS +/* + * WARNING: GetFieldDataVoidPtr checks nothing, and thus should only be + * used with extreme caution (that is, checking the alignment + * and byte order by hand). + */ +void *GetFieldDataVoidPtr_FUNC(FieldData_pa fd) +{ + REQUIRE(VALID_REF(fd)); + + void *Result = GetFieldDataVoidPtr_MACRO(fd); + + ENSURE(VALID_REF(Result)); + return Result; +} +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + +/* + */ +void CopyFieldValue(FieldData_pa dst, + LgIndex_t dstindex, + FieldData_pa src, + LgIndex_t srcindex) +{ + REQUIRE(VALID_REF(dst)); + REQUIRE(VALID_REF(src)); +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ + REQUIRE(dstindex >= 0 && dstindex < GetFieldDataNumValues(dst) && + srcindex >= 0 && srcindex < GetFieldDataNumValues(src)); + + Boolean_t DoBruteForceCopy = TRUE; + + if (IsFieldDataDirectAccessAllowed(src) && + IsFieldDataDirectAccessAllowed(dst) && + GetFieldDataType(src) == GetFieldDataType(dst)) + { + switch (GetFieldDataType(src)) + { + case FieldDataType_Int64 : CHECK(FALSE); /* Future work: remove and let fall through */ + case FieldDataType_Double : + { + CHECK(sizeof(UInt64_t) == 8 && sizeof(double) == 8); + UInt64_t *dst_ptr = GetFieldData8BytePtr(dst) + dstindex; + UInt64_t *src_ptr = GetFieldData8BytePtr(src) + srcindex; + *dst_ptr = *src_ptr; + DoBruteForceCopy = FALSE; + } break; + case FieldDataType_Float : + case FieldDataType_Int32 : + { + CHECK(sizeof(UInt32_t) == 4 && sizeof(float) == 4); + UInt32_t *dst_ptr = GetFieldData4BytePtr(dst) + dstindex; + UInt32_t *src_ptr = GetFieldData4BytePtr(src) + srcindex; + *dst_ptr = *src_ptr; + DoBruteForceCopy = FALSE; + } break; + case FieldDataType_Int16 : + { + CHECK(sizeof(UInt16_t) == 2); + UInt16_t *dst_ptr = GetFieldData2BytePtr(dst) + dstindex; + UInt16_t *src_ptr = GetFieldData2BytePtr(src) + srcindex; + *dst_ptr = *src_ptr; + } break; + case FieldDataType_Byte : + { + GetFieldDataBytePtr(dst)[dstindex] = GetFieldDataBytePtr(src)[srcindex]; + DoBruteForceCopy = FALSE; + } break; + case FieldDataType_Bit : break; /* handle below */ + default : CHECK(FALSE); /* Future work: when more complex types are added, remove this CHECK */ + } + } + + if (DoBruteForceCopy) + { + double val = GetFieldValue(src, srcindex); + SetFieldValue(dst, dstindex, val); + } +} /* CopyFieldValue() */ + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ + + +/* + */ +void SetFieldDataPtrToAllZeros(FieldData_pa fd) +{ + REQUIRE(VALID_REF(fd)); +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ + + LgIndex_t NumValues = GetFieldDataNumValues(fd); + + /* + * memset each byte to 0 works for floats and doubles and works regardless + * of byte ordering or alignment. + */ + size_t NumBytesToMemSet = 0; + if (IsFieldDataDirectAccessAllowed(fd)) + { + switch (GetFieldDataType(fd)) + { + case FieldDataType_Int64 : CHECK(FALSE); /* Future work: remove CHECK */ + case FieldDataType_Double : + { + CHECK(sizeof(UInt64_t) == 8 && sizeof(double) == 8); + NumBytesToMemSet = NumValues * sizeof(Int64_t); + } break; + case FieldDataType_Int32 : + case FieldDataType_Float : + { + CHECK(sizeof(UInt32_t) == 4 && sizeof(float) == 4); + NumBytesToMemSet = NumValues * sizeof(Int32_t); + } break; + case FieldDataType_Int16 : + { + CHECK(sizeof(UInt16_t) == 2); + NumBytesToMemSet = NumValues * sizeof(Int16_t); + } break; + case FieldDataType_Byte : + { + NumBytesToMemSet = NumValues * sizeof(Byte_t); + } break; + case FieldDataType_Bit : + { + NumBytesToMemSet = ((NumValues + 7) / 8) * sizeof(Byte_t); + } break; + default : + { + CHECK(FALSE); + } break; + } + } + + if (NumBytesToMemSet > 0) + { + void *fd_data = GetFieldDataVoidPtr(fd); + memset(fd_data, 0, NumBytesToMemSet); + } + else + { + int ii; + for (ii = 0; ii < NumValues; ii++) + SetFieldValue(fd, ii, 0.0); + } + +} /* SetFieldDataPtrToAllZeros() */ + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/datautil.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/datautil.cpp new file mode 100644 index 0000000000..783abec0c4 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/datautil.cpp @@ -0,0 +1,941 @@ +/* + * 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"); +} + + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/filestream.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/filestream.cpp new file mode 100644 index 0000000000..049f99ed74 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/filestream.cpp @@ -0,0 +1,78 @@ +/* + * 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 + +/* + ***************************************************************** + ***************************************************************** + ******* ******** + ****** Copyright (C) 1988-2008 Tecplot, Inc. ******* + ******* ******** + ***************************************************************** + ***************************************************************** +*/ + +#define FILESTREAMMODULE + +#include "GLOBAL.h" +#include "TASSERT.h" +#include "ALLOC.h" +#include "SYSTEM.h" +#include "FILESTREAM.h" + +/** + */ +FileStream_s *FileStreamAlloc(FILE *File, + Boolean_t IsByteOrderNative) +{ + REQUIRE(VALID_REF(File) || File == NULL); + + FileStream_s *Result = ALLOC_ITEM(FileStream_s, "FileStream"); + if (Result != NULL) + { + Result->File = File; + Result->IsByteOrderNative = IsByteOrderNative; + } + + ENSURE(VALID_REF(Result) || Result == NULL); + return Result; +} + +/** + */ +void FileStreamDealloc(FileStream_s **FileStream) +{ + REQUIRE(VALID_REF(FileStream)); + REQUIRE(VALID_REF(*FileStream) || *FileStream == NULL); + + if (*FileStream != NULL) + { + FREE_ITEM(*FileStream, "FileStream"); + *FileStream = NULL; + } + + ENSURE(*FileStream == NULL); +} diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/geom2.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/geom2.cpp new file mode 100644 index 0000000000..198f096fd9 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/geom2.cpp @@ -0,0 +1,89 @@ +/* + * 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 + +/* +***************************************************************** +***************************************************************** +******* ******** +****** Copyright (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +***************************************************************** +***************************************************************** +*/ + +#define GEOM2MODULE +#include "GLOBAL.h" +#include "TASSERT.h" +#include "Q_UNICODE.h" +#include "ALLOC.h" + +#include "GEOM.h" +#include "TEXT.h" +#include "STRUTIL.h" +#include "GEOM2.h" + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif +#include "DATASET0.h" + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# if 0 /* 3D geometry arrowheads are not drawn at this time. */ +#endif +# if 0 /* 3D geometry arrowheads are not drawn at this time. */ +# endif +#if 0 +#endif +# ifndef NO_ASSERTS +# endif +# ifndef NO_ASSERTS +# endif +#endif /* TECPLOTKERNEL */ + + +FieldDataType_e GetGeomFieldDataType(Geom_s const* Geom) +{ + FieldDataType_e Result; + + REQUIRE(VALID_REF(Geom)); + REQUIRE(VALID_REF(Geom->GeomData.Generic.V1Base)); + + Result = Geom->DataType; + + ENSURE(VALID_GEOM_FIELD_DATA_TYPE(Result)); + /* + * Check that the geom's field data arrays (if they exist) + * have the same type as the geometry. + */ + ENSURE(IMPLICATION(VALID_REF(Geom->GeomData.Generic.V1Base), Result == GetFieldDataType(Geom->GeomData.Generic.V1Base))); + ENSURE(IMPLICATION(VALID_REF(Geom->GeomData.Generic.V2Base), Result == GetFieldDataType(Geom->GeomData.Generic.V2Base))); + ENSURE(IMPLICATION(VALID_REF(Geom->GeomData.Generic.V3Base), Result == GetFieldDataType(Geom->GeomData.Generic.V3Base))); + + return Result; +} diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/q_msg.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/q_msg.cpp new file mode 100644 index 0000000000..6a20cf5604 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/q_msg.cpp @@ -0,0 +1,415 @@ +/* + * 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 Q_MSGMODULE +#include "GLOBAL.h" +#include "TASSERT.h" +#include "Q_UNICODE.h" +#include "ALLOC.h" +#include "ARRLIST.h" + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if !defined ENGINE +#if defined MOTIF +#endif +#if defined MSWIN +#endif +#endif +#endif + +#include "STRUTIL.h" +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +using std::string; +using namespace tecplot::strutil; +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#define MAXCHARACTERSPERLINE 60 +/* + * Wrap a string so it contains at most CharactersPerLine + * characters. Embedded newlines are left alone. Spaces + * following newlines are also left alone. + */ +Boolean_t WrapString(const char *OldString, + char **NewString) +{ + size_t L; + if (OldString == NULL) + return (FALSE); + + /* + * Assume Old string has ample spaces. Will only be + * replacing some spaces with newlines and removing + * other spaces. New string can be allocated to be + * same length as old string. + */ + + L = strlen(OldString); + *NewString = ALLOC_ARRAY(L + 1, char, "new error message string"); + if (*NewString == NULL) + return (FALSE); + + strcpy(*NewString, OldString); + + if (L > MAXCHARACTERSPERLINE) + { + char *LineStart = *NewString; + char *LastWord = *NewString; + char *WPtr = *NewString; + while (WPtr && (*WPtr != '\0')) + { + size_t CurLen; + /* + * Find next hard newline. If there is one befor the + * line should be chopped then reset the Last Word to + * be at the first word after the newline. + */ + WPtr = strchr(LineStart, '\n'); + if (WPtr && ((WPtr - LineStart) < MAXCHARACTERSPERLINE)) + { + WPtr++; + while (*WPtr == '\n') + WPtr++; + LineStart = WPtr; + /* + * Skip over trailing spaces. Special handling to + * allow indent after hard newline. + */ + while (*WPtr == ' ') + WPtr++; + LastWord = WPtr; + continue; + } + /* + * Find next "word" + */ + WPtr = strchr(LastWord, ' '); + if (WPtr != NULL) + { + while (*WPtr == ' ') + WPtr++; + } + + if (WPtr == NULL) + { + CurLen = strlen(LineStart); + } + else + { + CurLen = WPtr - LineStart; + } + + if (CurLen > MAXCHARACTERSPERLINE) + { + /* + * Line is too long. Back up to previous + * word and replace preceeding space with + * a newline. + */ + if (LastWord == LineStart) + { + /* + * Bad news, line has very long word. + */ + if (WPtr && (*WPtr != '\0')) + { + *(WPtr - 1) = '\n'; + LastWord = WPtr; + } + } + else + { + *(LastWord - 1) = '\n'; + } + LineStart = LastWord; + } + else + LastWord = WPtr; + } + } + return (TRUE); +} + + +static void SendWarningToFile(FILE *F, + const char *S) +{ + char *S2; + REQUIRE(VALID_REF(F)); + REQUIRE(VALID_REF(S)); + if (WrapString(S, &S2)) + { + fprintf(F, "Warning: %s\n", S2); + FREE_ARRAY(S2, "temp warning string"); + } +} + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + +/** + * Show the warning message. Note that the Format string can be the only + * argument, in which case it is essentially the warning message itself. + * + * param Format + * C Format string or a simple message. + * param ... + * Zero or more variable arguments. The number of arguments must correspond + * to the placeholders in the format string. + */ +void Warning(TranslatedString Format, + ...) /* zero or more arguments */ +{ + REQUIRE(!Format.isNull()); + + static Boolean_t InWarning = FALSE; /* ...used to prevent recursive deadlock */ + if (!InWarning) + { +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + InWarning = TRUE; + { + /* + * Attempt to format the string. Failing that simply use the original format + * string argument which, if we ran out of memory while formatting, is + * probably just an warning message saying that we ran out of memory in some + * previous operation anyway. + */ + Boolean_t cleanUp = TRUE; + + va_list Arguments; + va_start(Arguments, Format); + char* message = vFormatString(Format.c_str(), Arguments); + va_end(Arguments); + + if (message == NULL) + { + cleanUp = FALSE; // ...this boolean allows us to "carefully" cast away the const'ness + message = (char*)Format.c_str(); + } + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#ifdef MSWIN +#endif +#if defined UNIXX +#endif +#if defined MSWIN +#endif +#else /* !TECPLOTKERNEL */ + { + SendWarningToFile(stderr, message); + } +#endif + + if (cleanUp) + FREE_ARRAY(message, "message"); + } + InWarning = FALSE; + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + } +} + + +static void SendErrToFile(FILE *File, + const char *Msg) +{ + char *FormattedMsg; + REQUIRE(VALID_REF(File)); + REQUIRE(VALID_REF(Msg)); + if (WrapString(Msg, &FormattedMsg)) + { + fprintf(File, "Err: %s\n", FormattedMsg); + FREE_ARRAY(FormattedMsg, "temp error string"); + } + else + fprintf(File, "Err: %s\n", Msg); +} + + +/* Fall-back ErrMsg procedure when nothing else works */ +static void DefaultErrMsg(const char *Msg) +{ + REQUIRE(VALID_REF(Msg)); + +#ifdef MSWIN +#ifdef TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#else + MessageBox(NULL, Msg, "Error", MB_OK | MB_ICONERROR); +#endif +#else + SendErrToFile(stderr, Msg); +#endif +} + +static void PostErrorMessage(TranslatedString Format, + va_list Arguments) +{ + REQUIRE(!Format.isNull()); + + /* + * Attempt to format the string. Failing that simply use the original format + * string argument which, if we ran out of memory while formatting, is + * probably just an error message saying that we ran out of memory in some + * previous operation anyway. + */ + Boolean_t cleanUp = TRUE; + char* messageString = vFormatString(Format.c_str(), Arguments); + if (messageString == NULL) + { + cleanUp = FALSE; // ...this boolean allows us to "carefully" cast away the const'ness + messageString = (char*)Format.c_str(); + } + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#ifdef MSWIN +#endif +#if defined UNIXX +#if !defined ENGINE +#endif +#endif +#else /* !TECPLOTKERNEL */ + { + DefaultErrMsg(messageString); + } +#endif + + /* cleanup if we allocated the string */ + if (cleanUp) + FREE_ARRAY(messageString, "messageString"); +} + +/* + * NOTES: + * This function is thread safe in that it may be safely called by multiple + * threads however when running interactively only the first error message is + * queued for display on idle. In batch mode all messages are sent to the + * batch log file. + */ +void vErrMsg(TranslatedString Format, + va_list Arguments) +{ + REQUIRE(!Format.isNull()); + + static Boolean_t InErrMsg = FALSE; /* ...used to prevent recursive deadlock */ + if (!InErrMsg) + { +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + InErrMsg = TRUE; + { + PostErrorMessage(Format, Arguments); + } + InErrMsg = FALSE; + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + } +} + +/** + * Show the error message. Note that the Format string can be the only + * argument, in which case it is essentially the error message itself. + * + * @param Format + * C Format string or a simple message. + * @param ... + * Zero or more variable arguments. The number of arguments must correspond + * to the placeholders in the format string. + */ +void ErrMsg(TranslatedString Format, + ...) /* zero or more arguments */ +{ + REQUIRE(!Format.isNull()); + + va_list Arguments; + va_start(Arguments, Format); +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#else + PostErrorMessage(Format, Arguments); +#endif + va_end(Arguments); +} + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if !defined ENGINE +#endif +#if !defined ENGINE +#if defined MOTIF +#endif +#if defined MSWIN +#endif +#endif +#if !defined ENGINE +#if defined MOTIF +#endif +#if defined MSWIN +#endif +#endif +#if !defined ENGINE +#if defined MOTIF +#endif /* MOTIF */ +#if defined MSWIN +#endif +#if defined MOTIF +#endif /* MOTIF */ +#endif +#if !defined ENGINE +#endif +#endif /* TECPLOTKERNEL */ + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/q_unicode.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/q_unicode.cpp new file mode 100644 index 0000000000..4d4db61e1d --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/q_unicode.cpp @@ -0,0 +1,447 @@ +/* + * 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 Q_UNICODEMODULE + +#include "GLOBAL.h" +#include "TASSERT.h" + +#if !defined TECPLOTKERNEL +#include "TranslatedString.h" +#endif + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#include "ALLOC.h" + +#include "Q_UNICODE.h" + +using namespace std; + +namespace tecplot +{ +namespace strutil +{ + +typedef std::map EnvStringPoolMap_t; +static EnvStringPoolMap_t mapEnvStringPool; + + +#if defined MSWIN + + +string WStringToString(wstring str) +{ + REQUIRE("str is any wide string"); + string Result = WideCharToUtf8(str.c_str()); + + ENSURE("Result is any string"); + return Result; +} + +wstring StringToWString(string str) +{ + REQUIRE("str is any string"); + + wstring Result = Utf8ToWideChar(str.c_str()); + + ENSURE("Result is any string"); + return Result; +} +#endif + +/************************************************ + * Utf8Api + ************************************************/ +#define VALID_CODE_PAGE(cp) \ + ( (cp) == 932 || (cp) == CP_UTF8 || (cp) == CP_ACP || (cp) == CP_OEMCP || (cp) == CP_THREAD_ACP ) + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if defined MSWIN && !defined ENGINE +#endif +#if defined MSWIN +#endif +#endif + + +#if defined MSWIN + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ + +std::string WideCharToMultiByte(const wchar_t* WideString, + unsigned int CodePage) +{ + REQUIRE(VALID_REF(WideString)); + REQUIRE(VALID_CODE_PAGE(CodePage)); + + string strResult; + wstring wString(WideString); + + + if (wString.length() > 0) + { + size_t nLen = + (size_t) ::WideCharToMultiByte(CodePage, + 0, + wString.c_str(), + -1, + NULL, + 0, + NULL, + NULL); + if (nLen > 0) + { + char *pBuffer = ALLOC_ARRAY(nLen, char, "pBuffer"); + + VERIFY(::WideCharToMultiByte(CodePage, + 0, + WideString, + (int)(wString.length() + 1), + pBuffer, + (int)nLen, + NULL, + NULL) != 0); + + strResult = pBuffer; + FREE_ARRAY(pBuffer, "pBuffer"); + + } + else + { + // this should never be an error + CHECK(FALSE); + } + } + else + { + // output 'str' remains empty + } + + ENSURE("strResult is a valid STL string"); + return strResult; + + +} + +wstring MultiByteToWideChar(const char *UTF8String, + unsigned int CodePage) +{ + REQUIRE(VALID_REF(UTF8String)); + REQUIRE(VALID_CODE_PAGE(CodePage)); + + wstring strResult; + string UTF8str(UTF8String); + + size_t wLen; + + if (UTF8str.length() > 0) + { + wLen = + (size_t) ::MultiByteToWideChar(CodePage, + 0, + UTF8str.c_str(), + -1, + NULL, + 0); + if (wLen > 0) + { + wchar_t *wBuffer = ALLOC_ARRAY(wLen + 1, wchar_t, "wBuffer"); + VERIFY(::MultiByteToWideChar(CodePage, + 0, + UTF8str.c_str(), + (int)(UTF8str.length() + 1), + wBuffer, + (int)wLen) != 0); + + strResult = wBuffer; + FREE_ARRAY(wBuffer, "wBuffer"); + + } + else + { + CHECK(FALSE); // We should never get an error here + } + } + else + { + // strResult is left empty + } + + ENSURE("strResult is a valid CString"); + + wstring strRet(strResult); + return strRet; + +} +#endif + + + +#if defined MSWIN +std::string WideCharToUtf8(const wchar_t *str) +{ + REQUIRE(VALID_REF(str)); /* really cannot be NULL - 2007-10-22 CAM/DTO */ + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + UINT CodePage = CP_ACP; + + string Result = ""; + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + Result = WideCharToMultiByte(str, CodePage); + + ENSURE("Result is any string"); + return Result; +} + +wstring Utf8ToWideChar(const char *str) +{ + REQUIRE(VALID_REF(str)); /* really cannot be NULL - 2007-10-22 CAM/DTO */ + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + UINT CodePage = CP_ACP; + wstring Result; + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + Result = MultiByteToWideChar(str, CodePage); + + ENSURE("Result is any string"); + return Result; +} +#endif + + +Boolean_t IsValidUtf8LeadByte(Byte_t uch) +{ + REQUIRE("uch is any byte"); + Boolean_t Result = + uch <= 0x7F || + (uch >= 0xC0 && uch <= 0xDF) || + (uch >= 0xE0 && uch <= 0xEF) || + (uch >= 0xF0 && uch <= 0xF4); + + ENSURE(VALID_BOOLEAN(Result)); + return Result; +} + +Boolean_t IsValidUtf8ContinuingByte(Byte_t uch) +{ + REQUIRE("uch is any char"); + + Boolean_t Result = + (uch >= 0x80 && uch <= 0xBF); + + ENSURE(VALID_BOOLEAN(Result)); + return Result; +} + +Boolean_t IsValidUtf8Byte(Byte_t uch) +{ + REQUIRE("uch is any char"); + Boolean_t Result = + IsValidUtf8LeadByte(uch) || + IsValidUtf8ContinuingByte(uch); + + REQUIRE(VALID_BOOLEAN(Result)); + return Result; +} + + +Boolean_t ShouldConvertWideStringToUtf8String(const wchar_t *str) +{ + Boolean_t Result = FALSE; + +#if defined MSWIN && defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* MSWIN and TECPLOTKERNEL */ + + ENSURE(VALID_BOOLEAN(Result)); + return Result; + +} + +Boolean_t IsValidUtf8String(const char *str) +{ + Boolean_t IsValid = TRUE; + REQUIRE(VALID_REF(str)); + +#if defined MSWIN + size_t len = strlen(str); + Boolean_t InUtf8Sequence = FALSE; + int Utf8SequenceCount = 0; + int MaxUtf8SequenceCount = 0; + + /* we want to process the final \0, so go to <= len */ + + for (size_t ii = 0; IsValid && ii <= len; ii++) + { + Byte_t uch = (Byte_t)str[ii]; + + if (uch <= 0x7F) + { + /* This must be the end of a sequence, + so the sequence count must match + the max sequence count */ + + InUtf8Sequence = FALSE; + IsValid = (Utf8SequenceCount == MaxUtf8SequenceCount); + Utf8SequenceCount = 0; + MaxUtf8SequenceCount = 0; + } + else if (uch >= 0x80 && uch <= 0xBF) + { + /* Continuing byte in a multi byte sequence */ + if (InUtf8Sequence) + { + Utf8SequenceCount++; + } + else + { + IsValid = FALSE; + } + + } + else if (uch >= 0xC0 && uch <= 0xDF) + { + /* Lead byte of 000080-0007FF */ + IsValid = (Utf8SequenceCount == MaxUtf8SequenceCount); + InUtf8Sequence = TRUE; + Utf8SequenceCount = 0; + MaxUtf8SequenceCount = 1; + } + else if (uch >= 0xE0 && uch <= 0xEF) + { + /* Lead byte of 000800-00FFFF */ + IsValid = (Utf8SequenceCount == MaxUtf8SequenceCount); + InUtf8Sequence = TRUE; + Utf8SequenceCount = 0; + MaxUtf8SequenceCount = 2; + } + else if (uch >= 0xF0 && uch <= 0xF4) + { + /* Lead byte of 010000-10FFFF */ + IsValid = (Utf8SequenceCount == MaxUtf8SequenceCount); + Utf8SequenceCount = 0; + InUtf8Sequence = TRUE; + MaxUtf8SequenceCount = 3; + } + + else + { + /* Invalid Utf 8 */ + IsValid = FALSE; + } + } +#endif + + ENSURE(VALID_BOOLEAN(IsValid)); + return IsValid; +} + + +/** + */ +Boolean_t IsNullOrZeroLengthString(const char *str) +{ + REQUIRE(VALID_REF_OR_NULL(str)); + + Boolean_t Result = (str == NULL || strlen(str) == 0); + + ENSURE(VALID_BOOLEAN(Result)); + return Result; +} + +/** + */ +Boolean_t IsNullOrZeroLengthString(TranslatedString TS) +{ + REQUIRE(TS.isValid()); + return TS.isNullOrZeroLength(); +} + + +} +} + +#if defined MSWIN && TECPLOTKERNEL && (!defined NO_ASSERTS || defined CHECKED_BUILD) +/* Keeping Trace out of the release builds + will verify for us that it has been optimized away. + + See the definition of TRACE in MASTER.h for + more information... */ +void MSWinTrace(const char *Format, ...) +{ + REQUIRE(VALID_REF(Format)); + + const int BufferSize = 512; /* Only print the first 512 characers */ + va_list Arguments; + + /* Don't use ALLOC_ARRAY here */ + char *buffer = new char[BufferSize]; + memset(buffer, 0, BufferSize); + + va_start(Arguments, Format); + _vsnprintf(buffer, BufferSize - 1, Format, Arguments); + va_end(Arguments); + + ::OutputDebugStringA(buffer); + + delete [] buffer; +} + + + +#endif diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/set.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/set.cpp new file mode 100644 index 0000000000..2f6252a4c9 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/set.cpp @@ -0,0 +1,696 @@ +/* + * 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 + + +/* +***************************************************************** +***************************************************************** +******* ******** +****** Copyright (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +***************************************************************** +***************************************************************** +*/ + + + +#define SETMODULE +#include "GLOBAL.h" +#include "TASSERT.h" +#include "Q_UNICODE.h" +#include "ALLOC.h" +#include "SET.h" + + +/* * SET FUNCTIONS * */ + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if InitNumZones > InitNumVars +#else +#endif +#if ZoneExpansionFactor > VarExpansionFactor +#else +#endif +#else +#define SetInitSize (PadOut(1,SetBitSize)) +#define SetExpansionFactor 2 +#endif + +using namespace tecplot::strutil; + +/* + */ +Set_pa AllocSet(Boolean_t show_error_msg) +{ + Set_pa Set = ALLOC_ITEM(struct _Set_a, "Set header"); + if (Set) + { + Set->size = SetInitSize; + Set->data = ALLOC_ARRAY(SetInitSize / SetBitSize, SetData_t, "Set data"); + if (Set->data == NULL) + DeallocSet(&Set); + else + ClearSet(Set); + } + if ((Set == NULL) && show_error_msg) + { +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# else + fprintf(stderr, "Out of memory for sets"); +# endif + } + return Set; +} /* AllocSet() */ + + +/* + */ +void DeallocSet(Set_pa *Set) +{ + if (Set && *Set) + { + if ((*Set)->data) + FREE_ARRAY((*Set)->data, "Set data"); + FREE_ITEM(*Set, "Set header"); + *Set = NULL; + } +} /* DeallocSet() */ + + +/** + * This function adapts the DeallocSet function to work with the + * ArrayList's deallocation callback. + */ +Boolean_t SetItemDestructor(void *ItemRef, + ArbParam_t ClientData) +{ + Set_pa *SetRef = (Set_pa *)ItemRef; + + REQUIRE(VALID_REF(SetRef)); + REQUIRE(VALID_REF(*SetRef) || *SetRef == NULL); + + if (*SetRef != NULL) + DeallocSet(SetRef); + + ENSURE(*SetRef == NULL); + return TRUE; +} + + +/* + */ +Boolean_t ExpandSet(Set_pa Set, + SetIndex_t max_val, + Boolean_t show_error_msg) +{ + SetData_t *data; + long new_size; + + REQUIRE(max_val >= 0); + + if (!Set) + { + if (show_error_msg) + { +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# else + fprintf(stderr, "Null Set expand"); +# endif + } + return FALSE; + } + + if (max_val <= Set->size) + return TRUE; + + new_size = Set->size; + while (new_size < max_val) + new_size *= SetExpansionFactor; + + new_size = PadOut(new_size, SetBitSize); + + data = ALLOC_ARRAY(new_size / SetBitSize, SetData_t, "new Set data"); + + if (!data) + { + if (show_error_msg) + { +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# else + fprintf(stderr, "Out of memory for sets"); +# endif + } + return FALSE; + } + size_t old_set_size_in_bytes = sizeof(data[0]) * (Set->size / SetBitSize); + memcpy(data, Set->data, old_set_size_in_bytes); + + size_t new_set_size_in_bytes = sizeof(data[0]) * (new_size / SetBitSize); + size_t numBytesToReset = new_set_size_in_bytes - old_set_size_in_bytes; + memset(((char*)data) + old_set_size_in_bytes, 0, numBytesToReset); + + FREE_ARRAY(Set->data, "old Set data"); + Set->data = data; + Set->size = new_size; + return TRUE; +} /* ExpandSet() */ + + +/* + */ +Boolean_t CopySet(Set_pa dst, + Set_pa src, + Boolean_t show_error_msg) +{ + if (dst && dst->data && + src && src->data && + ExpandSet(dst, src->size, show_error_msg)) + { + SetIndex_t src_size_in_words = src->size / SetBitSize; + size_t numBytesToCopy = sizeof(dst->data[0]) * src_size_in_words; + memcpy(dst->data, src->data, numBytesToCopy); + + SetIndex_t dst_size_in_words = dst->size / SetBitSize; + CHECK(dst_size_in_words>=src_size_in_words); // ...guaranteed by above ExpandSet() call + size_t numBytesToReset = sizeof(dst->data[0]) * (dst_size_in_words - src_size_in_words); + memset((char*)(dst->data + src_size_in_words), 0, numBytesToReset); + + return TRUE; + } + else + return FALSE; +} /* CopySet() */ + + +/* + */ +Boolean_t AppendSet(Set_pa dst, + Set_pa src, + Boolean_t show_error_msg) +{ + if (dst && dst->data && + src && src->data) + { + SetIndex_t member; + ForAllMembersInSet(member, src) + { + if (!AddToSet(dst, member, TRUE)) + return FALSE; + } + return TRUE; + } + else + return FALSE; +} /* AppendSet() */ + + +/* + */ +void ClearSet(Set_pa Set) +{ + if (Set && Set->data) + memset(Set->data, 0, Set->size / SetBitSize * sizeof(Set->data[0])); +} /* ClearSet() */ + + +#if defined USE_FUNCTIONS_FOR_SETS +/* + */ +Boolean_t AddToSet(Set_pa Set, + SetIndex_t member, + Boolean_t show_error_msg) +{ + REQUIRE(member >= 0); + if (Set && + Set->data && + ((member + 1 <= Set->size) || ExpandSet(Set, member + 1, show_error_msg))) + { + SetIndex_t word = member / SetBitSize; + SetData_t bit = (SetData_t)1 << (member % SetBitSize); + Set->data[word] |= bit; + return TRUE; + } + else + return FALSE; +} /* AddToSet() */ +#endif + + +/* + */ +void RemoveFromSet(Set_pa Set, + SetIndex_t member) +{ + REQUIRE(member >= 0); + if (Set && (member < Set->size) && Set->data) + { + SetIndex_t word = member / SetBitSize; + SetData_t bit = (SetData_t)1 << (member % SetBitSize); + Set->data[word] &= (((SetData_t) - 1) ^ bit); + } +} /* RemoveFromSet() */ + + +/** + * Similar to RemoveFromSet except it shifts the Set. + */ +void DeleteSetMember(Set_pa Set, + SetIndex_t Member) +{ + SetIndex_t LastMember; + + REQUIRE(VALID_REF(Set)); + REQUIRE(Member >= 0); + + LastMember = GetPrevMember(Set, BAD_SET_VALUE); + if (Member <= LastMember) + { + ShiftSet(Set, Member + 1, LastMember, -1); + RemoveFromSet(Set, LastMember); + } +} + + +/** + * Similar to AddToSet except that if the new member is within the currently + * defined set the members are shifted accordingly. + */ +Boolean_t InsertSetMember(Set_pa Set, + SetIndex_t Member, + Boolean_t ShowErrMsg) +{ + Boolean_t IsOk = TRUE; + SetIndex_t OrigLastMember; + + REQUIRE(VALID_REF(Set)); + + /* first, determine if we need to shift the set */ + OrigLastMember = GetPrevMember(Set, BAD_SET_VALUE); + if (Member <= OrigLastMember) + { + IsOk = ExpandSet(Set, (OrigLastMember + 1) + 1, ShowErrMsg); + ShiftSet(Set, Member, OrigLastMember, 1); + } + + if (IsOk) + IsOk = AddToSet(Set, Member, ShowErrMsg); + + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + +#if defined USE_FUNCTIONS_FOR_SETS +/* + */ +Boolean_t InSet(Set_pa Set, + SetIndex_t member) +{ + /* + * Sometimes InSet is called with negative numbers. This is not correct, but + * its what we have to work with. Maybe some day, we can make this assertion. + REQUIRE(member>=0); + */ + if (Set && (0 <= member && member < Set->size)) + { + SetIndex_t word = member / SetBitSize; + SetData_t bit = (SetData_t)1 << (member % SetBitSize); + return (Set->data[word]&bit) != 0; + } + else + return FALSE; +} /* InSet() */ +#endif + + +/* + */ +Boolean_t IsEmpty(Set_pa Set) +{ + if (Set && Set->data) + { + SetIndex_t set_size_in_words = Set->size / SetBitSize; + SetIndex_t word; + for (word = 0; word < set_size_in_words; word++) + if (Set->data[word] != 0) + return FALSE; + } + return TRUE; +} /* IsEmpty() */ + + +/* + */ +Boolean_t HasVoids(Set_pa Set) +{ + Boolean_t Result = FALSE; + SetIndex_t ContiguousMember = 0; + SetIndex_t Member = 0; + + REQUIRE(VALID_REF(Set)); + + /* look for voids in the set */ + ForAllMembersInSet(Member, Set) + { + if (Member == ContiguousMember) + { + ContiguousMember++; + } + else + { + Result = TRUE; + break; + } + } + + ENSURE(VALID_BOOLEAN(Result)); + return Result; +} + + +/* + */ +SetIndex_t MemberCount(Set_pa Set) +{ + SetIndex_t count = 0; + if (Set && Set->data) + { + SetIndex_t set_size_in_words = Set->size / SetBitSize; + SetIndex_t word; + for (word = 0; word < set_size_in_words; word++) + { + SetData_t word_val = Set->data[word]; + while (word_val) + { + if (word_val&1) + count++; + word_val = word_val >> 1; + } + } + } + return count; +} /* MemberCount() */ + + +/* + */ +SetIndex_t GetNextMember(Set_pa Set, + SetIndex_t start_at) +{ + SetIndex_t next_member = BAD_SET_VALUE; + if (Set && Set->data) + { + SetIndex_t set_size_in_words = Set->size / SetBitSize; + SetIndex_t word; + SetData_t word_val = 0; + int bit; + if (start_at == BAD_SET_VALUE) + { + word = 0; + bit = 0; + if (word < set_size_in_words) + word_val = Set->data[0]; + } + else if (start_at + 1 < Set->size) + { + word = (start_at + 1) / SetBitSize; + bit = (start_at + 1) % SetBitSize; + if (word < set_size_in_words) + word_val = Set->data[word] >> bit; + } + else + { + return BAD_SET_VALUE; + } + while ((word < set_size_in_words) && (word_val == 0)) + { + word++; + bit = 0; + if (word < set_size_in_words) + word_val = Set->data[word]; + } + if (word < set_size_in_words) + { + while (!(word_val&1)) + { + word_val >>= 1; + bit++; + } + next_member = word * SetBitSize + bit; + } + } + return next_member; +} /* GetNextMember() */ + + +/* + */ +SetIndex_t GetPrevMember(Set_pa Set, + SetIndex_t start_at) +{ + SetIndex_t next_member = BAD_SET_VALUE; + if (Set && Set->data) + { + SetIndex_t set_size_in_words = Set->size / SetBitSize; + SetIndex_t word; + SetData_t word_val = 0; + int bit; + if (start_at == BAD_SET_VALUE) + { + word = set_size_in_words - 1; + bit = SetBitSize - 1; + if (word >= 0) + word_val = Set->data[word]; + } + else if (start_at > 0) + { + word = (start_at - 1) / SetBitSize; + bit = (start_at - 1) % SetBitSize; + if (word >= 0) + word_val = Set->data[word] << (SetBitSize - bit - 1); + } + else + { + return BAD_SET_VALUE; + } + while ((word >= 0) && (word_val == 0)) + { + word--; + bit = SetBitSize - 1; + if (word >= 0) + word_val = Set->data[word] << (SetBitSize - bit - 1); + } + if (word >= 0) + { + while (!(word_val&SetLastBit)) + { + word_val <<= 1; + bit--; + } + next_member = word * SetBitSize + bit; + } + } + return next_member; +} /* GetPrevMember() */ + + +/* + */ +Boolean_t EqualSets(Set_pa set1, + Set_pa set2) +{ + SetIndex_t set1_size_in_words, + set2_size_in_words, + min_set_size_in_words, + ii; + if (!set1 || !set2) + return FALSE; + + set1_size_in_words = set1->size / SetBitSize; + set2_size_in_words = set2->size / SetBitSize; + min_set_size_in_words = MIN(set1_size_in_words, set2_size_in_words); + + for (ii = 0; ii < min_set_size_in_words; ii++) + if (set1->data[ii] != set2->data[ii]) + return FALSE; + for (ii = min_set_size_in_words; ii < set1_size_in_words; ii++) + if (set1->data[ii] != 0) + return FALSE; + for (ii = min_set_size_in_words; ii < set2_size_in_words; ii++) + if (set2->data[ii] != 0) + return FALSE; + + return TRUE; + +} /* EqualSets() */ + + +Boolean_t IsSubSet(Set_pa childset, + Set_pa parentset) +{ + SetIndex_t s; + + ForAllMembersInSet(s, childset) + { + if (!InSet(parentset, s)) + return (FALSE); + } + + return (TRUE); + +} /* IsSubSet() */ + + + + + + +/* + * functions added 11/7 by byron. These are roughed in for now and could + * stand to be optimized later..... + */ + +/* + * Return the number of members in a set that preceed a given member. + */ + +SetIndex_t MemberOffset(Set_pa Set, + SetIndex_t Member) +{ + SetIndex_t I; + SetIndex_t Offset = -1; + if (InSet(Set, Member)) + { + for (I = 0; I <= Member; I++) + { + if (InSet(Set, I)) + Offset++; + } + } + return (Offset); +} + +/* + * Return the position in the set of the nth member of a set. + */ +SetIndex_t OffsetMember(Set_pa Set, + SetIndex_t Offset) +{ + SetIndex_t I; + SetIndex_t Member = BAD_SET_VALUE; + for (I = 0; I <= Offset; I++) + { + Member = GetNextMember(Set, Member); + if (Member == BAD_SET_VALUE) + break; + } + return (Member); +} + +Boolean_t CopySetMember(Set_pa DstSet, + SetIndex_t DstOffset, + Set_pa SrcSet, + SetIndex_t SrcOffset) +{ + if (InSet(SrcSet, SrcOffset)) + return (AddToSet(DstSet, DstOffset, TRUE)); + else + RemoveFromSet(DstSet, DstOffset); + return (TRUE); +} + + + +/* + * Initial: + * v---ShiftPos1 v--ShiftPos2 + * +-------------------------------------+ + * | | | | | | | |x| | | | | | | |x| | | | + * +-------------------------------------+ + * + * Shift +2 + * v---ShiftPos1 v--ShiftPos2 + * +-------------------------------------+ + * | | | | | | | | | |x| | | | | | | |x| | + * +-------------------------------------+ + * + * + * Shift all bits between ShiftPos1 and ShiftPos2 + * by ShiftAmount. The bits that the shift + * replaces fill in the hole left by the shift + * + * + */ +void ShiftSet(Set_pa Set, + SetIndex_t ShiftPos1, + SetIndex_t ShiftPos2, + SetIndex_t ShiftAmount) +{ + Set_pa NewSet; + SetIndex_t DPos; + SetIndex_t SPos; + + if ((Set == NULL) || (IsEmpty(Set))) + return; + + NewSet = AllocSet(TRUE); + + if (NewSet == NULL) + return; + + if (!CopySet(NewSet, Set, TRUE)) + return; + + if (ShiftAmount < 0) + { + DPos = ShiftPos2; + SPos = ShiftPos1 - 1; + while (DPos > ShiftPos2 + ShiftAmount) + CopySetMember(NewSet, DPos--, Set, SPos--); + SPos = ShiftPos2; + while (SPos >= ShiftPos1) + CopySetMember(NewSet, DPos--, Set, SPos--); + } + else if (ShiftAmount > 0) + { + DPos = ShiftPos1; + SPos = ShiftPos2 + 1; + while (DPos < ShiftPos1 + ShiftAmount) + CopySetMember(NewSet, DPos++, Set, SPos++); + SPos = ShiftPos1; + while (SPos <= ShiftPos2) + CopySetMember(NewSet, DPos++, Set, SPos++); + } + CopySet(Set, NewSet, TRUE); + DeallocSet(&NewSet); +} + + + diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/stdafx.h b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/stdafx.h new file mode 100644 index 0000000000..066d102e7c --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/stdafx.h @@ -0,0 +1,130 @@ +/* + * 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/ + * + */ +#if !defined STDAFX_H_ +# define STDAFX_H_ + +/* +****************************************************************** +****************************************************************** +******* ******** +****** (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +****************************************************************** +****************************************************************** +*/ +/* + * stdafx.h : include file for standard system include files, + * or project specific include files that are used frequently, but + * are changed infrequently + * Used for Windows only + */ +#if defined _WIN32 + +/* + * Set NDEBUG before including "custafx.h" since that file may + * use NDEBUG. (In fact, for SmartHeap builds this is the case.) + * CAM 2007-04-11 + * + * Previous comment: "Note that _DEBUG is defined by the Windows compiler + * if any of the multi-threaded DLL runtime libraries are used." + */ +#if !defined _DEBUG +#if !defined NDEBUG +#define NDEBUG +#endif +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ + +#if !defined MSWIN +#define MSWIN +#endif + +#define ENGLISH_ONLY // remove to support non-english dll's + +#if !defined WINVER +#define WINVER 0x0500 +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if defined CHECKED_BUILD || defined _DEBUG && !defined COREAPI +#if defined _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES +#endif +#else +#endif +#endif /* TECPLOTKERNEL */ + +/* Windows builds are UNICODE */ +#pragma warning(disable : 4786) /* truncated identifiers in debug symbol table. */ +#pragma warning(disable : 4996) /* deprecated functions */ + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if !defined UNICODE +#endif +#if !defined _AFXDLL +#endif +#if defined _M_IX86 +#else +#endif +#if defined _WIN64 +#if !defined _M_IA64 && !defined _M_AMD64 +#endif +#endif +#if !defined MSWIN +#endif +#if !defined THREED +#endif +#ifndef _AFX_NO_AFXCMN_SUPPORT +#endif /* _AFX_NO_AFXCMN_SUPPORT */ +#ifndef _AFX +#endif +#else /* !TECPLOTKERNEL */ +#define AfxIsValidAddress(ptr,bb) ((ptr)!=NULL) +#endif + +/* 64-bit adjustments */ +#if defined _M_IA64 || defined _M_AMD64 +#define WININT INT_PTR +#define WINUINT UINT_PTR +#else +#define WININT int +#define WINUINT UINT +#endif + +#define WINCALLBACK CALLBACK + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if defined (NDEBUG) +#else +#endif +#endif /* TECPLOTKERNEL */ +#endif /* _WIN32 */ + + +#endif /* STDAFX_H_ */ diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/strlist.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/strlist.cpp new file mode 100644 index 0000000000..ab34a5274c --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/strlist.cpp @@ -0,0 +1,1065 @@ +/* + * 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 STRLISTMODULE +#include "GLOBAL.h" +#include "TASSERT.h" +#include "Q_UNICODE.h" +#include "STRUTIL.h" +#include "ALLOC.h" +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif +#include "ARRLIST.h" +#include "STRLIST.h" + +/* END HEADER */ + +using namespace tecplot::strutil; + +/* + * This set of functions provide a wrapper around the array list utilities + * thereby making it aware of item allocation and deallocation. All strings + * given to the string list and returned to the client are copies. Therefore + * it is the client's responsibility to deallocate string results when no + * longer needed. + */ + + +/* + * Destructor for cleaning up string allocations. + * + * param ItemRef + * Reference to the string item to destroy. + * param ClientData + * Any client data needed for destroying the string. + * + * return + * TRUE is a requirement + */ +static Boolean_t StringListItemDestructor(void *ItemRef, + ArbParam_t ClientData) +{ + char **StringRef = (char **)ItemRef; + + REQUIRE(VALID_REF(StringRef)); + REQUIRE(VALID_REF(*StringRef) || *StringRef == NULL); + + if (*StringRef != NULL) + { + FREE_ARRAY(*StringRef, "string"); + *StringRef = NULL; + } + + ENSURE(*StringRef == NULL); + return TRUE; +} + +/* + * String item duplicator. + * + * param TargetItemRef + * Reference to the string list item to receive the duplicate. + * param SourceItemRef + * Reference to the string list item to duplicate. + * param ClientData + * Any client data required for duplication. + * + * return + * TRUE if the duplication was a success + * FALSE otherwise. If the duplication failed it + * is the client's responsibility to cleanup any + * partial duplication + */ +static Boolean_t StringListItemDuplicator(void *TargetItemRef, + void *SourceItemRef, + ArbParam_t ClientData) +{ + Boolean_t IsOk = TRUE; + char **TargetStringRef = (char **)TargetItemRef; + char **SourceStringRef = (char **)SourceItemRef; + + REQUIRE(VALID_REF(TargetStringRef)); + REQUIRE(VALID_REF(SourceStringRef)); + REQUIRE(VALID_REF(*SourceStringRef) || *SourceStringRef == NULL); + + if (*SourceStringRef != NULL) + IsOk = ((*TargetStringRef = DupString(dontTranslate(*SourceStringRef))) != NULL); + else + *TargetStringRef = NULL; + + ENSURE(VALID_REF(*TargetStringRef) || *TargetStringRef == NULL); + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; +} + + +/* + * Determine if the string list handle and its members are sane. + */ +Boolean_t StringListValid(StringList_pa stringList) +{ + Boolean_t isValid = ArrayListIsValid((ArrayList_pa)stringList); + + if (isValid) + { + LgIndex_t stringCount = ArrayListGetCount((ArrayList_pa)stringList); + +#if defined PERFORM_EXPENSIVE_STRLIST_TESTS + { + for (LgIndex_t index = 0; index < stringCount; index++) + { + char *string = ArrayListGetCharPtr((ArrayList_pa)stringList, index); + if (string != NULL && !VALID_REF(string)) + { + isValid = FALSE; + break; + } + } +#else + { + /* Check first and last only */ + if (stringCount > 0) + { + char *string = ArrayListGetCharPtr((ArrayList_pa)stringList, 0); + if (string != NULL && !VALID_REF(string)) + { + isValid = FALSE; + } + } + if (isValid && stringCount > 1) + { + char *string = ArrayListGetCharPtr((ArrayList_pa)stringList, stringCount - 1); + if (string != NULL && !VALID_REF(string)) + { + isValid = FALSE; + } + } + } +#endif /* PERFORM_SKIP_EXPENSIVE_STRLIST_TESTS */ + } + + ENSURE(VALID_BOOLEAN(isValid)); + return isValid; + } + + + /* + * Remove all members of the string list. + */ + void StringListClear(StringList_pa StringList) + { + REQUIRE(StringListValid(StringList)); + + ArrayListDeleteAllItems((ArrayList_pa)StringList, StringListItemDestructor, 0); + + ENSURE(StringListValid(StringList) && StringListCount(StringList) == 0); + } + + + /* + * Remove 'Count' strings from the list beginning at the specified offset. + * The members following the items removed are shifted down accordingly to + * fill the vacated space. + */ + void StringListRemoveStrings(StringList_pa StringList, + LgIndex_t StringOffset, + LgIndex_t Count) + { + REQUIRE(StringListValid(StringList)); + REQUIRE(0 <= StringOffset && StringOffset <= StringListCount(StringList) - 1); + REQUIRE(1 <= Count && StringOffset + Count <= StringListCount(StringList)); + + ArrayListDeleteItems((ArrayList_pa)StringList, StringOffset, Count, + StringListItemDestructor, 0); + + ENSURE(StringListValid(StringList)); + } + + + /* + * Remove the string from the list at the specified offset. The members + * following the item removed are shifted down accordingly to fill the + * vacated space. + */ + void StringListRemoveString(StringList_pa StringList, + LgIndex_t StringOffset) + { + REQUIRE(StringListValid(StringList)); + REQUIRE(0 <= StringOffset && StringOffset <= StringListCount(StringList) - 1); + + ArrayListDeleteItems((ArrayList_pa)StringList, StringOffset, 1, + StringListItemDestructor, 0); + + ENSURE(StringListValid(StringList)); + } + + + /* + * Deallocate the string list members and handle and set the handle to NULL. + */ + void LIBCALL StringListDealloc(StringList_pa *StringList) + { + REQUIRE(VALID_REF(StringList)); + REQUIRE(*StringList == NULL || StringListValid(*StringList)); + + if (*StringList != NULL) + ArrayListDealloc((ArrayList_pa *)StringList, StringListItemDestructor, 0); + + ENSURE(*StringList == NULL); + } + + + /* + * Allocate a string list handle. A handle of NULL is + * returned if sufficient memory is not available. + */ + StringList_pa StringListAlloc(void) + { + StringList_pa Result; + + Result = (StringList_pa)ArrayListAlloc(0, ArrayListType_CharPtr, NULL, 0); + + ENSURE(Result == NULL || StringListValid(Result)); + return Result; + } + + + /* + * Append a copy of the string to the string list. The string list will be + * expanded to accommodate the additional item. A return value of TRUE + * indicates the operation was successful otherwise FALSE is returned + * indicating that sufficient memory was not available for the additional + * item. + */ + Boolean_t StringListAppendString(StringList_pa StringList, + const char *String) + { + Boolean_t IsOk; + + REQUIRE(StringListValid(StringList)); + REQUIRE(String == NULL || VALID_REF(String)); + + IsOk = StringListSetString(StringList, StringListCount(StringList), String); + + ENSURE(StringListValid(StringList)); + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; + } + + + /* + * Return the number of strings currently in the string list. + */ + LgIndex_t LIBCALL StringListCount(StringList_pa StringList) + { + LgIndex_t Result; + + REQUIRE(StringListValid(StringList)); + + Result = ArrayListGetCount((ArrayList_pa)StringList); + + ENSURE(Result >= 0); + return Result; + } + + + /* + * Return a copy of the string at the specified offset in the string list. + */ + char * LIBCALL StringListGetString(StringList_pa StringList, + LgIndex_t StringOffset) + { + char *Result; + const char *StringRef; + + REQUIRE(StringListValid(StringList)); + REQUIRE(0 <= StringOffset && StringOffset <= StringListCount(StringList) - 1); + + StringRef = StringListGetStringRef(StringList, StringOffset); + if (StringRef == NULL) + Result = NULL; + else + Result = DupString(dontTranslate(StringRef)); + + ENSURE(Result == NULL || VALID_REF(Result)); + return Result; + } + + +#if !defined USE_MACROS_FOR_FUNCTIONS + /* + * Returns actual string at the specified offset in the string list. Do not + * attempt to free this string. Changing this string should be done with + * utmost caution. + */ + const char *StringListGetStringRef_FUNC(StringList_pa StringList, + LgIndex_t StringOffset) + { + const char *Result; + + REQUIRE(StringListValid(StringList)); + REQUIRE(0 <= StringOffset && StringOffset <= StringListCount(StringList) - 1); + + Result = StringListGetStringRef_MACRO(StringList, StringOffset); + + ENSURE(Result == NULL || VALID_REF(Result)); + return Result; + } +#endif + + + /* + * Place a copy of the specified string at the specified offset. If the offset + * is beyond the end of the string list it is sized accordingly and the + * intervening string references between the last item of the original + * state and the last item of the new state are assigned NULL. If a string + * already exists at the specified location its resources are released. + * A return value of TRUE indicates the operation was successful otherwise + * FALSE is returned indicating that sufficient memory was not available + * for the additional item at the specified offset. + */ + Boolean_t StringListSetString(StringList_pa StringList, + LgIndex_t StringOffset, + const char *String) + { + Boolean_t IsOk; + ArrayListItem_u ItemCopy; + + REQUIRE(StringListValid(StringList)); + REQUIRE(StringOffset >= 0); + REQUIRE(String == NULL || VALID_REF(String)); + + if (String != NULL) + { + ItemCopy.CharPtr = DupString(dontTranslate(String)); + IsOk = (ItemCopy.CharPtr != NULL); + } + else + { + ItemCopy.CharPtr = NULL; + IsOk = TRUE; + } + + if (IsOk) + IsOk = ArrayListSetItem((ArrayList_pa)StringList, StringOffset, ItemCopy, + StringListItemDestructor, 0); + + ENSURE(StringListValid(StringList)); + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; + } + + + /* + * Insert a copy of the string into the string list at the specified offset. + * The string list will be expanded to accommodate the additional item. + * A return value of TRUE indicates the operation was successful otherwise + * FALSE is returned indicating that sufficient memory was not available + * for the additional item. + */ + Boolean_t StringListInsertString(StringList_pa StringList, + LgIndex_t StringOffset, + const char *String) + { + Boolean_t IsOk; + ArrayListItem_u ItemCopy; + + REQUIRE(StringListValid(StringList)); + REQUIRE(StringOffset >= 0); + REQUIRE(String == NULL || VALID_REF(String)); + + if (String != NULL) + { + ItemCopy.CharPtr = DupString(dontTranslate(String)); + IsOk = (ItemCopy.CharPtr != NULL); + } + else + { + ItemCopy.CharPtr = NULL; + IsOk = TRUE; + } + + if (IsOk) + IsOk = ArrayListInsertItem( + (ArrayList_pa)StringList, StringOffset, ItemCopy); + + ENSURE(StringListValid(StringList)); + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; + } + + + /* + * Return a handle to a duplicate of the specified string list and its contents. + * A handle of NULL is returned if sufficient memory is not available. + */ + StringList_pa StringListCopy(StringList_pa StringList) + { + StringList_pa Result; + + REQUIRE(StringListValid(StringList)); + + Result = (StringList_pa)ArrayListCopy((ArrayList_pa)StringList, + StringListItemDuplicator, 0); + + ENSURE(Result == NULL || + (StringListValid(Result) && + StringListCount(Result) == StringListCount(StringList))); + return Result; + } + + + + /* + * Append a copy of the contents of the source list to the target list. + * A return value of TRUE indicates the operation was successful otherwise + * FALSE is returned indicating that sufficient memory was not available + * for the request. + */ + Boolean_t StringListAppend(StringList_pa Target, + StringList_pa Source) + { + Boolean_t IsOk; + StringList_pa SourceCopy; + + REQUIRE(StringListValid(Target)); + REQUIRE(StringListValid(Source)); + + SourceCopy = StringListCopy(Source); + IsOk = (SourceCopy != NULL); + if (IsOk) + { + ArrayListAppend((ArrayList_pa)Target, (ArrayList_pa)SourceCopy); + /* deallocate the list but not the string items since Target now owns them */ + ArrayListDealloc((ArrayList_pa *)(void *)&SourceCopy, NULL, 0); + } + + ENSURE(StringListValid(Target)); + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; + } + + + + /* + * Return a new line, '\n', separated string representation of the string list. + * Caller is responsible for de-allocating the result. + */ + char *StringListToNLString(StringList_pa StringList) + { + char *Result; + int Count; + size_t Length = 0; + + REQUIRE(StringListValid(StringList)); + + /* determine the resulting new line, '\n', separated string length */ + Count = StringListCount(StringList); + if (Count >= 1) + { + int Index; + for (Index = 0, Length = strlen("\n") * (Count - 1); + Index < Count; + Index++) + { + char *String = ArrayListGetCharPtr((ArrayList_pa)StringList, Index); + if (String != NULL) + Length += strlen(String); + } + } + + /* create a new line, '\n', separated string */ + Result = ALLOC_ARRAY(Length + 1, char, "new line separated string"); + if (Result != NULL) + { + int Index; + for (Index = 0, strcpy(Result, ""); + Index < Count; + Index++) + { + char *String = ArrayListGetCharPtr( + (ArrayList_pa)StringList, Index); + + if (Index != 0) + strcat(Result, "\n"); + + if (String != NULL) + strcat(Result, String); + } + } + + ENSURE(Result == NULL || VALID_REF(Result)); + return Result; + } + + + /* + * Create a string list from the new line, '\n', separated string. The string + * is copied and therefore owned and managed by the caller. + */ + StringList_pa StringListFromNLString(const char *String) + { + StringList_pa Result; + LgIndex_t StartIndex; + LgIndex_t EndIndex; + + REQUIRE(VALID_REF(String)); + + /* create the string list and scan the entire string */ + Result = StringListAlloc(); + for (StartIndex = EndIndex = 0; Result != NULL; EndIndex++) + { + /* end of sub-string ? */ + if (String[EndIndex] == '\n' || String[EndIndex] == '\0') + { + /* extract the sub-string and append it to the string list */ + LgIndex_t Length = EndIndex - StartIndex; + char *SubString = ALLOC_ARRAY(Length + 1, char, "sub string"); + if (SubString != NULL) + { + CopySubString(SubString, String, StartIndex, Length); + StringListAppendString(Result, SubString); + + FREE_ARRAY(SubString, "sub string"); + + if (String[EndIndex] != '\0') + StartIndex = EndIndex + 1; + else + break; /* nothing left to scan */ + } + else + { + /* memory allocation failure: bail out */ + StringListDealloc(&Result); + Result = NULL; + break; + } + } + } + + ENSURE(Result == NULL || StringListValid(Result)); + return Result; + } + + + /* + * Return a 'C' string array representation of the string list. + * Caller is responsible for de-allocating the result. + */ + char **StringListToArray(StringList_pa StringList) + { + char **Result; + + REQUIRE(StringListValid(StringList)); + + Result = (char **)ArrayListToArray((ArrayList_pa)StringList, + StringListItemDuplicator, 0); + + ENSURE(Result == NULL || VALID_REF(Result)); + return Result; + } + + + + /* + * Create a string list from the 'C' string array. The string array + * is copied and therefore owned and managed by the caller. + */ + StringList_pa StringListFromArray(const char **StringArray, + LgIndex_t Count) + { + StringList_pa Result; + + REQUIRE((Count == 0 && StringArray == NULL) || + (Count >= 1 && VALID_REF(StringArray))); + + Result = (StringList_pa)ArrayListFromArray((void *)StringArray, + Count, ArrayListType_CharPtr, + StringListItemDuplicator, 0); + + ENSURE(Result == NULL || StringListValid(Result)); + return Result; + } + + + +#define ISJOINCHAR(c) ((c == ';') || (c == '+')) + + static void SkipWhiteSpaceOrComma(const char **CPtr) + { + REQUIRE(VALID_REF(CPtr) && VALID_REF(*CPtr)); + while (ISWHITESPACE(**CPtr) || (**CPtr == ',')) + (*CPtr)++; + } + + /* + * Obtain the next sub-string. This can be of the form: + * + * [del]any-character-sequence[del] + * + * or + * + * limited-character-sequence + * + * where a limited-character-sequence cannot contain + * any of the following characters: +;, + * + */ + static Boolean_t GetNextSubString(const char **OriginalCPtr, + char **NextSubString) + { + Boolean_t IsOk = TRUE; + const char *CStart; + const char *CPtr; + char InsideDelimiter = '\0'; + + REQUIRE(VALID_REF(OriginalCPtr) && (VALID_REF(*OriginalCPtr))); + REQUIRE(VALID_REF(NextSubString)); + + *NextSubString = NULL; + + CPtr = *OriginalCPtr; + SkipWhiteSpaceOrComma(&CPtr); + + if (*CPtr == '"' || *CPtr == '\'') + { + InsideDelimiter = *CPtr; + CPtr++; + } + + CStart = CPtr; + + while (*CPtr && + ((InsideDelimiter && (*CPtr != InsideDelimiter)) || + (!InsideDelimiter && (*CPtr != ',') && + !ISJOINCHAR(*CPtr) && + !ISWHITESPACE(*CPtr)))) + { + if (InsideDelimiter && + (*CPtr == '\\') && + (*(CPtr + 1) == InsideDelimiter)) + CPtr += 2; + else + CPtr++; + } + + if (InsideDelimiter && (*CPtr != InsideDelimiter)) + IsOk = FALSE; + + + if (IsOk && CStart < CPtr) + { + size_t StrLen = (size_t)(CPtr - CStart); + *NextSubString = ALLOC_ARRAY(StrLen + 1, char, "GetNextSubString: NextSubString"); + if (*NextSubString) + { + char *NPtr = *NextSubString; + /* + * Don't just copy the string because escaped delimiters need to have + * the escape removed... + */ + while (CStart < CPtr) + { + if ((*CStart == '\\') && (*(CStart + 1) == InsideDelimiter)) + CStart++; + *NPtr++ = *CStart++; + } + *NPtr = '\0'; + } + else + IsOk = FALSE; + } + + if (IsOk) + { + if (InsideDelimiter) + CPtr++; + SkipWhiteSpaceOrComma(&CPtr); + *OriginalCPtr = CPtr; + } + + ENSURE(VALID_BOOLEAN(IsOk)); + return IsOk; + } + + + + + /* + * Return a string list representation of a compound string. + * + * The compound String parameter has the following form: + * + * [del][del] [GroupJoinCharacter] [del][del] [GroupJoinCharacter] ..... + * or + * ... + * + * where: + * [del] is an optional single quote or a double quote. [del] must be used + * if contains spaces, commas, or the plus symbol. + * + * GroupJoinCharacter can be either a "+" or a ";" + * + * The GroupJoinCharacter symbol is used to separate character sequences that + * are to be grouped together. If the GroupJoinCharacter symbol is omitted then + * a new group is started. + * + * Internally, the original string is converted to a list of strings where + * each string uses newlines to separate one sub-string from the next. + */ + StringList_pa StringListFromCompound(const char *String) + { + const char *CPtr; + StringList_pa Result; + Boolean_t IsOk = TRUE; + char *CurString = NULL; + + REQUIRE(VALID_REF(String)); + SkipWhiteSpaceOrComma(&String); + REQUIRE(!ISJOINCHAR(*String)); + + /* extract character sequences */ + Result = StringListAlloc(); + CPtr = String; + + while (IsOk && *CPtr != '\0') + { + char *NextSubString = NULL; + Boolean_t WantsToJoin = FALSE; + + if (ISJOINCHAR(*CPtr)) + { + WantsToJoin = TRUE; + CPtr++; + SkipWhiteSpaceOrComma(&CPtr); + } + + IsOk = GetNextSubString(&CPtr, + &NextSubString); + + if (IsOk) + { + /* + * Tack on the sub-string to the running string. + */ + if (WantsToJoin) + TackOnChar(&CurString, '\n'); + if (NextSubString != NULL && strlen(NextSubString) != 0) + IsOk = TackOnString(&CurString, NextSubString, FALSE, FALSE); + else if (CurString == NULL) + CurString = DupString(dontTranslate("")); + } + + if (NextSubString != NULL) + FREE_ARRAY(NextSubString, "StringListFromCompound: NextSubString"); + + /* + * If this is the end of processing or if the next character is + * not a join character then add the current string to the stringlist. + */ + + if (IsOk && !ISJOINCHAR(*CPtr)) + { + StringListAppendString(Result, CurString); + if (CurString != NULL) + FREE_ARRAY(CurString, "current string"); + CurString = NULL; + } + } + + if (CurString != NULL) + FREE_ARRAY(CurString, "current string"); + + if (!IsOk) + StringListDealloc(&Result); + + ENSURE(Result == NULL || StringListValid(Result)); + return Result; + } + + + /* + * Return a compound string representation of a string list. + * + * One common usage in Tecplot: + * The $!OpenLayout command in tecplot has the sub-option + * ALTDATALOADINSTRUCTIONS that has the form: + * '"instr-string1" [GroupJoinCharacter] "instr-string2" [+] ...' + */ + char *StringListToCompound(StringList_pa StringList, + char GroupJoinCharacter, + const char *CharsToEscape) + { + Boolean_t IsOk = TRUE; + LgIndex_t Index; + LgIndex_t Count; + char *Result = NULL; + + REQUIRE(StringListValid(StringList)); + REQUIRE(StringListCount(StringList) >= 1); + REQUIRE(ISJOINCHAR(GroupJoinCharacter)); + REQUIRE(VALID_REF(CharsToEscape)); + + for (Index = 0, Count = StringListCount(StringList), IsOk = TRUE; + Index < Count && IsOk; + Index++) + { + char *String = StringListGetString(StringList, Index); + + if (String != NULL && strlen(String) != 0) + { + char *CStart = NULL; + char *CEnd = NULL; + char *EscapedString = NULL; + const char *EscChar = NULL; + char *StrChar = NULL; + + /* First scan the string and escape any specified characters. */ + /* Note that the Escape sequence is a double backslash because */ + /* it the first escape escapes the escape for variable usage. */ + for (StrChar = String; *StrChar != '\0'; StrChar++) + { + for (EscChar = CharsToEscape; *EscChar != '\0'; EscChar++) + if (*StrChar == *EscChar) + { + IsOk = TackOnChar(&EscapedString, '\\'); + IsOk = TackOnChar(&EscapedString, '\\'); + break; + } + IsOk = TackOnChar(&EscapedString, *StrChar); + } + + CEnd = EscapedString; + while (IsOk && *CEnd != '\0') + { + int Len = 0; + char *TString; + + CStart = CEnd; + while (*CEnd != '\0' && *CEnd != '\n') + { + Len++; + if (*CEnd == '"') + Len++; + CEnd++; + } + + TString = ALLOC_ARRAY(Len + 4, char, "temp compound sub-string"); + if (TString != NULL) + { + char *TStr; + + /* prepend the new string with either */ + /* a space character or the plus symbol */ + if (CStart == EscapedString) + { + if (Index != 0) + IsOk = TackOnChar(&Result, ' '); + } + else + { + IsOk = TackOnChar(&Result, GroupJoinCharacter); + } + + /* stuff TString and append the new string */ + TStr = TString; + *TStr++ = '"'; + while (CStart != CEnd) + { + if (*CStart == '"') + *TStr++ = '\\'; + *TStr++ = *CStart++; + } + *TStr++ = '"'; + *TStr = '\0'; + + TackOnString(&Result, TString, FALSE, FALSE); + FREE_ARRAY(TString, "StringListToCompound"); + TString = NULL; + if (*CEnd) + CEnd++; + } + else + { + IsOk = FALSE; + } + } + + if (EscapedString != NULL) + FREE_ARRAY(EscapedString, "escaped string"); + } + else + { + /* a null pointer or length of zero indicates an empty sub-string */ + if (Index == 0) + TackOnString(&Result, "\"\"", FALSE, FALSE); + else + TackOnString(&Result, " \"\"", FALSE, FALSE); + } + + if (String != NULL) + FREE_ARRAY(String, "string list item"); + } + + if (!IsOk) + { + if (Result != NULL) + { + FREE_ARRAY(Result, "StringListToCompound"); + Result = NULL; + } + } + + ENSURE(Result == NULL || VALID_REF(Result)); + return Result; + } + + + /** + * Holds the comparator function pointer. + */ + static StringListStringComparator_pf ComparatorFunction = NULL; + + + /** + * Forwards the comparison test to the 'Comparator' supplied to the + * 'StringListSort' function. + * + * param Item1 + * Item to compare against Item2. + * param Item2 + * Item to compare against Item1. + * param ClientData + * Contextual information that was passed to the 'ArrayListQSort' function. + * + * return + * -1: if Item1 is less than Item2 + * 0: if Item1 is equal to Item2 + * 1: if Item1 is greater than Item2 + */ + static int STDCALL ComparatorProxy(ArrayListItem_u Item1, + ArrayListItem_u Item2, + ArbParam_t ClientData) + { + /* forward the request */ + return ComparatorFunction(Item1.CharPtr, Item2.CharPtr, ClientData); + } + + + /** + * Compares two strings from a list string. Note that either string may be + * NULL as StringLists allow for NULL elements. + * + * param String1 + * String to compare against String2. + * param String2 + * String to compare against String1. + * param ClientData + * Contextual information that was passed to the 'StringListSort' function. + * + * return + * - A value less than zero if String1 is less than String2. + * - A value of zero if String1 is equal to String2. + * - A value greater than zero if String1 is greater than String2. + */ + static int STDCALL DefaultStrcmpComparator(const char *String1, + const char *String2, + ArbParam_t ClientData) + { + int Result = 0; /* ...quite compiler */ + + REQUIRE(VALID_REF(String1) || String1 == NULL); + REQUIRE(VALID_REF(String2) || String2 == NULL); + + if (String1 != NULL && String2 != NULL) + { + Result = strcmp(String1, String2); + if (Result < 0) + Result = -1; + else if (Result > 0) + Result = 1; + } + else if (String1 == NULL && String2 == NULL) + Result = 0; + else if (String1 == NULL) + Result = -1; + else if (String2 == NULL) + Result = 1; + else + CHECK(FALSE); + + ENSURE((Result == -1) || (Result == 0) || (Result == 1)); + return Result; + } + + /** + * Sorts the string list by repeatedly calling the 'Comparator' function until + * the list is in order. + * + * param StringList + * String list to sort. + * param Comparator + * Function called to compare two string list strings or NULL for the + * default sort. The default sorting handles NULL elements and uses the + * system's strcmp utility for comparing valid strings elements. + * param ClientData + * Contextual information that is passed along to the comparator function. + */ + void StringListSort(StringList_pa StringList, + StringListStringComparator_pf Comparator, + ArbParam_t ClientData) + { +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + REQUIRE(VALID_REF(StringList)); + REQUIRE(VALID_FN_REF(Comparator) || Comparator == NULL); + + /* set up for comparator proxy */ + if (Comparator != NULL) + ComparatorFunction = Comparator; + else + ComparatorFunction = DefaultStrcmpComparator; + + /* sort the array using the comparator proxy to forward */ + /* the comparison request to the supplied comparator */ + ArrayListQSort((ArrayList_pa)StringList, ComparatorProxy, ClientData); + + /* cleanup */ + ComparatorFunction = NULL; + } diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/strutil.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/strutil.cpp new file mode 100644 index 0000000000..9611722224 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/strutil.cpp @@ -0,0 +1,936 @@ +/* + * 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 STRUTILMODULE +#include "GLOBAL.h" +#include "TASSERT.h" +#include "Q_UNICODE.h" +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif +#include "ARRLIST.h" +#include "STRLIST.h" +#include "STRUTIL.h" +#include "ALLOC.h" + +#include "Q_MSG.h" + +#include +#include // ...needed to find std::tolower and std::toupper +#include +#include "TranslatedString.h" +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +using namespace std; +using namespace tecplot::strutil; + +#ifdef MSWIN +# pragma warning (disable : 4786) /* STL warning about trucated identifiers */ +#endif + +/* END HEADER */ + +/** + */ +#define INITIAL_FORMAT_BUFFER_SIZE 16384*3 +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif +static char *FormatStringBuffer = NULL; +static int FormatStringBufferSize = INITIAL_FORMAT_BUFFER_SIZE; + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if defined MSWIN +#else +#endif /* !MSWIN */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +/** + * This should be one of the last functions called by Tecplot while mopping up. + */ +void FormatStringBufferCleanup(void) +{ + /* + * NOTE: We use free instead of FREE_ARRAY for the scratch buffer because in + * debug mode FREE_ARRAY uses ErrMsg which uses vFormatString causing + * infinite recursion. + */ + if (FormatStringBuffer != NULL) + free(FormatStringBuffer); + FormatStringBuffer = NULL; +} + +/** + */ +char *vFormatString(const char *Format, + va_list Arguments) +{ + char *Result = NULL; + + REQUIRE(VALID_REF(Format)); + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + /* + * NOTE: We use malloc instead of ALLOC_ARRAY for the scratch buffer because + * in debug mode ALLOC_ARRAY uses ErrMsg which uses vFormatString + * causing infinite recursion. + */ + if (FormatStringBuffer == NULL) + FormatStringBuffer = (char *)malloc(FormatStringBufferSize); + + if (FormatStringBuffer != NULL) + { + Boolean_t TryAgain = FALSE; + do + { + /* + * Assign a value other than '\0' to the end of the buffer so that we + * can determine if the buffer needs to be expanded. If after we call + * vsnprintf the end of the buffer has a '\0' we need to expand it. + */ + FormatStringBuffer[FormatStringBufferSize - 1] = (char)!'\0'; + +# if defined MSWIN + memset(FormatStringBuffer, 0, FormatStringBufferSize - 1); + + TryAgain = + _vsnprintf(FormatStringBuffer, + FormatStringBufferSize, + Format, + Arguments) == -1; +# elif defined IRIX62 + vsprintf(FormatStringBuffer, + Format, + Arguments); + CHECK(strlen(FormatStringBuffer) < FormatStringBufferSize); +# else + vsnprintf(FormatStringBuffer, + FormatStringBufferSize, + Format, + Arguments); +# endif + +#ifndef MSWIN + TryAgain = (FormatStringBuffer[FormatStringBufferSize - 1] == '\0'); +#endif + if (TryAgain) + { + /* + * Reallocate the buffer and try again. + * + * NOTE: We use malloc/free instead of ALLOC/FREE_ARRAY for the + * scratch buffer because in debug mode ALLOC/FREE_ARRAY + * uses ErrMsg which uses vFormatString causing infinite + * recursion. + */ + free(FormatStringBuffer); + FormatStringBufferSize += MAX(1, FormatStringBufferSize / 2); + FormatStringBuffer = (char *)malloc(FormatStringBufferSize); + TryAgain = (FormatStringBuffer != NULL); + if (!TryAgain) + FormatStringBufferSize = INITIAL_FORMAT_BUFFER_SIZE; + } + } + while (TryAgain); + + if (FormatStringBuffer != NULL) + Result = DupString(dontTranslate(FormatStringBuffer)); + } + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + ENSURE(VALID_REF(Result) || Result == NULL); + return Result; +} + +/** + */ +char *FormatString(TranslatedString Format, + ...) /* 0 or more variable arguments */ +{ + REQUIRE(!Format.isNull()); + + va_list Arguments; + va_start(Arguments, Format); + char *Result = vFormatString(Format.c_str(), Arguments); + va_end(Arguments); + + ENSURE(VALID_REF(Result) || Result == NULL); + return Result; +} + +/** + */ +int FormatString(string& Buffer, + TranslatedString Format + ...) /* 0 or more variable arguments */ +{ + REQUIRE(!Format.isNull()); + + va_list Arguments; + va_start(Arguments, Format); + char *FormattedString = vFormatString(Format.c_str(), Arguments); + va_end(Arguments); + + int Result; + if (FormattedString != NULL) + { + Buffer.assign(FormattedString); + Result = (int)Buffer.size(); + FREE_ARRAY(FormattedString, "FormattedString"); + } + else + Result = -1; + + + ENSURE(Result == -1 || Result >= 0); + return Result; +} + +/** + * Returns a duplicate of the string or NULL if sufficient memory is not + * available. + * + * NOTE: This function was created because ResetString(...) does not + * duplicate zero length strings but returns NULL instead. + */ +char *DupString(TranslatedString String) +{ + REQUIRE(VALID_TRANSLATED_STRING(String)); + + char *Result = ALLOC_ARRAY(strlen(String.c_str()) + 1, char, "duplicate string"); + if (Result != NULL) + strcpy(Result, String.c_str()); + + ENSURE(Result == NULL || (VALID_REF(Result) && strcmp(Result, String.c_str()) == 0)); + return Result; +} + + +/* + * Copy up to 'Count' characters from the 'Source' string beginning at + * position 'Index' to the 'Target' string. The actual number of characters + * copied may be less than 'Count' if a '\0' was encountered in the + * 'Source' string before 'Count' characters were copied. + * + * NOTE: The 'Target' and 'Source' strings may overlap. + */ +void CopySubString(char *Target, + const char *Source, + int Index, + int Count) +{ + LgIndex_t Length = 0; + + REQUIRE(VALID_REF(Target)); + REQUIRE("Target string is sized to accommodate a string who's length " + "is at least MIN(strlen(&Source[Index]), Count) characters."); + REQUIRE(VALID_REF(Source)); + REQUIRE(0 <= Index && Index <= (LgIndex_t)strlen(Source)); + REQUIRE(Count >= 0); + + Length = MIN((LgIndex_t)strlen(&Source[Index]), Count); + memmove(Target, &Source[Index], Length); + Target[Length] = '\0'; + + ENSURE(VALID_REF(Target) && (LgIndex_t)strlen(Target) == Length); +} + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ + +/* + * Remove any leading white space from the string and return + * a reference to it. NOTE: The input string is modified. + */ +char *StringFlushLeft(char *String) +{ + char *Result = String; + char *Start = String; + + REQUIRE(VALID_REF(String)); + + /* move the substring beginning at the first non-whitespace */ + /* character to the head of the string */ + while (isspace(*Start)) + Start++; + if (Start != String) + memmove(String, Start, strlen(Start) + 1); + + ENSURE(VALID_REF(Result) && Result == String); + return Result; +} + + +/* + * Remove any trailing white space from the string and return + * a reference to it. NOTE: The input string is modified. + */ +static char *StringFlushRight(char *String) +{ + char *Result = String; + char *End = NULL; + + REQUIRE(VALID_REF(String)); + + for (End = EndOfString(String); End != String && isspace(End[-1]); End--) + End[-1] = '\0'; + + ENSURE(VALID_REF(Result) && Result == String); + return Result; +} + + +/* + * Remove any leading and trailing white space from the string + * and return a reference to it. The return value is not + * absolutely necessary since the input string is modified + * but it is convenient sometimes. + * NOTE: The input string is modified but no memory is + * allocated nor deallocated. + */ +char *TrimLeadAndTrailSpaces(char *String) +{ + REQUIRE((String == NULL) || VALID_REF(String)); + if (String) + return (StringFlushLeft(StringFlushRight(String))); + else + return String; +} + + +/* + * If the specified string is longer than the maximum specified length + * truncate it and return a reference to it. + * + * String + * String to truncate if necessary. + * MaxLength + * Length at which to truncate the specified string if exceeded. + * + * Return + * Reference to the input string. + */ + +// Okay for UTF-8 +char *StringTruncate(char *String, + LgIndex_t MaxLength) +{ + REQUIRE(VALID_REF(String)); + REQUIRE(MaxLength >= 0); + + if ((LgIndex_t)strlen(String) > MaxLength) + String[MaxLength] = '\0';/* UTF8_SetAt(String,'\0',MaxLength); */ + + ENSURE(VALID_REF(String)); + ENSURE((LgIndex_t)strlen(String) <= MaxLength); + return String; +} + + +/* + * Trim and truncate the specified string such that its trimmed length + * does not exceed the specified length and return a reference to it. + * + * String + * String to trim and truncate if necessary. + * MaxLength + * Length at which to truncate the trimmed string if exceeded. + * + * Return + * Reference to the input string. + */ +char *StringTrimAndTruncate(char *String, + LgIndex_t MaxLength) +{ + REQUIRE(VALID_REF(String)); + REQUIRE(MaxLength >= 0); + + TrimLeadAndTrailSpaces(String); + StringTruncate(String, MaxLength); + + ENSURE(VALID_REF(String)); + ENSURE((LgIndex_t)strlen(String) <= MaxLength); + return String; +} + +/** + */ + +#ifndef MSWIN +StringList_pa LineBreakString(const char *String, + UInt32_t WrapMargin) +{ + REQUIRE(VALID_REF(String)); + + StringList_pa Result = StringListAlloc(); + if (Result != NULL) + { + Boolean_t IsOk = TRUE; + if (strlen(String) > WrapMargin) + { + char *StringCopy = DupString(dontTranslate(String)); + IsOk = (StringCopy != NULL); + if (IsOk) + { + char *CPtr = StringCopy; + char *SubString = StringCopy; + UInt32_t SubStringLen = 0; + while (*CPtr != '\0' && IsOk) + { + while (*CPtr != '\0' && SubStringLen < WrapMargin) + { + /* look for a hard break */ + if (*CPtr == '\n') + { + *CPtr = '\0'; /* replace the newline */ + CPtr++; + break; + } + + CPtr++; + SubStringLen++; + } + + /* + * If we didn't find a hard break or the end of the string + * then we need to back up and find the closest space. + */ + if (*CPtr != '\0' && SubStringLen == WrapMargin) + { + /* find the closes space from the right */ + if (*CPtr != ' ') + { + while (CPtr != SubString && *CPtr != ' ') + CPtr--; + if (*CPtr != ' ') + { + /* + * Bummer, this line will exceed the wrap margin. + * Search forward for the next space or newline. + */ + while (*CPtr != '\0' && *CPtr != ' ' && *CPtr != '\n') + CPtr++; + while (*CPtr != '\0' && *CPtr == ' ') + CPtr++; /* skip over the white space */ + } + } + + if (*CPtr != '\0') + { + *CPtr = '\0'; + CPtr++; + } + StringFlushRight(SubString); + } + + IsOk = StringListAppendString(Result, SubString); + SubString = CPtr; + SubStringLen = 0; + } + + FREE_ARRAY(StringCopy, "StringCopy"); + } + } + else + IsOk = StringListAppendString(Result, String); + + if (!IsOk) + StringListDealloc(&Result); + } + + ENSURE(Result == NULL || VALID_REF(Result)); + return Result; +} +#endif + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif /* TECPLOTKERNEL */ + + +/** + * Lexicographically compares, at most, the first 'Len' characters of + * s1 and s2. + * + * param s1 + * First string or NULL. + * param s2 + * Second string or NULL. + * param Len + * Maximum number of characters to compare. + * return + * Integer value greater than, equal to, or less than zero according + * to whether the first 'Len' characters of 's1' are greater than, + * equal to, or less than 's2'. + */ + +// Okay for UTF-8 +int ustrncmp(const char *s1, + const char *s2, + size_t Len) +{ + REQUIRE((s1 == NULL) || VALID_REF(s1)); + REQUIRE((s2 == NULL) || VALID_REF(s2)); + REQUIRE(Len >= 0); + + char *t1; + char *t2; + char ct1; + char ct2; + size_t I = 0; + if ((s1 == NULL) && (s2 == NULL)) + return 0; + if (s1 == NULL) + return -1; + else if (s2 == NULL) + return 1; + + t1 = (char*)s1; + t2 = (char*)s2; + + while (*t1 && *t2 && (I < Len)) + { + ct1 = CAPITAL(*t1); + ct2 = CAPITAL(*t2); + if (ct1 != ct2) + return (ct1 - ct2); + t1++; + t2++; + I++; + } + if ((I == Len) || + ((*t1 == '\0') && (*t2 == '\0'))) + return 0; + else + return CAPITAL(*t1) - CAPITAL(*t2); + + +} + + +/** + * Lexicographically compares the characters of s1 and s2. + * + * param s1 + * First string or NULL. + * param s2 + * Second string or NULL. + * return + * Integer value greater than, equal to, or less than zero according to + * whether the characters of 's1' are greater than, equal to, or less + * than 's2'. + */ +int ustrcmp(const char *s1, + const char *s2) +{ + REQUIRE((s1 == NULL) || VALID_REF(s1)); + REQUIRE((s2 == NULL) || VALID_REF(s2)); + + return (ustrncmp(s1, s2, INT_MAX)); +} + + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if !defined NO_ASSERTS && defined DEBUG_ALLOC +#endif +#endif /* TECPLOTKERNEL */ + + +/* + * The problem with passing file names for release builds is that + * the full path name is used (i.e., c:\user\craig\v7.5\tecplot\alloc.c) + */ + +// Okay for UTF-8 + +#if !defined NO_ASSERTS +Boolean_t InternalResetString(char **SBase, + const char *NewString, + Boolean_t IssueErrMsg, + const char *FileName, + int LineNumber) +#else +Boolean_t InternalResetString(char **SBase, + const char *NewString, + Boolean_t IssueErrMsg) +#endif +{ + REQUIRE(VALID_REF(SBase)); + REQUIRE(*SBase == NULL || VALID_REF(*SBase)); + REQUIRE(NewString == NULL || VALID_REF(NewString)); + REQUIRE(IMPLICATION(VALID_REF(*SBase), *SBase != NewString)); /* Prevent calling with same string. */ + REQUIRE(VALID_BOOLEAN(IssueErrMsg)); + REQUIRE(VALID_NON_ZERO_LEN_STR(FileName)); + REQUIRE(LineNumber >= 1); + + if (*SBase) + { +#if !defined NO_ASSERTS && defined DEBUG_ALLOC + char S[80+1]; + MakeDebugRecord(FileName, LineNumber, "releasing", *SBase, S, 80); + FREE_ARRAY(*SBase, S); +#else + FREE_ARRAY(*SBase, ""); +#endif + } + if (NewString == NULL) + { + *SBase = NULL; + return (TRUE); + } + else + { +#if !defined NO_ASSERTS && defined DEBUG_ALLOC + char S[80+1]; + MakeDebugRecord(FileName, LineNumber, "duplicating", NewString, S, 80); + *SBase = ALLOC_ARRAY(strlen(NewString) + 1, char, S); +#else +# if defined MSWIN && defined _DEBUG && !defined(MAKEARCHIVE) && !defined(NO_ASSERTS) + /* Allow the MFC memory leak detection to report the leak at the + * calling programs location, and not here (which is fairly useless). + * But first, we have to turn off the preprocessor definition of new + * and get to the original. */ +# undef new + *SBase = new(FileName, LineNumber) char[strlen(NewString)+1]; +# define new DEBUG_NEW +# else + *SBase = ALLOC_ARRAY(strlen(NewString) + 1, char, ""); +# endif +#endif + if (*SBase) + { + strcpy(*SBase, NewString); + return (TRUE); + } + else + { + if (IssueErrMsg) + ErrMsg(translate("Out of memory")); + return (FALSE); + } + } +} + + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + + +/* + * Unfortunately, this routine uses the interface of DeleteStringToAdd + * forcing StringToAdd to be non-const. Another copy of this routine + * for const char *'s is below. Eventually we should get rid of + * the two routines and DeleteStringToAdd, always using the const version + * and deleting the string if necessary in the code that calls TackOnString. + */ +Boolean_t TackOnString(char **SBase, + const char *StringToAdd, + Boolean_t DeleteStringToAdd, + Boolean_t ConvertNewlinesToAscii) +{ + size_t CurLen; + size_t NewLen; + int NumNewlines = 0; + char *NewString; + const char *CPtr = StringToAdd; + Boolean_t IsOk = TRUE; + + REQUIRE(VALID_REF(SBase)); + REQUIRE((StringToAdd == NULL) || VALID_REF(StringToAdd)); + REQUIRE(VALID_BOOLEAN(DeleteStringToAdd)); + REQUIRE(VALID_BOOLEAN(ConvertNewlinesToAscii)); + + if ((StringToAdd == NULL) || + (*StringToAdd == '\0')) + { + if (StringToAdd && + (*StringToAdd == '\0') && + DeleteStringToAdd) + { + char *TMP = (char *)StringToAdd; + FREE_ARRAY(TMP, "empty string to add"); + } + } + else + { + + if (*SBase == NULL) + CurLen = 0; + else + CurLen = strlen(*SBase); + + while (*CPtr) + if (*CPtr++ == '\n') + NumNewlines++; + + NewLen = CurLen + strlen(StringToAdd) + 1 + NumNewlines; + + NewString = ALLOC_ARRAY(NewLen, char, StringToAdd); + + if (NewString == NULL) + { + if (DeleteStringToAdd) + { + char *TMP = (char *)StringToAdd; + FREE_ARRAY(TMP, StringToAdd); + } + IsOk = FALSE; + } + else + { + if (*SBase) + { + strcpy(NewString, *SBase); + FREE_ARRAY(*SBase, (CurLen > 0 ? *SBase : "previous text")); + } + else + *NewString = '\0'; + + { + char *NPtr = EndOfString(NewString); + const char *APtr = StringToAdd; + while (*APtr) + { + if ((*APtr == '\n') && ConvertNewlinesToAscii) + { + *NPtr++ = '\\'; + *NPtr++ = 'n'; + } + else + *NPtr++ = *APtr; //UTF8_AssignAndIncrement(&NPtr,(char**)&APtr,TRUE,FALSE); //*NPtr++ = *APtr; + APtr++; + } + *NPtr = '\0'; + } + + if (DeleteStringToAdd) + { + char *TMP = (char *)StringToAdd; + FREE_ARRAY(TMP, StringToAdd); + } + + *SBase = NewString; + } + } + + ENSURE(VALID_BOOLEAN(IsOk)); + return (IsOk); +} + + +/* + * See TackOnString for discussion. + */ + +// Okay for UTF-8 +Boolean_t TackOnConstString(char **SBase, + const char *StringToAdd, + Boolean_t ConvertNewlinesToAscii) +{ + size_t CurLen; + size_t NewLen; + int NumNewlines = 0; + char *NewString; + const char *CPtr = StringToAdd; + Boolean_t IsOk = TRUE; + + REQUIRE(VALID_REF(SBase)); + REQUIRE((StringToAdd == NULL) || VALID_REF(StringToAdd)); + REQUIRE(VALID_BOOLEAN(ConvertNewlinesToAscii)); + + if ((StringToAdd != NULL) && + (*StringToAdd != '\0')) + { + if (*SBase == NULL) + CurLen = 0; + else + CurLen = strlen(*SBase); + + while (*CPtr) + if (*CPtr++ == '\n') + NumNewlines++; + + NewLen = CurLen + strlen(StringToAdd) + 1 + NumNewlines; + + NewString = ALLOC_ARRAY(NewLen, char, StringToAdd); + + if (NewString == NULL) + { + IsOk = FALSE; + } + else + { + if (*SBase) + { + strcpy(NewString, *SBase); + FREE_ARRAY(*SBase, (CurLen > 0 ? *SBase : "previous text")); + } + else + *NewString = '\0'; + + { + char *NPtr = EndOfString(NewString); + const char *APtr = StringToAdd; + while (*APtr) + { + if ((*APtr == '\n') && ConvertNewlinesToAscii) + { + *NPtr++ = '\\'; + *NPtr++ = 'n'; + } + else + *NPtr++ = *APtr; // UTF8_AssignAndIncrement(&NPtr,(char**)&APtr,TRUE,FALSE); + APtr++; + } + *NPtr = '\0'; + } + *SBase = NewString; + } + } + + ENSURE(VALID_BOOLEAN(IsOk)); + return (IsOk); +} + + +// Okay for UTF-8 +Boolean_t TackOnChar(char **SBase, + char CharToAdd) +{ + REQUIRE(VALID_REF(SBase)); + + char S[2]; + S[0] = CharToAdd; + S[1] = '\0'; + + return (TackOnString(SBase, S, FALSE, FALSE)); +} + + + +/** + * Converts all one character new line characters in the allocated string + * to a two character "\n" sequence. + * + * param String + * String to scan and convert if necessary. Note that the string will + * be reallocated if any new line characters are discovered. + * + * return + * TRUE if the request was successfull, FALSE otherwise. + */ + +// Okay for UTF-8 +Boolean_t ReplaceNewlineWithBackslashN(char **String) +{ + size_t I; + LgIndex_t NewlineCount; + size_t Length; + char *Replacement; + + REQUIRE(VALID_REF(String)); + REQUIRE(VALID_REF(*String)); + + /* count how many new line character are present */ + NewlineCount = 0; + Length = strlen(*String); + for (I = 0; I < Length; I++) + if ((*String)[I] == '\n') + NewlineCount++; + + if (NewlineCount != 0) + { + /* allocate a new string and convert */ + Replacement = ALLOC_ARRAY(Length + NewlineCount + 1, char, + "replacement string"); + if (Replacement != NULL) + { + size_t J; + for (I = J = 0; I < Length + 1; I++, J++) + { + if ((*String)[I] == '\n') + { + Replacement[J] = '\\'; + J++; + Replacement[J] = 'n'; + } + else + { + Replacement[J] = (*String)[I]; + } + } + + /* sanity check */ + CHECK(I == Length + 1); + CHECK(J == Length + NewlineCount + 1); + } + + /* release the old string and record the new one */ + FREE_ARRAY(*String, "original string"); + *String = Replacement; + } + + ENSURE(*String == NULL || VALID_REF(*String)); + return (*String != NULL); +} + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if defined TECPLOTKERNEL +#if !defined NO_ASSERTS +#endif /* !NO_ASSERTS */ +#endif /*TECPLOTKERNEL*/ +#endif diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/tassert.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/tassert.cpp new file mode 100644 index 0000000000..75b3586225 --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/tassert.cpp @@ -0,0 +1,261 @@ +/* + * 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 + +/* +***************************************************************** +***************************************************************** +******* ******** +****** Copyright (C) 1988-2008 Tecplot, Inc. ******* +******* ******** +***************************************************************** +***************************************************************** +*/ + +#define TASSERTMODULE +#include "GLOBAL.h" +#include "TASSERT.h" +#include "Q_UNICODE.h" +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if defined (MSWIN) +#endif +#endif + +#include "STRUTIL.h" + +using namespace tecplot::strutil; +using namespace std; + +#define MAX_ERRMSG_LENGTH 2096 + +/* the mopup from assert and the writing out of crash.lay are */ +/* used by TUASSERT and thus are needed even if NO_ASSERTS */ +/* is set */ +#if !defined NO_TU_ASSERTS || !defined NO_ASSERTS + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if defined MSWIN /* ...Unix/Linux calls this via signal handlers */ +#endif +#endif /* TECPLOTKERNEL */ + +#endif /* Mopup function needed ... */ + + + +#if !defined STD_ASSERTS +/* + * Define the final assertion notification function. + */ +#if defined UNIXX && !defined NO_ASSERTS +/******************************************************************* + * * + * UNIX * + * * + *******************************************************************/ + + +# if defined NDEBUG +/* + * if NDEBUG is defined __assert is NOT defined so we must supply + * our own assertion notification function..... + */ +# define ASSERT assert +static void UnixAssert(const char *expression, + const char *file_name, + int line) +{ + fprintf(stderr, "Assertion: %s\n" + "Tecplot version: %s\n" + "File Name: %s\n" + "Line Number: %d\n", + expression, TecVersionId, file_name, line); + exit(ExitCode_AssertionFailure); +} +static TAssertFailureNotifyFunc assert_failure_notify = UnixAssert; +# else +/* + * NDEBUG is not defined so __assert is available.... + */ +# if defined LINUX +# define LOWLEVELASSERTFUNCTION __linuxassertproxy +/* + * In linux, __assert does not exist but rather + * __assert_fail which has a differnt API. Thus + * a proxy is provided + */ +static void __linuxassertproxy(const char *__assertion, + const char *__file, + int __line) +{ + __assert_fail(__assertion, __file, __line, __ASSERT_FUNCTION); +} +# elif defined DARWIN +# define LOWLEVELASSERTFUNCTION __darwinassertproxy +/* + * In Darwin (Mac OS X), __assert is #defined to a call to __eprintf, + * which also has a different API. Another proxy... + */ +static void __darwinassertproxy(const char *__assertion, + const char *__file, + int __line) +{ + __eprintf("Assertion: %s\n" + "Tecplot version: %s\n" + "File Name: %s\n" + "Line Number: %d\n", + __assertion, TecVersionId, __file, (unsigned)__line); +} +# else +# define LOWLEVELASSERTFUNCTION __assert +# endif + +static TAssertFailureNotifyFunc assert_failure_notify = (TAssertFailureNotifyFunc) LOWLEVELASSERTFUNCTION; + +# endif +#endif /* UNIXX */ + +#if defined UNIXX && !defined NO_ASSERTS +/* + * Replace the current assert failure notification function and + * return the current one. + * + * Assumptions: + * new function points to valid function (not null) that + * conforms to the specified prototype + * + * Guarantees: + * result is a pointer to the previously installed + * function (not null) + */ +TAssertFailureNotifyFunc InstallTAssertFailureNotify( + TAssertFailureNotifyFunc new_function) /* new notification function */ +{ + TAssertFailureNotifyFunc result = 0; /* old function address */ + + ASSERT(new_function != 0); + + result = assert_failure_notify; + assert_failure_notify = new_function; + + ASSERT(result != 0); + return result; +} + + + + + + +/* + * Perform the installed assert failure notification action. + */ +void TAssert(const char *expression, /* text representation of the assertion */ + const char *file_name, /* name of the file containing the assertion */ + int line) /* line number in the file of the assertion */ +{ + static Boolean_t InTAssert = FALSE; +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + char Message[MAX_ERRMSG_LENGTH+1]; + ASSERT(expression != 0 && strlen(expression) != 0); + ASSERT(file_name != 0 && strlen(file_name) != 0); + ASSERT(line >= 1); + + /* check for recursion */ + if (InTAssert) + { + fprintf(stderr, "Already in assert!\n"); + fprintf(stderr, "Assertion: %s\n" + "Tecplot version: %s\n" + "File Name: %s\n" + "Line Number: %d\n", + expression, TecVersionId, file_name, line); + PrintCurBacktrace(stderr, 100); + ASSERT(FALSE); /*... really exit */ + } + + InTAssert = TRUE; + + sprintf(Message, "Assertion: %s\n" + "Tecplot version: %s\n" + "File Name: %s\n" + "Line Number: %d\n", + expression, TecVersionId, file_name, line); + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +# if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +# else + fprintf(stderr, "%s", Message); +# endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + (*assert_failure_notify)(expression, file_name, line); +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif + + InTAssert = FALSE; /* just in case assert_failure_notify has an ignore */ +} +#endif /* defined UNIXX && !defined NO_ASSERTS */ +#endif /* STD_ASSERTS */ + + +#if defined MSWIN && defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#if defined CHECKED_BUILD +#endif +#if !defined ENGINE +# if defined CHECKED_BUILD +# endif // CHECKED_BUILD +#endif //!ENGINE +#endif /* MSWIN */ + + +#if defined NICE_NOT_IMPLEMENTED +static Boolean_t NotImplementedCalled = FALSE; +void NiceNotImplemented(void) +{ + if (!NotImplementedCalled) + { + Warning("Not Implemented!"); + NotImplementedCalled = TRUE; + } +} +#endif diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/tecxxx.cpp b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/tecxxx.cpp new file mode 100644 index 0000000000..dbace9f91f --- /dev/null +++ b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio/tecsrc/tecxxx.cpp @@ -0,0 +1,4812 @@ +/* + * 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. ******* +******* ******** +****************************************************************** +****************************************************************** +*/ +/* Source file revision $Revision: 7627 $ */ + +#include "GLOBAL.h" +#include "TASSERT.h" +#include "Q_UNICODE.h" +#include "SYSTEM.h" +#include "FILESTREAM.h" +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif +#include "DATAIO4.h" +#include "DATASET0.h" +#include "TECXXX.h" +#include "DATAUTIL.h" +#include "ALLOC.h" +#include + +#if !defined MAKEARCHIVE +#include "AUXDATA.h" +#endif /* MAKEARCHIVE */ + +#if defined MSWIN +#include +#endif + +#if defined UNIXX +#include +#include +#include +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif +using namespace std; + +#if defined MAKEARCHIVE + #if defined MSWIN && defined _DEBUG +/* For debug .dll builds, send debug info to debug window. */ + #define PRINT0(s) do { OutputDebugString(s); } while (0) + #define PRINT1(s,a1) do { char buffer[512]; sprintf(buffer,s,a1); OutputDebugString(buffer); } while (0) + #define PRINT2(s,a1,a2) do { char buffer[512]; sprintf(buffer,s,a1,a2); OutputDebugString(buffer); } while (0) + #else +/* For all other builds (including release .dll), send debug info to stdout. */ + #define PRINT0(s) printf(s) + #define PRINT1(s,a1) printf(s,a1) + #define PRINT2(s,a1,a2) printf(s,a1,a2) +#endif +#else + #if defined MSWIN +/* For nonarchive, Windows, don't send debug info. */ + #define PRINT0(s) ((void)0) + #define PRINT1(s,a1) ((void)0) + #define PRINT2(s,a1,a2) ((void)0) + #else +/* For nonarchive, nonwindows, send debug info to stdout. */ + #define PRINT0(s) printf(s) + #define PRINT1(s,a1) printf(s,a1) + #define PRINT2(s,a1,a2) printf(s,a1,a2) + #endif +#endif + +typedef char *FNameType; +typedef FILE *FilePtr; + +#define MaxNumFiles 10 +#define MAX_DUPLIST_VARS 50 /* maybe crank up in the future */ + +#define BYTES_PER_CHUNK 4096 +#define TECIO_NO_NEIGHBORING_ELEM 0 +#define TECIO_NO_NEIGHBORING_ZONE 0 + +#if defined MAKEARCHIVE +static LgIndex_t DebugLevel[MaxNumFiles] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +#endif +static INTEGER4 IsOpen[MaxNumFiles] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static INTEGER4 NumErrs[MaxNumFiles] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static INTEGER4 NumVars[MaxNumFiles]; +static FNameType DestFName[MaxNumFiles] = {NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL + }; +static FNameType BlckFName[MaxNumFiles] = {NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL + }; +static FileStream_s* BlckFile[MaxNumFiles]; +static FileStream_s* HeadFile[MaxNumFiles]; +static vector MinMaxOffset[MaxNumFiles]; /* vector dimensioned by num zones */ +static vector VarMinValue[MaxNumFiles]; /* vector dimensioned by num vars */ +static vector VarMaxValue[MaxNumFiles]; /* vector dimensioned by num vars */ +static INTEGER4 DoWriteForeign = FALSE; /* ...default is to write native */ +static INTEGER4 IsWritingNative[MaxNumFiles]; +static INTEGER4 IsBlock[MaxNumFiles]; +static INTEGER4 ZoneType[MaxNumFiles]; +static LgIndex_t IMax[MaxNumFiles]; /* ones based indices */ +static LgIndex_t JMax[MaxNumFiles]; /* ones based indices */ +static LgIndex_t KMax[MaxNumFiles]; /* ones based indices */ +static vector TotalNumFaceNodes[MaxNumFiles]; /* vector dimensioned by num zones */ +static LgIndex_t TotalNumFaceBndryFaces[MaxNumFiles]; +static LgIndex_t TotalNumFaceBndryConns[MaxNumFiles]; +static LgIndex_t ICellMax[MaxNumFiles]; +static LgIndex_t JCellMax[MaxNumFiles]; +static LgIndex_t KCellMax[MaxNumFiles]; +static vector NumFaceConnections[MaxNumFiles]; /* vector dimensioned by num zones */ +static INTEGER4 FaceNeighborMode[MaxNumFiles]; +static vector FaceNeighborsOrMapWritten[MaxNumFiles]; /* vector dimensioned by num zones */ +static INTEGER4 NumIndices[MaxNumFiles]; +static LgIndex_t NumDataValuesWritten[MaxNumFiles]; +static LgIndex_t NumOrderedCCDataValuesWritten[MaxNumFiles]; /* CC data only */ +static LgIndex_t NumDataValuesToWrite[MaxNumFiles]; +static vector NumRunningVarValues[MaxNumFiles]; /* vector dimensioned by num vars */ +static vector IsSharedVar[MaxNumFiles]; /* vector dimensioned by num vars */ +static vector IsPassiveVar[MaxNumFiles]; /* vector dimensioned by num vars */ +static INTEGER4 CurZone[MaxNumFiles]; /* zero based zone numbers */ +static INTEGER4 CurVar[MaxNumFiles]; /* zero based var numbers */ +static INTEGER4 FieldDataType; +static INTEGER4 CurFile = -1; +static vector IsCellCentered[MaxNumFiles]; /* vector dimensioned by num vars */ +static Boolean_t HasFECONNECT[MaxNumFiles]; +static INTEGER4 FileTypes[MaxNumFiles]; +static vector NumConnectivityNodes[MaxNumFiles]; /* vector dimensioned by num zones */ +static vector ConnectivityWritten[MaxNumFiles]; /* vector dimensioned by num zones */ + +/* + * From preplot.cpp: + * + * ZoneType 0=ORDERED,1=FELINESEG,2=FETRIANGLE, + * 3=FEQUADRILATERAL,4=FETETRAHEDRON,5=FEBRICK, + * 6=FEPOLYGON,7=FEPOLYHEDRON + */ +#define ORDERED 0 +#define FELINESEG 1 +#define FETRIANGLE 2 +#define FEQUADRILATERAL 3 +#define FETETRAHEDRON 4 +#define FEBRICK 5 +#define FEPOLYGON 6 +#define FEPOLYHEDRON 7 +/* + * FileType 0=FULLFILE,1=GRIDFILE,2=SOLUTIONFILE + */ +#define FULLFILE 0 +#define GRIDFILE 1 +#define SOLUTIONFILE 2 + +#if defined MAKEARCHIVE +static char const* ZoneTypes[] = +{ + "ORDERED", + "FELINESEG", + "FETRIANGLE", + "FEQUADRILATERAL", + "FETETRAHEDRON", + "FEBRICK", + "FEPOLYGON", + "FEPOLYHEDRON" +}; +#endif /* MAKEARCHIVE */ + + +static void WriteErr(const char *routine_name) +{ + #if defined MAKEARCHIVE + PRINT2("Err: (%s) Write failure on file %d.\n", routine_name, CurFile + 1); + #endif + NumErrs[CurFile]++; +} + +static LgIndex_t TecXXXZoneNum = 0; + +Boolean_t ParseDupList(LgIndex_t **ShareVarFromZone, + LgIndex_t *ShareConnectivityFromZone, + const char *DupList) +{ + Boolean_t IsOk = TRUE; + + REQUIRE(VALID_REF(ShareVarFromZone) && *ShareVarFromZone == NULL); + REQUIRE(VALID_REF(ShareConnectivityFromZone)); + REQUIRE(VALID_REF(DupList)); + + while (IsOk && *DupList) + { + /* skip leading spaces */ + while (*DupList && *DupList == ' ') + DupList++; + + /* is this the FECONNECT keyword? */ + if (*DupList && !strncmp(DupList, "FECONNECT", 9)) + *ShareConnectivityFromZone = TecXXXZoneNum; + + else if (*DupList && !isdigit(*DupList)) + IsOk = FALSE; /* syntax error */ + + else if (*DupList) + { + char *NotUsed = NULL; + EntIndex_t WhichVar = strtol(DupList, &NotUsed, 10); + EntIndex_t numVarsForFile = NumVars[CurFile]; + + if (0 < WhichVar && WhichVar < numVarsForFile) + { + if (!(*ShareVarFromZone)) + { + *ShareVarFromZone = ALLOC_ARRAY(numVarsForFile, LgIndex_t, "Variable sharing list"); + if (*ShareVarFromZone) + memset(*ShareVarFromZone, (char)0, numVarsForFile * sizeof(LgIndex_t)); + } + + if (*ShareVarFromZone) + (*ShareVarFromZone)[WhichVar - 1] = TecXXXZoneNum; + else + IsOk = FALSE; + } + else + { + /* Invalid var num */ + IsOk = FALSE; + } + } + + /* + * Skip to the comma. This + * will also allow the syntax error + * of more than one consecutive comma + */ + + while (*DupList && *DupList != ',') + DupList++; + + /* skip past the comma (can handle the syntax error of more than 1 comma) */ + while (*DupList && *DupList == ',') + DupList++; + } + + return IsOk; +} + +/** + */ +static FileStream_s *OpenFileStream(const char *FilePath, + const char *AccessMode, + Boolean_t IsByteOrderNative) +{ + REQUIRE(VALID_REF(FilePath)); + REQUIRE(VALID_REF(AccessMode)); + + FileStream_s *Result = NULL; + FILE *File = TP_FOPEN(FilePath, AccessMode); + if (File != NULL) + { + Result = FileStreamAlloc(File, IsByteOrderNative); + if (Result == NULL) + TP_FCLOSE(File); + } + + ENSURE((VALID_REF(Result) && VALID_REF(Result->File)) || Result == NULL); + return Result; +} + +/** + */ +static void CloseFileStream(FileStream_s **FileStream) +{ + REQUIRE(VALID_REF(FileStream)); + REQUIRE(VALID_REF(*FileStream) || *FileStream == NULL); + + if (*FileStream != NULL) + { + TP_FCLOSE((*FileStream)->File); + FileStreamDealloc(FileStream); + } + + ENSURE(*FileStream == NULL); +} + +/** + * Get the best terminator (separator) character to use for the string. First + * precedence goes to the new line then the command and finally by default the + * space. NOTE: We use a do loop to allow it to be used as a single statement. + */ +#define GET_BEST_TERMINATOR_CHAR(CompoundStr, TerminatorChar) \ + do \ + { \ + if (strchr((CompoundStr), '\n') != NULL) \ + (TerminatorChar) = '\n'; \ + else if (strchr((CompoundStr), ',') != NULL) \ + (TerminatorChar) = ','; \ + else \ + (TerminatorChar) = ' '; \ + } while (0) + + +/** + * TECINIXXX + */ +INTEGER4 LIBCALL TECINI112(char *Title, + char *Variables, + char *FName, + char *ScratchDir, + INTEGER4 *FileType, + INTEGER4 *Debug, + INTEGER4 *VIsDouble) +{ + size_t L; + int I; + char RName[80]; + char *CPtr; + int NewFile = -1; + + /* + * Note that users should not mix TECXXX, TEC100XXX, and TEC110XXX calls, but + * just in case, initialize the TecXXXZoneNum variable. It may not help, but + * it doesn't hurt... + */ + TecXXXZoneNum = 0; + + #if defined MAKEARCHIVE + InitInputSpecs(); + #endif + + for (I = 0; (I < MaxNumFiles) && (NewFile == -1); I++) + { + if (!IsOpen[I]) + NewFile = I; + } + + if (NewFile == -1) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECINI112) Too many files (%d) opened for printing.\n", NewFile); + #endif + return (-1); + } + + if (CurFile == -1) + CurFile = 0; + + #if defined MAKEARCHIVE + DebugLevel[NewFile] = *Debug; + #endif + /* check sizes for array sized by number of variables */ + CHECK(VarMinValue[NewFile].empty()); + CHECK(VarMaxValue[NewFile].empty()); + CHECK(NumRunningVarValues[NewFile].empty()); + CHECK(IsSharedVar[NewFile].empty()); + CHECK(IsPassiveVar[NewFile].empty()); + CHECK(IsCellCentered[NewFile].empty()); + + /* check sizes for array sized by number of zones */ + CHECK(MinMaxOffset[NewFile].empty()); + CHECK(TotalNumFaceNodes[NewFile].empty()); + CHECK(NumFaceConnections[NewFile].empty()); + CHECK(FaceNeighborsOrMapWritten[NewFile].empty()); + CHECK(NumConnectivityNodes[NewFile].empty()); + CHECK(ConnectivityWritten[NewFile].empty()); + + CurZone[NewFile] = -1; + L = 0; + if (FName != NULL) + L = strlen(FName); + if (L == 0) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECINI112) Bad file name for file %d.\n", NewFile); + #endif + return (-1); + } + DestFName[NewFile] = ALLOC_ARRAY(L + 1, char, "data set fname"); + strcpy(DestFName[NewFile], FName); + + #if defined (DOS) + { + sprintf(RName, "BLCKFILE.%03d", (int)(NewFile + 1)); + } + #else + { + sprintf(RName, "tp%1dXXXXXX", NewFile + 1); + } + #endif + + L = strlen(RName); + if (ScratchDir != NULL) + L += strlen(ScratchDir) + 1; /* +1 for the slash delimeter */ + BlckFName[NewFile] = ALLOC_ARRAY(L + 1, char, "data set fname"); + if (ScratchDir != NULL) + { + strcpy(BlckFName[NewFile], ScratchDir); + #if defined DOS || defined MSWIN + { + strcat(BlckFName[NewFile], "\\"); + } + #else + { + strcat(BlckFName[NewFile], "/"); + } + #endif + } + else + BlckFName[NewFile][0] = '\0'; + + strcat(BlckFName[NewFile], RName); + CHECK(strlen(BlckFName[NewFile]) <= L); + + #if defined MSWIN + { + _mktemp(BlckFName[NewFile]); + } + #elif defined UNIXX + { + /* + * POSIX compiant behavior is to make + * sure umask is set correctly first. + */ + mode_t OrigUmask = umask(0022); /* ...should produce rw------- */ + int FileDesc = mkstemp(BlckFName[NewFile]); + if (FileDesc != -1) + close(FileDesc); + umask(OrigUmask); + } + #endif + + #if defined MAKEARCHIVE + if (DebugLevel[NewFile]) + { + PRINT2("Scratch File #%d: %s\n", NewFile + 1, BlckFName[NewFile]); + PRINT2("Dest File #%d: %s\n", NewFile + 1, DestFName[NewFile]); + } + #endif + + IsWritingNative[NewFile] = !DoWriteForeign; + + #if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ + #endif + + HeadFile[NewFile] = OpenFileStream(DestFName[NewFile], "wb", IsWritingNative[NewFile]); + BlckFile[NewFile] = OpenFileStream(BlckFName[NewFile], "wb", IsWritingNative[NewFile]); + + if (BlckFile[NewFile] == NULL) + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECINI112) Cannot open scratch file for output.\n"); + PRINT0(" Check permissions in scratch directory.\n"); + #endif + NumErrs[NewFile]++; + return (-1); + } + if (HeadFile[NewFile] == NULL) + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECINI112) Cannot open plot file. Check permissions.\n"); + #endif + NumErrs[NewFile]++; + return (-1); + } + + writeBinaryVersionNumber(*HeadFile[NewFile], + TecplotBinaryFileVersion); + WriteBinaryMagic(HeadFile[NewFile]); + + /* Write file type */ + if (*FileType >= FULLFILE && *FileType <= SOLUTIONFILE) + FileTypes[NewFile] = *FileType; + else + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECINI112) Bad filetype argument. Check documentation.\n"); + #endif + NumErrs[NewFile]++; + return (-1); + } + + CHECK(TecplotBinaryFileVersion == 112); + if (!WriteBinaryInt32(HeadFile[NewFile], (LgIndex_t)FileTypes[NewFile])) + { + WriteErr("TECINI112"); + return (-1); + } + + if (!DumpDatafileString(HeadFile[NewFile], + Title, + TRUE)) + { + WriteErr("TECINI112"); + return (-1); + } + + NumVars[NewFile] = 0; + CPtr = Variables; + + + /* + * Three possible variable name separators are accepted with the following + * precidence: newline, comma, and space. + */ + { + char terminator; + + GET_BEST_TERMINATOR_CHAR(CPtr, terminator); + while (*CPtr) + { + /* strip leading spaces */ + while (*CPtr && *CPtr == ' ') + CPtr++; + + if (*CPtr) + { + NumVars[NewFile]++; + /* skip to terminating character */ + while (*CPtr && *CPtr != terminator) + CPtr++; + /* skip past terminating character */ + if (*CPtr) + CPtr++; + } + } + } + +#if 0 + /* A grid file can have no variables in it as long as there is a connectivity list */ + if (NumVars[NewFile] == 0 && FileTypes[NewFile] != GRIDFILE) + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECINI110) No variable names were defined.\n"); + #endif + NumErrs[NewFile]++; + return (-1); + } +#endif + + #if defined MAKEARCHIVE + if (DebugLevel[NewFile]) + PRINT1("NumVars=%d\n", NumVars[NewFile]); + #endif + /* make sure var-sized arrays are big enough for all vars */ + try + { + VarMinValue[NewFile].resize(NumVars[NewFile]); + VarMaxValue[NewFile].resize(NumVars[NewFile]); + NumRunningVarValues[NewFile].resize(NumVars[NewFile]); + IsSharedVar[NewFile].resize(NumVars[NewFile]); + IsPassiveVar[NewFile].resize(NumVars[NewFile]); + IsCellCentered[NewFile].resize(NumVars[NewFile]); + } + catch (std::bad_alloc const&) + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECINI112) Memory allocation error.\n"); + #endif + NumErrs[NewFile]++; + return (-1); + } + + if (!WriteBinaryInt32(HeadFile[NewFile], (LgIndex_t)NumVars[NewFile])) + { + WriteErr("TECINI110"); + return (-1); + } + + CPtr = Variables; + { + char terminator; + char TString[MaxChrsVarName+1]; + int I; + + GET_BEST_TERMINATOR_CHAR(CPtr, terminator); + while (*CPtr) + { + /* skip leading space characters */ + while (*CPtr && *CPtr == ' ') + CPtr++; + if (*CPtr) + { + I = 0; + /* skip to terminator */ + while (*CPtr && *CPtr != terminator) + { + TString[I++] = *CPtr++; + } + /* skip past terminator */ + if (*CPtr) + CPtr++; + + /* strip trailing spaces */ + I--; + while (I >= 0 && TString[I] == ' ') + I--; + + TString[I+1] = '\0'; + + if (!DumpDatafileString(HeadFile[NewFile], TString, TRUE)) + { + WriteErr("TECINI110"); + return (-1); + } + } + } + } + + IsOpen[NewFile] = 1; + + if (*VIsDouble) + FieldDataType = FieldDataType_Double; + else + FieldDataType = FieldDataType_Float; + + return (0); +} + +INTEGER4 LIBCALL TECINI111(char *Title, + char *Variables, + char *FName, + char *ScratchDir, + INTEGER4 *FileType, + INTEGER4 *Debug, + INTEGER4 *VIsDouble) +{ + return TECINI112(Title, + Variables, + FName, + ScratchDir, + FileType, + Debug, + VIsDouble); +} + +INTEGER4 LIBCALL TECINI110(char *Title, + char *Variables, + char *FName, + char *ScratchDir, + INTEGER4 *Debug, + INTEGER4 *VIsDouble) +{ + INTEGER4 FType = FULLFILE; + + TecXXXZoneNum = 0; + return TECINI112(Title, + Variables, + FName, + ScratchDir, + &FType, + Debug, + VIsDouble); +} + +INTEGER4 LIBCALL TECINI100(char *Title, + char *Variables, + char *FName, + char *ScratchDir, + INTEGER4 *Debug, + INTEGER4 *VIsDouble) +{ + INTEGER4 FType = FULLFILE; + + TecXXXZoneNum = 0; + return TECINI112(Title, + Variables, + FName, + ScratchDir, + &FType, + Debug, + VIsDouble); +} + +INTEGER4 LIBCALL TECINI(char *Title, + char *Variables, + char *FName, + char *ScratchDir, + INTEGER4 *Debug, + INTEGER4 *VIsDouble) +{ + INTEGER4 FType = FULLFILE; + + TecXXXZoneNum = 0; + return TECINI112(Title, + Variables, + FName, + ScratchDir, + &FType, + Debug, + VIsDouble); +} + +#if defined MAKEARCHIVE && !defined _WIN32 /* every platform but Windows Intel */ +LIBFUNCTION INTEGER4 LIBCALL tecini112_(char *Title, + char *Variables, + char *FName, + char *ScratchDir, + INTEGER4 *FileType, + INTEGER4 *Debug, + INTEGER4 *VIsDouble) +{ + return TECINI112(Title, Variables, FName, ScratchDir, FileType, Debug, VIsDouble); +} + +LIBFUNCTION INTEGER4 LIBCALL tecini111_(char *Title, + char *Variables, + char *FName, + char *ScratchDir, + INTEGER4 *FileType, + INTEGER4 *Debug, + INTEGER4 *VIsDouble) +{ + return TECINI112(Title, Variables, FName, ScratchDir, FileType, Debug, VIsDouble); +} + +LIBFUNCTION INTEGER4 LIBCALL tecini110_(char *Title, + char *Variables, + char *FName, + char *ScratchDir, + INTEGER4 *Debug, + INTEGER4 *VIsDouble) +{ + INTEGER4 FType = FULLFILE; + return TECINI112(Title, Variables, FName, ScratchDir, &FType, Debug, VIsDouble); +} + +LIBFUNCTION INTEGER4 LIBCALL tecini100_(char *Title, + char *Variables, + char *FName, + char *ScratchDir, + INTEGER4 *Debug, + INTEGER4 *VIsDouble) +{ + INTEGER4 FType = FULLFILE; + return TECINI112(Title, Variables, FName, ScratchDir, &FType, Debug, VIsDouble); +} + +LIBFUNCTION INTEGER4 LIBCALL tecini_(char *Title, + char *Variables, + char *FName, + char *ScratchDir, + INTEGER4 *Debug, + INTEGER4 *VIsDouble) +{ + INTEGER4 FType = FULLFILE; + return TECINI112(Title, + Variables, + FName, + ScratchDir, + &FType, + Debug, + VIsDouble); +} +#endif + + +static int CheckData(const char *routine_name) +{ + + if (NumDataValuesToWrite[CurFile] != NumDataValuesWritten[CurFile]) + { + #if defined MAKEARCHIVE + PRINT2("Err: (%s) Wrong number of data values in file %d:\n", routine_name, CurFile + 1); + PRINT2(" %d data values for Zone %d were processed,\n", NumDataValuesWritten[CurFile], CurZone[CurFile] + 1); + PRINT1(" %d data values were expected.\n", NumDataValuesToWrite[CurFile]); + #endif + NumErrs[CurFile]++; + return (-1); + } + return (0); +} + +static int CheckFile(const char *routine_name) +{ + if ((CurFile == -1) || (!IsOpen[CurFile])) + { + #if defined MAKEARCHIVE + PRINT2("Err: (%s) Attempt to use invalid file (%d).\n", + routine_name, CurFile + 1); + #endif + return (-1); + } + return (0); +} + +/** + * Advances CurVar[CurFile] to the next non-shared active variable. TECDATXXX + * clients should not supply values for shared or passive variables. + */ +static void AdvanceToNextVarWithValues(void) +{ + /* search for the next variable with values */ + do + { + CurVar[CurFile]++; + } + while (CurVar[CurFile] < NumVars[CurFile] && + (IsSharedVar[CurFile][CurVar[CurFile]] || + IsPassiveVar[CurFile][CurVar[CurFile]])); +} + +/** + * TECZNEXXX + */ +INTEGER4 LIBCALL TECZNE112(char *ZnTitle, + INTEGER4 *ZnType, + INTEGER4 *IMxOrNumPts, + INTEGER4 *JMxOrNumElements, + INTEGER4 *KMxOrNumFaces, + INTEGER4 *ICellMx, + INTEGER4 *JCellMx, + INTEGER4 *KCellMx, + double *SolutionTime, + INTEGER4 *StrandID, + INTEGER4 *ParentZone, + INTEGER4 *IsBlk, + INTEGER4 *NumFaceConn, + INTEGER4 *FNMode, + INTEGER4 *NumFaceNodes, + INTEGER4 *NumFaceBndryFaces, + INTEGER4 *NumFaceBndryConns, + INTEGER4 *PassiveVarList, + INTEGER4 *ValueLocation, + INTEGER4 *ShareVarFromZone, + INTEGER4 *ShareConnectivityFromZone) +{ + int I; + int IsOk = 1; + + if (CheckFile("TECZNE112") < 0) + return (-1); + + if (CurZone[CurFile] > -1) + { + if (CheckData("TECZNE112") < 0) + return (-1); + } + + if (NumVars[CurFile] == 0) + { + WriteErr("TECZNE112"); + #if defined MAKEARCHIVE + PRINT1("Err: (TECZNE112) Cannot write out zones if numvars is equal to zero (file %d).\n", + CurFile + 1); + #endif + return (-1); + } + + if (CurZone[CurFile] > MaxNumZonesOrVars - 2) /* -1 based */ + { + WriteErr("TECZNE112"); + #if defined MAKEARCHIVE + PRINT2("Err: (TECZNE112) Exceeded max number of zones (%d) in file %d.\n", + MaxNumZonesOrVars, CurFile + 1); + #endif + return (-1); + } + + if (*StrandID < -1) + { + #if defined MAKEARCHIVE + PRINT2("Err: (TECZNE112) Invalid StrandID supplied for file %d, zone %d.\n", + CurFile + 1, CurZone[CurFile] + 1 + 1); + #endif + return (-1); + } + + if (*ParentZone < 0) + { + #if defined MAKEARCHIVE + PRINT2("Err: (TECZNE112) Invalid ParentZone supplied for file %d, zone %d.\n", + CurFile + 1, CurZone[CurFile] + 1 + 1); + #endif + return (-1); + } + + /* + * This is a temporary error. Point format should no longer be written to the file + * and should instead be converted to block format before being written. Since the + * conversion has not yet been implemented, it is an error to use point data. + * TODO (JN): Remove this error when point to block conversion has been implemented. + */ + if (*IsBlk != 1) + { + #if defined MAKEARCHIVE + PRINT2("Err: (TECZNE112) Point data is not currently allowed. " + " Please use block format for file %d, zone %d.\n", + CurFile + 1, CurZone[CurFile] + 1 + 1); + #endif + return (-1); + } + + NumDataValuesWritten[CurFile] = 0; + NumOrderedCCDataValuesWritten[CurFile] = 0; + CurZone[CurFile]++; + + /* Resize zone-dimensioned arrays (CurZone[] is 0-based) */ + try + { + MinMaxOffset[CurFile].resize(CurZone[CurFile] + 1); + TotalNumFaceNodes[CurFile].resize(CurZone[CurFile] + 1); + NumFaceConnections[CurFile].resize(CurZone[CurFile] + 1); + FaceNeighborsOrMapWritten[CurFile].resize(CurZone[CurFile] + 1); + NumConnectivityNodes[CurFile].resize(CurZone[CurFile] + 1); + ConnectivityWritten[CurFile].resize(CurZone[CurFile] + 1); + } + catch (std::bad_alloc const&) + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECZNE112) Memory allocation error.\n"); + #endif + NumErrs[CurFile]++; + return (-1); + } + + ZoneType[CurFile] = *ZnType; + IMax[CurFile] = *IMxOrNumPts; + JMax[CurFile] = *JMxOrNumElements; + KMax[CurFile] = *KMxOrNumFaces; + ICellMax[CurFile] = *ICellMx; + JCellMax[CurFile] = *JCellMx; + KCellMax[CurFile] = *KCellMx; + /* Set the flags that connectivity, face neighbors or face map hasn't been written for the zone yet. */ + FaceNeighborsOrMapWritten[CurFile][CurZone[CurFile]] = FALSE; + ConnectivityWritten[CurFile][CurZone[CurFile]] = FALSE; + + if (ZoneType[CurFile] == ZoneType_FEPolygon || + ZoneType[CurFile] == ZoneType_FEPolyhedron) + { + NumFaceConnections[CurFile][CurZone[CurFile]] = 0; /* ...not used for polytope data */ + FaceNeighborMode[CurFile] = 0; /* ...not used for polytope data */ + NumConnectivityNodes[CurFile][CurZone[CurFile]] = 0; /* ...not used for polytope data */ + + IsBlock[CurFile] = TRUE; /* ...polytope data is always block */ + TotalNumFaceNodes[CurFile][CurZone[CurFile]] = *NumFaceNodes; + TotalNumFaceBndryFaces[CurFile] = *NumFaceBndryFaces; + TotalNumFaceBndryConns[CurFile] = *NumFaceBndryConns; + } + else /* ...classic data */ + { + IsBlock[CurFile] = *IsBlk; + NumFaceConnections[CurFile][CurZone[CurFile]] = *NumFaceConn; + FaceNeighborMode[CurFile] = *FNMode; + + TotalNumFaceNodes[CurFile][CurZone[CurFile]] = 0; /* ...not used for classic data */ + TotalNumFaceBndryFaces[CurFile] = 0; /* ...not used for classic data */ + TotalNumFaceBndryConns[CurFile] = 0; /* ...not used for classic data */ + } + + WriteBinaryReal(HeadFile[CurFile], + (double)ZoneMarker, + FieldDataType_Float); + if (!DumpDatafileString(HeadFile[CurFile], + ZnTitle, + TRUE)) + { + WriteErr("TECZNE112"); + return (-1); + } + + if ((ShareVarFromZone && *ShareConnectivityFromZone) && + CurZone[CurFile] == 0) + { + /* can't have a duplist if there's nothing to duplicate */ + IsOk = 0; + } + + if (IsOk == 0) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECZNE112) Bad zone format for file %d.\n", CurFile + 1); + #endif + NumErrs[CurFile]++; + return (-1); + } + + switch (ZoneType[CurFile]) + { + case ORDERED: + NumIndices[CurFile] = 0; + break; + case FELINESEG: + NumIndices[CurFile] = 2; + break; + case FETRIANGLE: + NumIndices[CurFile] = 3; + break; + case FEQUADRILATERAL: + NumIndices[CurFile] = 4; + break; + case FETETRAHEDRON: + NumIndices[CurFile] = 4; + break; + case FEBRICK: + NumIndices[CurFile] = 8; + break; + } + + /* ...not used for poly or ordered data and don't count sharing or solution files. */ + if (ZoneType[CurFile] != ZoneType_FEPolygon && + ZoneType[CurFile] != ZoneType_FEPolyhedron && + *ShareConnectivityFromZone == 0 && + FileTypes[CurFile] != SOLUTIONFILE) + NumConnectivityNodes[CurFile][CurZone[CurFile]] = NumIndices[CurFile] * JMax[CurFile]; + + /* + * We do not check any return values until the end. If these calls fail, + * WriteFieldDataType below should fail as well. + */ + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)(*ParentZone) - 1); /* ...ParentZone is zero based for binary file */ + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)(*StrandID) - 1); /* ...StrandID is zero based for binary file */ + WriteBinaryReal(HeadFile[CurFile], *SolutionTime, FieldDataType_Double); + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t) - 1); /* No Zone Color Assignment */ + WriteBinaryInt32(HeadFile[CurFile], ZoneType[CurFile]); + + NumDataValuesToWrite[CurFile] = 0; + for (I = 0; I < NumVars[CurFile]; I++) + { + IsSharedVar[CurFile][I] = (ShareVarFromZone != NULL && ShareVarFromZone[I] != 0); /* ...shared? */ + IsPassiveVar[CurFile][I] = (PassiveVarList != NULL && PassiveVarList[I] == 1); /* ...passive? */ + } + + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)(ValueLocation != NULL ? 1 : 0)); /* ...are var locations specified? */ + if (ValueLocation) + { + for (I = 0; I < NumVars[CurFile]; I++) + { + int VIndex; + LgIndex_t NumNodes; + LgIndex_t NumCells; + + if (ZoneType[CurFile] == ORDERED) + { + NumNodes = IMax[CurFile] * JMax[CurFile] * KMax[CurFile]; + NumCells = (MAX(IMax[CurFile] - 1, 1) * + MAX(JMax[CurFile] - 1, 1) * + MAX(KMax[CurFile] - 1, 1)); + } + else + { + NumNodes = IMax[CurFile]; + NumCells = JMax[CurFile]; + } + + if (IsSharedVar[CurFile][I]) + VIndex = ShareVarFromZone[I] - 1; + else + VIndex = I; + + if (VIndex == 0) + NumRunningVarValues[CurFile][I] = 0; + else + NumRunningVarValues[CurFile][VIndex] = NumRunningVarValues[CurFile][VIndex-1]; + + IsCellCentered[CurFile][VIndex] = (ValueLocation[I] == ValueLocation_CellCentered); + if (ValueLocation[I] == ValueLocation_CellCentered) + { + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)1); + if (!IsSharedVar[CurFile][I] && !IsPassiveVar[CurFile][I]) + { + NumDataValuesToWrite[CurFile] += NumCells; + NumRunningVarValues[CurFile][VIndex] += NumCells; + } + } + else if (ValueLocation[I] == ValueLocation_Nodal) + { + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)0); + if (!IsSharedVar[CurFile][I] && !IsPassiveVar[CurFile][I]) + { + NumDataValuesToWrite[CurFile] += NumNodes; + NumRunningVarValues[CurFile][VIndex] += NumNodes; + } + } + else + { + #if defined MAKEARCHIVE + PRINT2("Err: (TECZNE112) Bad zone value location for file %d, variable %d.\n", CurFile + 1, I + 1); + #endif + NumErrs[CurFile]++; + return(-1); + } + } + } + else + { + LgIndex_t NumNodes; + if (ZoneType[CurFile] == ORDERED) + { + NumNodes = IMax[CurFile] * JMax[CurFile] * KMax[CurFile]; + } + else + { + NumNodes = IMax[CurFile]; + } + + for (I = 0; I < NumVars[CurFile]; I++) + { + int VIndex; + if (IsSharedVar[CurFile][I]) + VIndex = ShareVarFromZone[I] - 1; + else + VIndex = I; + + if (VIndex == 0) + NumRunningVarValues[CurFile][I] = 0; + else + NumRunningVarValues[CurFile][VIndex] = NumRunningVarValues[CurFile][VIndex-1]; + + IsCellCentered[CurFile][VIndex] = FALSE; + if (!IsSharedVar[CurFile][I] && !IsPassiveVar[CurFile][I]) + { + NumDataValuesToWrite[CurFile] += NumNodes; + NumRunningVarValues[CurFile][VIndex] += NumNodes; + } + } + } + + /* + * As of binary version 108 Tecplot introduced + * the ability to output its auto-generated face + * neighbor array in its raw form. For now + * TecIO will always decline to perform this + * step and instead fall back to the delivering + * one neighbor at a time. + */ + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)0); /* IsRawFNAvailable */ + + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)NumFaceConnections[CurFile][CurZone[CurFile]]); + if (NumFaceConnections[CurFile][CurZone[CurFile]] > 0) + { + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)FaceNeighborMode[CurFile]); + if (ZoneType[CurFile] != ORDERED) + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)0); /* FEFaceNeighborsComplete */ + } + + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)IMax[CurFile]); + if (ZoneType[CurFile] == FEPOLYGON || + ZoneType[CurFile] == FEPOLYHEDRON) + { + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)KMax[CurFile]); + + /* + * As of binary version 111 these items moved from the data section to + * the header. + */ + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)TotalNumFaceNodes[CurFile][CurZone[CurFile]]); + if (TotalNumFaceBndryFaces[CurFile] > 0) + { + /* Each boundary face must have >= 1 boundary connection. */ + if (TotalNumFaceBndryConns[CurFile] < TotalNumFaceBndryFaces[CurFile]) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECZNE112) There must be at least 1 boundary connection for each boundary face in zone %d.\n", + CurZone[CurFile] + 1); + PRINT2(" %d boundary faces and %d boundary connections were specified.\n", + TotalNumFaceBndryFaces[CurFile], TotalNumFaceBndryConns[CurFile]); + #endif + NumErrs[CurFile]++; + return(-1); + } + + /* + * As a convenience for the ASCII format, TecUtil, and TECIO layers if any + * boundary connections exists we automatically add a no-neighboring + * connection as the first item so that they can user 0 for no-neighboring + * element in the element list regardless if they have boundary connections + * or not. + */ + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)TotalNumFaceBndryFaces[CurFile] + 1); /* ...add a boundary face for no neighboring element as a convenience */ + } + else + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)TotalNumFaceBndryFaces[CurFile]); + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)TotalNumFaceBndryConns[CurFile]); + } + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)JMax[CurFile]); + + if (ZoneType[CurFile] == ORDERED) + { + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)KMax[CurFile]); + } + else + { + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)ICellMax[CurFile]); + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)JCellMax[CurFile]); + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)KCellMax[CurFile]); + } + + /* + * Aux data. This has to be over-written by the aux data writing routine. + * Because it currently at the end of the header section we don't need to + * keep track of the position for seeking back to it. + */ + WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)0); + + WriteBinaryReal(BlckFile[CurFile], + (double)ZoneMarker, + FieldDataType_Float); + + for (I = 0; I < NumVars[CurFile]; I++) + { + if (!WriteFieldDataType(BlckFile[CurFile], + (FieldDataType_e)FieldDataType, + TRUE)) + { + WriteErr("TECZNE112"); + return (-1); + } + } + + /* Passive variable identification */ + if (PassiveVarList) + { + WriteBinaryInt32(BlckFile[CurFile], 1); + for (I = 0; I < NumVars[CurFile]; I++) + WriteBinaryInt32(BlckFile[CurFile], PassiveVarList[I]); + } + else + WriteBinaryInt32(BlckFile[CurFile], 0); + + /* get the CurVar[CurFile] on the first active variable */ + CurVar[CurFile] = -1; + AdvanceToNextVarWithValues(); + + /* Variable & Connectivity Sharing */ + if (ShareVarFromZone) + { + WriteBinaryInt32(BlckFile[CurFile], 1); + for (I = 0; I < NumVars[CurFile]; I++) + WriteBinaryInt32(BlckFile[CurFile], ShareVarFromZone[I] - 1); + } + else + WriteBinaryInt32(BlckFile[CurFile], 0); + WriteBinaryInt32(BlckFile[CurFile], *ShareConnectivityFromZone - 1); + + /* + * Create place holders or the variable min/max value. We will come back + * later after writing the data portion with the real min/max values. In the + * mean time, keep track of the starting point so we can seek back to this + * place. + */ + MinMaxOffset[CurFile][CurZone[CurFile]] = (FileOffset_t)TP_FTELL(BlckFile[CurFile]->File); + + for (I = 0; I < NumVars[CurFile]; I++) + { + /* initialize to unset values */ + VarMinValue[CurFile][I] = LARGEDOUBLE; + VarMaxValue[CurFile][I] = -LARGEDOUBLE; + + if (!IsSharedVar[CurFile][I] && !IsPassiveVar[CurFile][I]) + { + WriteBinaryReal(BlckFile[CurFile], 0.0, FieldDataType_Double); + WriteBinaryReal(BlckFile[CurFile], 0.0, FieldDataType_Double); + } + } + + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + { + PRINT1("Writing Zone %d:\n", CurZone[CurFile] + 1); + PRINT1(" Title = %s\n", ZnTitle); + PRINT1(" Type = %s\n", ZoneTypes[ZoneType[CurFile]]); + PRINT1(" IMax = %d\n", IMax[CurFile]); + PRINT1(" JMax = %d\n", JMax[CurFile]); + PRINT1(" KMax = %d\n", KMax[CurFile]); + if (ShareVarFromZone) + { + char DupList[1024] = ""; + + for (I = 0; I < NumVars[CurFile]; I++) + { + if (I > 0) + strcat(DupList, ","); + sprintf(&DupList[strlen(DupList)], "%d", ShareVarFromZone[I]); + } + PRINT1(" DupList = %s\n", DupList); + } + } + #endif + + return (0); +} + +INTEGER4 LIBCALL TECZNE111(char *ZnTitle, + INTEGER4 *ZnType, + INTEGER4 *IMxOrNumPts, + INTEGER4 *JMxOrNumElements, + INTEGER4 *KMxOrNumFaces, + INTEGER4 *ICellMx, + INTEGER4 *JCellMx, + INTEGER4 *KCellMx, + double *SolutionTime, + INTEGER4 *StrandID, + INTEGER4 *ParentZone, + INTEGER4 *IsBlk, + INTEGER4 *NumFaceConn, + INTEGER4 *FNMode, + INTEGER4 *NumFaceNodes, + INTEGER4 *NumFaceBndryFaces, + INTEGER4 *NumFaceBndryConns, + INTEGER4 *PassiveVarList, + INTEGER4 *ValueLocation, + INTEGER4 *ShareVarFromZone, + INTEGER4 *ShareConnectivityFromZone) +{ + return TECZNE112(ZnTitle, + ZnType, + IMxOrNumPts, + JMxOrNumElements, + KMxOrNumFaces, + ICellMx, + JCellMx, + KCellMx, + SolutionTime, + StrandID, + ParentZone, + IsBlk, + NumFaceConn, + FNMode, + NumFaceNodes, + NumFaceBndryFaces, + NumFaceBndryConns, + PassiveVarList, + ValueLocation, + ShareVarFromZone, + ShareConnectivityFromZone); +} + +INTEGER4 LIBCALL TECZNE110(char *ZnTitle, + INTEGER4 *ZnType, + INTEGER4 *IMxOrNumPts, + INTEGER4 *JMxOrNumElements, + INTEGER4 *KMx, + INTEGER4 *ICellMx, + INTEGER4 *JCellMx, + INTEGER4 *KCellMx, + double *SolutionTime, + INTEGER4 *StrandID, + INTEGER4 *ParentZone, + INTEGER4 *IsBlk, + INTEGER4 *NumFaceConn, + INTEGER4 *FNMode, + INTEGER4 *PassiveVarList, + INTEGER4 *ValueLocation, + INTEGER4 *ShareVarFromZone, + INTEGER4 *ShareConnectivityFromZone) +{ + INTEGER4 NumFaceNodes = 0; + INTEGER4 NumFaceBndryFaces = 0; + INTEGER4 NumFaceBndryConns = 0; + + return TECZNE112(ZnTitle, + ZnType, + IMxOrNumPts, + JMxOrNumElements, + KMx, + ICellMx, + JCellMx, + KCellMx, + SolutionTime, + StrandID, + ParentZone, + IsBlk, + NumFaceConn, + FNMode, + &NumFaceNodes, + &NumFaceBndryFaces, + &NumFaceBndryConns, + PassiveVarList, + ValueLocation, + ShareVarFromZone, + ShareConnectivityFromZone); +} + +INTEGER4 LIBCALL TECZNE100(char *ZnTitle, + INTEGER4 *ZnType, + INTEGER4 *IMxOrNumPts, + INTEGER4 *JMxOrNumElements, + INTEGER4 *KMx, + INTEGER4 *ICellMx, + INTEGER4 *JCellMx, + INTEGER4 *KCellMx, + INTEGER4 *IsBlk, + INTEGER4 *NumFaceConn, + INTEGER4 *FNMode, + INTEGER4 *ValueLocation, + INTEGER4 *ShareVarFromZone, + INTEGER4 *ShareConnectivityFromZone) +{ + double SolutionTime = 0.0; + INTEGER4 StrandID = STRAND_ID_STATIC + 1; /* TECXXX is ones based for StrandID */ + INTEGER4 ParentZone = BAD_SET_VALUE + 1; /* TECXXX is ones based for ParentZone */ + INTEGER4 NumFaceNodes = 0; + INTEGER4 NumFaceBndryFaces = 0; + INTEGER4 NumFaceBndryConns = 0; + + return TECZNE112(ZnTitle, + ZnType, + IMxOrNumPts, + JMxOrNumElements, + KMx, + ICellMx, + JCellMx, + KCellMx, + &SolutionTime, + &StrandID, + &ParentZone, + IsBlk, + NumFaceConn, + FNMode, + &NumFaceNodes, + &NumFaceBndryFaces, + &NumFaceBndryConns, + NULL, /* PassiveVarList */ + ValueLocation, + ShareVarFromZone, + ShareConnectivityFromZone); +} + +#if !defined INDEX_16_BIT // not supported in this test-only mode +INTEGER4 LIBCALL TECZNE(char *ZoneTitle, + INTEGER4 *IMx, + INTEGER4 *JMx, + INTEGER4 *KMx, + char *ZFormat, + char *DupList) +{ + + LgIndex_t ZoneType; + LgIndex_t IsBlock; + LgIndex_t *ShareVarFromZone = NULL; + LgIndex_t ShareConnectivityFromZone; + LgIndex_t Result = 0; + + + if (ZFormat == NULL) + Result = -1; + else if (!strcmp(ZFormat, "BLOCK")) + { + IsBlock = 1; + ZoneType = ZoneType_Ordered; + } + else if (!strcmp(ZFormat, "FEBLOCK")) + { + IsBlock = 1; + switch (*KMx) + { + /* + * From preplot.c: + * + * ZoneType 0=ORDERED,1=FELINESEG,2=FETRIANGLE, + * 3=FEQUADRILATERAL,4=FETETRAHEDRON,5=FEBRICK + */ + case 0: /* Triangular. */ + ZoneType = 2; + break; + case 1: /* Quadrilateral */ + ZoneType = 3; + break; + case 2: /* Tetrahedral */ + ZoneType = 4; + break; + case 3: /* Brick. */ + ZoneType = 5; + break; + } + } + else if (!strcmp(ZFormat, "POINT")) + { + IsBlock = 0; + ZoneType = ZoneType_Ordered; + } + else if (!strcmp(ZFormat, "FEPOINT")) + { + IsBlock = 0; + switch (*KMx) + { + case 0: /* Triangular. */ + ZoneType = 2; + break; + case 1: /* Quadrilateral */ + ZoneType = 3; + break; + case 2: /* Tetrahedral */ + ZoneType = 4; + break; + case 3: /* Brick. */ + ZoneType = 5; + break; + } + } + else + Result = -1; + + ShareConnectivityFromZone = 0; + + + if (Result == 0 && + DupList && + !ParseDupList(&ShareVarFromZone, &ShareConnectivityFromZone, DupList)) + { + Result = -1; + } + + /*Result = TECZNE((char *)ZoneTitle, IMx, JMx, KMx, (char *)ZFormat,(char*)DupList);*/ + if (Result == 0) + { + INTEGER4 ICellMx = 0; + INTEGER4 JCellMx = 0; + INTEGER4 KCellMx = 0; + INTEGER4 NumFaceConnections = 0; + INTEGER4 FaceNeighborMode = FaceNeighborMode_LocalOneToOne; + double SolutionTime = 0.0; + INTEGER4 StrandID = STRAND_ID_STATIC + 1; /* TECXXX is ones based for StrandID */ + INTEGER4 ParentZone = BAD_SET_VALUE + 1; /* TECXXX is ones based for ParentZone */ + INTEGER4 NumFaceNodes = 0; + INTEGER4 NumFaceBndryFaces = 0; + INTEGER4 NumFaceBndryConns = 0; + + Result = TECZNE112((char *)ZoneTitle, + &ZoneType, + IMx, + JMx, + KMx, + &ICellMx, + &JCellMx, + &KCellMx, + &SolutionTime, + &StrandID, + &ParentZone, + &IsBlock, + &NumFaceConnections, + &FaceNeighborMode, + &NumFaceNodes, + &NumFaceBndryFaces, + &NumFaceBndryConns, + NULL, /* PassiveVarList */ + NULL, /* ValueLocation */ + DupList ? ShareVarFromZone : NULL, + &ShareConnectivityFromZone); + TecXXXZoneNum++; + } + + if (ShareVarFromZone) + FREE_ARRAY(ShareVarFromZone, "Variable sharing list"); + + return (INTEGER4) Result; +} +#endif // INDEX_16_BIT -- not supported in this test-only mode + +#if defined MAKEARCHIVE && !defined _WIN32 /* every platform but Windows Intel */ +LIBFUNCTION INTEGER4 LIBCALL teczne112_(char *ZoneTitle, + INTEGER4 *ZnType, + INTEGER4 *IMxOrNumPts, + INTEGER4 *JMxOrNumElements, + INTEGER4 *KMx, + INTEGER4 *ICellMx, + INTEGER4 *JCellMx, + INTEGER4 *KCellMx, + double *SolutionTime, + INTEGER4 *StrandID, + INTEGER4 *ParentZone, + INTEGER4 *IsBlk, + INTEGER4 *NumFaceConn, + INTEGER4 *FNMode, + INTEGER4 *NumFaceNodes, + INTEGER4 *NumFaceBndryFaces, + INTEGER4 *NumFaceBndryConns, + INTEGER4 *PassiveVarList, + INTEGER4 *ValueLocation, + INTEGER4 *ShareVarFromZone, + INTEGER4 *ShareConnectivityFromZone) +{ + return TECZNE112(ZoneTitle, + ZnType, + IMxOrNumPts, + JMxOrNumElements, + KMx, + ICellMx, + JCellMx, + KCellMx, + SolutionTime, + StrandID, + ParentZone, + IsBlk, + NumFaceConn, + FNMode, + NumFaceNodes, + NumFaceBndryFaces, + NumFaceBndryConns, + PassiveVarList, + ValueLocation, + ShareVarFromZone, + ShareConnectivityFromZone); +} + +LIBFUNCTION INTEGER4 LIBCALL teczne111_(char *ZoneTitle, + INTEGER4 *ZnType, + INTEGER4 *IMxOrNumPts, + INTEGER4 *JMxOrNumElements, + INTEGER4 *KMx, + INTEGER4 *ICellMx, + INTEGER4 *JCellMx, + INTEGER4 *KCellMx, + double *SolutionTime, + INTEGER4 *StrandID, + INTEGER4 *ParentZone, + INTEGER4 *IsBlk, + INTEGER4 *NumFaceConn, + INTEGER4 *FNMode, + INTEGER4 *NumFaceNodes, + INTEGER4 *NumFaceBndryFaces, + INTEGER4 *NumFaceBndryConns, + INTEGER4 *PassiveVarList, + INTEGER4 *ValueLocation, + INTEGER4 *ShareVarFromZone, + INTEGER4 *ShareConnectivityFromZone) +{ + return TECZNE112(ZoneTitle, + ZnType, + IMxOrNumPts, + JMxOrNumElements, + KMx, + ICellMx, + JCellMx, + KCellMx, + SolutionTime, + StrandID, + ParentZone, + IsBlk, + NumFaceConn, + FNMode, + NumFaceNodes, + NumFaceBndryFaces, + NumFaceBndryConns, + PassiveVarList, + ValueLocation, + ShareVarFromZone, + ShareConnectivityFromZone); +} + +LIBFUNCTION INTEGER4 LIBCALL teczne110_(char *ZoneTitle, + INTEGER4 *ZnType, + INTEGER4 *IMxOrNumPts, + INTEGER4 *JMxOrNumElements, + INTEGER4 *KMx, + INTEGER4 *ICellMx, + INTEGER4 *JCellMx, + INTEGER4 *KCellMx, + double *SolutionTime, + INTEGER4 *StrandID, + INTEGER4 *ParentZone, + INTEGER4 *IsBlk, + INTEGER4 *NumFaceConn, + INTEGER4 *FNMode, + INTEGER4 *PassiveVarList, + INTEGER4 *ValueLocation, + INTEGER4 *ShareVarFromZone, + INTEGER4 *ShareConnectivityFromZone) +{ + INTEGER4 NumFaceNodes = 0; + INTEGER4 NumFaceBndryFaces = 0; + INTEGER4 NumFaceBndryConns = 0; + + return TECZNE112(ZoneTitle, + ZnType, + IMxOrNumPts, + JMxOrNumElements, + KMx, + ICellMx, + JCellMx, + KCellMx, + SolutionTime, + StrandID, + ParentZone, + IsBlk, + NumFaceConn, + FNMode, + &NumFaceNodes, + &NumFaceBndryFaces, + &NumFaceBndryConns, + PassiveVarList, + ValueLocation, + ShareVarFromZone, + ShareConnectivityFromZone); +} + +LIBFUNCTION INTEGER4 LIBCALL teczne100_(char *ZoneTitle, + INTEGER4 *ZnType, + INTEGER4 *IMxOrNumPts, + INTEGER4 *JMxOrNumElements, + INTEGER4 *KMx, + INTEGER4 *ICellMx, + INTEGER4 *JCellMx, + INTEGER4 *KCellMx, + INTEGER4 *IsBlk, + INTEGER4 *NumFaceConn, + INTEGER4 *FNMode, + INTEGER4 *ValueLocation, + INTEGER4 *ShareVarFromZone, + INTEGER4 *ShareConnectivityFromZone) +{ + return TECZNE100(ZoneTitle, + ZnType, + IMxOrNumPts, + JMxOrNumElements, + KMx, + ICellMx, + JCellMx, + KCellMx, + IsBlk, + NumFaceConn, + FNMode, + ValueLocation, + ShareVarFromZone, + ShareConnectivityFromZone); +} + +LIBFUNCTION INTEGER4 LIBCALL teczne_(char *ZoneTitle, + INTEGER4 *IMx, + INTEGER4 *JMx, + INTEGER4 *KMx, + char *ZFormat, + char *DupList) +{ + return TECZNE(ZoneTitle, + IMx, + JMx, + KMx, + ZFormat, + DupList); +} +#endif + +/** + * Rewrite the var min/max place holders which currently have zero in them. + */ +static void RewritePendingMinMaxValues(void) +{ + FileOffset_t CurrentOffset = (FileOffset_t)TP_FTELL(BlckFile[CurFile]->File); + + TP_FSEEK(BlckFile[CurFile]->File, MinMaxOffset[CurFile][CurZone[CurFile]], SEEK_SET); + int I; + for (I = 0; I < NumVars[CurFile]; I++) + { + if (!IsSharedVar[CurFile][I] && !IsPassiveVar[CurFile][I]) + { + WriteBinaryReal(BlckFile[CurFile], VarMinValue[CurFile][I], FieldDataType_Double); + WriteBinaryReal(BlckFile[CurFile], VarMaxValue[CurFile][I], FieldDataType_Double); + } + } + + /* return the original position */ + TP_FSEEK(BlckFile[CurFile]->File, CurrentOffset, SEEK_SET); +} + +/** + * TECDATXXX + */ +INTEGER4 LIBCALL TECDAT112(INTEGER4 *N, + void *Data, + INTEGER4 *IsDouble) +{ + LgIndex_t I; + double *dptr = (double *)Data; + float *fptr = (float *)Data; + + if (CheckFile("TECDAT112") < 0) + return (-1); + + #if defined MAKEARCHIVE + if (DebugLevel[CurFile] && (*N > 1)) + PRINT2("Writing %d values to file %d.\n", *N, CurFile + 1); + #endif + + for (I = 0; I < *N; I++) + { + double Value = (*IsDouble == 1 ? dptr[I] : fptr[I]); + + /* keep track of var min/max */ + if (Value < VarMinValue[CurFile][CurVar[CurFile]]) + VarMinValue[CurFile][CurVar[CurFile]] = Value; + if (Value > VarMaxValue[CurFile][CurVar[CurFile]]) + VarMaxValue[CurFile][CurVar[CurFile]] = Value; + + if (!WriteBinaryReal(BlckFile[CurFile], Value, (FieldDataType_e)FieldDataType)) + { + WriteErr("TECDAT112"); + return (-1); + } + + /* + * As of version 103 Tecplot writes binary data files so that the ordered + * cell centered field data includes the ghost cells. This makes it much + * easier for Tecplot to map the data when reading by simply writing out + * field data's as a block. As of version 104 the ghost cells of the + * slowest moving index are not included. + */ + if (IsCellCentered[CurFile][CurVar[CurFile]] && ZoneType[CurFile] == ORDERED) + { + CHECK(IsBlock[CurFile]); /* ...ordered CC data must be block format */ + LgIndex_t PIndex = (NumOrderedCCDataValuesWritten[CurFile]); + LgIndex_t FinalIMax = MAX(IMax[CurFile] - 1, 1); + LgIndex_t FinalJMax = MAX(JMax[CurFile] - 1, 1); + LgIndex_t FinalKMax = MAX(KMax[CurFile] - 1, 1); + LgIndex_t IIndex = (PIndex % IMax[CurFile]); + LgIndex_t JIndex = ((PIndex % (IMax[CurFile] * JMax[CurFile])) / IMax[CurFile]); + LgIndex_t KIndex = (PIndex / (IMax[CurFile] * JMax[CurFile])); + LgIndex_t IMaxAdjust = 0; + LgIndex_t JMaxAdjust = 0; + LgIndex_t KMaxAdjust = 0; + if (KMax[CurFile] > 1) + KMaxAdjust = 1; /* ...K is slowest */ + else if (JMax[CurFile] > 1) + JMaxAdjust = 1; /* ...J is slowest */ + else if (IMax[CurFile] > 1) + IMaxAdjust = 1; /* ...I is slowest */ + + if (IIndex + 1 == FinalIMax && FinalIMax < IMax[CurFile] - IMaxAdjust) + { + NumOrderedCCDataValuesWritten[CurFile]++; + if (!WriteBinaryReal(BlckFile[CurFile], 0.0, (FieldDataType_e)FieldDataType)) + { + WriteErr("TECDAT112"); + return (-1); + } + } + if (IIndex + 1 == FinalIMax && + (JIndex + 1 == FinalJMax && FinalJMax < JMax[CurFile] - JMaxAdjust)) + { + LgIndex_t II; + for (II = 1; II <= IMax[CurFile] - IMaxAdjust; II++) + { + NumOrderedCCDataValuesWritten[CurFile]++; + if (!WriteBinaryReal(BlckFile[CurFile], 0.0, (FieldDataType_e)FieldDataType)) + { + WriteErr("TECDAT112"); + return (-1); + } + } + } + if (IIndex + 1 == FinalIMax && + JIndex + 1 == FinalJMax && + (KIndex + 1 == FinalKMax && FinalKMax < KMax[CurFile] - KMaxAdjust)) + { + LgIndex_t JJ, II; + for (JJ = 1; JJ <= JMax[CurFile] - JMaxAdjust; JJ++) + for (II = 1; II <= IMax[CurFile] - IMaxAdjust; II++) + { + NumOrderedCCDataValuesWritten[CurFile]++; + if (!WriteBinaryReal(BlckFile[CurFile], 0.0, (FieldDataType_e)FieldDataType)) + { + WriteErr("TECDAT112"); + return (-1); + } + } + } + + /* increment for the original cell value */ + NumOrderedCCDataValuesWritten[CurFile]++; + } + + /* update the number of data points written */ + NumDataValuesWritten[CurFile]++; + + if (IsBlock[CurFile]) + { + /* for block format update the variable when all values have been given */ + if (NumRunningVarValues[CurFile][CurVar[CurFile]] == NumDataValuesWritten[CurFile]) + { + AdvanceToNextVarWithValues(); /* ...move on to the next variable */ + if (CurVar[CurFile] < NumVars[CurFile] && + IsCellCentered[CurFile][CurVar[CurFile]] && + ZoneType[CurFile] == ORDERED) + NumOrderedCCDataValuesWritten[CurFile] = 0; /* reset for next CC variable */ + } + } + else + { + /* for point format update the variable after each value */ + AdvanceToNextVarWithValues(); + if (CurVar[CurFile] >= NumVars[CurFile]) + { + /* reset to the first active variable */ + CurVar[CurFile] = -1; + AdvanceToNextVarWithValues(); + } + } + + #if defined MAKEARCHIVE + if (DebugLevel[CurFile] > 1) + PRINT2("%d %G\n", NumDataValuesWritten[CurFile] + I + 1, Value); + #endif + } + + /* + * If this is the last call to TECDAT112, + * then we may have to set the 'repeat adjacency list' + * flag in the file. + */ + if (HasFECONNECT[CurFile] && + + /* (essentialy this is CheckData() but we don't want to print + an error message) */ + (NumDataValuesToWrite[CurFile] == NumDataValuesWritten[CurFile])) + { + if (!WriteBinaryInt32(BlckFile[CurFile], (LgIndex_t)1)) + { + WriteErr("TECDAT112"); + return (-1); + } + } + + /* re-write min/max values when all data has been delivered */ + if (NumDataValuesToWrite[CurFile] == NumDataValuesWritten[CurFile]) + RewritePendingMinMaxValues(); + + return (0); +} + +INTEGER4 LIBCALL TECDAT111(INTEGER4 *N, + void *Data, + INTEGER4 *IsDouble) +{ + return TECDAT112(N, + Data, + IsDouble); +} + +INTEGER4 LIBCALL TECDAT110(INTEGER4 *N, + void *FieldData, + INTEGER4 *IsDouble) +{ + return TECDAT112(N, + FieldData, + IsDouble); +} + +INTEGER4 LIBCALL TECDAT100(INTEGER4 *N, + void *FieldData, + INTEGER4 *IsDouble) +{ + return TECDAT112(N, + FieldData, + IsDouble); +} + +INTEGER4 LIBCALL TECDAT(INTEGER4 *N, + void *FieldData, + INTEGER4 *IsDouble) +{ + return TECDAT112(N, + FieldData, + IsDouble); +} + +#if defined MAKEARCHIVE && !defined _WIN32 /* every platform but Windows Intel */ +LIBFUNCTION INTEGER4 LIBCALL tecdat112_(INTEGER4 *N, + void *Data, + INTEGER4 *IsDouble) +{ + return TECDAT112(N, Data, IsDouble); +} + +LIBFUNCTION INTEGER4 LIBCALL tecdat111_(INTEGER4 *N, + void *Data, + INTEGER4 *IsDouble) +{ + return TECDAT112(N, Data, IsDouble); +} + +LIBFUNCTION INTEGER4 LIBCALL tecdat110_(INTEGER4 *N, + void *Data, + INTEGER4 *IsDouble) +{ + return TECDAT112(N, Data, IsDouble); +} + +LIBFUNCTION INTEGER4 LIBCALL tecdat100_(INTEGER4 *N, + void *Data, + INTEGER4 *IsDouble) +{ + return TECDAT112(N, Data, IsDouble); +} + +LIBFUNCTION INTEGER4 LIBCALL tecdat_(INTEGER4 *N, + void *FieldData, + INTEGER4 *IsDouble) +{ + return TECDAT112(N, + FieldData, + IsDouble); +} +#endif + +/** + * TECNODXXX + */ +INTEGER4 LIBCALL TECNOD112(INTEGER4 *NData) +{ + LgIndex_t L = NumConnectivityNodes[CurFile][CurZone[CurFile]]; + LgIndex_t I; + + ConnectivityWritten[CurFile][CurZone[CurFile]] = TRUE; + + if (CheckFile("TECNOD112") < 0) + return (-1); + + if (ZoneType[CurFile] == FEPOLYGON || + ZoneType[CurFile] == FEPOLYHEDRON) + { + /* Wrong way to specify connectivity for polygons and polyhedrons */ + #if defined MAKEARCHIVE + PRINT0("Err: (TECNOD112) Cannot call TECNOD112 for polygonal or polyhedral zones.\n"); + #endif + NumErrs[CurFile]++; + return (-1); + } + + if (HasFECONNECT[CurFile]) + { + /* + * The connectivity list is duplicated, + * so we shouldn't be calling TECNOD112() + */ + return (-1); + } + + if (FileTypes[CurFile] == SOLUTIONFILE) + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECNOD112) Cannot call TECNOD112 if file type is SOLUTIONFILE.\n"); + #endif + NumErrs[CurFile]++; + return (-1); + } + + if (ZoneType[CurFile] == ORDERED) + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECNOD112) Cannot call TECNOD110 if zone type is ORDERED.\n"); + #endif + NumErrs[CurFile]++; + return (-1); + } + + if (CheckData("TECNOD112") < 0) + return (-1); + + for (I = 0; I < L; I++) + { + if ((NData[I] > IMax[CurFile]) || + (NData[I] < 1)) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECNOD112) Invalid node map value at position %d:\n", I); + PRINT2(" node map value = %d, max value = %d.\n", NData[I], IMax[CurFile]); + #endif + NumErrs[CurFile]++; + return (-1); + } + /* + * As of version 103 Tecplot assumes that node maps are zero based + * instead of ones based. Since we have to maintain the contract we + * subtract 1 for the caller. + */ + if (!WriteBinaryInt32(BlckFile[CurFile], NData[I] - 1)) /* zero based */ + { + WriteErr("TECNOD112"); + return (-1); + } + } + return (0); +} + +INTEGER4 LIBCALL TECNOD111(INTEGER4 *NData) +{ + return TECNOD112(NData); +} + +INTEGER4 LIBCALL TECNOD110(INTEGER4 *NData) +{ + return TECNOD112(NData); +} + +INTEGER4 LIBCALL TECNOD100(INTEGER4 *NData) +{ + return TECNOD112(NData); +} + +INTEGER4 LIBCALL TECNOD(INTEGER4 *NData) +{ + return TECNOD112(NData); +} + +#if defined MAKEARCHIVE && !defined _WIN32 /* every platform but Windows Intel */ +LIBFUNCTION INTEGER4 LIBCALL tecnod112_(INTEGER4 *NData) +{ + return TECNOD112(NData); +} + +LIBFUNCTION INTEGER4 LIBCALL tecnod111_(INTEGER4 *NData) +{ + return TECNOD112(NData); +} + +LIBFUNCTION INTEGER4 LIBCALL tecnod110_(INTEGER4 *NData) +{ + return TECNOD112(NData); +} + +LIBFUNCTION INTEGER4 LIBCALL tecnod100_(INTEGER4 *NData) +{ + return TECNOD112(NData); +} + +LIBFUNCTION INTEGER4 LIBCALL tecnod_(INTEGER4 *NData) +{ + return TECNOD112(NData); +} +#endif + +/** + * TECENDXXX + */ +INTEGER4 LIBCALL TECEND112(void) +{ + int RetVal = 0; + + /** + * Validate that all zone data was given for the file since there are no + * more chances to give it. Note that solution files don't define the + * connectivity again. + */ + if (FileTypes[CurFile] != SOLUTIONFILE) + { + for (int ZoneIndex = 0; (RetVal == 0) && (ZoneIndex <= CurZone[CurFile]); ZoneIndex++) + { + if (((NumConnectivityNodes[CurFile][ZoneIndex] > 0) && + (ConnectivityWritten[CurFile][ZoneIndex] == FALSE))) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECEND112) File %d is being closed without writing connectivity data.\n", CurFile + 1); + PRINT1(" Zone %d was defined with a Classic FE zone type but TECNOD112() was not called.\n", ZoneIndex + 1); + #endif + NumErrs[CurFile]++; + RetVal = -1; + } + if (((NumFaceConnections[CurFile][ZoneIndex] > 0) && + (FaceNeighborsOrMapWritten[CurFile][ZoneIndex] == FALSE))) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECEND112) File %d is being closed without writing face neighbor data.\n", CurFile + 1); + PRINT2(" %d connections were specified for zone %d but TECFACE112() was not called.\n", + NumFaceConnections[CurFile][ZoneIndex], ZoneIndex + 1); + #endif + NumErrs[CurFile]++; + RetVal = -1; + } + else if (((TotalNumFaceNodes[CurFile][ZoneIndex] > 0) && + (FaceNeighborsOrMapWritten[CurFile][ZoneIndex] == FALSE))) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECEND112) File %d is being closed without writing face map data.\n", CurFile + 1); + PRINT2(" %d face nodes were specified for zone %d but TECPOLY112() was not called.\n", + TotalNumFaceNodes[CurFile][ZoneIndex], ZoneIndex + 1); + #endif + NumErrs[CurFile]++; + RetVal = -1; + } + } + } + + if (RetVal == 0) + { + if (CheckFile("TECEND112") < 0) + RetVal = -1; + } + + if (RetVal == 0) + { + if (CheckData("TECEND112") < 0) + RetVal = -1; + } + + if (RetVal == 0) + if (!WriteBinaryReal(HeadFile[CurFile], EndHeaderMarker, FieldDataType_Float)) + { + WriteErr("TECEND112"); + RetVal = -1; + } + + CloseFileStream(&BlckFile[CurFile]); + + if (RetVal == 0) + { + BlckFile[CurFile] = OpenFileStream(BlckFName[CurFile], "rb", IsWritingNative[CurFile]); + + /* Append data from BlckFile to HeadFile... */ + char buffer[BYTES_PER_CHUNK]; + size_t bytesRead = 0; + while ((RetVal == 0) && + (feof(BlckFile[CurFile]->File) == 0)) + { + bytesRead = fread((void*)buffer, 1, BYTES_PER_CHUNK, BlckFile[CurFile]->File); + if (ferror(BlckFile[CurFile]->File) == 0) + { + if (bytesRead != fwrite((void*)buffer, 1, bytesRead, HeadFile[CurFile]->File)) + { + /* do not call WriteErr, use custom message instead */ + #if defined MAKEARCHIVE + PRINT1("Err: (TECEND112) Write failure during repack on file %d.\n", CurFile + 1); + #endif + NumErrs[CurFile]++; + RetVal = -1; + } + } + else + { + /* do not call WriteErr, use custom message instead */ + #if defined MAKEARCHIVE + PRINT1("Err: (TECEND112) Write failure during repack on file %d.\n", CurFile + 1); + #endif + NumErrs[CurFile]++; + RetVal = -1; + } + } + CloseFileStream(&BlckFile[CurFile]); + } + + TP_UNLINK(BlckFName[CurFile]); + + CloseFileStream(&HeadFile[CurFile]); + + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + { + PRINT1("File %d closed.\n", CurFile + 1); + if (NumErrs[CurFile]) + { + PRINT0("********************************************\n"); + PRINT1(" %d Errors occurred on this file\n", NumErrs[CurFile]); + PRINT0("********************************************\n"); + } + } + #endif + + NumErrs[CurFile] = 0; + IsOpen[CurFile] = 0; + if (DestFName[CurFile]) + FREE_ARRAY(DestFName[CurFile], "data set fname"); + if (BlckFName[CurFile]) + FREE_ARRAY(BlckFName[CurFile], "data set fname"); + BlckFName[CurFile] = NULL; + DestFName[CurFile] = NULL; + + /* reset arrays sized by number of variables */ + VarMinValue[CurFile].clear(); + VarMaxValue[CurFile].clear(); + NumRunningVarValues[CurFile].clear(); + IsSharedVar[CurFile].clear(); + IsPassiveVar[CurFile].clear(); + IsCellCentered[CurFile].clear(); + + /* reset arrays sized by number of zones */ + MinMaxOffset[CurFile].clear(); + TotalNumFaceNodes[CurFile].clear(); + NumFaceConnections[CurFile].clear(); + FaceNeighborsOrMapWritten[CurFile].clear(); + NumConnectivityNodes[CurFile].clear(); + ConnectivityWritten[CurFile].clear(); + + CurFile = 0; + while ((CurFile < MaxNumFiles) && !IsOpen[CurFile]) + CurFile++; + + if (CurFile == MaxNumFiles) + CurFile = -1; + + return RetVal; +} + +INTEGER4 LIBCALL TECEND111(void) +{ + return TECEND112(); +} + +INTEGER4 LIBCALL TECEND110(void) +{ + return TECEND112(); +} + +INTEGER4 LIBCALL TECEND100(void) +{ + return TECEND112(); +} + +INTEGER4 LIBCALL TECEND(void) +{ + return TECEND112(); +} + +#if defined MAKEARCHIVE && !defined _WIN32 /* every platform but Windows Intel */ +LIBFUNCTION INTEGER4 LIBCALL tecend112_(void) +{ + return TECEND112(); +} + +LIBFUNCTION INTEGER4 LIBCALL tecend111_(void) +{ + return TECEND112(); +} + +LIBFUNCTION INTEGER4 LIBCALL tecend110_(void) +{ + return TECEND112(); +} + +LIBFUNCTION INTEGER4 LIBCALL tecend100_(void) +{ + return TECEND112(); +} + +LIBFUNCTION INTEGER4 LIBCALL tecend_(void) +{ + return TECEND112(); +} +#endif + + + + +static void GetNextLabel(const char **CPtr, + char *NextLabel) +{ + int N = 0; + char *NPtr = NextLabel; + *NPtr = '\0'; + /* Find label start */ + while ((**CPtr) && (**CPtr != '"')) + (*CPtr)++; + if (**CPtr) + (*CPtr)++; + while ((N < 60) && (**CPtr) && (**CPtr != '"')) + { + if (**CPtr == '\\') + { + (*CPtr)++; + } + *NPtr++ = **CPtr; + N++; + (*CPtr)++; + } + if (**CPtr) + (*CPtr)++; + *NPtr = '\0'; +} + + +/** + * TECLABXXX + */ +INTEGER4 LIBCALL TECLAB112(char *S) +{ + const char *CPtr = (const char *)S; + LgIndex_t N = 0; + char Label[60]; + + if (CheckFile("TECLAB112") < 0) + return (-1); + + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + PRINT0("\nInserting Custom Labels:\n"); + #endif + + do + { + GetNextLabel(&CPtr, Label); + if (*Label) + N++; + } + while (*Label); + + if (N == 0) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECLAB112) Invalid custom label string: %s\n", + (S ? S : " ")); + #endif + NumErrs[CurFile]++; + return (-1); + } + + WriteBinaryReal(HeadFile[CurFile], CustomLabelMarker, FieldDataType_Float); + if (!WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)N)) + { + WriteErr("TECLAB112"); + return (-1); + } + + CPtr = (const char *)S; + do + { + GetNextLabel(&CPtr, Label); + if (*Label) + { + if (!DumpDatafileString(HeadFile[CurFile], Label, TRUE)) + { + WriteErr("TECLAB112"); + return (-1); + } + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + printf(" %s\n", Label); + #endif + } + } + while (*Label); + + return (0); +} + +INTEGER4 LIBCALL TECLAB111(char *S) +{ + return TECLAB112(S); +} + +INTEGER4 LIBCALL TECLAB110(char *S) +{ + return TECLAB112(S); +} + +INTEGER4 LIBCALL TECLAB100(char *S) +{ + return TECLAB112(S); +} + +INTEGER4 LIBCALL TECLAB(char *S) +{ + return TECLAB112(S); +} + +#if defined MAKEARCHIVE && !defined _WIN32 /* every platform but Windows Intel */ +LIBFUNCTION INTEGER4 LIBCALL teclab112_(char *S) +{ + return TECLAB112(S); +} + +LIBFUNCTION INTEGER4 LIBCALL teclab111_(char *S) +{ + return TECLAB112(S); +} + +LIBFUNCTION INTEGER4 LIBCALL teclab110_(char *S) +{ + return TECLAB112(S); +} + +LIBFUNCTION INTEGER4 LIBCALL teclab100_(char *S) +{ + return TECLAB112(S); +} + +LIBFUNCTION INTEGER4 LIBCALL teclab_(char *S) +{ + return TECLAB112(S); +} +#endif + + +/** + * TECUSRXXX + */ +INTEGER4 LIBCALL TECUSR112(char *S) +{ + if (CheckFile("TECUSR112") < 0) + return (-1); + + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + PRINT1("\nInserting UserRec: %s\n", S); + #endif + + if ((S == NULL) || (*S == '\0')) + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECUSR112) Invalid TECUSR110 string\n"); + #endif + NumErrs[CurFile]++; + return (-1); + } + + WriteBinaryReal(HeadFile[CurFile], UserRecMarker, FieldDataType_Float); + if (!DumpDatafileString(HeadFile[CurFile], S, TRUE)) + { + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + printf("Err: (TECUSR112) Write failure for file %d\n", CurFile + 1); + #endif + NumErrs[CurFile]++; + return (-1); + } + return (0); +} + +INTEGER4 LIBCALL TECUSR111(char *S) +{ + return TECUSR112(S); +} + +INTEGER4 LIBCALL TECUSR110(char *S) +{ + return TECUSR112(S); +} + +INTEGER4 LIBCALL TECUSR100(char *S) +{ + return TECUSR112(S); +} + +INTEGER4 LIBCALL TECUSR(char *S) +{ + return TECUSR112(S); +} + +#if defined MAKEARCHIVE && !defined _WIN32 /* every platform but Windows Intel */ +LIBFUNCTION INTEGER4 LIBCALL tecusr112_(char *S) +{ + return TECUSR112(S); +} + +LIBFUNCTION INTEGER4 LIBCALL tecusr111_(char *S) +{ + return TECUSR112(S); +} + +LIBFUNCTION INTEGER4 LIBCALL tecusr110_(char *S) +{ + return TECUSR112(S); +} + +LIBFUNCTION INTEGER4 LIBCALL tecusr100_(char *S) +{ + return TECUSR112(S); +} + +LIBFUNCTION INTEGER4 LIBCALL tecusr_(char *S) +{ + return TECUSR112(S); +} +#endif + +#if 0 // NOT_CURRENTLY_USED +static int WriteGeomDataBlock(float *Data, + LgIndex_t NumPts) +{ + LgIndex_t I; + + for (I = 0; I < NumPts; I++) + { + if (!WriteBinaryReal(HeadFile[CurFile], Data[I], FieldDataType_Float)) + { + return (-1); + } + } + return (0); +} + + +static void ShowDebugColor(LgIndex_t Color) +{ + #if defined MAKEARCHIVE + switch (Color) + { + case 0 : PRINT0("BLACK\n"); break; + case 1 : PRINT0("RED\n"); break; + case 2 : PRINT0("GREEN\n"); break; + case 3 : PRINT0("BLUE\n"); break; + case 4 : PRINT0("CYAN\n"); break; + case 5 : PRINT0("YELLOW\n"); break; + case 6 : PRINT0("PURPLE\n"); break; + case 7 : PRINT0("WHITE\n"); break; + case 8 : + case 9 : + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: PRINT1("CUSTOM%1d\n", Color-7); break; + default : PRINT0("INVALID\n"); + } + #endif +} +#endif /* NOT_CURRENTLY_USED */ + + +/** + * TECGEOXXX + */ +INTEGER4 LIBCALL TECGEO112(double *XOrThetaPos, + double *YOrRPos, + double *ZPos, + INTEGER4 *PosCoordMode, /* 0=Grid, 1=Frame, 3=Grid3D */ + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *Color, + INTEGER4 *FillColor, + INTEGER4 *IsFilled, + INTEGER4 *GeomType, + INTEGER4 *LinePattern, + double *PatternLength, + double *LineThickness, + INTEGER4 *NumEllipsePts, + INTEGER4 *ArrowheadStyle, + INTEGER4 *ArrowheadAttachment, + double *ArrowheadSize, + double *ArrowheadAngle, + INTEGER4 *Scope, + INTEGER4 *Clipping, + INTEGER4 *NumSegments, + INTEGER4 *NumSegPts, + float *XOrThetaGeomData, + float *YOrRGeomData, + float *ZGeomData, + char *mfc) +{ + int I, RetVal; + int RawDataSize = 0; + double Fract; + + Geom_s Geom; + + if (CheckFile("TECGEO112") < 0) + return (-1); + + Geom.PositionCoordSys = (CoordSys_e) * PosCoordMode; + if (Geom.PositionCoordSys == CoordSys_Frame) + Fract = 0.01; + else + Fract = 1.0; + + Geom.AnchorPos.Generic.V1 = (*XOrThetaPos) * Fract; + Geom.AnchorPos.Generic.V2 = (*YOrRPos) * Fract; + Geom.AnchorPos.Generic.V3 = (*ZPos) * Fract; + Geom.AttachToZone = *AttachToZone != 0; + Geom.Zone = *Zone - 1; + Geom.BColor = (ColorIndex_t) * Color; + Geom.FillBColor = (ColorIndex_t) * FillColor; + Geom.IsFilled = *IsFilled; + Geom.GeomType = (GeomType_e) * GeomType; + Geom.LinePattern = (LinePattern_e) * LinePattern; + Geom.PatternLength = *PatternLength / 100.0; + Geom.LineThickness = *LineThickness / 100.0; + Geom.NumEllipsePts = *NumEllipsePts; + Geom.ArrowheadStyle = (ArrowheadStyle_e) * ArrowheadStyle; + Geom.ArrowheadAttachment = (ArrowheadAttachment_e) * ArrowheadAttachment; + Geom.ArrowheadSize = *ArrowheadSize / 100.0; + Geom.ArrowheadAngle = *ArrowheadAngle / DEGPERRADIANS; + Geom.Scope = (Scope_e) * Scope; + Geom.DrawOrder = DrawOrder_AfterData; + Geom.Clipping = (Clipping_e) * Clipping; + Geom.NumSegments = *NumSegments; + Geom.MacroFunctionCommand = mfc; + Geom.ImageFileName = NULL; + Geom.ImageNumber = 0; + Geom.MaintainAspectRatio = TRUE; + Geom.PixelAspectRatio = 1.0; + Geom.ImageResizeFilter = ImageResizeFilter_Texture; + + if (Geom.GeomType == GeomType_LineSegs3D) + { + Geom.GeomType = GeomType_LineSegs; + Geom.PositionCoordSys = CoordSys_Grid3D; + } + + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + PRINT0("\nInserting Geometry\n"); + #endif + + switch (Geom.GeomType) + { + case GeomType_LineSegs : + { + int I; + RawDataSize = 0; + for (I = 0; I < *NumSegments; I++) + { + Geom.NumSegPts[I] = NumSegPts[I]; + RawDataSize += NumSegPts[I]; + } + } break; + case GeomType_Rectangle : + case GeomType_Square : + case GeomType_Circle : + case GeomType_Ellipse : + { + RawDataSize = 1; + } break; + case GeomType_Image : + { + CHECK(FALSE); /* Images not allowed in data files. */ + } break; + default : + { + CHECK(FALSE); + } break; + } + + Geom.DataType = FieldDataType_Float; + Geom.GeomData.Generic.V1Base = AllocScratchNodalFieldDataPtr(RawDataSize, FieldDataType_Float, TRUE); + Geom.GeomData.Generic.V2Base = AllocScratchNodalFieldDataPtr(RawDataSize, FieldDataType_Float, TRUE); + Geom.GeomData.Generic.V3Base = AllocScratchNodalFieldDataPtr(RawDataSize, FieldDataType_Float, TRUE); + + for (I = 0; I < RawDataSize; I++) + { + SetFieldValue(Geom.GeomData.Generic.V1Base, I, (double)XOrThetaGeomData[I]*Fract); + SetFieldValue(Geom.GeomData.Generic.V2Base, I, (double)YOrRGeomData[I]*Fract); + SetFieldValue(Geom.GeomData.Generic.V3Base, I, (double)ZGeomData[I]*Fract); + } + + if (DumpGeometry(HeadFile[CurFile], &Geom, TRUE, FALSE)) + RetVal = 0; + else + RetVal = -1; + + DeallocScratchNodalFieldDataPtr(&Geom.GeomData.Generic.V1Base); + DeallocScratchNodalFieldDataPtr(&Geom.GeomData.Generic.V2Base); + DeallocScratchNodalFieldDataPtr(&Geom.GeomData.Generic.V3Base); + + return RetVal; +} + +INTEGER4 LIBCALL TECGEO111(double *XOrThetaPos, + double *YOrRPos, + double *ZPos, + INTEGER4 *PosCoordMode, /* 0=Grid, 1=Frame, 3=Grid3D */ + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *Color, + INTEGER4 *FillColor, + INTEGER4 *IsFilled, + INTEGER4 *GeomType, + INTEGER4 *LinePattern, + double *PatternLength, + double *LineThickness, + INTEGER4 *NumEllipsePts, + INTEGER4 *ArrowheadStyle, + INTEGER4 *ArrowheadAttachment, + double *ArrowheadSize, + double *ArrowheadAngle, + INTEGER4 *Scope, + INTEGER4 *Clipping, + INTEGER4 *NumSegments, + INTEGER4 *NumSegPts, + float *XOrThetaGeomData, + float *YOrRGeomData, + float *ZGeomData, + char *mfc) +{ + return TECGEO112(XOrThetaPos, + YOrRPos, + ZPos, + PosCoordMode, + AttachToZone, + Zone, + Color, + FillColor, + IsFilled, + GeomType, + LinePattern, + PatternLength, + LineThickness, + NumEllipsePts, + ArrowheadStyle, + ArrowheadAttachment, + ArrowheadSize, + ArrowheadAngle, + Scope, + Clipping, + NumSegments, + NumSegPts, + XOrThetaGeomData, + YOrRGeomData, + ZGeomData, + mfc); +} + +INTEGER4 LIBCALL TECGEO110(double *XOrThetaPos, + double *YOrRPos, + double *ZPos, + INTEGER4 *PosCoordMode, /* 0=Grid, 1=Frame, 3=Grid3D */ + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *Color, + INTEGER4 *FillColor, + INTEGER4 *IsFilled, + INTEGER4 *GeomType, + INTEGER4 *LinePattern, + double *PatternLength, + double *LineThickness, + INTEGER4 *NumEllipsePts, + INTEGER4 *ArrowheadStyle, + INTEGER4 *ArrowheadAttachment, + double *ArrowheadSize, + double *ArrowheadAngle, + INTEGER4 *Scope, + INTEGER4 *Clipping, + INTEGER4 *NumSegments, + INTEGER4 *NumSegPts, + float *XOrThetaGeomData, + float *YOrRGeomData, + float *ZGeomData, + char *mfc) +{ + return TECGEO112(XOrThetaPos, + YOrRPos, + ZPos, + PosCoordMode, + AttachToZone, + Zone, + Color, + FillColor, + IsFilled, + GeomType, + LinePattern, + PatternLength, + LineThickness, + NumEllipsePts, + ArrowheadStyle, + ArrowheadAttachment, + ArrowheadSize, + ArrowheadAngle, + Scope, + Clipping, + NumSegments, + NumSegPts, + XOrThetaGeomData, + YOrRGeomData, + ZGeomData, + mfc); +} + +INTEGER4 LIBCALL TECGEO100(double *XOrThetaPos, + double *YOrRPos, + double *ZPos, + INTEGER4 *PosCoordMode, /* 0=Grid, 1=Frame, 3=Grid3D */ + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *Color, + INTEGER4 *FillColor, + INTEGER4 *IsFilled, + INTEGER4 *GeomType, + INTEGER4 *LinePattern, + double *PatternLength, + double *LineThickness, + INTEGER4 *NumEllipsePts, + INTEGER4 *ArrowheadStyle, + INTEGER4 *ArrowheadAttachment, + double *ArrowheadSize, + double *ArrowheadAngle, + INTEGER4 *Scope, + INTEGER4 *Clipping, + INTEGER4 *NumSegments, + INTEGER4 *NumSegPts, + float *XOrThetaGeomData, + float *YOrRGeomData, + float *ZGeomData, + char *mfc) +{ + return TECGEO112(XOrThetaPos, + YOrRPos, + ZPos, + PosCoordMode, + AttachToZone, + Zone, + Color, + FillColor, + IsFilled, + GeomType, + LinePattern, + PatternLength, + LineThickness, + NumEllipsePts, + ArrowheadStyle, + ArrowheadAttachment, + ArrowheadSize, + ArrowheadAngle, + Scope, + Clipping, + NumSegments, + NumSegPts, + XOrThetaGeomData, + YOrRGeomData, + ZGeomData, + mfc); +} + +INTEGER4 LIBCALL TECGEO(double *XPos, + double *YPos, + double *ZPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *Color, + INTEGER4 *FillColor, + INTEGER4 *IsFilled, + INTEGER4 *GeomType, + INTEGER4 *LinePattern, + double *PatternLength, + double *LineThickness, + INTEGER4 *NumEllipsePts, + INTEGER4 *ArrowheadStyle, + INTEGER4 *ArrowheadAttachment, + double *ArrowheadSize, + double *ArrowheadAngle, + INTEGER4 *Scope, + INTEGER4 *NumSegments, + INTEGER4 *NumSegPts, + float *XGeomData, + float *YGeomData, + float *ZGeomData, + char *mfc) +{ + int Clipping = (int)Clipping_ClipToViewport; + return TECGEO112(XPos, + YPos, + ZPos, + PosCoordMode, + AttachToZone, + Zone, + Color, + FillColor, + IsFilled, + GeomType, + LinePattern, + PatternLength, + LineThickness, + NumEllipsePts, + ArrowheadStyle, + ArrowheadAttachment, + ArrowheadSize, + ArrowheadAngle, + Scope, + &Clipping, + NumSegments, + NumSegPts, + XGeomData, + YGeomData, + ZGeomData, + mfc); +} + +#if defined MAKEARCHIVE && !defined _WIN32 /* every platform but Windows Intel */ +LIBFUNCTION INTEGER4 LIBCALL tecgeo112_(double *XPos, + double *YPos, + double *ZPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *Color, + INTEGER4 *FillColor, + INTEGER4 *IsFilled, + INTEGER4 *GeomType, + INTEGER4 *LinePattern, + double *PatternLength, + double *LineThickness, + INTEGER4 *NumEllipsePts, + INTEGER4 *ArrowheadStyle, + INTEGER4 *ArrowheadAttachment, + double *ArrowheadSize, + double *ArrowheadAngle, + INTEGER4 *Scope, + INTEGER4 *Clipping, + INTEGER4 *NumSegments, + INTEGER4 *NumSegPts, + float *XGeomData, + float *YGeomData, + float *ZGeomData, + char *mfc) +{ + return TECGEO112(XPos, + YPos, + ZPos, + PosCoordMode, + AttachToZone, + Zone, + Color, + FillColor, + IsFilled, + GeomType, + LinePattern, + PatternLength, + LineThickness, + NumEllipsePts, + ArrowheadStyle, + ArrowheadAttachment, + ArrowheadSize, + ArrowheadAngle, + Scope, + Clipping, + NumSegments, + NumSegPts, + XGeomData, + YGeomData, + ZGeomData, + mfc); +} + +LIBFUNCTION INTEGER4 LIBCALL tecgeo111_(double *XPos, + double *YPos, + double *ZPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *Color, + INTEGER4 *FillColor, + INTEGER4 *IsFilled, + INTEGER4 *GeomType, + INTEGER4 *LinePattern, + double *PatternLength, + double *LineThickness, + INTEGER4 *NumEllipsePts, + INTEGER4 *ArrowheadStyle, + INTEGER4 *ArrowheadAttachment, + double *ArrowheadSize, + double *ArrowheadAngle, + INTEGER4 *Scope, + INTEGER4 *Clipping, + INTEGER4 *NumSegments, + INTEGER4 *NumSegPts, + float *XGeomData, + float *YGeomData, + float *ZGeomData, + char *mfc) +{ + return TECGEO112(XPos, + YPos, + ZPos, + PosCoordMode, + AttachToZone, + Zone, + Color, + FillColor, + IsFilled, + GeomType, + LinePattern, + PatternLength, + LineThickness, + NumEllipsePts, + ArrowheadStyle, + ArrowheadAttachment, + ArrowheadSize, + ArrowheadAngle, + Scope, + Clipping, + NumSegments, + NumSegPts, + XGeomData, + YGeomData, + ZGeomData, + mfc); +} + +LIBFUNCTION INTEGER4 LIBCALL tecgeo110_(double *XPos, + double *YPos, + double *ZPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *Color, + INTEGER4 *FillColor, + INTEGER4 *IsFilled, + INTEGER4 *GeomType, + INTEGER4 *LinePattern, + double *PatternLength, + double *LineThickness, + INTEGER4 *NumEllipsePts, + INTEGER4 *ArrowheadStyle, + INTEGER4 *ArrowheadAttachment, + double *ArrowheadSize, + double *ArrowheadAngle, + INTEGER4 *Scope, + INTEGER4 *Clipping, + INTEGER4 *NumSegments, + INTEGER4 *NumSegPts, + float *XGeomData, + float *YGeomData, + float *ZGeomData, + char *mfc) +{ + return TECGEO112(XPos, + YPos, + ZPos, + PosCoordMode, + AttachToZone, + Zone, + Color, + FillColor, + IsFilled, + GeomType, + LinePattern, + PatternLength, + LineThickness, + NumEllipsePts, + ArrowheadStyle, + ArrowheadAttachment, + ArrowheadSize, + ArrowheadAngle, + Scope, + Clipping, + NumSegments, + NumSegPts, + XGeomData, + YGeomData, + ZGeomData, + mfc); +} + +LIBFUNCTION INTEGER4 LIBCALL tecgeo100_(double *XPos, + double *YPos, + double *ZPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *Color, + INTEGER4 *FillColor, + INTEGER4 *IsFilled, + INTEGER4 *GeomType, + INTEGER4 *LinePattern, + double *PatternLength, + double *LineThickness, + INTEGER4 *NumEllipsePts, + INTEGER4 *ArrowheadStyle, + INTEGER4 *ArrowheadAttachment, + double *ArrowheadSize, + double *ArrowheadAngle, + INTEGER4 *Scope, + INTEGER4 *Clipping, + INTEGER4 *NumSegments, + INTEGER4 *NumSegPts, + float *XGeomData, + float *YGeomData, + float *ZGeomData, + char *mfc) +{ + return TECGEO112(XPos, + YPos, + ZPos, + PosCoordMode, + AttachToZone, + Zone, + Color, + FillColor, + IsFilled, + GeomType, + LinePattern, + PatternLength, + LineThickness, + NumEllipsePts, + ArrowheadStyle, + ArrowheadAttachment, + ArrowheadSize, + ArrowheadAngle, + Scope, + Clipping, + NumSegments, + NumSegPts, + XGeomData, + YGeomData, + ZGeomData, + mfc); +} + +LIBFUNCTION INTEGER4 LIBCALL tecgeo_(double *XPos, + double *YPos, + double *ZPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *Color, + INTEGER4 *FillColor, + INTEGER4 *IsFilled, + INTEGER4 *GeomType, + INTEGER4 *LinePattern, + double *PatternLength, + double *LineThickness, + INTEGER4 *NumEllipsePts, + INTEGER4 *ArrowheadStyle, + INTEGER4 *ArrowheadAttachment, + double *ArrowheadSize, + double *ArrowheadAngle, + INTEGER4 *Scope, + INTEGER4 *NumSegments, + INTEGER4 *NumSegPts, + float *XGeomData, + float *YGeomData, + float *ZGeomData, + char *mfc) +{ + return TECGEO(XPos, + YPos, + ZPos, + PosCoordMode, + AttachToZone, + Zone, + Color, + FillColor, + IsFilled, + GeomType, + LinePattern, + PatternLength, + LineThickness, + NumEllipsePts, + ArrowheadStyle, + ArrowheadAttachment, + ArrowheadSize, + ArrowheadAngle, + Scope, + NumSegments, + NumSegPts, + XGeomData, + YGeomData, + ZGeomData, + mfc); +} +#endif + +/** + * TECTXTXXX + */ +INTEGER4 LIBCALL TECTXT112(double *XOrThetaPos, + double *YOrRPos, + double *ZOrUnusedPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *BFont, + INTEGER4 *FontHeightUnits, + double *FontHeight, + INTEGER4 *BoxType, + double *BoxMargin, + double *BoxLineThickness, + INTEGER4 *BoxColor, + INTEGER4 *BoxFillColor, + double *Angle, + INTEGER4 *Anchor, + double *LineSpacing, + INTEGER4 *TextColor, + INTEGER4 *Scope, + INTEGER4 *Clipping, + char *String, + char *mfc) +{ + int RetVal; + Text_s Text; + double Fract; + if (CheckFile("TECTXT112") < 0) + return (-1); + + Text.PositionCoordSys = (CoordSys_e) * PosCoordMode; + if (Text.PositionCoordSys == CoordSys_Frame) + Fract = 0.01; + else + Fract = 1.0; + + Text.AnchorPos.Generic.V1 = (*XOrThetaPos) * Fract; + Text.AnchorPos.Generic.V2 = (*YOrRPos) * Fract; + Text.AnchorPos.Generic.V3 = (*ZOrUnusedPos) * Fract; + Text.AttachToZone = *AttachToZone != 0; + Text.Zone = *Zone - 1; + Text.BColor = (ColorIndex_t) * TextColor; + Text.TextShape.Font = (Font_e) * BFont; + Text.TextShape.SizeUnits = (Units_e) * FontHeightUnits; + if (Text.TextShape.SizeUnits == Units_Frame) + Text.TextShape.Height = (*FontHeight) / 100.0; + else + Text.TextShape.Height = *FontHeight; + Text.Box.BoxType = (TextBox_e) * BoxType; + Text.Box.Margin = *BoxMargin / 100.0; + Text.Box.LineThickness = *BoxLineThickness / 100.0; + Text.Box.BColor = (ColorIndex_t) * BoxColor; + Text.Box.FillBColor = (ColorIndex_t) * BoxFillColor; + Text.Anchor = (TextAnchor_e) * Anchor; + Text.LineSpacing = *LineSpacing; + Text.Angle = *Angle / DEGPERRADIANS; + Text.Scope = (Scope_e) * Scope; + Text.Text = String; + Text.MacroFunctionCommand = mfc; + Text.Clipping = (Clipping_e) * Clipping; + + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + PRINT1("\nInserting Text: %s\n", String); + #endif + + if (DumpText(HeadFile[CurFile], &Text, TRUE, FALSE)) + RetVal = 0; + else + RetVal = -1; + + return RetVal; +} + +INTEGER4 LIBCALL TECTXT111(double *XOrThetaPos, + double *YOrRPos, + double *ZOrUnusedPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *BFont, + INTEGER4 *FontHeightUnits, + double *FontHeight, + INTEGER4 *BoxType, + double *BoxMargin, + double *BoxLineThickness, + INTEGER4 *BoxColor, + INTEGER4 *BoxFillColor, + double *Angle, + INTEGER4 *Anchor, + double *LineSpacing, + INTEGER4 *TextColor, + INTEGER4 *Scope, + INTEGER4 *Clipping, + char *String, + char *mfc) +{ + return TECTXT112(XOrThetaPos, + YOrRPos, + ZOrUnusedPos, + PosCoordMode, + AttachToZone, + Zone, + BFont, + FontHeightUnits, + FontHeight, + BoxType, + BoxMargin, + BoxLineThickness, + BoxColor, + BoxFillColor, + Angle, + Anchor, + LineSpacing, + TextColor, + Scope, + Clipping, + String, + mfc); +} + +INTEGER4 LIBCALL TECTXT110(double *XOrThetaPos, + double *YOrRPos, + double *ZOrUnusedPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *BFont, + INTEGER4 *FontHeightUnits, + double *FontHeight, + INTEGER4 *BoxType, + double *BoxMargin, + double *BoxLineThickness, + INTEGER4 *BoxColor, + INTEGER4 *BoxFillColor, + double *Angle, + INTEGER4 *Anchor, + double *LineSpacing, + INTEGER4 *TextColor, + INTEGER4 *Scope, + INTEGER4 *Clipping, + char *String, + char *mfc) +{ + return TECTXT112(XOrThetaPos, + YOrRPos, + ZOrUnusedPos, + PosCoordMode, + AttachToZone, + Zone, + BFont, + FontHeightUnits, + FontHeight, + BoxType, + BoxMargin, + BoxLineThickness, + BoxColor, + BoxFillColor, + Angle, + Anchor, + LineSpacing, + TextColor, + Scope, + Clipping, + String, + mfc); +} + +INTEGER4 LIBCALL TECTXT100(double *XOrThetaPos, + double *YOrRPos, + double *ZOrUnusedPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *BFont, + INTEGER4 *FontHeightUnits, + double *FontHeight, + INTEGER4 *BoxType, + double *BoxMargin, + double *BoxLineThickness, + INTEGER4 *BoxColor, + INTEGER4 *BoxFillColor, + double *Angle, + INTEGER4 *Anchor, + double *LineSpacing, + INTEGER4 *TextColor, + INTEGER4 *Scope, + INTEGER4 *Clipping, + char *String, + char *mfc) +{ + return TECTXT112(XOrThetaPos, + YOrRPos, + ZOrUnusedPos, + PosCoordMode, + AttachToZone, + Zone, + BFont, + FontHeightUnits, + FontHeight, + BoxType, + BoxMargin, + BoxLineThickness, + BoxColor, + BoxFillColor, + Angle, + Anchor, + LineSpacing, + TextColor, + Scope, + Clipping, + String, + mfc); +} + +INTEGER4 LIBCALL TECTXT(double *XPos, + double *YPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *BFont, + INTEGER4 *FontHeightUnits, + double *FontHeight, + INTEGER4 *BoxType, + double *BoxMargin, + double *BoxLineThickness, + INTEGER4 *BoxColor, + INTEGER4 *BoxFillColor, + double *Angle, + INTEGER4 *Anchor, + double *LineSpacing, + INTEGER4 *TextColor, + INTEGER4 *Scope, + char *Text, + char *mfc) +{ + double ZPos = 0.0; + int Clipping = (int)Clipping_ClipToViewport; + return TECTXT112(XPos, + YPos, + &ZPos, + PosCoordMode, + AttachToZone, + Zone, + BFont, + FontHeightUnits, + FontHeight, + BoxType, + BoxMargin, + BoxLineThickness, + BoxColor, + BoxFillColor, + Angle, + Anchor, + LineSpacing, + TextColor, + Scope, + &Clipping, + Text, + mfc); +} + +#if defined MAKEARCHIVE && !defined _WIN32 /* every platform but Windows Intel */ +LIBFUNCTION INTEGER4 LIBCALL tectxt112_(double *XOrThetaPos, + double *YOrRPos, + double *ZOrUnusedPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *BFont, + INTEGER4 *FontHeightUnits, + double *FontHeight, + INTEGER4 *BoxType, + double *BoxMargin, + double *BoxLineThickness, + INTEGER4 *BoxColor, + INTEGER4 *BoxFillColor, + double *Angle, + INTEGER4 *Anchor, + double *LineSpacing, + INTEGER4 *TextColor, + INTEGER4 *Scope, + INTEGER4 *Clipping, + char *String, + char *mfc) +{ + return TECTXT112(XOrThetaPos, + YOrRPos, + ZOrUnusedPos, + PosCoordMode, + AttachToZone, + Zone, + BFont, + FontHeightUnits, + FontHeight, + BoxType, + BoxMargin, + BoxLineThickness, + BoxColor, + BoxFillColor, + Angle, + Anchor, + LineSpacing, + TextColor, + Scope, + Clipping, + String, + mfc); +} + +LIBFUNCTION INTEGER4 LIBCALL tectxt111_(double *XOrThetaPos, + double *YOrRPos, + double *ZOrUnusedPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *BFont, + INTEGER4 *FontHeightUnits, + double *FontHeight, + INTEGER4 *BoxType, + double *BoxMargin, + double *BoxLineThickness, + INTEGER4 *BoxColor, + INTEGER4 *BoxFillColor, + double *Angle, + INTEGER4 *Anchor, + double *LineSpacing, + INTEGER4 *TextColor, + INTEGER4 *Scope, + INTEGER4 *Clipping, + char *String, + char *mfc) +{ + return TECTXT112(XOrThetaPos, + YOrRPos, + ZOrUnusedPos, + PosCoordMode, + AttachToZone, + Zone, + BFont, + FontHeightUnits, + FontHeight, + BoxType, + BoxMargin, + BoxLineThickness, + BoxColor, + BoxFillColor, + Angle, + Anchor, + LineSpacing, + TextColor, + Scope, + Clipping, + String, + mfc); +} + +LIBFUNCTION INTEGER4 LIBCALL tectxt110_(double *XOrThetaPos, + double *YOrRPos, + double *ZOrUnusedPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *BFont, + INTEGER4 *FontHeightUnits, + double *FontHeight, + INTEGER4 *BoxType, + double *BoxMargin, + double *BoxLineThickness, + INTEGER4 *BoxColor, + INTEGER4 *BoxFillColor, + double *Angle, + INTEGER4 *Anchor, + double *LineSpacing, + INTEGER4 *TextColor, + INTEGER4 *Scope, + INTEGER4 *Clipping, + char *String, + char *mfc) +{ + return TECTXT112(XOrThetaPos, + YOrRPos, + ZOrUnusedPos, + PosCoordMode, + AttachToZone, + Zone, + BFont, + FontHeightUnits, + FontHeight, + BoxType, + BoxMargin, + BoxLineThickness, + BoxColor, + BoxFillColor, + Angle, + Anchor, + LineSpacing, + TextColor, + Scope, + Clipping, + String, + mfc); +} + +LIBFUNCTION INTEGER4 LIBCALL tectxt100_(double *XOrThetaPos, + double *YOrRPos, + double *ZOrUnusedPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *BFont, + INTEGER4 *FontHeightUnits, + double *FontHeight, + INTEGER4 *BoxType, + double *BoxMargin, + double *BoxLineThickness, + INTEGER4 *BoxColor, + INTEGER4 *BoxFillColor, + double *Angle, + INTEGER4 *Anchor, + double *LineSpacing, + INTEGER4 *TextColor, + INTEGER4 *Scope, + INTEGER4 *Clipping, + char *String, + char *mfc) +{ + return TECTXT112(XOrThetaPos, + YOrRPos, + ZOrUnusedPos, + PosCoordMode, + AttachToZone, + Zone, + BFont, + FontHeightUnits, + FontHeight, + BoxType, + BoxMargin, + BoxLineThickness, + BoxColor, + BoxFillColor, + Angle, + Anchor, + LineSpacing, + TextColor, + Scope, + Clipping, + String, + mfc); +} + +LIBFUNCTION INTEGER4 LIBCALL tectxt_(double *XPos, + double *YPos, + INTEGER4 *PosCoordMode, + INTEGER4 *AttachToZone, + INTEGER4 *Zone, + INTEGER4 *BFont, + INTEGER4 *FontHeightUnits, + double *FontHeight, + INTEGER4 *BoxType, + double *BoxMargin, + double *BoxLineThickness, + INTEGER4 *BoxColor, + INTEGER4 *BoxFillColor, + double *Angle, + INTEGER4 *Anchor, + double *LineSpacing, + INTEGER4 *TextColor, + INTEGER4 *Scope, + char *Text, + char *mfc) +{ + return TECTXT(XPos, + YPos, + PosCoordMode, + AttachToZone, + Zone, + BFont, + FontHeightUnits, + FontHeight, + BoxType, + BoxMargin, + BoxLineThickness, + BoxColor, + BoxFillColor, + Angle, + Anchor, + LineSpacing, + TextColor, + Scope, + Text, + mfc); +} +#endif + + +/** + * TECFILXXX + */ +INTEGER4 LIBCALL TECFIL112(INTEGER4 *F) +{ + if ((*F < 1) || (*F > MaxNumFiles)) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECFIL112) Invalid file number requested (%d). File not changed.\n", *F); + #endif + return (-1); + } + + if (!IsOpen[*F-1]) + { + #if defined MAKEARCHIVE + int I; + PRINT1("Err: (TECFIL112) file %d is not open. File not changed.\n", *F); + PRINT0("\n\nFile states are:\n"); + for (I = 0; I < MaxNumFiles; I++) + PRINT2("file %d, IsOpen=%d\n", I + 1, IsOpen[I]); + PRINT1("Current File is: %d\n", CurFile + 1); + #endif + return (-1); + } + CurFile = *F - 1; + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + { + PRINT1("Switching to file #%d\n\n", CurFile + 1); + PRINT0("Current State is:\n"); + PRINT1(" Debug = %d\n", DebugLevel[CurFile]); + PRINT1(" NumVars = %d\n", NumVars[CurFile]); + PRINT1(" DestFName = %s\n", DestFName[CurFile]); + PRINT1(" BlckFName = %s\n", BlckFName[CurFile]); + PRINT1(" ZoneType = %s\n", ZoneTypes[ZoneType[CurFile]]); + + if (ZoneType[CurFile] == ORDERED) + { + PRINT1(" IMax = %d\n", IMax[CurFile]); + PRINT1(" JMax = %d\n", JMax[CurFile]); + PRINT1(" KMax = %d\n", KMax[CurFile]); + } + else + { + PRINT1(" NumPoints = %d\n", IMax[CurFile]); + PRINT1(" NumElmnts = %d\n", JMax[CurFile]); + } + PRINT1(" NumDataValuesWritten = %d\n", NumDataValuesWritten[CurFile]); + PRINT1(" CurZone = %d\n", CurZone[CurFile] + 1); + } + #endif /* MAKEARCHIVE */ + return (0); +} + +INTEGER4 LIBCALL TECFIL111(INTEGER4 *F) +{ + return TECFIL112(F); +} + +INTEGER4 LIBCALL TECFIL110(INTEGER4 *F) +{ + return TECFIL112(F); +} + +INTEGER4 LIBCALL TECFIL100(INTEGER4 *F) +{ + return TECFIL112(F); +} + +INTEGER4 LIBCALL TECFIL(INTEGER4 *F) +{ + return TECFIL112(F); +} + +#if defined MAKEARCHIVE && !defined _WIN32 /* every platform but Windows Intel */ +LIBFUNCTION INTEGER4 LIBCALL tecfil112_(INTEGER4 *F) +{ + return TECFIL112(F); +} + +LIBFUNCTION INTEGER4 LIBCALL tecfil111_(INTEGER4 *F) +{ + return TECFIL112(F); +} + +LIBFUNCTION INTEGER4 LIBCALL tecfil110_(INTEGER4 *F) +{ + return TECFIL112(F); +} + +LIBFUNCTION INTEGER4 LIBCALL tecfil100_(INTEGER4 *F) +{ + return TECFIL112(F); +} + +LIBFUNCTION INTEGER4 LIBCALL tecfil_(INTEGER4 *F) +{ + return TECFIL112(F); +} +#endif + +/** + * TECFOREIGNXXX + */ +void LIBCALL TECFOREIGN112(INTEGER4 *OutputForeignByteOrder) +{ + REQUIRE(VALID_REF(OutputForeignByteOrder)); + + DoWriteForeign = (*OutputForeignByteOrder != 0); +} + +void LIBCALL TECFOREIGN111(INTEGER4 *OutputForeignByteOrder) +{ + TECFOREIGN112(OutputForeignByteOrder); +} + +void LIBCALL TECFOREIGN110(INTEGER4 *OutputForeignByteOrder) +{ + TECFOREIGN112(OutputForeignByteOrder); +} + +void LIBCALL TECFOREIGN100(INTEGER4 *OutputForeignByteOrder) +{ + TECFOREIGN112(OutputForeignByteOrder); +} + +#if defined MAKEARCHIVE && !defined _WIN32 /* every platform but Windows Intel */ +LIBFUNCTION void LIBCALL tecforeign112_(INTEGER4 *OutputForeignByteOrder) +{ + TECFOREIGN112(OutputForeignByteOrder); +} + +LIBFUNCTION void LIBCALL tecforeign111_(INTEGER4 *OutputForeignByteOrder) +{ + TECFOREIGN112(OutputForeignByteOrder); +} + +LIBFUNCTION void LIBCALL tecforeign110_(INTEGER4 *OutputForeignByteOrder) +{ + TECFOREIGN112(OutputForeignByteOrder); +} + +LIBFUNCTION void LIBCALL tecforeign100_(INTEGER4 *OutputForeignByteOrder) +{ + TECFOREIGN112(OutputForeignByteOrder); +} +#endif + +#if defined MAKEARCHIVE + +/** + * A valid auxiliary data name character must begin with a '_' or alpha + * character and may be followed by one or more '_', '.', alpha or digit + * characters. + */ +static Boolean_t AuxDataIsValidNameChar(char Char, + Boolean_t IsLeadChar) +{ + Boolean_t IsValidNameChar; + + REQUIRE(0 <= Char && "Char <= 127"); + REQUIRE(VALID_BOOLEAN(IsLeadChar)); + + IsValidNameChar = (Char == '_' || + isalpha(Char)); + if (!IsLeadChar) + IsValidNameChar = (IsValidNameChar || + Char == '.' || + isdigit(Char)); + + ENSURE(VALID_BOOLEAN(IsValidNameChar)); + return IsValidNameChar; +} + +/** + * Indicates if the auxiliary data name is valid. A valid auxiliary data name + * must begin with a '_' or alpha character and may be followed by one or + * more '_', '.', alpha or digit characters. + */ +static Boolean_t AuxDataIsValidName(const char *Name) +{ + Boolean_t IsValidName; + const char *NPtr; + REQUIRE(VALID_REF(Name)); + + for (NPtr = Name, IsValidName = AuxDataIsValidNameChar(*NPtr, TRUE); + IsValidName && *NPtr != '\0'; + NPtr++) + { + IsValidName = AuxDataIsValidNameChar(*NPtr, FALSE); + } + + ENSURE(VALID_BOOLEAN(IsValidName)); + return IsValidName; +} + +#endif /* MAKEARCHIVE */ + +/** + * TECAUXSTRXXX + */ +LIBFUNCTION INTEGER4 LIBCALL TECAUXSTR112(char *Name, + char *Value) +{ + if (CheckFile("TECAUXSTR112") < 0) + return (-1); + + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + PRINT2("\nInserting data set aux data: '%s' = '%s'\n", Name, Value); + #endif + + if ((Name == NULL) || !AuxDataIsValidName(Name)) + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECAUXSTR112) Invalid Name string\n"); + #endif + NumErrs[CurFile]++; + return (-1); + } + + if ((Value == NULL) || (*Value == '\0')) + { + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + PRINT0("Err: (TECAUXSTR112) Invalid Value string\n"); + #endif + NumErrs[CurFile]++; + return (-1); + } + + /* + * Because the auxiliary data is at the end of the header section we don't + * need to seek back to it. + */ + if (!WriteBinaryReal(HeadFile[CurFile], DataSetAuxMarker, FieldDataType_Float) || + !DumpDatafileString(HeadFile[CurFile], Name, TRUE /* WriteBinary */) || + !WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)AuxDataType_String) || + !DumpDatafileString(HeadFile[CurFile], (const char *)Value, TRUE /* WriteBinary */)) + { + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + printf("Err: (TECAUXSTR112) Write failure for file %d\n", CurFile + 1); + #endif + NumErrs[CurFile]++; + return (-1); + } + return (0); +} + +LIBFUNCTION INTEGER4 LIBCALL TECAUXSTR111(char *Name, + char *Value) +{ + return TECAUXSTR112(Name, Value); +} + +LIBFUNCTION INTEGER4 LIBCALL TECAUXSTR110(char *Name, + char *Value) +{ + return TECAUXSTR112(Name, Value); +} + +LIBFUNCTION INTEGER4 LIBCALL TECAUXSTR100(char *Name, + char *Value) +{ + return TECAUXSTR112(Name, Value); +} + +#if defined MAKEARCHIVE && !defined _WIN32 /* every platform but Windows Intel */ +LIBFUNCTION INTEGER4 LIBCALL tecauxstr112_(char *Name, + char *Value) +{ + return TECAUXSTR112(Name, Value); +} + +LIBFUNCTION INTEGER4 LIBCALL tecauxstr111_(char *Name, + char *Value) +{ + return TECAUXSTR112(Name, Value); +} + +LIBFUNCTION INTEGER4 LIBCALL tecauxstr110_(char *Name, + char *Value) +{ + return TECAUXSTR112(Name, Value); +} + +LIBFUNCTION INTEGER4 LIBCALL tecauxstr100_(char *Name, + char *Value) +{ + return TECAUXSTR112(Name, Value); +} +#endif + + +/** + * TECZAUXSTRXXX + */ +LIBFUNCTION INTEGER4 LIBCALL TECZAUXSTR112(char *Name, + char *Value) +{ + if (CheckFile("TECZAUXSTR112") < 0) + return (-1); + + if (CurZone[CurFile] == -1) + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECZAUXSTR112) Must call TECZNE112 prior to TECZAUXSTR112\n"); + #endif + NumErrs[CurFile]++; + return (-1); + } + + + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + PRINT2("\nInserting zone aux data: '%s' = '%s'\n", Name, Value); + #endif + + if ((Name == NULL) || !AuxDataIsValidName(Name)) + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECZAUXSTR112) Invalid Name string\n"); + #endif + NumErrs[CurFile]++; + return (-1); + } + + if ((Value == NULL) || (*Value == '\0')) + { + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + PRINT0("Err: (TECZAUXSTR112) Invalid Value string\n"); + #endif + NumErrs[CurFile]++; + return (-1); + } + + /* + * Have to back over the 0 already written, then write another one afterward. + */ + if (TP_FSEEK(HeadFile[CurFile]->File, -4, SEEK_CUR) || + !WriteBinaryInt32(HeadFile[CurFile], 1) || + !DumpDatafileString(HeadFile[CurFile], Name, TRUE /* WriteBinary */) || + !WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)AuxDataType_String) || + !DumpDatafileString(HeadFile[CurFile], (const char *)Value, TRUE /* WriteBinary */) || + !WriteBinaryInt32(HeadFile[CurFile], 0)) + { + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + printf("Err: (TECZAUXSTR112) Write failure for file %d\n", CurFile + 1); + #endif + NumErrs[CurFile]++; + return (-1); + } + + return (0); +} + +LIBFUNCTION INTEGER4 LIBCALL TECZAUXSTR111(char *Name, + char *Value) +{ + return TECZAUXSTR112(Name, Value); +} + +LIBFUNCTION INTEGER4 LIBCALL TECZAUXSTR110(char *Name, + char *Value) +{ + return TECZAUXSTR112(Name, Value); +} + +LIBFUNCTION INTEGER4 LIBCALL TECZAUXSTR100(char *Name, + char *Value) +{ + return TECZAUXSTR112(Name, Value); +} + +#if defined MAKEARCHIVE && !defined _WIN32 /* every platform but Windows Intel */ +LIBFUNCTION INTEGER4 LIBCALL teczauxstr112_(char *Name, + char *Value) +{ + return TECZAUXSTR112(Name, Value); +} + +LIBFUNCTION INTEGER4 LIBCALL teczauxstr111_(char *Name, + char *Value) +{ + return TECZAUXSTR112(Name, Value); +} + +LIBFUNCTION INTEGER4 LIBCALL teczauxstr110_(char *Name, + char *Value) +{ + return TECZAUXSTR112(Name, Value); +} + +LIBFUNCTION INTEGER4 LIBCALL teczauxstr100_(char *Name, + char *Value) +{ + return TECZAUXSTR112(Name, Value); +} +#endif + + +/** + * TECVAUXSTRXXX + */ +LIBFUNCTION INTEGER4 LIBCALL TECVAUXSTR112(INTEGER4 *Var, + char *Name, + char *Value) +{ + if (CheckFile("TECVAUXSTR112") < 0) + return (-1); + + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + PRINT2("\nInserting variable aux data: '%s' = '%s'\n", Name, Value); + #endif + + if ((Name == NULL) || !AuxDataIsValidName(Name)) + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECVAUXSTR112) Invalid Name string\n"); + #endif + NumErrs[CurFile]++; + return (-1); + } + + if ((Value == NULL) || (*Value == '\0')) + { + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + PRINT0("Err: (TECVAUXSTR112) Invalid Value string\n"); + #endif + NumErrs[CurFile]++; + return (-1); + } + + if (!WriteBinaryReal(HeadFile[CurFile], VarAuxMarker, FieldDataType_Float) || + !WriteBinaryInt32(HeadFile[CurFile], *Var - 1) || + !DumpDatafileString(HeadFile[CurFile], Name, TRUE /* WriteBinary */) || + !WriteBinaryInt32(HeadFile[CurFile], (LgIndex_t)AuxDataType_String) || + !DumpDatafileString(HeadFile[CurFile], (const char *)Value, TRUE /* WriteBinary */)) + { + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + printf("Err: (TECVAUXSTR112) Write failure for file %d\n", CurFile + 1); + #endif + NumErrs[CurFile]++; + return (-1); + } + + return (0); +} + +LIBFUNCTION INTEGER4 LIBCALL TECVAUXSTR111(INTEGER4 *Var, + char *Name, + char *Value) +{ + return TECVAUXSTR112(Var, Name, Value); +} + +LIBFUNCTION INTEGER4 LIBCALL TECVAUXSTR110(INTEGER4 *Var, + char *Name, + char *Value) +{ + return TECVAUXSTR112(Var, Name, Value); +} + +LIBFUNCTION INTEGER4 LIBCALL TECVAUXSTR100(INTEGER4 *Var, + char *Name, + char *Value) +{ + return TECVAUXSTR112(Var, Name, Value); +} + +#if defined MAKEARCHIVE && !defined _WIN32 /* every platform but Windows Intel */ +LIBFUNCTION INTEGER4 LIBCALL tecvauxstr112_(INTEGER4 *Var, + char *Name, + char *Value) +{ + return TECVAUXSTR112(Var, Name, Value); +} + +LIBFUNCTION INTEGER4 LIBCALL tecvauxstr111_(INTEGER4 *Var, + char *Name, + char *Value) +{ + return TECVAUXSTR112(Var, Name, Value); +} + +LIBFUNCTION INTEGER4 LIBCALL tecvauxstr110_(INTEGER4 *Var, + char *Name, + char *Value) +{ + return TECVAUXSTR112(Var, Name, Value); +} + +LIBFUNCTION INTEGER4 LIBCALL tecvauxstr100_(INTEGER4 *Var, + char *Name, + char *Value) +{ + return TECVAUXSTR112(Var, Name, Value); +} +#endif + + +/** + * TECFACEXXX + */ +LIBFUNCTION INTEGER4 LIBCALL TECFACE112(INTEGER4 *FaceConnections) +{ + INTEGER4 i, *Ptr; + + /* Mark that the face neighbors have been written for the zone even if it fails so as not to add extra error messages. */ + FaceNeighborsOrMapWritten[CurFile][CurZone[CurFile]] = TRUE; + + if (CheckFile("TECFACE112") < 0) + return (-1); + + if (ZoneType[CurFile] == FEPOLYGON || + ZoneType[CurFile] == FEPOLYHEDRON) + { + /* Wrong way to specify face neighbors for polygons and polyhedrons */ + #if defined MAKEARCHIVE + PRINT0("Err: (TECFACE112) Cannot call TECFACE112 for polygonal or polyhedral zones.\n"); + #endif + NumErrs[CurFile]++; + return (-1); + } + + if (FileTypes[CurFile] == SOLUTIONFILE) + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECFACE112) Cannot call TECFACE112 if the file type is SOLUTIONFILE.\n"); + #endif + NumErrs[CurFile]++; + return (-1); + } + + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + PRINT0("\nInserting face neighbor data\n"); + #endif + + if (FaceConnections == NULL) + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECFACE112) Invalid array\n"); + #endif + NumErrs[CurFile]++; + return (-1); + } + + /* + * Face neighbor connection have the following format for both + * binary: + * + * LOCALONETOONE 3 cz,fz,cz + * LOCALONETOMANY nz+4 cz,fz,oz,nz,cz1,cz2,...,czn + * GLOBALONETOONE 4 cz,fz,ZZ,CZ + * 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 + * + * NOTE: + * As of version 103 Tecplot assumes that face neighbors are zero based + * instead of ones based. Since we have to maintain the contract we + * subtract 1 for the caller. + */ + Ptr = FaceConnections; + i = 0; + while (i < NumFaceConnections[CurFile][CurZone[CurFile]]) + { + INTEGER4 n; + INTEGER4 NumNum = 0; + + switch (FaceNeighborMode[CurFile]) + { + case FaceNeighborMode_LocalOneToOne: + NumNum = 3; + i++; + break; + case FaceNeighborMode_LocalOneToMany: + NumNum = 4 + Ptr[3]; + i += Ptr[3]; + break; + case FaceNeighborMode_GlobalOneToOne: + NumNum = 4; + i++; + break; + case FaceNeighborMode_GlobalOneToMany: + NumNum = 4 + 2 * Ptr[3]; + i += Ptr[3]; + break; + default: + CHECK(FALSE); + break; + } + + n = 0; + if (FaceNeighborMode[CurFile] == FaceNeighborMode_LocalOneToMany || + FaceNeighborMode[CurFile] == FaceNeighborMode_GlobalOneToMany) + { + /* + * Write cz,fz,oz,nz: we do this by hand because the oz and nz values + * are not zero based values. + */ + if (!WriteBinaryInt32(BlckFile[CurFile], Ptr[n++] - 1) || /* zero based as of version 103 */ + !WriteBinaryInt32(BlckFile[CurFile], Ptr[n++] - 1) || /* zero based as of version 103 */ + !WriteBinaryInt32(BlckFile[CurFile], Ptr[n++]) || /* ones based */ + !WriteBinaryInt32(BlckFile[CurFile], Ptr[n++])) /* ones based */ + { + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + printf("Err: (TECFACE112) Write failure for file %d\n", CurFile + 1); + #endif + NumErrs[CurFile]++; + return (-1); + } + + } + /* starting from where we left off, output the remaining values */ + for (; n < NumNum; n++) + if (!WriteBinaryInt32(BlckFile[CurFile], Ptr[n] - 1)) /* zero based as of version 103 */ + { + #if defined MAKEARCHIVE + if (DebugLevel[CurFile]) + printf("Err: (TECFACE112) Write failure for file %d\n", CurFile + 1); + #endif + NumErrs[CurFile]++; + return (-1); + } + Ptr += NumNum; + } + + return (0); +} + +LIBFUNCTION INTEGER4 LIBCALL TECFACE111(INTEGER4 *FaceConnections) +{ + return TECFACE112(FaceConnections); +} + +LIBFUNCTION INTEGER4 LIBCALL TECFACE110(INTEGER4 *FaceConnections) +{ + return TECFACE112(FaceConnections); +} + +LIBFUNCTION INTEGER4 LIBCALL TECFACE100(INTEGER4 *FaceConnections) +{ + return TECFACE112(FaceConnections); +} + +#if defined MAKEARCHIVE && !defined _WIN32 /* every platform but Windows Intel */ +LIBFUNCTION INTEGER4 LIBCALL tecface112_(INTEGER4 *FaceConnections) +{ + return TECFACE112(FaceConnections); +} + +LIBFUNCTION INTEGER4 LIBCALL tecface111_(INTEGER4 *FaceConnections) +{ + return TECFACE112(FaceConnections); +} + +LIBFUNCTION INTEGER4 LIBCALL tecface110_(INTEGER4 *FaceConnections) +{ + return TECFACE112(FaceConnections); +} + +LIBFUNCTION INTEGER4 LIBCALL tecface100_(INTEGER4 *FaceConnections) +{ + return TECFACE112(FaceConnections); +} +#endif + + +/** + * TECPOLYXXX + */ +LIBFUNCTION INTEGER4 LIBCALL TECPOLY112(INTEGER4 *FaceNodeCounts, + INTEGER4 *FaceNodes, + INTEGER4 *FaceLeftElems, + INTEGER4 *FaceRightElems, + INTEGER4 *FaceBndryConnectionCounts, + INTEGER4 *FaceBndryConnectionElems, + INTEGER4 *FaceBndryConnectionZones) +{ + INTEGER4 NumFaces = KMax[CurFile]; + INTEGER4 Result = 0; + LgIndex_t Index; + LgIndex_t MinNeighborValue = TECIO_NO_NEIGHBORING_ELEM; + + /* Mark that the face map has been written for the zone even if it fails so as not to add extra error messages. */ + FaceNeighborsOrMapWritten[CurFile][CurZone[CurFile]] = TRUE; + + if (NumFaces == 0 || + (ZoneType[CurFile] != FEPOLYGON && + ZoneType[CurFile] != FEPOLYHEDRON)) + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECPOLY112) The zone type must be FEPOLYGON or FEPOLYHEDRON and have NumFaces (KMax) > 0.\n"); + PRINT1(" NumFaces = %d\n", NumFaces); + #endif + NumErrs[CurFile]++; + return (-1); + } + + if (ZoneType[CurFile] == FEPOLYHEDRON) /* FEPOLYGON doesn't need TotalNumFaceNodes since this is 2*NumFaces */ + { + if (TotalNumFaceNodes[CurFile][CurZone[CurFile]] <= 0) + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECPOLY112) TotalNumFaceNodes MUST be specified for polyhedral zones.\n"); + PRINT1(" TotalNumFaceNodes = %d\n", TotalNumFaceNodes[CurFile][CurZone[CurFile]]); + #endif + NumErrs[CurFile]++; + return (-1); + } + } + else + { + if (TotalNumFaceNodes[CurFile][CurZone[CurFile]] != (2 * NumFaces)) + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECPOLY112) TotalNumFaceNodes is specified for the polygonal zone but is not equal to 2 * NumFaces.\n"); + PRINT2(" TotalNumFaceNodes = %d. If specified, it must be 2 * %d.", TotalNumFaceNodes[CurFile][CurZone[CurFile]], NumFaces); + #endif + NumErrs[CurFile]++; + return (-1); + } + } + + if ((TotalNumFaceBndryFaces[CurFile] > 0 && + TotalNumFaceBndryConns[CurFile] > 0) || + (TotalNumFaceBndryFaces[CurFile] == 0 && + TotalNumFaceBndryConns[CurFile] == 0)) + { + if (TotalNumFaceBndryFaces[CurFile] > 0) + MinNeighborValue = -TotalNumFaceBndryFaces[CurFile]; + } + else + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECPOLY112) TotalNumFaceBndryFaces and TotalNumFaceBndryConns must both be 0 or both be > 0.\n"); + PRINT2(" TotalNumFaceBndryFaces = %d, TotalNumFaceBndryConns = %d\n", TotalNumFaceBndryFaces[CurFile], TotalNumFaceBndryConns[CurFile]); + #endif + NumErrs[CurFile]++; + return (-1); + } + + /* Write the facenodesoffsets array from the facenodecounts array. */ + if (Result == 0) + { + if (ZoneType[CurFile] == FEPOLYHEDRON) /* FEPOLYGON doesn't need to specify facenodesoffsets */ + { + Int32_t FaceNodeSum = 0; + if (!WriteBinaryInt32(BlckFile[CurFile], 0)) + Result = -1; + for (Index = 0; (Result == 0) && (Index < NumFaces); Index++) + { + FaceNodeSum += FaceNodeCounts[Index]; + if (FaceNodeCounts[Index] < 3) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECPOLY112) Invalid face node count value at face %d. There must be at least 3 nodes in a face.\n", Index + 1); + PRINT1(" Face node count value = %d.\n", FaceNodeCounts[Index]); + #endif + NumErrs[CurFile]++; + return (-1); + } + else if (FaceNodeSum > TotalNumFaceNodes[CurFile][CurZone[CurFile]]) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECPOLY112) The running face node count exceeds the TotalNumFaceNodes (%d) specified.\n", TotalNumFaceNodes[CurFile][CurZone[CurFile]]); + PRINT1(" Face node count value = %d.\n", FaceNodeCounts[Index]); + #endif + NumErrs[CurFile]++; + return (-1); + } + else if (!WriteBinaryInt32(BlckFile[CurFile], FaceNodeSum)) + Result = -1; + } + } + } + + /* Write the facenodes array but convert 1-based to 0-based. */ + for (Index = 0; (Result == 0) && (Index < TotalNumFaceNodes[CurFile][CurZone[CurFile]]); Index++) + { + if (FaceNodes[Index] < 1 || + FaceNodes[Index] > IMax[CurFile]) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECPOLY112) Invalid face node value at node %d:\n", Index + 1); + PRINT2(" face node value = %d, valid values are are 1 to %d (inclusive).\n", FaceNodes[Index], IMax[CurFile]); + #endif + NumErrs[CurFile]++; + return (-1); + } + else if (!WriteBinaryInt32(BlckFile[CurFile], FaceNodes[Index] - 1)) + Result = -1; + } + + /* Write the left elements array but convert 1-based to 0-based. */ + for (Index = 0; (Result == 0) && (Index < NumFaces); Index++) + { + if (FaceLeftElems[Index] < MinNeighborValue || + FaceLeftElems[Index] > JMax[CurFile]) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECPOLY112) Invalid left neighbor value at face %d:\n", Index); + PRINT2(" left neighbor value = %d, min value = %d,", FaceLeftElems[Index], MinNeighborValue); + PRINT1(" max value = %d.\n", JMax[CurFile]); + #endif + NumErrs[CurFile]++; + return (-1); + } + else if (!WriteBinaryInt32(BlckFile[CurFile], FaceLeftElems[Index] - 1)) + Result = -1; + } + /* Write the right elements array but convert 1-based to 0-based. */ + for (Index = 0; (Result == 0) && (Index < NumFaces); Index++) + { + if (FaceRightElems[Index] < MinNeighborValue || + FaceRightElems[Index] > JMax[CurFile]) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECPOLY112) Invalid right neighbor value at face %d:\n", Index); + PRINT2(" right neighbor value = %d, min value = %d,", FaceRightElems[Index], MinNeighborValue); + PRINT1(" max value = %d.\n", JMax[CurFile]); + #endif + NumErrs[CurFile]++; + return (-1); + } + else if (!WriteBinaryInt32(BlckFile[CurFile], FaceRightElems[Index] - 1)) + Result = -1; + + if (Result == 0 && + (FaceLeftElems[Index] == TECIO_NO_NEIGHBORING_ELEM && + FaceRightElems[Index] == TECIO_NO_NEIGHBORING_ELEM)) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECPOLY112) Both left and right neighbors are set to no neighboring element at face %d.\n", Index); + #endif + NumErrs[CurFile]++; + return (-1); + } + } + + /* Write the boundary arrays. */ + if (Result == 0 && TotalNumFaceBndryFaces[CurFile] > 0) + { + /* Write the boundaryconnectionoffsets array from the boundaryconnectioncounts array. */ + + /* + * As a convenience for the ASCII format, TecUtil, and TECIO layers if any + * boundary connections exists we automatically add a no-neighboring + * connection as the first item so that they can user 0 for no-neighboring + * element in the element list regardless if they have boundary connections + * or not. + * + * The first 2 offsets are always 0 so that -1 in the left/right element + * arrays always indicates "no neighboring element". + */ + if (!(WriteBinaryInt32(BlckFile[CurFile], 0) && + WriteBinaryInt32(BlckFile[CurFile], 0))) + Result = -1; + + Int32_t BndryConnCount = 0; + for (Index = 0; (Result == 0) && (Index < TotalNumFaceBndryFaces[CurFile]); Index++) + { + BndryConnCount += FaceBndryConnectionCounts[Index]; + if (FaceBndryConnectionCounts[Index] < 0 || + BndryConnCount > TotalNumFaceBndryConns[CurFile]) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECPOLY112) Invalid boundary connection count at boundary face %d:\n", Index + 1); + PRINT1(" boundary connection count = %d.\n", FaceBndryConnectionCounts[Index]); + #endif + NumErrs[CurFile]++; + return (-1); + } + else if (!WriteBinaryInt32(BlckFile[CurFile], BndryConnCount)) + Result = -1; + } + if (BndryConnCount != TotalNumFaceBndryConns[CurFile]) + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECPOLY112) Invalid number of boundary connections:\n"); + PRINT2(" number of boundary connections written = %d, total number of boundary connections = %d.", + BndryConnCount, TotalNumFaceBndryConns[CurFile]); + #endif + NumErrs[CurFile]++; + return (-1); + } + + /* Write the boundary connection elements but convert 1-based to 0-based. */ + BndryConnCount = 0; + for (Index = 0; (Result == 0) && (Index < TotalNumFaceBndryFaces[CurFile]); Index++) + { + for (LgIndex_t BIndex = 0; (Result == 0) && (BIndex < FaceBndryConnectionCounts[Index]); BIndex++) + { + if (BIndex > 0 && + FaceBndryConnectionElems[BndryConnCount] == TECIO_NO_NEIGHBORING_ELEM) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECPOLY112) Partially obscured faces must specify no neighboring element first. See boundary connections for face %d.\n", Index + 1); + #endif + NumErrs[CurFile]++; + return (-1); + } + if (FaceBndryConnectionElems[BndryConnCount] < TECIO_NO_NEIGHBORING_ELEM) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECPOLY112) Invalid boundary element value at boundary connections for face %d:\n", Index + 1); + #endif + NumErrs[CurFile]++; + return (-1); + } + if (FaceBndryConnectionElems[BndryConnCount] == TECIO_NO_NEIGHBORING_ELEM && + FaceBndryConnectionZones[BndryConnCount] != TECIO_NO_NEIGHBORING_ZONE) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECPOLY112) Invalid boundary element/zone pair at boundary connections for face %d:\n", Index + 1); + PRINT0(" Boundary elements specified as no neighboring element must also specify no neighboring zone.\n"); + #endif + NumErrs[CurFile]++; + return (-1); + } + else if (!WriteBinaryInt32(BlckFile[CurFile], FaceBndryConnectionElems[BndryConnCount] - 1)) + Result = -1; + BndryConnCount++; + } + } + + /* Write the boundary connection zones but convert 1-based to 0-based. */ + BndryConnCount = 0; + for (Index = 0; (Result == 0) && (Index < TotalNumFaceBndryFaces[CurFile]); Index++) + { + for (LgIndex_t BIndex = 0; (Result == 0) && (BIndex < FaceBndryConnectionCounts[Index]); BIndex++) + { + if (FaceBndryConnectionZones[BndryConnCount] < TECIO_NO_NEIGHBORING_ZONE) + { + #if defined MAKEARCHIVE + PRINT1("Err: (TECPOLY112) Invalid boundary zone value at boundary connections for face %d:\n", Index + 1); + #endif + NumErrs[CurFile]++; + return (-1); + } + else if (!WriteBinaryInt32(BlckFile[CurFile], FaceBndryConnectionZones[BndryConnCount] - 1)) + Result = -1; + BndryConnCount++; + } + } + } + if (Result != 0) + { + Result = -1; + WriteErr("TECPOLY112"); + } + + return Result; +} + +#if !defined INDEX_16_BIT // not supported in this test-only mode +LIBFUNCTION INTEGER4 LIBCALL TECPOLY111(INTEGER4 *FaceNodeCounts, + INTEGER4 *FaceNodes, + INTEGER4 *FaceLeftElems, + INTEGER4 *FaceRightElems, + INTEGER4 *FaceBndryConnectionCounts, + INTEGER4 *FaceBndryConnectionElems, + INTEGER2 *FaceBndryConnectionZones) +{ + INTEGER4 Result = 0; + EntIndex_t *FBCZones = NULL; + + if (TotalNumFaceBndryConns[CurFile] > 0) + { + ALLOC_ARRAY(TotalNumFaceBndryConns[CurFile], EntIndex_t, "32-bit FaceBndryConnectionZones"); + + if (FBCZones != NULL) + { + for (LgIndex_t ZoneI = 0; ZoneI < TotalNumFaceBndryFaces[CurFile]; ZoneI++) + FBCZones[ZoneI] = (EntIndex_t)FaceBndryConnectionZones[ZoneI]; + } + else + { + #if defined MAKEARCHIVE + PRINT0("Err: (TECPOLY111) Out of memory allocating temporary data.\n"); + #endif + NumErrs[CurFile]++; + return (-1); + } + } + + Result = TECPOLY112(FaceNodeCounts, + FaceNodes, + FaceLeftElems, + FaceRightElems, + FaceBndryConnectionCounts, + FaceBndryConnectionElems, + FBCZones); + + if (FBCZones != NULL) + FREE_ARRAY(FBCZones, "32-bit FaceBndryConnectionZones"); + + return Result; +} +#endif // INDEX_16_BIT -- not supported in this test-only mode + +#if defined MAKEARCHIVE && !defined _WIN32 /* every platform but Windows Intel */ +LIBFUNCTION INTEGER4 LIBCALL tecpoly112_(INTEGER4 *FaceNodeCounts, + INTEGER4 *FaceNodes, + INTEGER4 *FaceLeftElems, + INTEGER4 *FaceRightElems, + INTEGER4 *FaceBndryConnectionOffsets, + INTEGER4 *FaceBndryConnectionElems, + INTEGER4 *FaceBndryConnectionZones) +{ + return TECPOLY112(FaceNodeCounts, + FaceNodes, + FaceLeftElems, + FaceRightElems, + FaceBndryConnectionOffsets, + FaceBndryConnectionElems, + FaceBndryConnectionZones); +} + +LIBFUNCTION INTEGER4 LIBCALL tecpoly111_(INTEGER4 *FaceNodeCounts, + INTEGER4 *FaceNodes, + INTEGER4 *FaceLeftElems, + INTEGER4 *FaceRightElems, + INTEGER4 *FaceBndryConnectionOffsets, + INTEGER4 *FaceBndryConnectionElems, + INTEGER2 *FaceBndryConnectionZones) +{ + return TECPOLY111(FaceNodeCounts, + FaceNodes, + FaceLeftElems, + FaceRightElems, + FaceBndryConnectionOffsets, + FaceBndryConnectionElems, + FaceBndryConnectionZones); +} +#endif + +#if defined TECPLOTKERNEL +/* CORE SOURCE CODE REMOVED */ +#endif diff --git a/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio2009.zip b/applications/utilities/postProcessing/dataConversion/foamToTecplot360/tecio2009.zip new file mode 100644 index 0000000000000000000000000000000000000000..cf5c035ce90eb3b71fd8fdc94d874a6cf1b5abbf GIT binary patch literal 1314306 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⁡lDqWj;va6Ns#zD~?lhqQ8wH8)0kK{B-U+RU*we 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 z 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

b!^c*}VXhFfHz~F)Ae4il4lj@d6!MZ-SFE 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