cgnslib_3.1.4/0000775000076400007640000000000012170270045010233 500000000000000cgnslib_3.1.4/fortran_test/0000775000076400007640000000000012160611175012747 500000000000000cgnslib_3.1.4/fortran_test/csub.c0000664000076400007640000000324012160605674013775 00000000000000#include #include #include #include "fortran_macros.h" static int check_args(int *arg1, char *arg2, int *arg3, int len) { int n, err = 0; /* arg1 should be 1 */ if (*arg1 != 1) { printf ("first argument is %d and should be 1\n", *arg1); err++; } /* arg2 should be "string" */ if (strncmp (arg2, "string", 6)) { printf ("second argument is "); for (n = 0; n < 6; n++) { if (isascii(arg2[n]) && isprint(arg2[n])) putchar (arg2[n]); else printf ("0x%2.2X", (unsigned)arg2[n]); } printf (" and should be string\n"); err++; } /* the implicit string length should be 32 */ if (len != 32) { printf ("the implicit string length is %d and should be 32\n", len); err++; } /* arg3 should be 3 this may cause a segmentation violation if the argument passing is incorrect */ if (err) { printf ("the following test may cause a segmentation violation\n"); fflush (stdout); } if (*arg3 != 3) { printf ("last argument is %d and should be 3\n", *arg3); err++; } return err; } void FMNAME(cg_sub,CG_SUB)(int *i, STR_PSTR(str), int *j STR_PLEN(str)) { puts ("checking cg_sub"); if (check_args (i, STR_PTR(str), j, STR_LEN(str))) puts ("incorrect interface"); else puts ("OK"); } void FMNAME(adfsub,ADFSUB)(int *i, STR_PSTR(str), int *j STR_PLEN(str)) { puts ("checking adfsub"); if (check_args (i, STR_PTR(str), j, STR_LEN(str))) puts ("incorrect interface"); else puts ("OK"); } cgnslib_3.1.4/fortran_test/fortran_macros.h0000664000076400007640000001765112160605674016100 00000000000000/*------------------------------------------------------------------------- This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. -------------------------------------------------------------------------*/ #ifndef FORTRAN_MACROS_H #define FORTRAN_MACROS_H /**************************************************************/ /* Include file used to interface with FORTRAN */ /**************************************************************/ /* FMNAME is used when you prototype a FORTRAN routine for calling from C */ /* (which you HAVE to do), or when you create the subroutine */ /* INTEGER FMNAME(abc,ABC) (INTEGER ival, REAL rval); */ /* void FMNAME(abc,ABC) (INTEGER ival, REAL rval) */ /* { *ival = 1; *rval = 2.0; return; } */ /* FMCALL is used when you call a FORTRAN subroutine from C */ /* VINTEGER ival; */ /* VREAL rval; */ /* FMCALL(abc,ABC) (&ival, &rval); */ /* STR_PSTR is used in receiving arguments from FORTRAN */ /* STR_PLEN is used in end of arguments from FORTRAN (no comma before it) */ /* STR_PTR is used to get the address of a string from FORTRAN */ /* STR_LEN is used to get the length of a string from FORTRAN */ /* INTEGER FMNAME(abc,ABC) (STR_PSTR(str), INTEGER ival */ /* STR_PLEN(str)) */ /* { char *pointer = STR_PTR(str); int length = STR_LEN(str); } */ #ifdef NO_CONCATENATION # define IDENTITY(x) x # define CONCATENATE(a,b) IDENTITY(a)b #else # define CONCATENATE(a,b) a##b #endif /* upper case Fortran name */ #if defined(UPPERCASE) # define FMNAME(lname,uname) uname # define FMCALL(lname,uname) uname /* upper case Fortran name with trailing underscore */ #elif defined(UPPERCASE_) # define FMNAME(lname,uname) CONCATENATE(uname,_) # define FMCALL(lname,uname) CONCATENATE(uname,_) /* upper case Fortran name with 2 trailing underscores */ #elif defined(UPPERCASE__) # define FMNAME(lname,uname) CONCATENATE(uname,__) # define FMCALL(lname,uname) CONCATENATE(uname,__) /* lower case Fortran name */ #elif defined(LOWERCASE) # define FMNAME(lname,uname) lname # define FMCALL(lname,uname) lname /* lower case Fortran name with trailing underscore */ #elif defined(LOWERCASE_) # define FMNAME(lname,uname) CONCATENATE(lname,_) # define FMCALL(lname,uname) CONCATENATE(lname,_) /* lower case Fortran name with 2 trailing underscores */ #elif defined(LOWERCASE__) # define FMNAME(lname,uname) CONCATENATE(lname,__) # define FMCALL(lname,uname) CONCATENATE(lname,__) /* Cray Super Computer */ #elif defined(_CRAY) || defined(cray) # include # define FMNAME(lname,uname) uname # define FMCALL(lname,uname) uname # define STR_PSTR(str) _fcd str # define STR_PLEN(str) # define STR_PTR(str) _fcdtocp (str) # define STR_LEN(str) _fcdlen (str) /* Vax VMS */ #elif defined(VMS) # include # define FMNAME(lname,uname) uname # define FMCALL(lname,uname) uname # define STR_PSTR(str) struct dsc$descriptor_s *str # define STR_PLEN(str) # define STR_PTR(str) str->dsc$a_pointer # define STR_LEN(str) str->dsc$w_length /* MS Windows */ #elif defined(_WIN32) # if defined(__NUTC__) || defined(__WIN32_BINARY__) # define FMNAME(lname,uname) __cdecl lname # define FMCALL(lname,uname) lname # define STR_PSTR(str) char *str # define STR_PLEN(str) , int CONCATENATE(Len,str) # else # ifndef WIN32_FORTRAN # define WIN32_FORTRAN # endif # define FMNAME(lname,uname) __stdcall uname # define FMCALL(lname,uname) uname # define STR_PSTR(str) char *str, int CONCATENATE(Len,str) # define STR_PLEN(str) # endif # define STR_PTR(str) str # define STR_LEN(str) CONCATENATE(Len,str) /* assume lower case Fortran name with trailing underscore */ #else # define FMNAME(lname,uname) CONCATENATE(lname,_) # define FMCALL(lname,uname) CONCATENATE(lname,_) #endif #ifndef STR_PSTR # define STR_PSTR(str) char *str # define STR_PLEN(str) , int CONCATENATE(Len,str) # define STR_PTR(str) str # define STR_LEN(str) CONCATENATE(Len,str) #endif /*************/ /* Datatypes */ /*************/ typedef char VCHARACTER; typedef int VINTEGER; typedef double VREAL; typedef float VFLOAT; typedef VCHARACTER * CHARACTER; typedef VINTEGER * INTEGER; typedef VREAL * REAL; #if !defined(_WIN32) || !defined(_WINDEF_) typedef VFLOAT * PFLOAT; #endif /**************/ /* Prototypes */ /**************/ #ifdef __cplusplus extern "C" { #endif /*****************************************************************************/ /* tocstr - convert a fortran character string into a fortran integer array */ /* that has a trailing null character to look like a c-string */ /* */ /* character str (in) Fortran chacter string */ /* integer icstr(*) (out) Fortran integer array */ /* */ /* notes: */ /* 1) Trailing blanks are removed, and leading/trailing '"' are also. */ /* 2) To keep the trailing blanks, quote them '"' */ /* 3) It is a little faster to call this routine without any trailing */ /* blanks; ex. call tocstr (abc[1:notblk], icstr) */ /*****************************************************************************/ void FMNAME(tocstr,TOCSTR) ( STR_PSTR(str), /* (in) Fortran character string */ CHARACTER icstr /* (out) Fortran integer array */ STR_PLEN(str) /* (in) Compiler passed len of str */ ); /*****************************************************************************/ /* frcstr - convert a fortran integer array into a fortran character string */ /* */ /* integer icstr(*) (in) Fortran integer array */ /* character str (out) Fortran chacter string */ /*****************************************************************************/ void FMNAME(frcstr,FRCSTR) ( CHARACTER icstr, /* (in) Fortran integer array */ STR_PSTR(str) /* (out) Fortran character string */ STR_PLEN(str) /* (in) Compiler passed len of str */ ); /*************************************************************************/ /* fstr_to_cstr - convert a fortran character string into a c character */ /* string */ /*************************************************************************/ void fstr_to_cstr ( char *str, /* (in) Pointer to character string */ int ilen, /* (in) Max length of str */ char *icstr /* (out) C character string */ ); /*************************************************************************/ /* cstr_to_fstr - convert a c character string into a fortran character */ /* string */ /*************************************************************************/ void cstr_to_fstr ( char *icstr, /* (in) C character string */ int ilen, /* (in) Max length of str */ char *str /* (out) Pointer to character string */ ); #ifdef __cplusplus } #endif #endif /* FORTRAN_MACROS_H */ cgnslib_3.1.4/fortran_test/fmain.f0000664000076400007640000000030312160605674014133 00000000000000 program fmain integer*4 i,j character*32 string i = 1 j = 3 string = 'string' call cg_sub(i,string,j) call adfsub(i,string,j) stop end cgnslib_3.1.4/fortran_test/CMakeLists.txt0000664000076400007640000000145012160605674015436 00000000000000cmake_minimum_required(VERSION 2.4) project("fortran_test" C Fortran) #set(CMAKE_VERBOSE_MAKEFILE "ON") add_executable(LOWERCASE csub.c fmain.f) set_property(TARGET LOWERCASE PROPERTY "COMPILE_DEFINITIONS" "LOWERCASE") add_executable(LOWERCASE_ csub.c fmain.f) set_property(TARGET LOWERCASE_ PROPERTY COMPILE_DEFINITIONS "LOWERCASE_") add_executable(LOWERCASE__ csub.c fmain.f) set_property(TARGET LOWERCASE__ PROPERTY COMPILE_DEFINITIONS "LOWERCASE__") add_executable(UPPERCASE csub.c fmain.f) set_property(TARGET UPPERCASE PROPERTY COMPILE_DEFINITIONS "UPPERCASE") add_executable(UPPERCASE_ csub.c fmain.f) set_property(TARGET UPPERCASE_ PROPERTY COMPILE_DEFINITIONS "UPPERCASE_") add_executable(UPPERCASE__ csub.c fmain.f) set_property(TARGET UPPERCASE__ PROPERTY COMPILE_DEFINITIONS "UPPERCASE__") cgnslib_3.1.4/src/0000775000076400007640000000000012170266543011032 500000000000000cgnslib_3.1.4/src/cgnstools/0000775000076400007640000000000012170266543013045 500000000000000cgnslib_3.1.4/src/cgnstools/make.defs.in0000664000076400007640000000603712160605674015161 00000000000000@SET_MAKE@ CGNSDIR = @CGNSDIR@ include $(CGNSDIR)/make.defs CGNSLIB = $(CGNSDIR)/$(LIBCGNS) #----------------------------------------------------------------------- # installation directories # BIN_INSTALL_DIR - installation directory for shell script # EXE_INSTALL_DIR - installation directory for executables # WSH_INSTALL_DIR - installation directory for cgns wish executables # LIB_INSTALL_DIR - installation directory for tcl scripts #----------------------------------------------------------------------- BIN_INSTALL_DIR = @BIN_INSTALL_DIR@ EXE_INSTALL_DIR = @EXE_INSTALL_DIR@ WSH_INSTALL_DIR = $(EXE_INSTALL_DIR) LIB_INSTALL_DIR = @LIB_INSTALL_DIR@ #----------------------------------------------------------------------- # path to Tcl/Tk includes and libraries # you may have to set these if Tcl/Tk not in standard locations # in order to find tk.h and/or the Tcl/Tk libraries # # For example, if you have build Tcl/Tk locally under Unix/Linux # TCLROOT = $(HOME)/tcl8.3.1 # TKROOT = $(HOME)/tk8.3.1 # TKINCS = -I$(TKROOT)/generic -I$(TCLROOT)/generic # TKLIBS = $(TKROOT)/unix/libtk8.3.a $(TCLROOT)/unix/libtcl8.3.a -lm # # With CYGWIN source distribution: # TCLTKSRC = /usr/src/tcltk-20001125-1 # TKINCS = -I$(TCLTKSRC)/tk/win -I$(TCLTKSRC)/tk/generic \ # -I$(TCLTKSRC)/tk/xlib -I$(TCLTKSRC)/tcl/generic # TKLIBS = -ltk80 -ltcl80 -lm #----------------------------------------------------------------------- TKINCS = @TKINCS@ TKLIBS = @TKLIBS@ #----------------------------------------------------------------------- # X11 include path and library # X11LIBS not needed if included with TKLIBS above #----------------------------------------------------------------------- X11INCS = @X11INCS@ X11LIBS = @X11LIBS@ #----------------------------------------------------------------------- # OpenGL include path and libs # this is needed by the cgnsplot #----------------------------------------------------------------------- OGLINCS = @OGLINCS@ OGLLIBS = @OGLLIBS@ #----------------------------------------------------------------------- # compile options for cgnsplot # -DNO_MESH_BOUNDARIES - exclude structured mesh boundaries # -DNO_CUTTING_PLANE - disable cutting plane #----------------------------------------------------------------------- PLOTOPTS = @PLOTOPTS@ #----------------------------------------------------------------------- # this is where TkOGL lib is located relative to cgnsplot directory # and additional compile options and X libs needed for linking #----------------------------------------------------------------------- TKOGLLIB = ../tkogl/libtkogl.$(A) TKOGLXLIB = @TKOGLXLIB@ TKOGLOPTS = @TKOGLOPTS@ $(X11INCS) $(TKINCS) $(OGLINCS) #----------------------------------------------------------------------- # compile options for calculator # -DUSE_MATHERR - matherr used to trap math errors in calculator # -DREAD_NODE - allow direct reading of ADF nodes # -DSIGNAL=int - signal return is int istead of void #----------------------------------------------------------------------- CALCOPTS = @CALCOPTS@ cgnslib_3.1.4/src/cgnstools/LICENSE0000664000076400007640000000146512160605674014001 00000000000000This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. cgnslib_3.1.4/src/cgnstools/tkogl/0000775000076400007640000000000012167722166014171 500000000000000cgnslib_3.1.4/src/cgnstools/tkogl/nurbs.c0000664000076400007640000002151312160605670015401 00000000000000#include #if defined(__WIN32__) || defined(_WIN32) # define WIN32_LEAN_AND_MEAN # include # undef WIN32_LEAN_AND_MEAN #endif #include #include #include #include #include #include #include #include "nurbs.h" #include "tkogl.h" #include "tkoglparse.h" /*--------------------------------------------------------------------------- * * The routines below maintain a dynamic array of floats * *---------------------------------------------------------------------------*/ #define DEFAULTSIZE 8 typedef struct { int size; int count; GLfloat *value; } FloatArrayStruct, * FloatArray; static FloatArray NewFloatArray () { FloatArray ptr = malloc (sizeof(FloatArrayStruct)); assert (ptr != NULL); ptr->size = DEFAULTSIZE; ptr->count = 0; ptr->value = malloc (sizeof (GLfloat)*ptr->size); assert (ptr->value != NULL); return ptr; } static void DestroyFloatArray (FloatArray ptr) { assert (ptr!=NULL); assert (ptr->value != NULL); free (ptr->value); free (ptr); } static void AddFloat (FloatArray ptr, GLfloat val) { assert (ptr != NULL); assert (ptr->count <= ptr->size); if (ptr->count == ptr->size) { ptr->size *= 2; ptr->value = realloc (ptr->value, sizeof (GLfloat)*ptr->size); assert (ptr->value != NULL); } ptr->value[ptr->count++] = val; } #if 0 static void SetFloat (FloatArray ptr, int index, GLfloat val) { assert (ptr != NULL); assert (ptr->count <= ptr->size); assert (index <= ptr->count); if (index == ptr->size) { ptr->size *= 2; ptr->value = realloc (ptr->value, sizeof (GLfloat)*ptr->size); assert (ptr->value != NULL); } if (index == ptr->count) { ptr->count++; } ptr->value [index] = val; } #endif /*-------------------------------------------------------------------------- * * Main Procedure for generating nurbs surfaces * *--------------------------------------------------------------------------*/ #define ERRMSG(msg) { Tcl_AppendResult(interp,msg,(char*)NULL); \ result = TCL_ERROR; goto done; } #define ERRMSG2(msg1,msg2) { Tcl_AppendResult(interp,msg1,msg2,(char*)NULL); \ result = TCL_ERROR; goto done; } int NurbsSurface (Tcl_Interp *interp, int argc, char* argv []) { int result = TCL_OK; GLint uOrder = 4; GLint vOrder = 4; GLenum type = GL_MAP2_VERTEX_3; int nCoords = 3; FloatArray uKnot = NewFloatArray (); FloatArray vKnot = NewFloatArray (); FloatArray cPoint = NewFloatArray (); GLfloat samplingTolerance = 50.0; GLfloat displayMode = GLU_FILL; GLfloat culling = GL_FALSE; int iarg; int dlist = 0; for (iarg = 2; iarg < argc; iarg++) { int len = (int)strlen (argv [iarg]); if (strncmp (argv [iarg], "-uorder", len) == 0) { int val; iarg++; if (iarg >= argc) ERRMSG ("No value given for -uorder"); if (Tcl_GetInt (interp, argv [iarg], &val) != TCL_OK || val < 2 || val > 8) ERRMSG2 ("\nInvalid value for -uorder:", argv [iarg]); uOrder = val; } else if (strncmp (argv [iarg], "-vorder", len) == 0) { int val; iarg++; if (iarg >= argc) ERRMSG ("No value given for -vorder"); if (Tcl_GetInt (interp, argv [iarg], &val) != TCL_OK || val < 2 || val > 8) ERRMSG2 ("\nInvalid value for -vorder:", argv [iarg]); vOrder = val; } else if (strncmp (argv [iarg], "-uknots", len) == 0) { if (uKnot->count != 0) ERRMSG ("uknot values already given"); iarg++; while (iarg < argc && !(argv [iarg][0] == '-' && isalpha(argv [iarg][1]))) { double val; if (Tcl_GetDouble (interp, argv [iarg], &val) != TCL_OK) ERRMSG ("\nError parsing uknot value"); if (uKnot->count > 0 && uKnot->value [uKnot->count-1] > val) ERRMSG ("uknot values not in non-descending order"); AddFloat (uKnot, (GLfloat)val); iarg++; } iarg--; } else if (strncmp (argv [iarg], "-vknots", len) == 0) { if (vKnot->count != 0) ERRMSG ("vknot values already given"); iarg++; while (iarg < argc && !(argv [iarg][0] == '-' && isalpha(argv [iarg][1]))) { double val; if (Tcl_GetDouble (interp, argv [iarg], &val) != TCL_OK) ERRMSG ("\nError parsing uknot value"); if (vKnot->count > 0 && vKnot->value [vKnot->count-1] > val) ERRMSG ("vknot values not in non-descending order"); AddFloat (vKnot, (GLfloat)val); iarg++; } iarg--; } else if (strncmp (argv [iarg], "-controlpoints", len) == 0) { if (cPoint->count != 0) ERRMSG ("controlpoint values already given"); iarg++; while (iarg < argc && !(argv [iarg][0] == '-' && isalpha(argv [iarg][1]))) { double val; if (Tcl_GetDouble (interp, argv [iarg], &val) != TCL_OK) ERRMSG ("\nError parsing uknot value"); AddFloat (cPoint, (GLfloat)val); iarg++; } iarg--; } else if (strncmp (argv [iarg], "-type", len) == 0) { iarg++; if (iarg >= argc) ERRMSG ("No -type value given"); if (strcmp (argv [iarg], "map2vertex3") ==0) { type = GL_MAP2_VERTEX_3; nCoords = 3; } else if (strcmp (argv [iarg], "map2vertex4") == 0) { type = GL_MAP2_VERTEX_4; nCoords = 4; } else if (strcmp (argv [iarg], "map2color4") == 0) { type = GL_MAP2_COLOR_4; nCoords = 4; } else if (strcmp (argv [iarg], "map2normal") == 0) { type = GL_MAP2_NORMAL; nCoords = 3; } else if (strcmp (argv [iarg], "map2texturecoord1") == 0) { type = GL_MAP2_TEXTURE_COORD_1; nCoords = 1; } else if (strcmp (argv [iarg], "map2texturecoord2") == 0) { type = GL_MAP2_TEXTURE_COORD_2; nCoords = 2; } else if (strcmp (argv [iarg], "map2texturecoord3") == 0) { type = GL_MAP2_TEXTURE_COORD_3; nCoords = 3; } else if (strcmp (argv [iarg], "map2texturecoord4") == 0) { type = GL_MAP2_TEXTURE_COORD_4; nCoords = 4; } else ERRMSG2 ("not a valid type:", argv [iarg]); } else if (strncmp (argv [iarg], "-samplingtolerance", len) == 0) { double val; iarg++; if (iarg >= argc) ERRMSG ("No -samplingtolerance value given"); if (Tcl_GetDouble (interp, argv [iarg], &val) != TCL_OK) ERRMSG ("\nError parsing sampling tolerance"); samplingTolerance = (GLfloat)val; } else if (strncmp (argv [iarg], "-displaymode", len) == 0) { iarg++; if (iarg >= argc) ERRMSG ("No -displaymode value given"); if (strcmp (argv [iarg], "fill") == 0) { displayMode = GLU_FILL; } else if (strcmp (argv [iarg], "outlinepolygon") == 0) { displayMode = GLU_OUTLINE_POLYGON; } else if (strcmp (argv [iarg], "outlinepatch") == 0) { displayMode = GLU_OUTLINE_PATCH; } else { ERRMSG2 ("not a valid display mode:", argv [iarg]); } } else if (strncmp (argv [iarg], "-culling", len) == 0) { int val; iarg++; if (iarg >= argc) ERRMSG ("No -culling value given"); if (Tcl_GetBoolean (interp, argv [iarg], &val) != TCL_OK) ERRMSG ("\nError parsing culling value"); culling = (GLfloat)val; } else { ERRMSG2 ("invalid option:", argv [iarg]); } } if (vKnot->count == 0 || uKnot->count == 0 || cPoint->count == 0) ERRMSG ("All of -uknot, -vknot and -cpoint options must be specified"); /* Now try to guess the remaining arguments and call gluNurbsSurface */ { GLint uKnotCount = uKnot->count; GLint vKnotCount = vKnot->count; GLint vStride = nCoords; GLint uStride = nCoords * (vKnotCount - vOrder); static GLUnurbsObj* obj = NULL; if (uStride * (uKnotCount - uOrder) != cPoint->count) { char buf [80]; sprintf (buf, "%d", uStride * (uKnotCount - uOrder)); ERRMSG2 ("Incorrect number of controlpoint coordinates. Expected ", buf); } /* Theoretically, a nurbs object could be allocated for each invocation of NurbsSurface and then freed after the creation of the display list. However, this produces a segmentation violation on AIX OpenGL 1.0. Thus, only one nurbs object is ever allocated and never freed. */ if (obj == NULL) obj = gluNewNurbsRenderer(); dlist = glGenLists (1); gluNurbsProperty (obj, GLU_SAMPLING_TOLERANCE, samplingTolerance); gluNurbsProperty (obj, GLU_DISPLAY_MODE, displayMode); gluNurbsProperty (obj, GLU_CULLING, culling); glNewList (dlist, GL_COMPILE); gluBeginSurface (obj); gluNurbsSurface (obj, uKnotCount, uKnot->value, vKnotCount, vKnot->value, uStride, vStride, cPoint->value, uOrder, vOrder, type); gluEndSurface (obj); /* This is never used because of a bug in AIX OpenGL 1.0. gluDeleteNurbsObj (obj); */ glEndList(); glFlush(); } done: DestroyFloatArray (uKnot); DestroyFloatArray (vKnot); DestroyFloatArray (cPoint); if (result == TCL_OK) { char tmp[128]; sprintf (tmp, "%d", dlist); Tcl_SetResult(interp, tmp, TCL_VOLATILE); } return result; } cgnslib_3.1.4/src/cgnstools/tkogl/glphoto.c0000664000076400007640000000372112160605670015725 00000000000000#include #if defined(__WIN32__) || defined(_WIN32) # define WIN32_LEAN_AND_MEAN # include # undef WIN32_LEAN_AND_MEAN #endif #include #include #include #include #include "glphoto.h" #include "tkOGL.h" /*-------------------------------------------------------------------------- * * Main Procedure for processing glphoto commands * *--------------------------------------------------------------------------*/ int glPhoto (Tcl_Interp *interp, int argc, char* argv []) { #define ERRMSG(msg) \ { Tcl_AppendResult (interp, (msg), (char*) NULL);\ result = TCL_ERROR;\ goto done; } #define ERRMSG2(msg1, msg2) \ { Tcl_AppendResult (interp, (msg1), (msg2), (char*) NULL);\ result = TCL_ERROR;\ goto done; } int result = TCL_OK; Tk_PhotoHandle handle; Tk_PhotoImageBlock block; int len; if (argc < 1) ERRMSG ("No command specified for glphoto"); len = strlen (argv[0]); if (strncmp (argv [0], "put", len) == 0) { if (argc < 2) ERRMSG ("No photo image name specified for 'put' option"); handle = Tk_FindPhoto (interp,argv [1]); if (handle == NULL) ERRMSG2 ("Photo not defined: ", argv [1]); if (Tk_PhotoGetImage (handle, &block) != 1) ERRMSG2 ("Could not get image of photo ", argv [1]); printf ("width %d height %d pitch %d pixelsize %d offset %d %d %d\n", block.width, block.height, block.pitch, block.pixelSize, block.offset [0],block.offset [1],block.offset [2]); if (block.pixelSize != 3 && block.pixelSize != 4) ERRMSG ("Image has invalid pixel size"); glPixelStorei (GL_UNPACK_ALIGNMENT, 1); glPixelZoom (1.0, -1.0); glRasterPos2i (0, 0); glDrawPixels (block.width, block.height, block.pixelSize == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, block.pixelPtr); } else { ERRMSG2 ("Invalid glphoto command: ", argv [0]); } done: return result; } cgnslib_3.1.4/src/cgnstools/tkogl/tkogl.h0000664000076400007640000000173512160605670015401 00000000000000#ifndef _TK_OGL #define _TK_OGL #include #if defined(__WIN32__) || defined(_WIN32) # define WIN32_LEAN_AND_MEAN # include # undef WIN32_LEAN_AND_MEAN #endif #include #include #include #if defined(__WIN32__) || defined(_WIN32) # include "tkWinInt.h" # if defined(_MSC_VER) # define EXPORT(a,b) __declspec(dllexport) a b # define DllEntryPoint DllMain # else # if defined(__BORLANDC__) # include # define EXPORT(a,b) a _export b # else # define EXPORT(a,b) a b # endif # endif #else # define EXPORT(a,b) a b # include # include /* for XA_RGB_DEFAULT_MAP atom */ # include /* for XmuLookupStandardColormap() */ #endif typedef int (TkOGLExtProc) (Tcl_Interp* interp, int argc, char** argv); EXPORT (int,RegisterTkOGLExtension) (Tcl_Interp* interp, char* extname, TkOGLExtProc* extproc); #endif /* _TK_OGL */ cgnslib_3.1.4/src/cgnstools/tkogl/load3ds.c0000664000076400007640000006647512160605670015621 00000000000000#include #if defined(__WIN32__) || defined(_WIN32) # define WIN32_LEAN_AND_MEAN # include # undef WIN32_LEAN_AND_MEAN #endif #include #include #include #include #include #include "load3ds.h" #include "tkogl.h" /*---------------------------------------------------------------------------* * * The following are data structures corresponding to the * chunk/chunktype overall format of 3DStudio files * *---------------------------------------------------------------------------*/ typedef unsigned char byte; typedef unsigned short word; typedef unsigned long dword; typedef struct { word id; dword len; } TChunkHeader, *PChunkHeader; enum { CHUNK_RGBF = 0x0010, CHUNK_RGBB = 0x0011, CHUNK_PERCI = 0x0030, CHUNK_PERCF = 0x0031, CHUNK_MAIN = 0x4D4D, CHUNK_OBJMESH = 0x3D3D, CHUNK_BKGCOLOR = 0x1200, CHUNK_AMBCOLOR = 0x2100, CHUNK_OBJBLOCK = 0x4000, CHUNK_TRIMESH = 0x4100, CHUNK_VERTLIST = 0x4110, CHUNK_FACELIST = 0x4120, CHUNK_FACEMAT = 0x4130, CHUNK_MAPLIST = 0x4140, CHUNK_SMOOLIST = 0x4150, CHUNK_TRMATRIX = 0x4160, CHUNK_LIGHT = 0x4600, CHUNK_SPOTLIGHT = 0x4610, CHUNK_CAMERA = 0x4700, CHUNK_MATERIAL = 0xAFFF, CHUNK_MATNAME = 0xA000, CHUNK_AMBIENT = 0xA010, CHUNK_DIFFUSE = 0xA020, CHUNK_SPECULAR = 0xA030, CHUNK_SHININESS = 0xA040, CHUNK_SHININESS1= 0xA041, CHUNK_SHININESS2= 0xA042, CHUNK_TEXTURE = 0xA200, CHUNK_BUMPMAP = 0xA230, CHUNK_MAPFILE = 0xA300, CHUNK_KEYFRAMER = 0xB000, CHUNK_FRAMES = 0xB008, }; /*--------------------------------------------------------------------------- * * The following are forward declarations for * procedures for reading each chunk type * *---------------------------------------------------------------------------*/ typedef void ChunkReadProc (Tcl_DString* desc, FILE *f, long p); static ChunkReadProc ChunkReader, TriMeshReader, RGBFReader, RGBBReader, PercentIReader, PercentFReader, ObjBlockReader, VertListReader, FaceListReader, FaceMatReader, MapListReader, SmooListReader, TrMatrixReader, LightReader, SpotLightReader, CameraReader, MatNameReader, MapFileReader, FramesReader; /*--------------------------------------------------------------------------- * * The following is a table that associates each chunk type with the proper * chunk reader function and a string to be used in the property list * to be returned in a Tcl result * *---------------------------------------------------------------------------*/ struct { word id; char *name; ChunkReadProc* func; } ChunkNames[] = { {CHUNK_RGBF, "rgb", RGBFReader}, {CHUNK_RGBB, "rgb", RGBBReader}, {CHUNK_PERCI, "percent", PercentIReader}, {CHUNK_PERCF, "percent", PercentFReader}, {CHUNK_MAIN, "main", NULL}, {CHUNK_OBJMESH, "object-mesh", NULL}, {CHUNK_BKGCOLOR, "background", NULL}, {CHUNK_AMBCOLOR, "ambient", NULL}, {CHUNK_OBJBLOCK, "object-block", ObjBlockReader}, {CHUNK_TRIMESH, "tri-mesh", TriMeshReader}, {CHUNK_VERTLIST, "vertex-list", VertListReader}, {CHUNK_FACELIST, "face-list", FaceListReader}, {CHUNK_FACEMAT, "face-material", FaceMatReader}, {CHUNK_MAPLIST, "mappings-list", MapListReader}, {CHUNK_SMOOLIST, "smoothings", SmooListReader}, {CHUNK_TRMATRIX, "matrix", TrMatrixReader}, {CHUNK_LIGHT, "light", LightReader}, {CHUNK_SPOTLIGHT, "spotlight", SpotLightReader}, {CHUNK_CAMERA, "camera", CameraReader}, {CHUNK_MATERIAL, "material", NULL}, {CHUNK_MATNAME, "name", MatNameReader}, {CHUNK_AMBIENT, "ambient", NULL}, {CHUNK_DIFFUSE, "diffuse", NULL}, {CHUNK_SPECULAR, "specular", NULL}, {CHUNK_SHININESS, "shininess", NULL}, {CHUNK_SHININESS1, "shininess1", NULL}, {CHUNK_SHININESS2, "shininess2", NULL}, {CHUNK_TEXTURE, "texture-map", NULL}, {CHUNK_BUMPMAP, "bump-map", NULL}, {CHUNK_MAPFILE, "name", MapFileReader}, {CHUNK_KEYFRAMER, "keyframer-data", NULL}, {CHUNK_FRAMES, "frames", FramesReader}, }; /*--------------------------------------------------------------------------- * * The following are data structures for storing the geometry of a * Tri-Mesh object * *---------------------------------------------------------------------------*/ typedef GLfloat Vector [3]; typedef struct { int ivtx [3]; Vector normal; dword group; word flags; } FaceInfo; typedef struct SmoothInfoNode { Vector normal; dword group; struct SmoothInfoNode *next; } *SmoothList; typedef struct { Vector coord; char texFlag; GLfloat texCoord [2]; SmoothList smoothList; } VertexInfo; typedef struct FaceListNode { int idx; struct FaceListNode* next; } *FaceList; typedef struct { char name [80]; int displayList; FaceList faceList; int n; } MaterialFaceInfo; static int nmat = 0; static int nvtx = 0; static int nface = 0; static VertexInfo * vtx = NULL; static FaceInfo * face = NULL; static MaterialFaceInfo * matface = NULL; /*--------------------------------------------------------------------------- * * The following are procedures to search and modify some of the lists * used in keeping track of faces, vertices, materials, and smoothing groups * *---------------------------------------------------------------------------*/ static void AllocMatFace () { /* Allocate and initialize vector matface */ int i; assert (nmat >= 0); assert (matface == NULL); matface = (MaterialFaceInfo*) malloc (sizeof (MaterialFaceInfo) * nmat); assert (matface != NULL); for (i = 0; i < nmat; ++i) { matface [i].name [0] = '\0'; matface [i].displayList = -1; matface [i].n = 0; matface [i].faceList = (FaceList) NULL; } } static void FreeMatFace () { /* Frees the matface table */ int i, j; FaceList flist, tmp; if (matface == NULL) return; for (i = 0; i < nmat; ++i) { flist = matface [i].faceList; for (j = 0; j < matface [i].n; ++j) { assert (flist != NULL); tmp = flist->next; free (flist); flist = tmp; } assert (flist == NULL); } free (matface); matface = NULL; } static void AllocFace () { /* Allocates and initializes the face table */ assert (face == NULL); assert (nface > 0); face = (FaceInfo*) malloc (sizeof (FaceInfo) * nface); assert (face != NULL); } static void FreeFace () { /* Frees memory associated with the face table */ free (face); face = NULL; nface = 0; } static void AllocVtx () { /* Allocates and initializes the vtx table */ int i; assert (vtx == NULL); assert (nvtx > 0); vtx = (VertexInfo*) malloc (sizeof (VertexInfo) * nvtx); assert (vtx != NULL); for (i = 0; i < nvtx; i++) { vtx [i].smoothList = (SmoothList) NULL; } } static void FreeVtx () { /* Deallocates heap space associated with the vtx array */ int i; for (i = 0; i < nvtx; i++) { SmoothList ptr = vtx [i].smoothList, aux; while (ptr != NULL) { aux = ptr->next; free (ptr); ptr = aux; } } free (vtx); vtx = NULL; nvtx = 0; } static int FindMatFace () { /* Finds an unused matface entry in 'matface' and returns its index */ int i; if (matface == NULL) { AllocMatFace (); } for (i = 0; i < nmat; i++) { if (matface [i].faceList == NULL) return i; } return -1; } static void FindSmooth (int ivtx, dword group) { /* Finds the in the list of normals/smoothing groups of vertex ivtx * the entry corresponding to 'group'. If it does not exist yet, one * is created. The entry is moved to the head of the list in order * to speed up new searches */ SmoothList *ptr; assert (vtx != NULL); assert (ivtx < nvtx); ptr = &(vtx [ivtx].smoothList); while (*ptr != NULL) { if ((*ptr)->group == group) break; ptr = &((*ptr)->next); } if (*ptr == NULL) { *ptr = (SmoothList) malloc (sizeof (struct SmoothInfoNode)); (*ptr)->group = group; (*ptr)->normal [0] = (*ptr)->normal [1] = (*ptr)->normal [2] = 0.0; (*ptr)->next = (SmoothList) NULL; } if (ptr != &(vtx [ivtx].smoothList)) { /* Move to front */ SmoothList aux = *ptr; *ptr = aux->next; aux->next = vtx [ivtx].smoothList; vtx [ivtx].smoothList = aux; } } static void SmoothVertices () { /* Average all vertex normals */ int i; SmoothList ptr; assert (vtx != NULL); for (i = 0; i < nvtx; i++) { for (ptr = vtx [i].smoothList; ptr != NULL; ptr = ptr->next) { float hyp = (float)sqrt (ptr->normal [0]*ptr->normal [0]+ ptr->normal [1]*ptr->normal [1]+ ptr->normal [2]*ptr->normal [2]); if (hyp == 0.0) continue; ptr->normal [0] /= hyp; ptr->normal [1] /= hyp; ptr->normal [2] /= hyp; } } } static int RenderFaceList (FaceList ptr) { /* Renders all triangular faces in list 'ptr'. Returns * the number of the display list used. */ int disp = glGenLists (1); assert (disp >= 0); glNewList (disp, GL_COMPILE); glBegin (GL_TRIANGLES); for (;ptr != NULL; ptr = ptr->next) { int iface = ptr->idx; dword group = face [iface].group; int i; for (i = 0; i < 3; i++) { int ivtx = face [iface].ivtx [i]; FindSmooth (ivtx, group); glNormal3fv (vtx [ivtx].smoothList->normal); if (vtx [ivtx].texFlag) { glTexCoord2fv (vtx [ivtx].texCoord); } glVertex3fv (vtx [ivtx].coord); } } glEnd (); glEndList(); return disp; } static void RenderAllFaces (Tcl_DString* desc) { int imatface, iface; char buf [80]; SmoothVertices (); if (matface == NULL) { /* No material/face list was given: render all faces with * flat normals and material = {} */ int disp = glGenLists(1); assert (disp >= 0); Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, "material-face"); Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, "material"); Tcl_DStringAppendElement (desc, ""); Tcl_DStringEndSublist (desc); Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, "nfaces"); sprintf (buf, "%d", nface); Tcl_DStringAppendElement (desc, buf); Tcl_DStringEndSublist (desc); Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, "displaylist"); sprintf (buf, "%d", disp); Tcl_DStringAppendElement (desc, buf); Tcl_DStringEndSublist (desc); Tcl_DStringEndSublist (desc); glNewList (disp, GL_COMPILE); glBegin (GL_TRIANGLES); for (iface = 0; iface < nface; iface++) { int i; glNormal3fv (face [iface].normal); for (i = 0; i < 3; i++) { int ivtx = face [iface].ivtx [i]; glVertex3fv (vtx [ivtx].coord); if (vtx [ivtx].texFlag) { glTexCoord2fv (vtx [ivtx].texCoord); } } } glEnd (); glEndList(); } else { /* Render faces in separate display lists according to matface */ for (imatface = 0; imatface < nmat; imatface++) { FaceList flist = matface [imatface].faceList; if (flist == NULL) continue; matface [imatface].displayList = RenderFaceList (flist); Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, "material-face"); Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, "material"); Tcl_DStringAppendElement (desc, matface [imatface].name); Tcl_DStringEndSublist (desc); Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, "nfaces"); sprintf (buf, "%d", matface [imatface].n); Tcl_DStringAppendElement (desc, buf); Tcl_DStringEndSublist (desc); Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, "displaylist"); sprintf (buf, "%d", matface [imatface].displayList); Tcl_DStringAppendElement (desc, buf); Tcl_DStringEndSublist (desc); Tcl_DStringEndSublist (desc); } } } /*--------------------------------------------------------------------------- * * The following are procedures for reading simple types from * a file stream. They require a fair amount of byte swapping in order * to cope with the different way Intel microprocessors store ints, floats, * etc. All procs return 1 on success and 0 if fail. * *---------------------------------------------------------------------------*/ static int ReadWord (FILE *f, word *wptr) { #if defined(__WIN32__) || defined(_WIN32) || defined(LINUX) unsigned char b [2]; if (fread (b, 2, 1, f) != 1) return 0; #else unsigned char b [2], tmp; if (fread (b, 2, 1, f) != 1) return 0; tmp = b [0]; b [0] = b [1]; b [1] = tmp; #endif memcpy ((char*) wptr, b, 2); return 1; } static int ReadWords (FILE *f, word *wptr, int nwords) { while (nwords--) { if (ReadWord (f, wptr++) != 1) return 0; } return 1; } static int ReadDWord (FILE *f, dword *wptr) { #if defined(__WIN32__) || defined(_WIN32) || defined(LINUX) word b [2]; if (ReadWords (f, b, 2) != 1) return 0; #else word b [2], tmp; if (ReadWords (f, b, 2) != 1) return 0; tmp = b [0]; b [0] = b [1]; b [1] = tmp; #endif memcpy ((char*) wptr, (char*) b, 4); return 1; } static int ReadFloat (FILE *f, float* fptr) { #if defined(__WIN32__) || defined(_WIN32) || defined(LINUX) word b [2]; if (ReadWords (f, b, 2) != 1) return 0; #else word b [2], tmp; if (ReadWords (f, b, 2) != 1) return 0; tmp = b [0]; b [0] = b [1]; b [1] = tmp; #endif memcpy ((char*) fptr, b, 4); return 1; } static int ReadFloats (FILE *f, float *fptr, int nfloats) { while (nfloats--) { if (ReadFloat (f, fptr++) != 1) return 0; } return 1; } /*--------------------------------------------------------------------------- * * These are the various procedures for reading each chnk type. The * default behaviour is to read the chunk and * store the appropriate information * about the chunk in the Tcl Desc result string * *---------------------------------------------------------------------------*/ static int FindChunk(word id) { int i; for (i = 0; i < sizeof(ChunkNames)/sizeof(ChunkNames[0]); i++) if (id == ChunkNames[i].id) return i; return -1; } static void ChunkReader(Tcl_DString* desc, FILE *f, long p) { TChunkHeader h; int n; long pc; /* char buf [80];*/ while (ftell(f) < p) { pc = ftell(f); if (ReadWord (f, &h.id) != 1 || ReadDWord (f, &h.len) != 1) return; /* printf ("Chunk %x len = %d\n", h.id, h.len); fflush (stdout); */ n = FindChunk(h.id); if (n < 0) { /* printf ("Unknown id\n"); fflush (stdout); sprintf (buf, "unknown {id 0x%04X} {offset 0x%lX} {size %d}", h.id, pc, h.len); Tcl_DStringAppendElement (desc, buf); */ if (h.len == 0) return; fseek(f, pc + h.len, SEEK_SET); } else { Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, ChunkNames[n].name); pc = pc + h.len; if (ChunkNames[n].func != NULL) ChunkNames[n].func(desc, f, pc); else ChunkReader(desc, f, pc); Tcl_DStringEndSublist (desc); fseek(f, pc, SEEK_SET); } if (ferror(f)) break; } } static void TriMeshReader(Tcl_DString* desc, FILE *f, long p) { TChunkHeader h; int n; long pc; while (ftell(f) < p) { pc = ftell(f); if (ReadWord (f, &h.id) != 1 || ReadDWord (f, &h.len) != 1) return; n = FindChunk(h.id); if (n < 0) { fseek(f, pc + h.len, SEEK_SET); } else { Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, ChunkNames[n].name); pc = pc + h.len; if (ChunkNames[n].func != NULL) ChunkNames[n].func(desc, f, pc); else ChunkReader(desc, f, pc); Tcl_DStringEndSublist (desc); fseek(f, pc, SEEK_SET); } if (ferror(f)) break; } RenderAllFaces (desc); FreeVtx (); FreeMatFace (); FreeFace (); } static void RGBFReader (Tcl_DString* desc, FILE *f, long p) { float c[3]; char buf [80]; int i; if (ReadFloats (f, c, 3) != 1) return; for (i = 0; i < 3; ++i) { sprintf (buf, "%f", c[i]); Tcl_DStringAppendElement (desc, buf); } } static void RGBBReader (Tcl_DString* desc, FILE *f, long p) { byte c[3]; char buf [80]; int i; if (fread(&c, sizeof(c), 1, f) != 1) return; for (i = 0; i < 3; ++i) { sprintf (buf, "%f", c[i]/255.0); Tcl_DStringAppendElement (desc, buf); } } static void PercentIReader (Tcl_DString* desc, FILE *f, long p) { word perc; char buf [80]; if (ReadWord (f, &perc) != 1) return; sprintf (buf, "%d", perc); Tcl_DStringAppendElement (desc, buf); } static void PercentFReader (Tcl_DString* desc, FILE *f, long p) { float perc; char buf [80]; if (ReadFloat (f, &perc) != 1) return; sprintf (buf, "%f", perc); Tcl_DStringAppendElement (desc, buf); } static void ObjBlockReader (Tcl_DString* desc, FILE *f, long p) { int i, c; char buf [80]; /* Read ASCIIZ object name */ for (i = 0; i < 80; i++) { c = fgetc(f); if (c == EOF || c == '\0') break; buf [i] = c; } buf [i] = '\0'; Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, "name"); Tcl_DStringAppendElement (desc, buf); Tcl_DStringEndSublist (desc); /* Read rest of chunks inside this one. */ ChunkReader(desc, f, p); } static void VertListReader (Tcl_DString* desc, FILE *f, long p) { word ivtx, nv, i; float c[3]; char buf [80]; Vector max; Vector min; if (ReadWord (f, &nv) != 1) return; sprintf (buf, "%d", nv); Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, "vertices"); Tcl_DStringAppendElement (desc, buf); Tcl_DStringEndSublist (desc); nvtx = nv; AllocVtx (); for (ivtx = 0; ivtx < nv; ivtx++) { if (ReadFloats (f, c, 3) != 1) assert (0); vtx [ivtx].texFlag = 0; if (ivtx == 0) { for (i = 0; i < 3; i++) { vtx [ivtx].coord [i] = c [i]; min [i] = c [i]; max [i] = c [i]; } } else { for (i = 0; i < 3; i++) { vtx [ivtx].coord [i] = c [i]; if (c [i] > max [i]) max [i] = c [i]; if (c [i] < min [i]) min [i] = c [i]; } } } Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, "min"); for (i = 0; i < 3; i++) { sprintf (buf, "%f", min [i]); Tcl_DStringAppendElement (desc, buf); } Tcl_DStringEndSublist (desc); Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, "max"); for (i = 0; i < 3; i++) { sprintf (buf, "%f", max [i]); Tcl_DStringAppendElement (desc, buf); } Tcl_DStringEndSublist (desc); } static void FaceListReader (Tcl_DString* desc, FILE *f, long p) { word iface, nv; word c[4]; char buf [80]; if (ReadWord (f, &nv) != 1) return; sprintf (buf, "%d", nv); Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, "faces"); Tcl_DStringAppendElement (desc, buf); Tcl_DStringEndSublist (desc); nface = nv; AllocFace (); for (iface = 0; iface < nface; iface++) { Vector e1, e2; float hypot; if (ReadWords (f, c, 4) != 1) assert(0); face [iface].ivtx [0] = c[0]; face [iface].ivtx [1] = c[1]; face [iface].ivtx [2] = c[2]; e1 [0] = vtx[c[1]].coord[0]-vtx[c[0]].coord[0]; e1 [1] = vtx[c[1]].coord[1]-vtx[c[0]].coord[1]; e1 [2] = vtx[c[1]].coord[2]-vtx[c[0]].coord[2]; e2 [0] = vtx[c[2]].coord[0]-vtx[c[1]].coord[0]; e2 [1] = vtx[c[2]].coord[1]-vtx[c[1]].coord[1]; e2 [2] = vtx[c[2]].coord[2]-vtx[c[1]].coord[2]; face [iface].normal [0] = e1[1]*e2[2]-e1[2]*e2[1]; face [iface].normal [1] = e2[0]*e1[2]-e2[2]*e1[0]; face [iface].normal [2] = e1[0]*e2[1]-e1[1]*e2[0]; hypot = (float)sqrt (face [iface].normal [0] * face [iface].normal [0] + face [iface].normal [1] * face [iface].normal [1] + face [iface].normal [2] * face [iface].normal [2]); if (hypot != 0.0) { face [iface].normal [0] /= hypot; face [iface].normal [1] /= hypot; face [iface].normal [2] /= hypot; } face [iface].flags = c[3]; face [iface].group = 0; } /* Read rest of chunks inside this one. */ ChunkReader(desc, f, p); } static void FaceMatReader (Tcl_DString* desc, FILE *f, long p) { int c, i, imat; word n, nf; FaceList *ptr; char buf[80]; /* Read ASCIIZ object name */ for (i = 0; i < 80; i++) { c = fgetc(f); if (c == EOF || c == '\0') break; buf [i] = c; } assert (i < 80); buf [i] = '\0'; imat = FindMatFace (buf); assert (imat >= 0 && imat < nmat); strcpy (matface [imat].name, buf); if (ReadWord (f, &n) != 1) assert (0); matface [imat].n = n; ptr = &matface [imat].faceList; while (n-- > 0) { if (ReadWord (f, &nf) != 1) assert (0); *ptr = (FaceList) malloc (sizeof (struct FaceListNode)); assert (*ptr != NULL); (*ptr)->next = NULL; (*ptr)->idx = nf; ptr = &(*ptr)->next; } } static void MapListReader (Tcl_DString* desc, FILE *f, long p) { word ivtx, nv; float c[2]; char buf[80]; if (ReadWord (f, &nv) != 1) return; Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, "vertexmap"); sprintf (buf, "%d", nv); Tcl_DStringAppendElement (desc, buf); Tcl_DStringEndSublist (desc); for (ivtx = 0; ivtx < nv; ivtx++) { if (ReadFloats (f, c, 2) != 1) return; vtx [ivtx].texFlag = 1; vtx [ivtx].texCoord [0] = c [0]; vtx [ivtx].texCoord [1] = c [1]; } } static void SmooListReader (Tcl_DString* desc, FILE *f, long p) { dword s; int i, j, n, ivtx; n = 0; while (ftell(f) < p) { if (ReadDWord (f, &s) != 1) assert(0); assert (n <= nface); face [n].group = s; for (i = 0; i < 3; i++) { ivtx = face [n].ivtx[i]; FindSmooth (ivtx, s); for (j = 0; j < 3; j++) { vtx [ivtx].smoothList->normal[j] += face [n].normal[j]; } } n++; } assert (n == nface); } static void TrMatrixReader(Tcl_DString* desc, FILE *f, long p) { float rot[12]; int i; char buf [80]; if (ReadFloats (f, rot, 12) != 1) return; for (i = 0; i < 12; ++i) { sprintf (buf, "%f", rot [i]); Tcl_DStringAppendElement (desc, buf); } } static void LightReader(Tcl_DString* desc, FILE *f, long p) { float c[3]; int i; char buf [80]; if (ReadFloats (f, c, 3) != 1) return; Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, "position"); for (i = 0; i < 3; ++i) { sprintf (buf, "%f", c[i]); Tcl_DStringAppendElement (desc, buf); } Tcl_DStringEndSublist (desc); /* Read rest of chunks inside this one. */ ChunkReader(desc, f, p); } static void SpotLightReader(Tcl_DString* desc, FILE *f, long p) { float c[5]; char buf [80]; int i; if (ReadFloats (f, c, 5) != 1) return; Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, "target"); for (i = 0; i < 3; i++) { sprintf (buf, "%f", c[i]); Tcl_DStringAppendElement (desc, buf); } Tcl_DStringAppend (desc, "} {hotspot", -1); sprintf (buf, "%f", c[3]); Tcl_DStringAppendElement (desc, buf); Tcl_DStringAppend (desc, "} {falloff", -1); sprintf (buf, "%f", c[4]); Tcl_DStringAppendElement (desc, buf); Tcl_DStringEndSublist (desc); } static void CameraReader(Tcl_DString* desc, FILE *f, long p) { float c[8]; char buf [80]; int i; if (ReadFloats (f, c, 8) != 1) return; Tcl_DStringStartSublist (desc); Tcl_DStringAppendElement (desc, "position"); for (i = 0; i < 3; i++) { sprintf (buf, "%f", c[i]); Tcl_DStringAppendElement (desc, buf); } Tcl_DStringAppend (desc, "} {target", -1); for (i = 3; i < 6; i++) { sprintf (buf, "%f", c[i]); Tcl_DStringAppendElement (desc, buf); } Tcl_DStringAppend (desc, "} {bank", -1); sprintf (buf, "%f", c[6]); Tcl_DStringAppendElement (desc, buf); Tcl_DStringAppend (desc, "} {lens", -1); sprintf (buf, "%f", c[7]); Tcl_DStringAppendElement (desc, buf); Tcl_DStringEndSublist (desc); } static void MatNameReader (Tcl_DString* desc, FILE *f, long p) { int i, c; char buf [80]; /* Read ASCIIZ object name */ for (i = 0; i < 80; i++) { c = fgetc(f); if (c == EOF || c == '\0') break; buf [i] = c; } buf [i] = '\0'; nmat++; Tcl_DStringAppendElement (desc, buf); } static void MapFileReader (Tcl_DString* desc, FILE *f, long p) { int i, c; char buf [80]; /* Read ASCIIZ object name */ for (i = 0; i < 80; i++) { c = fgetc(f); if (c == EOF || c == '\0') break; buf [i] = c; } buf [i] = '\0'; Tcl_DStringAppendElement (desc, buf); } static void FramesReader (Tcl_DString* desc, FILE *f, long p) { dword c[2]; char buf[80]; if (ReadDWord (f, &c[0]) != 1 || ReadDWord (f, &c[1]) != 1) return; Tcl_DStringStartSublist (desc); Tcl_DStringAppend (desc, "start", -1); sprintf (buf, "%d", (int)c[0]); Tcl_DStringAppendElement (desc, buf); Tcl_DStringAppend (desc, "} {end", -1); sprintf (buf, "%d", (int)c[1]); Tcl_DStringAppendElement (desc, buf); Tcl_DStringEndSublist (desc); } /* *--------------------------------------------------------------------------- * * This procedure loads a 3ds file created by the 3D-Studio software * package and pipes any triangles it may find into the GL pipeline * * The syntax is: * * "load3ds" * * where * is the name of an ASC file * * Result: If OK, a list where each element is a property list of * objects described in the file. Otherwise, an error message. * *--------------------------------------------------------------------------- */ int glLoad3DStudio (interp, argc, argv) Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Arg count */ char *argv []; /* Argument strings. */ { int result = TCL_OK; long p; FILE * file3D; Tcl_DString desclist; char* filename; if (argc != 3) { Tcl_AppendResult (interp, "wrong # args", (char*) NULL); return TCL_ERROR; } filename = argv [2]; #if defined(__WIN32__) || defined(_WIN32) file3D = fopen (filename, "rb"); #else file3D = fopen (filename, "r"); #endif if (file3D == NULL) { Tcl_AppendResult (interp, "Could not read ", filename, (char*) NULL); return TCL_ERROR; } /* Find file size. */ fseek(file3D, 0, SEEK_END); p = ftell(file3D); fseek(file3D, 0, SEEK_SET); /* Allocate a dynamic string to hold the result */ Tcl_DStringInit (&desclist); /* Go! */ ChunkReader(&desclist, file3D, p); fclose (file3D); Tcl_DStringResult (interp, &desclist); Tcl_DStringFree (&desclist); return result; } cgnslib_3.1.4/src/cgnstools/tkogl/stripcr.tcl0000664000076400007640000000052712160605670016300 00000000000000# # Rewrites all .c and .h files stripping CR characters # inserted by DOS/Windows text editors # foreach fname [glob *.c *.h] { puts $fname set f [open $fname] set g [open foobar w] while {! [eof $f]} { gets $f line puts $g $line } close $f close $g file delete -force $fname file rename foobar $fname } cgnslib_3.1.4/src/cgnstools/tkogl/glphoto.h0000664000076400007640000000011212160605670015721 00000000000000int glPhoto _ANSI_ARGS_((Tcl_Interp *interp, int argc, char* argv [])); cgnslib_3.1.4/src/cgnstools/tkogl/nurbs.h0000664000076400007640000000010212160605670015375 00000000000000int NurbsSurface (Tcl_Interp *interp, int argc, char* argv []); cgnslib_3.1.4/src/cgnstools/tkogl/quadric.h0000664000076400007640000000007512160605670015705 00000000000000int Quadric (Tcl_Interp *interp, int argc, char* argv []); cgnslib_3.1.4/src/cgnstools/tkogl/tkoglparse.c0000664000076400007640000020033212160605670016421 00000000000000#include #include #include #include "tkogl.h" #include "tkoglparse.h" #define ERRMSG(msg) { Tcl_AppendResult(interp,msg,(char*)NULL); \ result = TCL_ERROR; goto done; } #define ERRMSG2(msg1,msg2) { Tcl_AppendResult(interp,msg1,msg2,(char*)NULL); \ result = TCL_ERROR; goto done; } #define MAXARGS 200 /*--------------------------------------------------------------------------- * * The following is a table that implements the binding between * GL enum constants and their tcl names * *---------------------------------------------------------------------------*/ typedef struct { char * name; GLenum code; } parseItem; static parseItem enumTable [] = { {"accum", GL_ACCUM}, {"accumbuffer", GL_ACCUM_BUFFER_BIT}, {"accumbufferbit", GL_ACCUM_BUFFER_BIT}, {"add", GL_ADD}, {"alphatest", GL_ALPHA_TEST}, {"always", GL_ALWAYS}, {"allattrib", GL_ALL_ATTRIB_BITS}, {"allattribbits", GL_ALL_ATTRIB_BITS}, {"ambient", GL_AMBIENT}, {"ambientanddiffuse", GL_AMBIENT_AND_DIFFUSE}, {"autonormal", GL_AUTO_NORMAL}, {"aux0", GL_AUX0}, {"aux1", GL_AUX1}, {"aux2", GL_AUX2}, {"aux3", GL_AUX3}, {"back", GL_BACK}, {"backleft", GL_BACK_LEFT}, {"backright", GL_BACK_RIGHT}, {"blend", GL_BLEND}, {"bluebias", GL_BLUE_BIAS}, {"bluescale", GL_BLUE_SCALE}, {"ccw", GL_CCW}, {"clamp", GL_CLAMP}, {"clipplane0", GL_CLIP_PLANE0}, {"clipplane1", GL_CLIP_PLANE1}, {"clipplane2", GL_CLIP_PLANE2}, {"clipplane3", GL_CLIP_PLANE3}, {"clipplane4", GL_CLIP_PLANE4}, {"clipplane5", GL_CLIP_PLANE5}, {"colorbuffer", GL_COLOR_BUFFER_BIT}, {"colorbufferbit", GL_COLOR_BUFFER_BIT}, {"colorindex", GL_COLOR_INDEX}, {"colormaterial", GL_COLOR_MATERIAL}, {"compile", GL_COMPILE}, {"compileandaxecute", GL_COMPILE_AND_EXECUTE}, {"constantattenuation", GL_CONSTANT_ATTENUATION}, {"cullface", GL_CULL_FACE}, {"current", GL_CURRENT_BIT}, {"currentbit", GL_CURRENT_BIT}, {"cw", GL_CW}, {"decal", GL_DECAL}, {"decr", GL_DECR}, {"depthbuffer", GL_DEPTH_BUFFER_BIT}, {"depthbufferbit", GL_DEPTH_BUFFER_BIT}, {"depthtest", GL_DEPTH_TEST}, {"diffuse", GL_DIFFUSE}, {"dither", GL_DITHER}, {"dstalpha", GL_DST_ALPHA}, {"dstcolor", GL_DST_COLOR}, {"enable", GL_ENABLE_BIT}, {"enablebit", GL_ENABLE_BIT}, {"emission", GL_EMISSION}, {"equal", GL_EQUAL}, {"eval", GL_EVAL_BIT}, {"evalbit", GL_EVAL_BIT}, {"exp", GL_EXP}, {"exp2", GL_EXP2}, {"eyelinear", GL_EYE_LINEAR}, {"eyeplane", GL_EYE_PLANE}, {"fill", GL_FILL}, {"flat", GL_FLAT}, {"fog", GL_FOG}, {"fogbit", GL_FOG_BIT}, {"fogcolor", GL_FOG_COLOR}, {"fogdensity", GL_FOG_DENSITY}, {"fogend", GL_FOG_END}, {"fogmode", GL_FOG_MODE}, {"fogstart", GL_FOG_START}, {"front", GL_FRONT}, {"frontandback", GL_FRONT_AND_BACK}, {"frontleft", GL_FRONT_LEFT}, {"frontright", GL_FRONT_RIGHT}, {"gequal", GL_GEQUAL}, {"greater", GL_GREATER}, {"greenbias", GL_GREEN_BIAS}, {"greenscale", GL_GREEN_SCALE}, {"hint", GL_HINT_BIT}, {"hintbit", GL_HINT_BIT}, {"incr", GL_INCR}, {"invert", GL_INVERT}, {"keep", GL_KEEP}, {"left", GL_LEFT}, {"lequal", GL_LEQUAL}, {"less", GL_LESS}, {"light0", GL_LIGHT0}, {"light1", GL_LIGHT1}, {"light2", GL_LIGHT2}, {"light3", GL_LIGHT3}, {"light4", GL_LIGHT4}, {"light5", GL_LIGHT5}, {"light6", GL_LIGHT6}, {"light7", GL_LIGHT7}, {"lighting", GL_LIGHTING}, {"lightingbit", GL_LIGHTING_BIT}, {"lightmodelambient", GL_LIGHT_MODEL_AMBIENT}, {"lightmodellocalviewer", GL_LIGHT_MODEL_LOCAL_VIEWER}, {"lightmodeltwoside", GL_LIGHT_MODEL_TWO_SIDE}, {"line", GL_LINE}, {"linebit", GL_LINE_BIT}, {"linear", GL_LINEAR}, {"linearattenuation", GL_LINEAR_ATTENUATION}, {"lineloop", GL_LINE_LOOP}, {"lines", GL_LINES}, {"linesmooth", GL_LINE_SMOOTH}, {"linestipple", GL_LINE_STIPPLE}, {"linestrip", GL_LINE_STRIP}, {"list", GL_LIST_BIT}, {"listbit", GL_LIST_BIT}, {"load", GL_LOAD}, {"map1color4", GL_MAP1_COLOR_4}, {"map1normal", GL_MAP1_NORMAL}, {"map1texturecoord1", GL_MAP1_TEXTURE_COORD_1}, {"map1texturecoord2", GL_MAP1_TEXTURE_COORD_2}, {"map1texturecoord3", GL_MAP1_TEXTURE_COORD_3}, {"map1texturecoord4", GL_MAP1_TEXTURE_COORD_4}, {"map1vertex3", GL_MAP1_VERTEX_3}, {"map1vertex4", GL_MAP1_VERTEX_4}, {"map2color4", GL_MAP2_COLOR_4}, {"map2normal", GL_MAP2_NORMAL}, {"map2texturecoord1", GL_MAP2_TEXTURE_COORD_1}, {"map2texturecoord2", GL_MAP2_TEXTURE_COORD_2}, {"map2texturecoord3", GL_MAP2_TEXTURE_COORD_3}, {"map2texturecoord4", GL_MAP2_TEXTURE_COORD_4}, {"map2vertex3", GL_MAP2_VERTEX_3}, {"map2vertex4", GL_MAP2_VERTEX_4}, {"modelview", GL_MODELVIEW}, {"modulate", GL_MODULATE}, {"mult", GL_MULT}, {"nearest", GL_NEAREST}, {"never", GL_NEVER}, {"none", GL_NONE}, {"normalize", GL_NORMALIZE}, {"notequal", GL_NOTEQUAL}, {"objectlinear", GL_OBJECT_LINEAR}, {"objectplane", GL_OBJECT_PLANE}, {"one", GL_ONE}, {"oneminusdstalpha", GL_ONE_MINUS_DST_ALPHA}, {"oneminusdstcolor", GL_ONE_MINUS_DST_COLOR}, {"oneminussrcalpha", GL_ONE_MINUS_SRC_ALPHA}, {"oneminussrccolor", GL_ONE_MINUS_SRC_COLOR}, {"packalignment", GL_PACK_ALIGNMENT}, {"packlsbfirst", GL_PACK_LSB_FIRST}, {"packrowlength", GL_PACK_ROW_LENGTH}, {"packskippixels", GL_PACK_SKIP_PIXELS}, {"packskiprows", GL_PACK_SKIP_ROWS}, {"packswapbytes", GL_PACK_SWAP_BYTES}, {"pixelmode", GL_PIXEL_MODE_BIT}, {"pixelmodebit", GL_PIXEL_MODE_BIT}, {"point", GL_POINT}, {"pointbit", GL_POINT_BIT}, {"points", GL_POINTS}, {"polygon", GL_POLYGON}, {"polygonbit", GL_POLYGON_BIT}, {"polygonstipple", GL_POLYGON_STIPPLE_BIT}, {"polygonstipplebit", GL_POLYGON_STIPPLE_BIT}, {"position", GL_POSITION}, {"projection", GL_PROJECTION}, {"q", GL_Q}, {"quadraticattenuation", GL_QUADRATIC_ATTENUATION}, {"quads", GL_QUADS}, {"quadstrip", GL_QUAD_STRIP}, {"r", GL_R}, {"redbias", GL_RED_BIAS}, {"redscale", GL_RED_SCALE}, {"repeat", GL_REPEAT}, {"replace", GL_REPLACE}, {"return", GL_RETURN}, {"right", GL_RIGHT}, {"s", GL_S}, {"scissor", GL_SCISSOR_TEST}, {"scissorbit", GL_SCISSOR_BIT}, {"shininess", GL_SHININESS}, {"smooth", GL_SMOOTH}, {"specular", GL_SPECULAR}, {"spheremap", GL_SPHERE_MAP}, {"spotcutoff", GL_SPOT_CUTOFF}, {"spotdirecion", GL_SPOT_DIRECTION}, {"spotexponent", GL_SPOT_EXPONENT}, {"srcalpha", GL_SRC_ALPHA}, {"srcalphasaturate", GL_SRC_ALPHA_SATURATE}, {"srccolor", GL_SRC_COLOR}, {"stenciltest", GL_STENCIL_TEST}, {"stencilbuffer", GL_STENCIL_BUFFER_BIT}, {"stencilbufferbit", GL_STENCIL_BUFFER_BIT}, {"t", GL_T}, {"texture", GL_TEXTURE}, {"texture1d", GL_TEXTURE_1D}, {"texture2d", GL_TEXTURE_2D}, {"texturebit", GL_TEXTURE_BIT}, {"texturebordercolor", GL_TEXTURE_BORDER_COLOR}, {"textureenv", GL_TEXTURE_ENV}, {"textureenvcolor", GL_TEXTURE_ENV_COLOR}, {"textureenvmode", GL_TEXTURE_ENV_MODE}, {"texturegenmode", GL_TEXTURE_GEN_MODE}, {"texturegens", GL_TEXTURE_GEN_S}, {"texturegent", GL_TEXTURE_GEN_T}, {"texturemagfilter", GL_TEXTURE_MAG_FILTER}, {"textureminfilter", GL_TEXTURE_MIN_FILTER}, {"texturewraps", GL_TEXTURE_WRAP_S}, {"texturewrapt", GL_TEXTURE_WRAP_T}, {"transform", GL_TRANSFORM_BIT}, {"transformbit", GL_TRANSFORM_BIT}, {"triangles", GL_TRIANGLES}, {"trianglefan", GL_TRIANGLE_FAN}, {"trianglestrip", GL_TRIANGLE_STRIP}, {"unpackalignment", GL_UNPACK_ALIGNMENT}, {"unpacklsbfirst", GL_UNPACK_LSB_FIRST}, {"unpackrowlength", GL_UNPACK_ROW_LENGTH}, {"unpackskippixels", GL_UNPACK_SKIP_PIXELS}, {"unpackskiprows", GL_UNPACK_SKIP_ROWS}, {"unpackswapbytes", GL_UNPACK_SWAP_BYTES}, {"viewport", GL_VIEWPORT_BIT}, {"viewportbit", GL_VIEWPORT_BIT}, {"zero", GL_ZERO} }; /*--------------------------------------------------------------------------- * * The following are tables of enum constants that are required as * arguments for various OpenGL functions * *---------------------------------------------------------------------------*/ static GLenum primTable [] = { GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_LINE_LOOP, GL_POLYGON, GL_QUADS, GL_QUAD_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN }; /* Names for capabilities set/reset by glEnable/glDisable */ static GLenum capabTable [] = { GL_ALPHA_TEST, GL_AUTO_NORMAL, GL_BLEND, GL_COLOR_MATERIAL, GL_CLIP_PLANE0, GL_CLIP_PLANE1, GL_CLIP_PLANE2, GL_CLIP_PLANE3, GL_CLIP_PLANE4, GL_CLIP_PLANE5, GL_CULL_FACE, GL_DEPTH_TEST, GL_DITHER, GL_FOG, GL_LINE_SMOOTH, GL_LIGHT0, GL_LIGHT1, GL_LIGHT2, GL_LIGHT3, GL_LIGHT4, GL_LIGHT5, GL_LIGHT6, GL_LIGHT7, GL_LIGHTING, GL_LINE_STIPPLE, GL_MAP1_VERTEX_3, GL_MAP1_VERTEX_4, GL_MAP1_COLOR_4, GL_MAP1_NORMAL, GL_MAP1_TEXTURE_COORD_1, GL_MAP1_TEXTURE_COORD_2, GL_MAP1_TEXTURE_COORD_3, GL_MAP1_TEXTURE_COORD_4, GL_MAP2_VERTEX_3, GL_MAP2_VERTEX_4, GL_MAP2_COLOR_4, GL_MAP2_NORMAL, GL_MAP2_TEXTURE_COORD_1, GL_MAP2_TEXTURE_COORD_2, GL_MAP2_TEXTURE_COORD_3, GL_MAP2_TEXTURE_COORD_4, GL_NORMALIZE, GL_SCISSOR_TEST, GL_STENCIL_TEST, GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_GEN_S, GL_TEXTURE_GEN_T }; /* Names for glMatrixMode */ static GLenum matrixModeTable [] = { GL_MODELVIEW, GL_PROJECTION, GL_TEXTURE, }; /* Names describing face sides (for glPolygonMode and Material) */ static GLenum faceTable [] = { GL_BACK, GL_FRONT, GL_FRONT_AND_BACK, }; /* Names describing face sides (for glCullFace) */ static GLenum cullFaceTable [] = { GL_BACK, GL_FRONT }; /* Names for glPolygonMode */ static GLenum pModeTable [] = { GL_FILL, GL_LINE, GL_POINT }; /* Names for glLightModel */ static GLenum lightModelTable [] = { GL_LIGHT_MODEL_AMBIENT, GL_LIGHT_MODEL_LOCAL_VIEWER, GL_LIGHT_MODEL_TWO_SIDE }; /* Names for Material attribute (glMaterial) */ static GLenum matParmTable[] = { GL_AMBIENT, GL_SPECULAR, GL_DIFFUSE, GL_EMISSION, GL_SHININESS, GL_AMBIENT_AND_DIFFUSE, GL_COLOR_INDEX }; /* Names for mode of glColorMaterial */ static GLenum modeColorMatTable[] = { GL_AMBIENT, GL_SPECULAR, GL_DIFFUSE, GL_EMISSION, GL_AMBIENT_AND_DIFFUSE }; /* Names for Light numbers (glLight) */ static GLenum lightNumberTable[] = { GL_LIGHT0, GL_LIGHT1, GL_LIGHT2, GL_LIGHT3, GL_LIGHT4, GL_LIGHT5, GL_LIGHT6, GL_LIGHT7 }; /* Names for Light attributes (glLight) */ static GLenum lightParmTable[] = { GL_AMBIENT, GL_CONSTANT_ATTENUATION, GL_DIFFUSE, GL_LINEAR_ATTENUATION, GL_POSITION, GL_QUADRATIC_ATTENUATION, GL_SPECULAR, GL_SPOT_CUTOFF, GL_SPOT_DIRECTION, GL_SPOT_EXPONENT }; /* Names for glShadeModel */ static GLenum shadeModelTable [] = { GL_FLAT, GL_SMOOTH }; /* Names for glClear */ static GLenum bufferTable [] = { GL_ACCUM_BUFFER_BIT, GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT }; /* Names for glPixelStore */ #if 0 static GLenum pixelStoreTable [] = { GL_PACK_ALIGNMENT, GL_PACK_LSB_FIRST, GL_PACK_ROW_LENGTH, GL_PACK_SKIP_PIXELS, GL_PACK_SKIP_ROWS, GL_PACK_SWAP_BYTES, GL_UNPACK_ALIGNMENT, GL_UNPACK_LSB_FIRST, GL_UNPACK_ROW_LENGTH, GL_UNPACK_SKIP_PIXELS, GL_UNPACK_SKIP_ROWS, GL_UNPACK_SWAP_BYTES }; #endif /* Param names for glPixelTransfer */ static GLenum pixelTransferTable [] = { GL_RED_SCALE, GL_GREEN_SCALE, GL_BLUE_SCALE, GL_RED_BIAS, GL_GREEN_BIAS, GL_BLUE_BIAS }; /* Target names for glTexParameter */ static GLenum targetTexParamTable [] = { GL_TEXTURE_1D, GL_TEXTURE_2D }; /* pnames for glTexParameter */ static GLenum nameTexParamTable [] = { GL_TEXTURE_BORDER_COLOR, GL_TEXTURE_MAG_FILTER, GL_TEXTURE_MIN_FILTER, GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T }; /* values for glTexParameter */ static GLenum valueTexParamTable [] = { GL_NEAREST, GL_LINEAR, GL_CLAMP, GL_REPEAT }; /* target names for glTexEnv */ static GLenum targetTexEnvTable [] = { GL_TEXTURE_ENV }; /* pnames for glTexEnv */ static GLenum nameTexEnvTable [] = { GL_TEXTURE_ENV_MODE, GL_TEXTURE_ENV_COLOR }; /* value names for glTexEnv */ static GLenum valueTexEnvTable [] = { GL_MODULATE, GL_DECAL, GL_BLEND }; /* coord names for glTexGen */ static GLenum coordTexGenTable [] = { GL_S, GL_T, GL_R, GL_Q }; /* pnames for glTexGen */ static GLenum nameTexGenTable [] = { GL_TEXTURE_GEN_MODE, GL_OBJECT_PLANE, GL_EYE_PLANE }; /* values for glTexGen */ static GLenum valueTexGenTable [] = { GL_OBJECT_LINEAR, GL_EYE_LINEAR, GL_SPHERE_MAP }; /* target names for glMap1 */ static GLenum targetMap1Table [] = { GL_MAP1_VERTEX_3, GL_MAP1_VERTEX_4, GL_MAP1_COLOR_4, GL_MAP1_NORMAL, GL_MAP1_TEXTURE_COORD_1, GL_MAP1_TEXTURE_COORD_2, GL_MAP1_TEXTURE_COORD_3, GL_MAP1_TEXTURE_COORD_4 }; /* target names for glMap2 */ static GLenum targetMap2Table [] = { GL_MAP2_VERTEX_3, GL_MAP2_VERTEX_4, GL_MAP2_COLOR_4, GL_MAP2_NORMAL, GL_MAP2_TEXTURE_COORD_1, GL_MAP2_TEXTURE_COORD_2, GL_MAP2_TEXTURE_COORD_3, GL_MAP2_TEXTURE_COORD_4 }; /* Names for glEvalMesh1 */ static GLenum modeMesh1Table [] = { GL_LINE, GL_POINT }; /* Names for glEvalMesh2 */ static GLenum modeMesh2Table [] = { GL_FILL, GL_LINE, GL_POINT }; /* Names for glFog */ static GLenum nameFogTable [] = { GL_FOG_MODE, GL_FOG_DENSITY, GL_FOG_START, GL_FOG_END, GL_FOG_COLOR }; /* Mode names for glFog (GL_FOG_MODE ...) */ static GLenum fogFogModeTable [] = { GL_EXP, GL_EXP2, GL_LINEAR }; /* Names for glFrontFace */ static GLenum nameFrontFaceTable [] = { GL_CW, GL_CCW }; /* mode names for glDrawBuffer */ static GLenum modeDrawBufferTable [] = { GL_FRONT, GL_BACK, GL_RIGHT, GL_LEFT, GL_FRONT_RIGHT, GL_FRONT_LEFT, GL_BACK_RIGHT, GL_BACK_LEFT, GL_FRONT_AND_BACK, GL_AUX0, GL_AUX1, GL_AUX2, GL_AUX3, GL_NONE }; /* mode names for glReadBuffer */ static GLenum modeReadBufferTable [] = { GL_FRONT, GL_BACK, GL_RIGHT, GL_LEFT, GL_FRONT_RIGHT, GL_FRONT_LEFT, GL_BACK_RIGHT, GL_BACK_LEFT, GL_AUX0, GL_AUX1, GL_AUX2, GL_AUX3 }; /* func names for glAlphaFunc, glDepthFunc and glStencilFunc */ static GLenum funcAlphaStencilTable [] = { GL_NEVER, GL_ALWAYS, GL_LESS, GL_LEQUAL, GL_EQUAL, GL_GEQUAL, GL_GREATER, GL_NOTEQUAL }; /* op names for glStencilOp */ static GLenum opStencilTable [] = { GL_KEEP, GL_ZERO, GL_REPLACE, GL_INCR, GL_DECR, GL_INVERT }; /* op names for glAccum */ static GLenum opAccumTable [] = { GL_ACCUM, GL_LOAD, GL_ADD, GL_MULT, GL_RETURN }; /* sfactor names for glBlendFunc */ static GLenum sfactorBlendTable [] = { GL_ZERO, GL_ONE, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA_SATURATE }; /* dfactor names for glBlendFunc */ static GLenum dfactorBlendTable [] = { GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA, }; /* clipplane names for glClipPlane */ static GLenum clipPlaneTable [] = { GL_CLIP_PLANE0, GL_CLIP_PLANE1, GL_CLIP_PLANE2, GL_CLIP_PLANE3, GL_CLIP_PLANE4, GL_CLIP_PLANE5 }; /* bit names for glPushAttrib */ static GLenum attribNameTable [] = { GL_ACCUM_BUFFER_BIT, GL_ALL_ATTRIB_BITS, GL_COLOR_BUFFER_BIT, GL_CURRENT_BIT, GL_DEPTH_BUFFER_BIT, GL_ENABLE_BIT, GL_EVAL_BIT, GL_FOG_BIT, GL_HINT_BIT, GL_LIGHTING_BIT, GL_LINE_BIT, GL_LIST_BIT, GL_PIXEL_MODE_BIT, GL_POINT_BIT, GL_POLYGON_BIT, GL_POLYGON_STIPPLE_BIT, GL_SCISSOR_BIT, GL_STENCIL_BUFFER_BIT, GL_TEXTURE_BIT, GL_TRANSFORM_BIT, GL_VIEWPORT_BIT }; /* names for glNewList */ static GLenum newListTable [] = { GL_COMPILE, GL_COMPILE_AND_EXECUTE }; /* target names for glHint */ static GLenum hintTargetTable [] = { GL_FOG_HINT, GL_LINE_SMOOTH_HINT, GL_PERSPECTIVE_CORRECTION_HINT, GL_POINT_SMOOTH_HINT, GL_POLYGON_SMOOTH_HINT }; /* mode names for glHint */ static GLenum hintModeTable [] = { GL_FASTEST, GL_NICEST, GL_DONT_CARE }; /*--------------------------------------------------------------------------- * * The following data structures describe what arguments each GL function * expects. * *---------------------------------------------------------------------------*/ typedef enum { ARG_ENUM, /* Name of parse table follows */ ARG_BIT_FIELD, /* Name of parse table follows */ ARG_FLOAT, /* Number of floats follow */ ARG_INT, /* Number of ints follow */ ARG_BOOLEAN, /* Number of booleans follow */ ARG_VAR_FLOAT, /* Min # args, max # args, defaults follow */ ARG_STRING, /* A char string */ ARG_DONT_CARE /* All remaining args are unprocessed initially */ } ArgType; typedef struct ArgDetailStruct { ArgType type; union { struct { GLenum * enumTable; int enumSize; } enumDetail; int nValues; struct { int minArgs, maxArgs; GLfloat def [3]; } varFloatDetail; } detail; struct ArgDetailStruct * next; } * ArgDetailList, ArgDetail; /*---------------------------------------------------------------------------- * * Each of the following procs generates an appropriate Arg Detail description * *---------------------------------------------------------------------------*/ #define ArgEnum(enumTable,next) \ ArgEnumTable (enumTable, sizeof(enumTable)/sizeof(GLenum), ARG_ENUM, next) #define ArgBitField(enumTable,next) \ ArgEnumTable (enumTable, sizeof(enumTable)/sizeof(GLenum), ARG_BIT_FIELD,\ next) static ArgDetailList ArgEnumTable (enumTable, enumTableSize, type, next) GLenum * enumTable; int enumTableSize; ArgDetailList next; ArgType type; { ArgDetailList arg = (ArgDetailList) malloc (sizeof (ArgDetail)); assert (arg != NULL); arg->type = type; arg->detail.enumDetail.enumTable = enumTable; arg->detail.enumDetail.enumSize = enumTableSize; arg->next = next; return arg; } static ArgDetailList ArgFloat (nValues, next) int nValues; ArgDetailList next; { ArgDetailList arg = (ArgDetailList) malloc (sizeof (ArgDetail)); assert (arg != NULL); arg->type = ARG_FLOAT; arg->detail.nValues = nValues; arg->next = next; return arg; } static ArgDetailList ArgInt (nValues, next) int nValues; ArgDetailList next; { ArgDetailList arg = (ArgDetailList) malloc (sizeof (ArgDetail)); assert (arg != NULL); arg->type = ARG_INT; arg->detail.nValues = nValues; arg->next = next; return arg; } static ArgDetailList ArgBoolean (nValues, next) int nValues; ArgDetailList next; { ArgDetailList arg = (ArgDetailList) malloc (sizeof (ArgDetail)); assert (arg != NULL); arg->type = ARG_BOOLEAN; arg->detail.nValues = nValues; arg->next = next; return arg; } static ArgDetailList ArgString (next) ArgDetailList next; { ArgDetailList arg = (ArgDetailList) malloc (sizeof (ArgDetail)); assert (arg != NULL); arg->type = ARG_STRING; arg->next = next; return arg; } static ArgDetailList ArgDontCare (next) ArgDetailList next; { ArgDetailList arg = (ArgDetailList) malloc (sizeof (ArgDetail)); assert (arg != NULL); arg->type = ARG_DONT_CARE; arg->next = next; return arg; } static ArgDetailList ArgVarFloat (minArgs, maxArgs, def0, def1, def2, next) int minArgs, maxArgs; GLfloat def0, def1, def2; ArgDetailList next; { ArgDetailList arg = (ArgDetailList) malloc (sizeof (ArgDetail)); assert (arg != NULL); assert (maxArgs - minArgs <= 3); arg->type = ARG_VAR_FLOAT; arg->detail.varFloatDetail.minArgs = minArgs; arg->detail.varFloatDetail.maxArgs = maxArgs; arg->detail.varFloatDetail.def[0] = (GLfloat)def0; arg->detail.varFloatDetail.def[1] = (GLfloat)def1; arg->detail.varFloatDetail.def[2] = (GLfloat)def2; arg->next = next; return arg; } /*--------------------------------------------------------------------------- * * Data structures that define how to parse command lines that generate * calls to GL functions. Each GL function has an entry in funcDescTable * which contains the corresponding tcl binding (that has to be preceded * by a dash in the style of tcl options), an encoded description of its * argument list and a function which is to be called if the parse is * successful * *---------------------------------------------------------------------------*/ typedef int TkOGLFunc _ANSI_ARGS_((Tcl_Interp* interp, void** args, int nargs)); static TkOGLFunc TkAccum, TkAlphaFunc, TkBegin, TkBlendFunc, TkCall, TkClear, TkClearAccum, TkClearColor, TkClearDepth, TkClearStencil, TkClipPlane, TkColor, TkColorMask, TkColorMaterial, TkCopyPixels, TkCullFace, TkDepthFunc, TkDepthMask, TkDisable, TkDrawBuffer, TkDrawPixels, TkEdgeFlag, TkEnable, TkEnd, TkEndList, TkEvalCoord1, TkEvalCoord2, TkEvalMesh1, TkEvalMesh2, TkFlush, TkFinish, TkFog, TkFrontFace, TkFrustum, TkHint, TkInitNames, TkLight, TkLightModel, TkLineStipple, TkLineWidth, TkLoadIdentity, TkLoadMatrix, TkLoadName, TkLookAt, TkMap1, TkMap2, TkMapGrid1, TkMapGrid2, TkMaterial, TkMatrixMode, TkMultMatrix, TkNewList, TkNormal, TkOrtho, TkPerspective, TkPickMatrix, TkPixelTransfer, TkPixelZoom, TkPointSize, TkPolygonMode, TkPopAttrib, TkPopMatrix, TkPopName, TkPushAttrib, TkPushMatrix, TkPushName, TkRasterPos, TkReadBuffer, TkReadPixels, TkRect, TkRotate, TkScale, TkScissor, TkShadeModel, TkStencilFunc, TkStencilMask, TkStencilOp, TkTexCoord, TkTexEnv, TkTexGen, TkTexImage1D, TkTexImage2D, TkTexParameter, TkTranslate, TkVertex; typedef struct funcDescStruct { TkOGLFunc *func; ArgDetailList argList; } FuncDesc; /*--------------------------------------------------------------------------- * * Initialization of the Hash Tables that govern the parsing * subsystem * *---------------------------------------------------------------------------*/ Tcl_HashTable funcDescHashTable, enumHashTable; static void InsDesc (tclName, func, argList) char * tclName; TkOGLFunc *func; ArgDetailList argList; { Tcl_HashEntry *descEntry; int newEntry = 0; FuncDesc * where; descEntry = Tcl_CreateHashEntry (&funcDescHashTable, tclName, &newEntry); assert (newEntry); where = (FuncDesc *) malloc (sizeof (FuncDesc)); assert (where!=NULL); (where)->func = func; (where)->argList = argList; Tcl_SetHashValue (descEntry, (ClientData) where); } void InitHashTables () { int i, newEntry; Tcl_HashEntry *enumEntry; Tcl_InitHashTable (&funcDescHashTable, TCL_STRING_KEYS); Tcl_InitHashTable (&enumHashTable, TCL_STRING_KEYS); for (i = 0; i < sizeof (enumTable)/sizeof(parseItem); i++) { enumEntry = Tcl_CreateHashEntry (&enumHashTable, enumTable [i].name, &newEntry); Tcl_SetHashValue (enumEntry, (ClientData)((size_t)(enumTable [i].code))); assert (newEntry); } InsDesc ("matrixmode" , TkMatrixMode, ArgEnum(matrixModeTable, NULL)); InsDesc ("pushmatrix" , TkPushMatrix, NULL); InsDesc ("popmatrix" , TkPopMatrix, NULL); InsDesc ("loadidentity",TkLoadIdentity,NULL); InsDesc ("multmatrix" , TkMultMatrix, ArgFloat(16, NULL)); InsDesc ("loadmatrix" , TkLoadMatrix, ArgFloat(16, NULL)); InsDesc ("translate" , TkTranslate, ArgFloat(3, NULL)); InsDesc ("rotate" , TkRotate, ArgFloat(4, NULL)); InsDesc ("scale" , TkScale, ArgFloat(3, NULL)); InsDesc ("call" , TkCall, ArgInt(1, NULL)); InsDesc ("calllist" , TkCall, ArgInt(1, NULL)); InsDesc ("vertex" , TkVertex, ArgVarFloat(2, 4, 0., 1., 0., NULL)); InsDesc ("normal" , TkNormal, ArgFloat(3, NULL)); InsDesc ("color" , TkColor, ArgVarFloat(3, 4, 1., 0., 0., NULL)); InsDesc ("clear" , TkClear, ArgBitField(bufferTable, NULL)); InsDesc ("clearcolor" , TkClearColor, ArgVarFloat(3, 4, 1., 0., 0., NULL)); InsDesc ("cleardepth" , TkClearDepth, ArgFloat(1, NULL)); InsDesc ("clearstencil",TkClearStencil,ArgInt(1, NULL)); InsDesc ("enable" , TkEnable, ArgEnum(capabTable, NULL)); InsDesc ("disable" , TkDisable, ArgEnum(capabTable, NULL)); InsDesc ("polygonmode", TkPolygonMode, ArgEnum(faceTable, ArgEnum (pModeTable, NULL))); InsDesc ("material" , TkMaterial, ArgEnum(faceTable, ArgEnum (matParmTable, ArgVarFloat(1,4, 0., 0., 1.,NULL)))); InsDesc ("light" , TkLight, ArgEnum(lightNumberTable, ArgEnum (lightParmTable, ArgVarFloat(1,4, 0., 0., 1.,NULL)))); InsDesc ("lightmodel" , TkLightModel, ArgEnum(lightModelTable, ArgVarFloat(1,4, .2, .2, 1.,NULL))); InsDesc ("shademodel" , TkShadeModel, ArgEnum(shadeModelTable, NULL)); InsDesc ("begin" , TkBegin, ArgEnum(primTable, NULL)); InsDesc ("end" , TkEnd, NULL); InsDesc ("perspective", TkPerspective, ArgFloat(4,NULL)); InsDesc ("lookat" , TkLookAt, ArgFloat(9,NULL)); InsDesc ("ortho" , TkOrtho, ArgFloat(6,NULL)); InsDesc ("frustum" , TkFrustum, ArgFloat(6,NULL)); InsDesc ("readpixels" , TkReadPixels, ArgInt(2, ArgString(NULL))); InsDesc ("drawpixels" , TkDrawPixels, ArgString(NULL)); InsDesc ("copypixels" , TkCopyPixels, ArgInt (4, NULL)); InsDesc ("pixelzoom" , TkPixelZoom, ArgFloat (2, NULL)); InsDesc ("rasterpos" , TkRasterPos, ArgVarFloat (2, 4, 0., 1., 0.,NULL)); InsDesc ("pixeltransfer", TkPixelTransfer, ArgEnum(pixelTransferTable, ArgFloat(1, NULL))); InsDesc ("texcoord" , TkTexCoord, ArgVarFloat (1, 4, 0., 0., 1.,NULL)); InsDesc ("teximage2d" , TkTexImage2D, ArgInt(2, ArgString(NULL))); InsDesc ("teximage1d" , TkTexImage1D, ArgInt(2, ArgString(NULL))); InsDesc ("texparameter",TkTexParameter,ArgEnum(targetTexParamTable, ArgEnum(nameTexParamTable, ArgDontCare(NULL)))); InsDesc ("texenv", TkTexEnv, ArgEnum(targetTexEnvTable, ArgEnum(nameTexEnvTable, ArgDontCare(NULL)))); InsDesc ("texgen", TkTexGen, ArgEnum(coordTexGenTable, ArgEnum(nameTexGenTable, ArgDontCare(NULL)))); InsDesc ("initnames", TkInitNames, NULL); InsDesc ("loadname", TkLoadName, ArgInt(1,NULL)); InsDesc ("pushname", TkPushName, ArgInt(1,NULL)); InsDesc ("popname", TkPopName, NULL); InsDesc ("pickmatrix", TkPickMatrix, ArgFloat(4,NULL)); InsDesc ("map1", TkMap1, ArgEnum(targetMap1Table, ArgFloat(2, ArgInt(2, ArgDontCare(NULL))))); InsDesc ("map2", TkMap2, ArgEnum(targetMap2Table, ArgFloat(2, ArgInt(2, ArgFloat(2, ArgInt(2, ArgDontCare(NULL))))))); InsDesc ("evalcoord1", TkEvalCoord1, ArgFloat (1, NULL)); InsDesc ("evalcoord2", TkEvalCoord2, ArgFloat (2, NULL)); InsDesc ("mapgrid1", TkMapGrid1, ArgInt (1, ArgFloat (2, NULL))); InsDesc ("mapgrid2", TkMapGrid2, ArgInt (1, ArgFloat (2, ArgInt (1, ArgFloat (2, NULL))))); InsDesc ("evalmesh1", TkEvalMesh1, ArgEnum (modeMesh1Table, ArgInt (2, NULL))); InsDesc ("evalmesh2", TkEvalMesh2, ArgEnum (modeMesh2Table, ArgInt (4, NULL))); InsDesc ("pointsize", TkPointSize, ArgFloat (1, NULL)); InsDesc ("linewidth", TkLineWidth, ArgFloat (1, NULL)); InsDesc ("linestipple", TkLineStipple, ArgInt (2, NULL)); InsDesc ("fog", TkFog, ArgEnum (nameFogTable, ArgDontCare(NULL))); InsDesc ("frontface", TkFrontFace, ArgEnum (nameFrontFaceTable, NULL)); InsDesc ("colormaterial", TkColorMaterial, ArgEnum (faceTable, ArgEnum (modeColorMatTable, NULL))); InsDesc ("clearaccum", TkClearAccum, ArgFloat (4,NULL)); InsDesc ("drawbuffer", TkDrawBuffer, ArgEnum (modeDrawBufferTable, NULL)); InsDesc ("colormask", TkColorMask, ArgBoolean (4, NULL)); InsDesc ("depthmask", TkDepthMask, ArgBoolean (1, NULL)); InsDesc ("stencilmask", TkStencilMask, ArgInt (1, NULL)); InsDesc ("scissor", TkScissor, ArgInt (4, NULL)); InsDesc ("alphafunc", TkAlphaFunc, ArgEnum (funcAlphaStencilTable, ArgFloat (1, NULL))); InsDesc ("depthfunc", TkDepthFunc, ArgEnum (funcAlphaStencilTable, NULL)); InsDesc ("stencilfunc", TkStencilFunc, ArgEnum (funcAlphaStencilTable, ArgInt(2, NULL))); InsDesc ("stencilop", TkStencilOp, ArgEnum (opStencilTable, ArgEnum (opStencilTable, ArgEnum (opStencilTable, NULL)))); InsDesc ("accum", TkAccum, ArgEnum (opAccumTable, ArgFloat (1, NULL))); InsDesc ("readbuffer", TkReadBuffer, ArgEnum (modeReadBufferTable, NULL)); InsDesc ("blendfunc", TkBlendFunc, ArgEnum (sfactorBlendTable, ArgEnum (dfactorBlendTable, NULL))); InsDesc ("clipplane", TkClipPlane, ArgEnum (clipPlaneTable, ArgFloat (4, NULL))); InsDesc ("pushattrib", TkPushAttrib, ArgBitField(attribNameTable, NULL)); InsDesc ("popattrib", TkPopAttrib, NULL); InsDesc ("newlist", TkNewList, ArgInt (1, ArgEnum (newListTable, NULL))); InsDesc ("endlist", TkEndList, NULL); InsDesc ("edgeflag", TkEdgeFlag, ArgBoolean (1, NULL)); InsDesc ("flush", TkFlush, NULL); InsDesc ("finish", TkFinish, NULL); InsDesc ("hint", TkHint, ArgEnum (hintTargetTable, ArgEnum (hintModeTable, NULL))); InsDesc ("rect", TkRect, ArgFloat (4, NULL)); InsDesc ("cullface", TkCullFace, ArgEnum (cullFaceTable, NULL)); } /*--------------------------------------------------------------------------- * * Main routines that parse a tcl binding for a GL function * *---------------------------------------------------------------------------*/ int SearchEnumVal (interp, name, val) Tcl_Interp* interp; char * name; GLenum* val; { Tcl_HashEntry* entry; char buf [80]; int i; for (i = 0; i < 80; i++) { buf [i] = tolower(name [i]); if (name [i] == '\0') break; } entry = Tcl_FindHashEntry (&enumHashTable, buf); if (entry == NULL) { Tcl_AppendResult (interp, "Not a valid enum:", name, (char*) NULL); return TCL_ERROR; } *val = (GLenum)((size_t)(Tcl_GetHashValue (entry))); return TCL_OK; } int SearchEnumName (interp, val, name) Tcl_Interp* interp; GLenum val; char ** name; { Tcl_HashEntry* entry; Tcl_HashSearch search; char buf [20]; entry = Tcl_FirstHashEntry (&enumHashTable, &search); while (entry != NULL) { if ((GLenum)((size_t)(Tcl_GetHashValue (entry))) == val) { *name = Tcl_GetHashKey (&enumHashTable, entry); return TCL_OK; } entry = Tcl_NextHashEntry (&search); } sprintf (buf, "%d", val); Tcl_AppendResult (interp, "not a known enum value: ", buf, (char*) NULL); return TCL_ERROR; } static int SearchEnum (interp, table, tablesize, name, val) Tcl_Interp* interp; GLenum* table; int tablesize; char * name; GLenum* val; { int i; if (SearchEnumVal (interp, name, val) != TCL_OK) return TCL_ERROR; for (i = 0; i < tablesize; i++) { if (table [i] == *val) return TCL_OK; } Tcl_AppendResult (interp, "Invalid enum for this function: ", name, "\n One of the following was expected: " , (char*) NULL); for (i = 0; i < tablesize; i++) { char* enumName; int result = SearchEnumName (interp, table [i], &enumName); assert (result == TCL_OK); Tcl_AppendResult (interp, enumName, ", ", (char*)NULL); } return TCL_ERROR; } FuncDesc* SearchFuncDesc (tclName) char * tclName; { Tcl_HashEntry* entry; char buf [80]; int i; for (i = 0; i < 80; i++) { buf [i] = tolower(tclName [i]); if (tclName [i] == '\0') break; } entry = Tcl_FindHashEntry (&funcDescHashTable, buf); if (entry == NULL) return NULL; return (FuncDesc*) (Tcl_GetHashValue (entry)); } int ParseGLFunc (interp, argc, argv, nArg) Tcl_Interp *interp; int argc; char *argv []; int *nArg; { static GLfloat floatArgs [MAXARGS]; static GLenum enumArgs [MAXARGS]; static GLint intArgs [MAXARGS]; static void *argVal [MAXARGS]; ArgDetailList argList; FuncDesc* funcDesc = NULL; char *glcmdstring = argv [0]; int iarg = 0; int ival = 0; int result = TCL_OK; assert (argc > 0); if (argv [0][0] != '-') { ERRMSG2 ("GL command should start with '-': ", argv [0]); } funcDesc = SearchFuncDesc (&argv [0][1]); if (funcDesc == NULL) { ERRMSG2 ("Invalid GL command: ", argv [0]); } argc--; argv++; argList = funcDesc->argList; for (iarg = 0; argList != NULL && iarg < argc && !(argv [iarg][0] == '-' && isalpha(argv [iarg][1])); iarg++, argList = argList->next) { assert (ival < MAXARGS); switch (argList->type) { case ARG_ENUM: { result = SearchEnum (interp, argList->detail.enumDetail.enumTable, argList->detail.enumDetail.enumSize, argv [iarg], &enumArgs [ival]); if (result != TCL_OK) goto done; argVal [ival] = &enumArgs [ival]; ival++; break; } case ARG_BIT_FIELD: { int i; int mask = 0; GLenum val; for (i = 0; iarg < argc && !(argv [iarg][0] == '-' && isalpha(argv [iarg][1])); iarg++, i++) { result = SearchEnum (interp, argList->detail.enumDetail.enumTable, argList->detail.enumDetail.enumSize, argv [iarg], &val); if (result != TCL_OK) goto done; mask |= val; } intArgs [ival] = mask; argVal [ival] = &intArgs [ival]; ival++; iarg--; break; } case ARG_FLOAT: { int i; for (i = 0; iarg < argc && i < argList->detail.nValues && !(argv [iarg][0] == '-' && isalpha(argv [iarg][1])); iarg++, i++) { double d; assert (iarg < MAXARGS); if (Tcl_GetDouble (interp, argv [iarg], &d) != TCL_OK) { result = TCL_ERROR; goto done; } floatArgs [ival] = (GLfloat)d; argVal [ival] = &floatArgs [ival]; ival++; } iarg--; if (i != argList->detail.nValues) { ERRMSG ("Not enough arguments were specified"); } break; } case ARG_DONT_CARE: { int i; for (i = 0; iarg < argc && !(argv [iarg][0] == '-' && isalpha(argv [iarg][1])); iarg++, i++) { assert (iarg < MAXARGS); argVal [ival] = argv [iarg]; ival++; } if (i != 0) iarg--; break; } case ARG_STRING: { if (iarg >= argc) { ERRMSG ("Not enough arguments were specified"); } argVal [ival] = argv [iarg]; ival++; break; } case ARG_INT: { int i; for (i = 0; iarg < argc && i < argList->detail.nValues && !(argv [iarg][0] == '-' && isalpha(argv [iarg][1])); iarg++, i++) { int j; assert (iarg < MAXARGS); if (Tcl_GetInt (interp, argv [iarg], &j) != TCL_OK) { result = TCL_ERROR; goto done; } intArgs [ival] = j; argVal [ival] = &intArgs [ival]; ival++; } iarg--; if (i != argList->detail.nValues) { ERRMSG ("Not enough arguments were specified"); } break; } case ARG_BOOLEAN: { int i; for (i = 0; iarg < argc && i < argList->detail.nValues && !(argv [iarg][0] == '-' && isalpha(argv [iarg][1])); iarg++, i++) { int j; assert (iarg < MAXARGS); if (Tcl_GetBoolean (interp, argv [iarg], &j) != TCL_OK) { result = TCL_ERROR; goto done; } intArgs [ival] = j; argVal [ival] = &intArgs [ival]; ival++; } iarg--; if (i != argList->detail.nValues) { ERRMSG ("Not enough arguments were specified"); } break; } case ARG_VAR_FLOAT: { int i, j; for (i = 0; iarg < argc && i < argList->detail.varFloatDetail.maxArgs && !(argv [iarg][0] == '-' && isalpha(argv [iarg][1])); iarg++, i++) { double d; assert (iarg < MAXARGS); if (Tcl_GetDouble (interp, argv [iarg], &d) != TCL_OK) { result = TCL_ERROR; goto done; } floatArgs [ival] = (GLfloat)d; argVal [ival] = &floatArgs [ival]; ival++; } if (i < argList->detail.varFloatDetail.minArgs) { ERRMSG ("Not enough arguments were specified"); } for (j = i-argList->detail.varFloatDetail.minArgs; i < argList->detail.varFloatDetail.maxArgs; i++,j++) { floatArgs [ival] = argList->detail.varFloatDetail.def [j]; argVal [ival] = &floatArgs [ival]; ival++; } iarg--; break; } } } if (argList != NULL) { ERRMSG2 ("Not enough arguments for command: ", argv [-1]); } done: if (result == TCL_OK) { result = (*(funcDesc->func)) (interp, argVal, ival); *nArg = iarg+1; } if (result == TCL_ERROR) { Tcl_AppendResult (interp, "\nError processing gl command ", glcmdstring, (char*)NULL); } return result; } /*--------------------------------------------------------------------------- * * Functions that implement the tcl bindings of each GL function * *---------------------------------------------------------------------------*/ static int TkMatrixMode (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { assert (nargs == 1); glMatrixMode (*((int*)args[0])); return TCL_OK; } static int TkPushMatrix (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { assert (nargs == 0); glPushMatrix(); return TCL_OK; } static int TkPopMatrix (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { assert (nargs == 0); glPopMatrix(); return TCL_OK; } static int TkLoadIdentity (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { assert (nargs == 0); glLoadIdentity(); return TCL_OK; } static int TkMultMatrix (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { assert (nargs == 16); glMultMatrixf ((GLfloat*) args [0]); return TCL_OK; } static int TkLoadMatrix (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { assert (nargs == 16); glLoadMatrixf ((GLfloat*) args [0]); return TCL_OK; } static int TkTranslate (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat* coord; assert (nargs == 3); coord = (GLfloat*) args [0]; glTranslatef (coord [0], coord [1], coord [2]); return TCL_OK; } static int TkRotate (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat* coord; assert (nargs == 4); coord = (GLfloat*) args [0]; glRotatef (coord [0], coord [1], coord [2], coord [3]); return TCL_OK; } static int TkScale (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat* coord = (GLfloat*) args [0]; glScalef (coord [0], coord [1], coord [2]); return TCL_OK; } static int TkCall (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { assert (nargs == 1); glCallList (*((int*) args [0])); return TCL_OK; } static int TkVertex (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat* coord; assert (nargs >= 2 && nargs <= 4); coord = (GLfloat*) args [0]; switch (nargs) { case 2: glVertex2fv (coord); break; case 3: glVertex3fv (coord); break; case 4: glVertex4fv (coord); break; } return TCL_OK; } static int TkNormal (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat* coord; assert (nargs == 3); coord = (GLfloat*) args [0]; glNormal3fv (coord); return TCL_OK; } static int TkColor (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat* coord; assert (nargs >= 3 && nargs <= 4); coord = (GLfloat*) args [0]; switch (nargs) { case 3: glColor3fv (coord); break; case 4: glColor4fv (coord); break; } return TCL_OK; } static int TkClear (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { glClear (*((int*) args [0])); return TCL_OK; } static int TkClearColor (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat* coord; assert (nargs == 3 || nargs == 4); coord = (GLfloat*) args [0]; glClearColor (coord [0], coord [1], coord [2], coord [3]); return TCL_OK; } static int TkClearDepth (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { glClearDepth ((double) *((GLfloat*) args [0])); return TCL_OK; } static int TkClearStencil (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { glClearStencil (*((GLint*) args[0])); return TCL_OK; } static int TkEnable (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { glEnable (*((GLenum*) args[0])); return TCL_OK; } static int TkDisable (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { assert (nargs == 1); glDisable (*((GLenum*) args[0])); return TCL_OK; } static int TkPolygonMode (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { assert (nargs == 2); glPolygonMode (*((GLenum*) args[0]),*((GLenum*) args[1])); return TCL_OK; } static int TkMaterial (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLenum face, parm; GLfloat* val; assert (nargs>2); face = *((GLenum*) args [0]); parm = *((GLenum*) args [1]); val = ((GLfloat*) args [2]); glMaterialfv (face, parm, val); return TCL_OK; } static int TkLight (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLenum light, parm; GLfloat* val; assert (nargs>2); light = *((GLenum*) args [0]); parm = *((GLenum*) args [1]); val = ((GLfloat*) args [2]); glLightfv (light, parm, val); return TCL_OK; } static int TkLightModel (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLenum parm; GLfloat* val; assert (nargs>=2); parm = *((GLenum*) args [0]); val = ((GLfloat*) args [1]); glLightModelfv (parm, val); return TCL_OK; } static int TkShadeModel (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { assert (nargs==1); glShadeModel (*((GLenum*) args [0])); return TCL_OK; } static int TkPerspective (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat* val = (GLfloat*) args [0]; assert (nargs == 4); gluPerspective ((double) val [0], (double) val [1], (double) val [2], (double) val [3]); return TCL_OK; } static int TkLookAt (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat* val = (GLfloat*) args [0]; assert (nargs == 9); gluLookAt ((double) val [0], (double) val [1], (double) val [2], (double) val [3], (double) val [4], (double) val [5], (double) val [6], (double) val [7], (double) val [8]); return TCL_OK; } static int TkOrtho (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat* val = (GLfloat*) args [0]; assert (nargs == 6); glOrtho ((double) val [0], (double) val [1], (double) val [2], (double) val [3], (double) val [4], (double) val [5]); return TCL_OK; } static int TkFrustum (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat* val = (GLfloat*) args [0]; assert (nargs == 6); glFrustum ((double) val [0], (double) val [1], (double) val [2], (double) val [3], (double) val [4], (double) val [5]); return TCL_OK; } static int TkBegin (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { assert (nargs == 1); glBegin (*((GLenum*) args [0])); return TCL_OK; } static int TkEnd (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { assert (nargs == 0); glEnd (); return TCL_OK; } static int TkReadPixels (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { int result = TCL_OK; char* imagename; int x, y; Tk_PhotoHandle handle; Tk_PhotoImageBlock block; assert (nargs == 3); x = *((int *) args [0]); y = *((int *) args [1]); imagename = (char*) args [2]; handle = Tk_FindPhoto (interp, imagename); if (handle == NULL) ERRMSG2 ("Photo not defined: ", imagename); if (Tk_PhotoGetImage (handle, &block) != 1) ERRMSG2 ("Could not get image of photo ", imagename); if (block.pixelSize != 3 && block.pixelSize != 4) ERRMSG ("Image has invalid pixel size"); switch (block.pitch - block.width * block.pixelSize) { case 0: { glPixelStorei (GL_PACK_ALIGNMENT, 1); break; } case 1: { glPixelStorei (GL_PACK_ALIGNMENT, 2); break; } case 2: case 3: { glPixelStorei (GL_PACK_ALIGNMENT, 4); break; } default: printf ("unknown alignment\n"); } glReadPixels (x, y, block.width, block.height, block.pixelSize == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, block.pixelPtr); /* Swap rows so that image will not end upside down */ { int iy; char *tmp; tmp = (char*) malloc (block.pitch); for (iy = 0; iy < block.height/2; iy++) { char *from = (char*)block.pixelPtr+iy*block.pitch; char *to = (char*)block.pixelPtr+(block.height-iy-1)*block.pitch; memcpy (tmp, from, block.pitch); memcpy (from, to, block.pitch); memcpy (to, tmp, block.pitch); } free (tmp); } done: return result; } static int TkDrawPixels (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { int result = TCL_OK; char* imagename; Tk_PhotoHandle handle; Tk_PhotoImageBlock block; assert (nargs == 1); imagename = (char*) args [0]; handle = Tk_FindPhoto (interp, imagename); if (handle == NULL) ERRMSG2 ("Photo not defined: ", imagename); if (Tk_PhotoGetImage (handle, &block) != 1) ERRMSG2 ("Could not get image of photo ", imagename); if (block.pixelSize != 3 && block.pixelSize != 4) ERRMSG ("Image has invalid pixel size"); glPixelStorei (GL_UNPACK_ALIGNMENT, 1); glDrawPixels (block.width, block.height, block.pixelSize == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, block.pixelPtr); done: return result; } static int TkCopyPixels (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLint *val = (GLint*) args [0]; assert (nargs == 4); glCopyPixels (val [0], val [1], val [2], val [3], GL_COLOR); return TCL_OK; } static int TkRasterPos (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat *val = (GLfloat*) args [0]; assert (nargs >= 2); glRasterPos4fv (val); return TCL_OK; } static int TkPixelZoom (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat *val = (GLfloat*) args [0]; assert (nargs == 2); glPixelZoom (val [0], val [1]); return TCL_OK; } static int TkPixelTransfer (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLenum parm; GLfloat val; assert (nargs == 2); parm = *((GLenum*) args [0]); val = *((GLfloat*) args [1]); glPixelTransferf (parm, val); return TCL_OK; } static int TkTexCoord (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat* coord; assert (nargs >= 2 && nargs <= 4); coord = (GLfloat*) args [0]; switch (nargs) { case 2: glTexCoord2fv (coord); break; case 3: glTexCoord3fv (coord); break; case 4: glTexCoord4fv (coord); break; } return TCL_OK; } #ifndef NDEBUG /* Create checkerboard texture */ #define checkImageWidth 64 #define checkImageHeight 64 GLubyte checkImage[checkImageWidth][checkImageHeight][3]; void makeCheckImage(void) { int i, j, c; for (i = 0; i < checkImageWidth; i++) { for (j = 0; j < checkImageHeight; j++) { c = (((i&0x8)==0)^((j&0x8)==0))*255; checkImage[i][j][0] = (GLubyte) c; checkImage[i][j][1] = (GLubyte) c; checkImage[i][j][2] = (GLubyte) c; } } } #endif static int TkTexImage2D (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { int result = TCL_OK; int level, border, i, n; char* imagename; Tk_PhotoHandle handle; Tk_PhotoImageBlock block; assert (nargs == 3); level = *((int*) args [0]); border = *((int*) args [1]); imagename = (char*) args [2]; handle = Tk_FindPhoto (interp, imagename); if (handle == NULL) ERRMSG2 ("Photo not defined: ", imagename); if (Tk_PhotoGetImage (handle, &block) != 1) ERRMSG2 ("Could not get image of photo ", imagename); if (block.pixelSize != 3 && block.pixelSize != 4) ERRMSG ("Image has invalid pixel size"); n = block.width - border; for (i = 0; i < 16; i++) { if (n == (1 << i)) break; } if (i == 16) { char buf [10]; sprintf (buf, "%d", block.width); ERRMSG2 ("image width must be a power of 2", buf); } n = block.height - border; for (i = 0; i < 16; i++) { if (n == (1 << i)) break; } if (i == 16) { char buf [20]; sprintf (buf, "%d", block.height); ERRMSG2 ("image height must be a power of 2", buf); } glPixelStorei (GL_UNPACK_ALIGNMENT, 1); glTexImage2D (GL_TEXTURE_2D, level, block.pixelSize, block.width, block.height, border, block.pixelSize == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, block.pixelPtr); done: return result; } static int TkTexImage1D (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { int result = TCL_OK; int level, border, i, n; char* imagename; Tk_PhotoHandle handle; Tk_PhotoImageBlock block; assert (nargs == 3); level = *((int*) args [0]); border = *((int*) args [1]); imagename = (char*) args [2]; handle = Tk_FindPhoto (interp, imagename); if (handle == NULL) ERRMSG2 ("Photo not defined: ", imagename); if (Tk_PhotoGetImage (handle, &block) != 1) ERRMSG2 ("Could not get image of photo ", imagename); if (block.pixelSize != 3 && block.pixelSize != 4) ERRMSG ("Image has invalid pixel size"); n = block.width - border; for (i = 0; i < 16; i++) { if (n == (1 << i)) break; } if (i == 16) { char buf [20]; sprintf (buf, "%d", block.width); ERRMSG2 ("image width must be a power of 2", buf); } glPixelStorei (GL_UNPACK_ALIGNMENT, 1); glTexImage1D (GL_TEXTURE_1D, level, block.pixelSize, block.width, border, block.pixelSize == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, block.pixelPtr); done: return result; } static int TkTexParameter (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { int result = TCL_OK; GLenum target, pname, pval; GLfloat val [4] = {0.0, 0.0, 0.0, 0.0}; assert (nargs >= 3 && nargs <= 6); target = *((GLenum*) args [0]); pname = *((GLenum*) args [1]); if (pname == GL_TEXTURE_BORDER_COLOR) { int i; for (i = 0; i+2 < nargs; i++) { double d; if (Tcl_GetDouble (interp, (char*) args [i+2], &d) != TCL_OK) { ERRMSG ("Invalid color coordinate"); } val [i] = (GLfloat)d; } glTexParameterfv (target, pname, val); } else { result = SearchEnum (interp, valueTexParamTable, sizeof (valueTexParamTable)/sizeof(GLenum), (char*) args [2], &pval); if (result != TCL_OK) goto done; glTexParameteri (target, pname, pval); } done: return result; } static int TkTexEnv (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { int result = TCL_OK; GLenum target, pname, pval; GLfloat val [4] = {0.0, 0.0, 0.0, 0.0}; assert (nargs >= 3 && nargs <= 6); target = *((GLenum*) args [0]); pname = *((GLenum*) args [1]); if (pname == GL_TEXTURE_ENV_COLOR) { int i; for (i = 0; i+2 < nargs; i++) { double d; if (Tcl_GetDouble (interp, (char*) args [i+2], &d) != TCL_OK) { ERRMSG ("Invalid color coordinate"); } val [i] = (GLfloat)d; } glTexEnvfv (target, pname, val); } else { result = SearchEnum (interp, valueTexEnvTable, sizeof(valueTexEnvTable)/sizeof(GLenum), (char*) args [2], &pval); if (result != TCL_OK) goto done; glTexEnvi (target, pname, pval); } done: return result; } static int TkTexGen (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { int result = TCL_OK; GLenum coord, pname, pval; GLfloat val [4] = {0.0, 0.0, 0.0, 0.0}; assert (nargs >= 3 && nargs <= 6); coord = *((GLenum*) args [0]); pname = *((GLenum*) args [1]); if (pname != GL_TEXTURE_GEN_MODE) { int i; for (i = 0; i+2 < nargs; i++) { double d; if (Tcl_GetDouble (interp, (char*) args [i+2], &d) != TCL_OK) { ERRMSG ("Invalid texgen coordinate"); } val [i] = (GLfloat)d; } glTexGenfv (coord, pname, val); } else { result = SearchEnum (interp, valueTexGenTable, sizeof(valueTexGenTable)/sizeof(GLenum), (char*) args [2], &pval); if (result != TCL_OK) goto done; glTexGeni (coord, pname, pval); } done: return result; } static int TkInitNames (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { glInitNames(); return TCL_OK; } static int TkLoadName (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { glLoadName(*((GLint*) args [0])); return TCL_OK; } static int TkPushName (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { glPushName(*((GLint*) args [0])); return TCL_OK; } static int TkPopName (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { glPopName (); return TCL_OK; } static int TkPickMatrix (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat *val = ((GLfloat*) args [0]); GLint viewport [4]; glGetIntegerv (GL_VIEWPORT, viewport); gluPickMatrix ((double) val [0], (double) (viewport [3] - val [1]), val [2], val [3], viewport); return TCL_OK; } static int TkMap1 (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLenum target = *((GLenum*) args [0]); GLfloat *u = ((GLfloat*) args [1]); GLint stride = *((GLint*) args [3]); GLint order = *((GLint*) args [4]); int result = TCL_OK; int i; GLfloat *pt; if (nargs - 5 != order * stride) { char buf [20]; sprintf (buf, "%d", order * stride); ERRMSG2 (buf, " coordinate values were expected"); } pt = (GLfloat*) malloc (sizeof (GLfloat) * stride * order); assert (pt != NULL); for (i = 0; i+5 < nargs; i++) { double d; if (Tcl_GetDouble (interp, (char*) args [i+5], &d) != TCL_OK) { free (pt); ERRMSG ("Invalid map1 coordinate"); } pt [i] = (GLfloat)d; } glMap1f (target, u [0], u [1], stride, order, pt); free (pt); done: return result; } static int TkMap2 (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLenum target = *((GLenum*) args [0]); GLfloat *u = ((GLfloat*) args [1]); GLint ustride = *((GLint*) args [3]); GLint uorder = *((GLint*) args [4]); GLfloat *v = ((GLfloat*) args [5]); GLint vstride = *((GLint*) args [7]); GLint vorder = *((GLint*) args [8]); int result = TCL_OK; int i; GLfloat *pt; if (nargs - 9 != uorder * vorder * ustride) { char buf [20]; sprintf (buf, "%d", uorder * vorder * ustride); ERRMSG2 (buf, " coordinate values were expected"); } if (vstride != ustride * uorder) { char buf [20]; sprintf (buf, "%d", uorder * ustride); ERRMSG2 (" vstride parameter should be ", buf); } pt = (GLfloat*) malloc (sizeof (GLfloat) * ustride * vorder * uorder); assert (pt != NULL); for (i = 0; i+9 < nargs; i++) { double d; if (Tcl_GetDouble (interp, (char*) args [i+9], &d) != TCL_OK) { free (pt); ERRMSG ("Invalid map1 coordinate"); } pt [i] = (GLfloat)d; } glMap2f (target, u [0], u [1], ustride, uorder, v [0], v [1], vstride, vorder, pt); free (pt); done: return result; } static int TkEvalCoord1 (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat *u = ((GLfloat*) args [0]); glEvalCoord1f (u[0]); return TCL_OK; } static int TkEvalCoord2 (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat *u = ((GLfloat*) args [0]); glEvalCoord2f (u[0], u[1]); return TCL_OK; } static int TkMapGrid1 (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLint n = *((GLint*) args [0]); GLfloat *u = ((GLfloat*) args [1]); glMapGrid1f (n, u[0], u[1]); return TCL_OK; } static int TkMapGrid2 (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLint nu = *((GLint*) args [0]); GLfloat *u = ((GLfloat*) args [1]); GLint nv = *((GLint*) args [3]); GLfloat *v = ((GLfloat*) args [4]); glMapGrid2f (nu, u[0], u[1], nv, v[0], v[1]); return TCL_OK; } static int TkEvalMesh1 (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLenum mode = *((GLenum*) args [0]); GLint *p = ((GLint*) args [1]); glEvalMesh1 (mode, p[0], p[1]); return TCL_OK; } static int TkEvalMesh2 (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLenum mode = *((GLenum*) args [0]); GLint *p = ((GLint*) args [1]); glEvalMesh2 (mode, p[0], p[1], p[2], p[3]); return TCL_OK; } static int TkPointSize (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat size = *((GLfloat*) args [0]); glPointSize (size); return TCL_OK; } static int TkLineWidth (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat width = *((GLfloat*) args [0]); glLineWidth (width); return TCL_OK; } static int TkLineStipple (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLint* arg = ((GLint*) args [0]); glLineStipple (arg [0], (GLushort) arg [1]); return TCL_OK; } static int TkFog (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { int result = TCL_OK; GLenum mode = *((GLenum*) args [0]); if (mode == GL_FOG_MODE) { GLenum fogmode; result = SearchEnum (interp, fogFogModeTable, sizeof(fogFogModeTable)/sizeof(GLenum), (char*) args [1], &fogmode); if (result != TCL_OK) goto done; glFogi (mode, fogmode); } else if (mode == GL_FOG_COLOR) { int i; GLfloat fogcolor[4] = {0.0, 0.0, 0.0, 1.0}; for (i = 0; i+1 < 4 && i+1 < nargs; i++) { double d; if (Tcl_GetDouble (interp, (char*)args[i+1], &d) !=TCL_OK) { ERRMSG ("\nInvalid fog color coordinate"); } fogcolor [i] = (GLfloat)d; } glFogfv (mode, fogcolor); } else { double d; if (Tcl_GetDouble (interp, (char*) args [1], &d) != TCL_OK) { ERRMSG ("\nInvalid fog argument"); } glFogf (mode, (GLfloat)d); } done: return result; } static int TkFrontFace (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLenum mode = *((GLenum*) args [0]); glFrontFace (mode); return TCL_OK; } static int TkColorMaterial (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLenum face = *((GLenum*) args [0]); GLenum mode = *((GLenum*) args [1]); glColorMaterial (face, mode); return TCL_OK; } static int TkClearAccum (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat* s = ((GLfloat*) args [0]); glClearAccum (s[0], s[1], s[2], s[3]); return TCL_OK; } static int TkDrawBuffer (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLenum mode = *((GLenum*) args [0]); glDrawBuffer (mode); return TCL_OK; } static int TkColorMask (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLboolean* s = ((GLboolean*) args [0]); glColorMask (s[0], s[1], s[2], s[3]); return TCL_OK; } static int TkDepthMask (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLboolean* s = ((GLboolean*) args [0]); glDepthMask (s[0]); return TCL_OK; } static int TkStencilMask (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLint* s = ((GLint*) args [0]); glStencilMask (s[0]); return TCL_OK; } static int TkScissor (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLint* s = ((GLint*) args [0]); glScissor (s[0],s[1],s[2],s[3]); return TCL_OK; } static int TkAlphaFunc (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLenum func = *((GLenum*) args [0]); GLfloat ref = *((GLfloat*) args [1]); glAlphaFunc (func, ref); return TCL_OK; } static int TkDepthFunc (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLenum func = *((GLenum*) args [0]); glDepthFunc (func); return TCL_OK; } static int TkStencilFunc (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLenum func = *((GLenum*) args [0]); GLint ref = *((GLint*) args [1]); GLint mask = *((GLint*) args [2]); glStencilFunc (func, ref, mask); return TCL_OK; } static int TkStencilOp (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLenum* op = ((GLenum*) args [0]); glStencilOp (op [0], op [1], op [2]); return TCL_OK; } static int TkAccum (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLenum op = *((GLenum*) args [0]); GLfloat val = *((GLfloat*) args [1]); glAccum (op, val); return TCL_OK; } static int TkReadBuffer(interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLenum mode = *((GLenum*) args [0]); glReadBuffer (mode); return TCL_OK; } static int TkBlendFunc (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLenum sfactor = *((GLenum*) args [0]); GLenum dfactor = *((GLenum*) args [1]); glBlendFunc (sfactor, dfactor); return TCL_OK; } static int TkClipPlane (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLenum clipplane = *((GLenum*) args [0]); GLdouble eq [4]; eq [0]= *((GLfloat*) args [1]); eq [1]= *((GLfloat*) args [2]); eq [2]= *((GLfloat*) args [3]); eq [3]= *((GLfloat*) args [4]); glClipPlane (clipplane, eq); return TCL_OK; } static int TkPushAttrib (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { glPushAttrib(*((GLint*) args [0])); return TCL_OK; } static int TkPopAttrib (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { glPopAttrib(); return TCL_OK; } static int TkNewList (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { glNewList(*((GLint*) args [0]), *((GLenum*) args [1])); return TCL_OK; } static int TkEndList (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { glEndList (); return TCL_OK; } static int TkEdgeFlag (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLboolean* s = ((GLboolean*) args [0]); glEdgeFlag (s[0]); return TCL_OK; } static int TkFlush (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { glFlush (); return TCL_OK; } static int TkFinish (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { glFinish (); return TCL_OK; } static int TkHint (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { glHint (*((GLenum*) args [0]), *((GLenum*) args [1])); return TCL_OK; } static int TkRect (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { GLfloat* coord; coord = (GLfloat*) args [0]; glRectf (coord [0], coord [1], coord [2], coord [3]); return TCL_OK; } static int TkCullFace (interp, args, nargs) Tcl_Interp* interp; void** args; int nargs; { glCullFace (*((GLenum*) args [0])); return TCL_OK; } cgnslib_3.1.4/src/cgnstools/tkogl/strokefont.h0000664000076400007640000000010312160605670016443 00000000000000int StrokeFontExt (Tcl_Interp *interp, int argc, char* argv []); cgnslib_3.1.4/src/cgnstools/tkogl/tkogl.c0000664000076400007640000012424012160605670015371 00000000000000/* * tkOGL.c -- * * This module implements "OGLwin" widgets. This is the TCL * interface to OpenGL. * */ #include #include #include #include #include #include "tkogl.h" #include "tkoglparse.h" #include "load3ds.h" #include "tess.h" #include "quadric.h" #include "nurbs.h" #include "get.h" #include "gencyl.h" #include "printstr.h" #include "feedback.h" #ifndef CONST # define CONST #endif /* * A data structure of the following type is kept for each glxwin * widget managed by this file: */ typedef struct { Tk_Window tkwin; /* Window that embodies the glxwin. NULL * means window has been deleted but * widget record hasn't been cleaned * up yet. */ Display *display; /* X's token for the window's display. */ Tcl_Interp *interp; /* Interpreter associated with widget. */ int width; /* Width to request for window. <= 0 means * don't request any size. */ int height; /* Height to request for window. <= 0 means * don't request any size. */ int absx, absy; /* Absolute x and y of window */ char* context; /* Name of gl window this window will share * display lists with */ int flags; /* Various flags; see below for * definitions. */ int doubleBuffer, /* Various options that control visual alloc. */ depthSize, stencilSize, alphaSize, accumSize; int updatePending; /* Set to 1 when redraw needed */ int redrawList; /* Number of redraw display list (or -1) */ double aspectRatio; /* If not 0, represents a fraction width/height which should be maintained when setting the viewport during the event loop */ Tk_3DBorder bgBorder; /* Used for drawing background. */ #if defined(__WIN32__) || defined(_WIN32) /* * Information required to manage the OpenGl window in WIN32 environment */ HPALETTE hPalette; HWND hwnd; HDC hdc; HGLRC hrc; TkWinDCState state; #else GLXContext cx; /* The GL X context */ #endif } OGLwin; /* * Information used for argv parsing. */ static Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_PIXELS, "-height", "height", "Height", "300" , Tk_Offset(OGLwin, height), 0}, {TK_CONFIG_PIXELS, "-width", "width", "Width", "300" , Tk_Offset(OGLwin, width), 0}, {TK_CONFIG_STRING, "-context", "context", "Context", NULL, Tk_Offset (OGLwin, context), TK_CONFIG_NULL_OK}, {TK_CONFIG_BOOLEAN, "-doublebuffer", "doublebuffer", "DoubleBuffer", "1", Tk_Offset (OGLwin, doubleBuffer), 0}, {TK_CONFIG_INT, "-depthsize", "depthsize", "DepthSize", "16", Tk_Offset (OGLwin, depthSize), 0}, {TK_CONFIG_INT, "-stencilsize", "stencilsize", "StencilSize", "0", Tk_Offset (OGLwin, stencilSize), 0}, {TK_CONFIG_INT, "-alphasize", "alphasize", "AlphaSize", "0", Tk_Offset (OGLwin, alphaSize), 0}, {TK_CONFIG_INT, "-accumsize", "accumsize", "AccumSize", "0", Tk_Offset (OGLwin, accumSize), 0}, {TK_CONFIG_DOUBLE, "-aspectratio", "aspectratio", "AspectRatio", "0", Tk_Offset (OGLwin, aspectRatio), 0}, {TK_CONFIG_BORDER, "-background", "background", "Background", "#d9d9d9", Tk_Offset(OGLwin, bgBorder), 0}, {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, (char *) NULL, 0, 0} }; /* * Forward declarations for procedures defined later in this file: */ static int OGLwinConfigure _ANSI_ARGS_((Tcl_Interp *interp, OGLwin *glxwinPtr, int argc, char **argv, int flags)); static void OGLwinDestroy _ANSI_ARGS_((char* clientData)); static void OGLwinEventProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr)); static int OGLwinWidgetCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *, int argc, char **argv)); static void OGLwinRedraw _ANSI_ARGS_ ((ClientData clientData)); int OGLwinCmd(ClientData, Tcl_Interp*, int, char**); static int UnusedDList (); static int FreeDisplayList (int) ; static void OGLwinViewport (OGLwin* oglwinPtr); static void MakeCurrent (OGLwin* oglwinPtr); #if defined(__WIN32__) || defined(_WIN32) static LONG WINAPI WndProc (HWND, UINT, WPARAM, LPARAM); static int WinMakeWindowExist (OGLwin*); static void SetDCPixelFormat (OGLwin*); #else static Colormap getColormap _ANSI_ARGS_((Display *dpy, XVisualInfo *vi)); #endif #define ERRMSG(msg) {\ Tcl_AppendResult(interp,msg,(char*)NULL); \ return TCL_ERROR; \ } #define ERRMSG2(msg1,msg2) {\ Tcl_AppendResult(interp,msg1,msg2,(char*)NULL); \ return TCL_ERROR; \ } #define ARRANGE_REDRAW(glxwinptr) \ if (!(glxwinptr)->updatePending) {\ Tcl_DoWhenIdle ((Tcl_IdleProc *)OGLwinRedraw, \ (ClientData)(glxwinptr));\ (glxwinPtr)->updatePending = 1;\ } #ifdef __WIN32__ /* *---------------------------------------------------------------------- * * DllEntryPoint -- * * This wrapper function is used by Windows to invoke the * initialization code for the DLL. If we are compiling * with Visual C++, this routine will be renamed to DllMain. * routine. * * Results: * Returns TRUE; * * Side effects: * None. * *---------------------------------------------------------------------- */ BOOL APIENTRY DllEntryPoint(hInst, reason, reserved) HINSTANCE hInst; /* Library instance handle. */ DWORD reason; /* Reason this function is being called. */ LPVOID reserved; /* Not used. */ { return TRUE; } static WNDCLASS childClass; /* Tk Window class for child windows. */ static int createCount = 0; static LONG WINAPI WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) /* * This is the event proc for the opengl window * */ { LONG result; switch (msg) { case WM_WINDOWPOSCHANGED: case WM_MOVE: break; default: return TkWinChildProc (hwnd, msg, wParam, lParam); } result = DefWindowProc(hwnd, msg, wParam, lParam); Tcl_ServiceAll(); return result; } #endif EXPORT(int,Tkogl_Init)(Tcl_Interp* interp) { Tk_Window topLevel; topLevel = Tk_MainWindow(interp); #ifdef __WIN32__ /*** Fix floating point exception bug ***/ # ifdef __BORLANDC__ /* This is how to do it in Borland C */ _control87(MCW_EM, MCW_EM); # else /* Don't know how to do it in Visual C++ - Need help here */ # endif #else /*** make sure OpenGL's GLX extension supported ***/ if (!glXQueryExtension(Tk_Display(topLevel), NULL, NULL)) { ERRMSG ("X server has no OpenGL GLX extension"); } #endif /*** Initialize the GL function parse tables ***/ InitHashTables (); /*** Create Tkogl main tcl commands ***/ Tcl_CreateCommand(interp, "OGLwin", (Tcl_CmdProc *)OGLwinCmd, (ClientData)topLevel, (Tcl_CmdDeleteProc *)0); /*** Init standard extensions ***/ if (RegisterTkOGLExtension (interp, "nurbssurface", NurbsSurface)!= TCL_OK) return TCL_ERROR; if (RegisterTkOGLExtension (interp, "load3ds", glLoad3DStudio) != TCL_OK) return TCL_ERROR; if (RegisterTkOGLExtension (interp, "tesselate", Tesselate) != TCL_OK) return TCL_ERROR; if (RegisterTkOGLExtension (interp, "cylinder", Quadric) != TCL_OK) return TCL_ERROR; if (RegisterTkOGLExtension (interp, "disk", Quadric) != TCL_OK) return TCL_ERROR; if (RegisterTkOGLExtension (interp, "partialdisk", Quadric) != TCL_OK) return TCL_ERROR; if (RegisterTkOGLExtension (interp, "sphere", Quadric) != TCL_OK) return TCL_ERROR; if (RegisterTkOGLExtension (interp, "get", GetGlVal) != TCL_OK) return TCL_ERROR; if (RegisterTkOGLExtension (interp, "gencyl", GenericCylinder) != TCL_OK) return TCL_ERROR; if (RegisterTkOGLExtension (interp, "printstring", PrintString) != TCL_OK) return TCL_ERROR; if (RegisterTkOGLExtension (interp, "loadbitmapfont", LoadBitmapFont) != TCL_OK) return TCL_ERROR; if (RegisterTkOGLExtension (interp, "feedback", Feedback) != TCL_OK) return TCL_ERROR; return Tcl_PkgProvide(interp, "Tkogl", "1.0"); } #ifdef __WIN32__ static int WinMakeWindowExist (OGLwin* oglWinPtr) /* ================== * * Forces window to exist so that we can setup MS's version of OpenGL */ { static char* TkOGLClassName = "TkOGL Class"; static int TkOGLClassInitted = 0; TkWindow *winPtr = (TkWindow *) oglWinPtr->tkwin; Display *dpy = Tk_Display (oglWinPtr->tkwin); Window parent; HWND hwnd, parentWin; HANDLE hInstance; WNDCLASS TkOGLClass; Tcl_HashEntry *hPtr; int new_flag; /* Destroy window if already exists */ if (winPtr->window != None) { XDestroyWindow(dpy, winPtr->window); } /* Find parent of window */ /* Necessary for creation */ if ((winPtr->parentPtr == NULL) || (winPtr->flags & TK_TOP_LEVEL)) { parent = XRootWindow(winPtr->display, winPtr->screenNum); } else { if (winPtr->parentPtr->window == None) { Tk_MakeWindowExist((Tk_Window) winPtr->parentPtr); } parent = winPtr->parentPtr->window; } /* Create a window class for TkOGL windows if not done this yet */ parentWin = Tk_GetHWND(parent); hInstance = Tk_GetHINSTANCE(); if (!TkOGLClassInitted) { TkOGLClassInitted = 1; TkOGLClass.style = CS_HREDRAW | CS_VREDRAW; TkOGLClass.cbClsExtra = 0; TkOGLClass.cbWndExtra = 4; /* to save struct OGLwin* */ TkOGLClass.hInstance = hInstance; TkOGLClass.hbrBackground = NULL; TkOGLClass.lpszMenuName = NULL; TkOGLClass.lpszClassName = TkOGLClassName; TkOGLClass.lpfnWndProc = WndProc; TkOGLClass.hIcon = NULL; TkOGLClass.hCursor = NULL; if (!RegisterClass(&TkOGLClass)){ Tcl_AppendResult(oglWinPtr->interp, "could not register TkOGL class", (char *) NULL); return TCL_ERROR; } } /* Create Window */ hwnd = CreateWindow(TkOGLClassName, NULL, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, oglWinPtr->width, oglWinPtr->height, parentWin, NULL, hInstance, NULL); SetWindowLong(hwnd, 0, (LONG) oglWinPtr); SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); oglWinPtr->hwnd = hwnd; oglWinPtr->hdc = GetDC(hwnd); SetDCPixelFormat (oglWinPtr); winPtr->window = Tk_AttachHWND ((Tk_Window) winPtr, hwnd); /* Don't know why the things below are necessary (copied from togl code) */ hPtr = Tcl_CreateHashEntry(&winPtr->dispPtr->winTable, (char *) winPtr->window, &new_flag); Tcl_SetHashValue(hPtr, winPtr); winPtr->dirtyAtts = 0; winPtr->dirtyChanges = 0; Tk_MapWindow (oglWinPtr->tkwin); /* XMapWindow (dpy, Tk_WindowId(oglWinPtr->tkwin)); */ wglMakeCurrent (oglWinPtr->hdc, oglWinPtr->hrc); return TCL_OK; } /* WinMakeWindowExist */ #endif int GetAbsXY (OGLwin *glxwinPtr) /* ======== * * Updates the absolute x and y values for the upper left corner of * the window. Returns 1 if the recomputed values differ from the previous * one, or 0 otherwise */ { Tk_Window root = glxwinPtr->tkwin; int x = Tk_X (root); int y = Tk_Y (root); int modified; do { root = Tk_Parent (root); x += Tk_X (root); y += Tk_Y (root); } while (!Tk_IsTopLevel (root)); modified = (x != glxwinPtr->absx || y != glxwinPtr->absy); glxwinPtr->absx = x; glxwinPtr->absy = y; return modified; } /* *-------------------------------------------------------------- * * OGLwinCmd -- * * This procedure is invoked to process the "OGLwin" Tcl * command. It creates a new "OGLwin" widget. * * Results: * A standard Tcl result. * * Side effects: * A new widget is created and configured. * *-------------------------------------------------------------- */ int OGLwinCmd(clientData, interp, argc, argv) ClientData clientData; /* Main window associated with * interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */ { Tk_Window mainwin = (Tk_Window) clientData; OGLwin *glxwinPtr; Tk_Window tkwin; #ifndef __WIN32__ Colormap cmap; XVisualInfo *vi; int configuration [50], *confPtr; #endif if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " pathName ?options?\"", (char *) NULL); return TCL_ERROR; } tkwin = Tk_CreateWindowFromPath(interp, mainwin, argv[1], (char *) NULL); if (tkwin == NULL) { ERRMSG ("Could not create window"); } /* * Allocate and initialize the widget record. */ glxwinPtr = (OGLwin *) ckalloc(sizeof(OGLwin)); glxwinPtr->tkwin = tkwin; glxwinPtr->display = Tk_Display(tkwin); glxwinPtr->interp = interp; glxwinPtr->width = 300; glxwinPtr->height = 300; glxwinPtr->absx = glxwinPtr->absy = 0; glxwinPtr->context = (char*) NULL; glxwinPtr->updatePending = 0; glxwinPtr->redrawList = -1; glxwinPtr->aspectRatio = 0.0; glxwinPtr->doubleBuffer = 1; glxwinPtr->depthSize = 16; glxwinPtr->alphaSize = 0; glxwinPtr->accumSize = 0; glxwinPtr->stencilSize = 0; glxwinPtr->bgBorder = NULL; #if defined(__WIN32__) || defined(_WIN32) glxwinPtr->hwnd = 0; glxwinPtr->hdc = 0; glxwinPtr->hrc = 0; glxwinPtr->hPalette = 0; #endif /* create the widget itself */ Tk_CreateEventHandler(glxwinPtr->tkwin, ExposureMask|StructureNotifyMask, OGLwinEventProc, (ClientData) glxwinPtr); Tcl_CreateCommand(interp, Tk_PathName(glxwinPtr->tkwin), (Tcl_CmdProc *)OGLwinWidgetCmd, (ClientData) glxwinPtr, (Tcl_CmdDeleteProc *)0); if (OGLwinConfigure(interp, glxwinPtr, argc-2, argv+2, 0) != TCL_OK) { Tk_DestroyWindow(glxwinPtr->tkwin); return TCL_ERROR; } #ifdef __WIN32__ if (WinMakeWindowExist (glxwinPtr) != TCL_OK) { Tcl_AppendResult(interp, "Could not make window exist", (char *) NULL); return TCL_ERROR; } #else /* * For OpenGL under X we may allocate the OpenGL X context and * visual here. First, we need to build a configuration * array corresponding to the the widget options. */ confPtr = configuration; *confPtr++ = GLX_RGBA; if (glxwinPtr->doubleBuffer) { *confPtr++ = GLX_DOUBLEBUFFER; } if (glxwinPtr->depthSize) { *confPtr++ = GLX_DEPTH_SIZE; *confPtr++ = glxwinPtr->depthSize; } if (glxwinPtr->stencilSize) { *confPtr++ = GLX_STENCIL_SIZE; *confPtr++ = glxwinPtr->stencilSize; } if (glxwinPtr->accumSize) { *confPtr++ = GLX_ACCUM_RED_SIZE; *confPtr++ = glxwinPtr->accumSize; *confPtr++ = GLX_ACCUM_GREEN_SIZE; *confPtr++ = glxwinPtr->accumSize; *confPtr++ = GLX_ACCUM_BLUE_SIZE; *confPtr++ = glxwinPtr->accumSize; if (glxwinPtr->alphaSize) { *confPtr++ = GLX_ACCUM_ALPHA_SIZE; *confPtr++ = glxwinPtr->accumSize; } } if (glxwinPtr->alphaSize) { *confPtr++ = GLX_ALPHA_SIZE; *confPtr++ = glxwinPtr->alphaSize; } /*** find an appropriate visual and a colormap for it ***/ /* first, try to find a 24 bit visual */ confPtr [0] = GLX_RED_SIZE; confPtr [1] = 8; confPtr [2] = GLX_GREEN_SIZE; confPtr [3] = 8; confPtr [4] = GLX_BLUE_SIZE; confPtr [5] = 8; confPtr [6] = None; vi = glXChooseVisual(glxwinPtr->display, DefaultScreen(glxwinPtr->display), configuration); if (vi == NULL) { /* try an 8 bit visual */ confPtr [0] = None; vi = glXChooseVisual(glxwinPtr->display, DefaultScreen(glxwinPtr->display), configuration); if (vi == NULL) { Tk_DestroyWindow(glxwinPtr->tkwin); ERRMSG ("no appropriate RGB visual"); } } cmap = getColormap(glxwinPtr->display, vi); if (!Tk_SetWindowVisual (tkwin, vi->visual, vi->depth, cmap)) { Tk_DestroyWindow(glxwinPtr->tkwin); ERRMSG ("Could not set window visual"); } Tk_SetWindowColormap (tkwin, cmap); if ((Tk_Parent(tkwin) != NULL) && (Tk_Colormap(tkwin) != Tk_Colormap (Tk_Parent(tkwin)))) { TkWmAddToColormapWindows(tkwin); } /* See if this window will share display lists with another */ if (glxwinPtr->context != NULL) { Tcl_CmdInfo info; if (!Tcl_GetCommandInfo (interp, glxwinPtr->context, &info) || info.proc != (Tcl_CmdProc *)OGLwinWidgetCmd) { Tcl_AppendResult (interp, "Not a gl window: ", glxwinPtr->context, (char*) NULL); Tk_DestroyWindow(glxwinPtr->tkwin); return TCL_ERROR; } glxwinPtr->cx = glXCreateContext(Tk_Display(tkwin), vi, ((OGLwin *)(info.clientData))->cx, /* direct rendering */ GL_TRUE); } else { glxwinPtr->cx = glXCreateContext(Tk_Display(tkwin), vi, /* no sharing of display lists */ NULL, /* direct rendering */ GL_TRUE); } if (glxwinPtr->cx == NULL) { Tcl_AppendResult (interp, "could not create rendering context", (char*) NULL); Tk_DestroyWindow(glxwinPtr->tkwin); return TCL_ERROR; } Tk_MapWindow (tkwin); XSetWMColormapWindows(glxwinPtr->display, Tk_WindowId(tkwin), &(Tk_WindowId(tkwin)), 1 ); #endif MakeCurrent(glxwinPtr); OGLwinViewport (glxwinPtr); ARRANGE_REDRAW(glxwinPtr); GetAbsXY (glxwinPtr); Tcl_SetResult(interp, Tk_PathName(glxwinPtr->tkwin), TCL_VOLATILE); return TCL_OK; } /*--------------------------------------------------------------------------- * * OGLwinViewport * * Called when window is resized. If a non-zero aspect ratio was defined * for that window, a corresponding viewport is set by centering it * inside the window. * *--------------------------------------------------------------------------- */ static void OGLwinViewport (OGLwin* oglWinPtr) { if (oglWinPtr->aspectRatio == 0.0) { glViewport (0, 0, oglWinPtr->width, oglWinPtr->height); } else { if (oglWinPtr->width/oglWinPtr->aspectRatio > oglWinPtr->height) { /* Should reduce the width of the viewport */ int adjWidth = (int) (oglWinPtr->height * oglWinPtr->aspectRatio); glViewport ((oglWinPtr->width - adjWidth) / 2, 0, adjWidth, oglWinPtr->height); } else { /* Should reduce the height of the viewport */ int adjHeight = (int) (oglWinPtr->width/oglWinPtr->aspectRatio); glViewport (0, (oglWinPtr->height - adjHeight) / 2, oglWinPtr->width, adjHeight); } } } /*--------------------------------------------------------------------------- * * MakeCurrent * * Called whenever it is necessary that the OpenGL context for a * given window is current. * *--------------------------------------------------------------------------- */ static void MakeCurrent (OGLwin* oglwinPtr) { static OGLwin* previous = NULL; if (oglwinPtr == previous) return; if (oglwinPtr == NULL) return; previous = oglwinPtr; #ifdef __WIN32__ wglMakeCurrent (oglwinPtr->hdc, oglwinPtr->hrc); #else glXMakeCurrent(oglwinPtr->display, Tk_WindowId(oglwinPtr->tkwin), oglwinPtr->cx); #endif } /*--------------------------------------------------------------------------- * * OGLwinRedraw * * Sample redraw routine. Redraws * display list redrawList if defined * *--------------------------------------------------------------------------- */ static void OGLwinRedraw (clientData) ClientData clientData; { OGLwin *glxwinPtr = (OGLwin *) clientData; Tk_Window tkwin = glxwinPtr->tkwin; glxwinPtr->updatePending = 0; if (tkwin == NULL || !Tk_IsMapped(tkwin)) { return; } #ifdef __WIN32__ assert (glxwinPtr->hwnd != 0); assert (glxwinPtr->hdc != 0); MakeCurrent (glxwinPtr); if (glxwinPtr->redrawList != -1) { glCallList (glxwinPtr->redrawList); } if (glxwinPtr->doubleBuffer) { SwapBuffers (glxwinPtr->hdc); } else { glFlush (); } #else MakeCurrent(glxwinPtr); if (glxwinPtr->redrawList != -1) { glCallList (glxwinPtr->redrawList); } if (glxwinPtr->doubleBuffer) { glXSwapBuffers(Tk_Display (glxwinPtr->tkwin), Tk_WindowId(glxwinPtr->tkwin)); /* buffer swap does implicit glFlush */ } else { glFlush(); /* explicit flush for single buffered case */ } #endif } /* *---------------------------------------------------------------------- * * Display list management. * *---------------------------------------------------------------------- */ static int UnusedDList () { /* Returns an integer number corresponding to a free display list */ return glGenLists (1); } static int FreeDisplayList (displayList) int displayList; { /* free the given display list. returns 0 if displayList is not in use or * 1 if it was correctly freed */ glDeleteLists (displayList, 1); return 1; } /*--------------------------------------------------------------------------- * * Management of Extensions to the TKOGL widget * *---------------------------------------------------------------------------*/ static struct TkOGLExtStruct { char* name; TkOGLExtProc* proc; struct TkOGLExtStruct* next; } *TkOGLExtTable = NULL; EXPORT(int,RegisterTkOGLExtension) (interp, extname, extproc) Tcl_Interp* interp; char* extname; TkOGLExtProc* extproc; { struct TkOGLExtStruct* ptr; ptr = (struct TkOGLExtStruct*) malloc (sizeof (struct TkOGLExtStruct)); assert (ptr != NULL); ptr->name = (char*) malloc (strlen (extname)+1); assert (ptr->name != NULL); strcpy (ptr->name, extname); ptr->proc = extproc; ptr->next = TkOGLExtTable; TkOGLExtTable = ptr; return TCL_OK; } /*--------------------------------------------------------------------------- * * Utility function to format the hit buffer used for selection as a * Tcl List * *---------------------------------------------------------------------------*/ static int ProcessHits (interp, nhits, selectbuf) Tcl_Interp* interp; int nhits; GLuint * selectbuf; { Tcl_DString hitlist; int i; unsigned int j; GLuint names, *ptr; Tcl_DStringInit (&hitlist); ptr = selectbuf; for (i = 0; i < nhits; i++) { char buf [80]; names = *ptr++; Tcl_DStringStartSublist (&hitlist); sprintf (buf, "%u", names); Tcl_DStringAppendElement (&hitlist, buf); sprintf (buf, "%f", ((double) (*ptr++)) / (unsigned int) 0xffffffff ); Tcl_DStringAppendElement (&hitlist, buf); sprintf (buf, "%f", ((double) (*ptr++)) / (unsigned int) 0xffffffff ); Tcl_DStringAppendElement (&hitlist, buf); for (j = 0; j < names; j++) { sprintf (buf, "%d", *ptr++); Tcl_DStringAppendElement (&hitlist, buf); } Tcl_DStringEndSublist (&hitlist); } Tcl_DStringResult (interp, &hitlist); Tcl_DStringFree (&hitlist); return TCL_OK; } /* *-------------------------------------------------------------- * * OGLwinWidgetCmd -- * * This procedure is invoked to process the Tcl command * that corresponds to a widget managed by this module. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *-------------------------------------------------------------- */ static int OGLwinWidgetCmd(clientData, interp, argc, argv) ClientData clientData; /* Information about glxwin widget. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */ { OGLwin *glxwinPtr = (OGLwin *) clientData; Tk_Window tkwin = glxwinPtr->tkwin; int result = TCL_OK; int length; char c; #ifdef __WIN32__ # define MAPWINDOW {\ if (!Tk_IsMapped (tkwin)) Tk_MapWindow (tkwin); \ assert (glxwinPtr->hdc != 0);\ MakeCurrent (glxwinPtr);\ } #else # define MAPWINDOW { \ if (!Tk_IsMapped (tkwin)) Tk_MapWindow (tkwin); \ MakeCurrent(glxwinPtr);\ } #endif if (argc < 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " option ?arg arg ...?\"", (char *) NULL); return TCL_ERROR; } Tcl_Preserve((ClientData) glxwinPtr); c = argv[1][0]; length = (int)strlen(argv[1]); if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0) && (length >= 2)) { /* Standard "configure" tk command */ if (argc == 2) { result = Tk_ConfigureInfo(interp, glxwinPtr->tkwin, configSpecs, (char *) glxwinPtr, (char *) NULL, 0); } else if (argc == 3) { result = Tk_ConfigureInfo(interp, glxwinPtr->tkwin, configSpecs, (char *) glxwinPtr, argv[2], 0); } else { result = OGLwinConfigure(interp, glxwinPtr, argc-2, argv+2, TK_CONFIG_ARGV_ONLY); } } else if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0) && (length >= 2)) { /* Standard "cget" tk command */ if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " cget option\"",(char *) NULL); goto error; } result = Tk_ConfigureValue(interp, glxwinPtr->tkwin, configSpecs, (char *) glxwinPtr, argv[2], 0); } else if ((c == 'm') && (length >= 4) && (strncmp(argv[1], "mainlist", length) == 0)) { /* Establishes the main display list for the widget */ int narg; MAPWINDOW; if (glxwinPtr->redrawList != -1) { glDeleteLists (glxwinPtr->redrawList, 1); } else { glxwinPtr->redrawList = UnusedDList(); if (glxwinPtr->redrawList == -1) { Tcl_AppendResult (interp, "Can't find unused display list", (char*) NULL); goto error; } } argc -= 2; argv += 2; glNewList (glxwinPtr->redrawList, GL_COMPILE); while (result == TCL_OK && argc > 0) { result = ParseGLFunc (interp, argc, argv, &narg); argc -= narg; argv += narg; } glEndList(); ARRANGE_REDRAW (glxwinPtr); } else if ((c == 'n') && (strncmp(argv[1], "newlist", length) == 0)) { /* Creates a new display list and returns its number */ int newlist, narg; MAPWINDOW; if (argc > 2 && isdigit (argv [2][0])) { if (Tcl_GetInt (interp, argv [2], &newlist) != TCL_OK) goto error; argc -= 3; argv += 3; } else { newlist = UnusedDList(); argc -= 2; argv += 2; } glNewList (newlist, GL_COMPILE); while (result == TCL_OK && argc > 0) { result = ParseGLFunc (interp, argc, argv, &narg); argc -= narg; argv += narg; } glEndList(); if (result == TCL_OK) { char tmp[128]; sprintf (tmp, "%d", newlist); Tcl_SetResult(interp, tmp, TCL_VOLATILE); } } else if ((c == 'e') && (strncmp(argv[1], "eval", length) == 0)) { /* sends the gl commands directly */ int narg; MAPWINDOW; argc -= 2; argv += 2; while (result == TCL_OK && argc > 0) { result = ParseGLFunc (interp, argc, argv, &narg); argc -= narg; argv += narg; } glFlush (); } else if ((c == 's') && (strncmp(argv[1], "select", length) == 0)) { /* sets rendermode to select, issue the commands, reset the rendermode * to render and returns the hits as a tcl list */ int narg, nvals, nhits; GLuint *selectbuf; if (argc < 3) { Tcl_AppendResult (interp, "no size for hit buffer specified", NULL); goto error; } if (Tcl_GetInt (interp, argv [2], &nvals) != TCL_OK || nvals <= 0) { Tcl_AppendResult (interp, "invalid hit buffer size", argv [2], NULL); goto error; } selectbuf = (GLuint*) malloc (sizeof (GLuint)*nvals); assert (selectbuf != NULL); MAPWINDOW; argc -= 3; argv += 3; glSelectBuffer (nvals, selectbuf); (void) glRenderMode (GL_SELECT); while (result == TCL_OK && argc > 0) { result = ParseGLFunc (interp, argc, argv, &narg); argc -= narg; argv += narg; } glFlush (); nhits = glRenderMode (GL_RENDER); result = ProcessHits (interp, nhits, selectbuf); free (selectbuf); } else if ((c == 'd') && (strncmp(argv[1], "deletelist", length) == 0)) { /* Free a given display list */ int listNumber; if (argc != 3) { Tcl_AppendResult (interp, "no display list number specified", (char*) NULL); goto error; } if (Tcl_GetInt (interp, argv [2], &listNumber) != TCL_OK) goto error; MAPWINDOW; if (!FreeDisplayList (listNumber)) { Tcl_AppendResult (interp, "not a display list: ", argv [2], (char*) NULL); goto error; } } else if ((c == 'p' && strncmp(argv[1], "project", length) == 0) || (c == 'u' && strncmp(argv[1], "unproject", length) == 0)) { /* Implementation of gluProject (gluUnProject) utility function */ /* Given 3 world(window) coordinates, returns the corresponding */ /* 3 window(world) coordinates */ GLdouble x, y, z, modelmatrix[16], projectmatrix[16]; GLint viewport [4], retval; if (argc != 5) { Tcl_AppendResult (interp, argv [1], ": x y z coordinates expected", (char*) NULL); goto error; } if (Tcl_GetDouble (interp, argv [2], &x) != TCL_OK || Tcl_GetDouble (interp, argv [3], &y) != TCL_OK || Tcl_GetDouble (interp, argv [4], &z) != TCL_OK) goto error; MAPWINDOW; glGetDoublev (GL_MODELVIEW_MATRIX, modelmatrix); glGetDoublev (GL_PROJECTION_MATRIX, projectmatrix); glGetIntegerv (GL_VIEWPORT, viewport); if (c == 'p') { retval = gluProject (x, y, z, modelmatrix, projectmatrix, viewport, &x, &y, &z); y = viewport [3] - y; } else { y = viewport [3] - y; retval = gluUnProject (x, y, z, modelmatrix, projectmatrix, viewport, &x, &y, &z); } if (retval) { char tmp[128]; sprintf (tmp, "%f %f %f", x, y, z); Tcl_SetResult(interp, tmp, TCL_VOLATILE); } } else if ((c == 'r') && (strncmp(argv[1], "redraw", length) == 0)) { /* perform the redraw */ ARRANGE_REDRAW(glxwinPtr); } else { /* handle extensions */ struct TkOGLExtStruct * extPtr = TkOGLExtTable; while (extPtr != NULL) { if (strncmp(argv[1], extPtr->name, length) == 0) { MAPWINDOW; result = (*extPtr->proc) (interp, argc, argv); break; } extPtr = extPtr->next; } if (extPtr == NULL) { Tcl_AppendResult (interp, "bad command: ", argv[1], (char*) NULL); goto error; } } Tcl_Release((ClientData) glxwinPtr); return result; error: Tcl_Release((ClientData) glxwinPtr); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * OGLwinConfigure -- * * This procedure is called to process an argv/argc list in * conjunction with the Tk option database to configure (or * reconfigure) a glxwin widget. * * Results: * The return value is a standard Tcl result. If TCL_ERROR is * returned, then interp->result contains an error message. * * Side effects: * Configuration information, such as colors, border width, * etc. get set for glxwinPtr; old resources get freed, * if there were any. * *---------------------------------------------------------------------- */ static int OGLwinConfigure(interp, glxwinPtr, argc, argv, flags) Tcl_Interp *interp; /* Used for error reporting. */ OGLwin *glxwinPtr; /* Information about widget. */ int argc; /* Number of valid entries in argv. */ char **argv; /* Arguments. */ int flags; /* Flags to pass to * Tk_ConfigureWidget. */ { if (Tk_ConfigureWidget(interp, glxwinPtr->tkwin, configSpecs, argc, (CONST char **)argv, (char *) glxwinPtr, flags) != TCL_OK) { return TCL_ERROR; } /* * Register the desired geometry for the window. Then arrange for * the window to be redisplayed. */ /* Tk_SetWindowBackground(glxwinPtr->tkwin, Tk_3DBorderColor(glxwinPtr->bgBorder)->pixel); */ if ((glxwinPtr->width > 0) || (glxwinPtr->height > 0)) { Tk_GeometryRequest(glxwinPtr->tkwin, glxwinPtr->width, glxwinPtr->height); } return TCL_OK; } /* *-------------------------------------------------------------- * * OGLwinEventProc -- * * This procedure is invoked by the Tk dispatcher for various * events on glxwins. * * Results: * None. * * Side effects: * When the window gets deleted, internal structures get * cleaned up. When it gets exposed, it is redisplayed. * *-------------------------------------------------------------- */ static void OGLwinEventProc(clientData, eventPtr) ClientData clientData; /* Information about window. */ XEvent *eventPtr; /* Information about event. */ { OGLwin *glxwinPtr = (OGLwin *) clientData; #ifdef __WIN32__ assert (glxwinPtr->hwnd != 0); if (eventPtr->type == Expose) { if (GetAbsXY (glxwinPtr)) { /* This Kludge is necessary since Windows Tk does not pass move events * to child windows and hence our OpenGL window might be redrawn * in its old position */ Tk_ResizeWindow (glxwinPtr->tkwin, glxwinPtr->width, glxwinPtr->height); } ARRANGE_REDRAW(glxwinPtr); } else if (eventPtr->type == ConfigureNotify) { GLsizei glnWidth = eventPtr->xconfigure.width; GLsizei glnHeight = eventPtr->xconfigure.height; glxwinPtr->width = glnWidth; glxwinPtr->height = glnHeight; OGLwinViewport (glxwinPtr); } #else if (eventPtr->type == Expose) { ARRANGE_REDRAW(glxwinPtr); } else if (eventPtr->type == ConfigureNotify) { glxwinPtr->width = eventPtr->xconfigure.width; glxwinPtr->height = eventPtr->xconfigure.height; OGLwinViewport (glxwinPtr); ARRANGE_REDRAW(glxwinPtr); } #endif /* WIN32 */ else if (eventPtr->type == DestroyNotify) { Tcl_DeleteCommand(glxwinPtr->interp, Tk_PathName(glxwinPtr->tkwin)); glxwinPtr->tkwin = NULL; if (glxwinPtr->updatePending) { Tcl_CancelIdleCall(OGLwinRedraw, (ClientData) glxwinPtr); } Tcl_EventuallyFree((ClientData) glxwinPtr, OGLwinDestroy); } } /* *---------------------------------------------------------------------- * * OGLwinDestroy -- * * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release * to clean up the internal structure of a glxwin at a safe time * (when no-one is using it anymore). * * Results: * None. * * Side effects: * Everything associated with the glxwin is freed up. * *---------------------------------------------------------------------- */ static void OGLwinDestroy(char* clientData) { OGLwin *glxwinPtr = (OGLwin *) clientData; #if defined(__WIN32__) || defined(_WIN32) if (glxwinPtr->hrc != 0) { wglMakeCurrent (NULL, NULL); wglDeleteContext (glxwinPtr->hrc); MakeCurrent (NULL); ReleaseDC (glxwinPtr->hwnd, glxwinPtr->hdc); if (glxwinPtr->hPalette != 0) { DeleteObject (glxwinPtr->hPalette); } } #endif Tk_FreeOptions(configSpecs, (char *) glxwinPtr, glxwinPtr->display, 0); ckfree((char *) glxwinPtr); } #ifdef __WIN32__ /* *---------------------------------------------------------------------- * * SetDCPixelFormat sets the pixel format for a device context in * preparation for creating a rendering context. * * Input parameters: * hdc = Device context handle * * Returns: * Nothing * *---------------------------------------------------------------------- */ static void SetDCPixelFormat (OGLwin* glxwinPtr) { HANDLE hHeap; int nColors, i; LPLOGPALETTE lpPalette; HDC hdc = glxwinPtr->hdc; BYTE byRedMask, byGreenMask, byBlueMask; PIXELFORMATDESCRIPTOR pfd = { sizeof (PIXELFORMATDESCRIPTOR), // Size of this structure 1, // Version number PFD_DRAW_TO_WINDOW | // Flags PFD_SUPPORT_OPENGL, PFD_TYPE_RGBA, // RGBA pixel values 24, // 24-bit color 0, 0, 0, 0, 0, 0, // Don't care about these 0, 0, // No alpha buffer 0, 0, 0, 0, 0, // No accumulation buffer 32, // 32-bit depth buffer 0, // No stencil buffer 0, // No auxiliary buffers PFD_MAIN_PLANE, // Layer type 0, // Reserved (must be 0) 0, 0, 0 // No layer masks }; int nPixelFormat = 0; XVisualInfo VisInf; XVisualInfo *visinfo = &VisInf; TkWinColormap *cmap = (TkWinColormap *) ckalloc(sizeof(TkWinColormap)); /* Just for portability, define the simplest visinfo */ visinfo->visual = DefaultVisual(glxwinPtr->display, DefaultScreen(glxwinPtr->display)); visinfo->depth = visinfo->visual->bits_per_rgb; /* Set pfd fields according to the capabilities needed */ if (glxwinPtr->doubleBuffer) { pfd.dwFlags |= PFD_DOUBLEBUFFER; } else { pfd.dwFlags &= ~PFD_DOUBLEBUFFER; } pfd.cDepthBits = glxwinPtr->depthSize; pfd.cStencilBits = glxwinPtr->stencilSize; pfd.cAccumBits = glxwinPtr->accumSize; pfd.cAlphaBits = glxwinPtr->alphaSize; nPixelFormat = ChoosePixelFormat (hdc, &pfd); SetPixelFormat (hdc, nPixelFormat, &pfd); DescribePixelFormat (hdc, nPixelFormat, sizeof (PIXELFORMATDESCRIPTOR), &pfd); glxwinPtr->depthSize = pfd.cDepthBits; glxwinPtr->stencilSize = pfd.cStencilBits; glxwinPtr->accumSize = pfd.cAccumBits; glxwinPtr->alphaSize = pfd.cAlphaBits; glxwinPtr->doubleBuffer = (pfd.dwFlags & PFD_DOUBLEBUFFER) != 0; if (pfd.dwFlags & PFD_NEED_PALETTE) { nColors = 1 << pfd.cColorBits; hHeap = GetProcessHeap (); (LPLOGPALETTE) lpPalette = HeapAlloc (hHeap, 0, sizeof (LOGPALETTE) + (nColors * sizeof (PALETTEENTRY))); lpPalette->palVersion = 0x300; lpPalette->palNumEntries = nColors; byRedMask = (1 << pfd.cRedBits) - 1; byGreenMask = (1 << pfd.cGreenBits) - 1; byBlueMask = (1 << pfd.cBlueBits) - 1; for (i=0; ipalPalEntry[i].peRed = (((i >> pfd.cRedShift) & byRedMask) * 255) / byRedMask; lpPalette->palPalEntry[i].peGreen = (((i >> pfd.cGreenShift) & byGreenMask) * 255) / byGreenMask; lpPalette->palPalEntry[i].peBlue = (((i >> pfd.cBlueShift) & byBlueMask) * 255) / byBlueMask; lpPalette->palPalEntry[i].peFlags = 0; } glxwinPtr->hPalette = CreatePalette (lpPalette); HeapFree (hHeap, 0, lpPalette); if (glxwinPtr->hPalette != NULL) { SelectPalette (hdc, glxwinPtr->hPalette, FALSE); RealizePalette (hdc); } cmap->palette = glxwinPtr->hPalette; cmap->size = nColors; cmap->stale = 0; /* Since this is a private colormap of a fix size, we do not need a valid hash table, but a dummy one */ Tcl_InitHashTable(&cmap->refCounts, TCL_ONE_WORD_KEYS); } else { cmap = (TkWinColormap *) DefaultColormap(glxwinPtr->display, DefaultScreen(glxwinPtr->display)); } /* Now, allocate the OpenGL context */ glxwinPtr->hrc = wglCreateContext (glxwinPtr->hdc); /* See if this window will share display lists with another */ if (glxwinPtr->context != NULL) { Tcl_CmdInfo info; if (!Tcl_GetCommandInfo (glxwinPtr->interp, glxwinPtr->context, &info) || info.proc != (Tcl_CmdProc *)OGLwinWidgetCmd) { Tcl_ResetResult (glxwinPtr->interp); Tcl_AppendResult (glxwinPtr->interp, "Not a gl window: ", glxwinPtr->context, (char*) NULL); Tcl_BackgroundError (glxwinPtr->interp); } else if (!wglShareLists(((OGLwin *)(info.clientData))->hrc, glxwinPtr->hrc)) { Tcl_ResetResult (glxwinPtr->interp); Tcl_AppendResult (glxwinPtr->interp, "Cannot share lists with: ", glxwinPtr->context, (char*) NULL); Tcl_BackgroundError (glxwinPtr->interp); } } /* Make sure Tk knows how to switch palettes */ Tk_SetWindowVisual (glxwinPtr->tkwin, visinfo->visual, visinfo->depth, (Colormap) cmap); } #else /*--------------------------------------------------------------------------- * * The following function allocates an X colormap appropriate for using * with OpenGL. This was taken from the example program 'glxdino' by * Mark Kilgard */ Colormap getColormap (Display *dpy, XVisualInfo * vi) { Status status; XStandardColormap *standardCmaps; Colormap cmap; int i, numCmaps; /* if no standard colormap but TrueColor, just make an unshared one */ status = XmuLookupStandardColormap(dpy, vi->screen, vi->visualid, vi->depth, XA_RGB_DEFAULT_MAP, /* replace */ False, /* retain */ True); if (status == 1 && (vi->class == DirectColor || vi->depth == 8)) { status = XGetRGBColormaps(dpy, RootWindow(dpy, vi->screen), &standardCmaps, &numCmaps, XA_RGB_DEFAULT_MAP); if (status == 1) for (i = 0; i < numCmaps; i++) if (standardCmaps[i].visualid == vi->visualid) { cmap = standardCmaps[i].colormap; XFree(standardCmaps); return cmap; } } cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone); return cmap; } #endif cgnslib_3.1.4/src/cgnstools/tkogl/printstr.h0000664000076400007640000000020112160605670016131 00000000000000int PrintString(Tcl_Interp *interp, int argc, char* argv []); int LoadBitmapFont(Tcl_Interp *interp, int argc, char* argv []); cgnslib_3.1.4/src/cgnstools/tkogl/feedback.h0000664000076400007640000000007612160605670016002 00000000000000int Feedback (Tcl_Interp *interp, int argc, char* argv []); cgnslib_3.1.4/src/cgnstools/tkogl/get.c0000664000076400007640000000446412160605670015035 00000000000000#include #include #if defined(__WIN32__) || defined(_WIN32) # define WIN32_LEAN_AND_MEAN # include # undef WIN32_LEAN_AND_MEAN #endif #include typedef enum { INTVAL, FLOATVAL, BOOLEANVAL, ISSETVAL } valType; typedef struct { char * name; GLenum code; valType type; int nVal; } getStruct; static getStruct getTable [] = { {"currentcolor", GL_CURRENT_COLOR, FLOATVAL, 4}, {"currentnormal", GL_CURRENT_NORMAL, FLOATVAL, 4}, {"modelviewmatrix", GL_MODELVIEW_MATRIX, FLOATVAL, 16}, {"projectionmatrix", GL_PROJECTION_MATRIX, FLOATVAL, 16}, {"viewport", GL_VIEWPORT, INTVAL, 4} }; #define ERRMSG(msg) { Tcl_AppendResult(interp,msg,(char*)NULL); \ result = TCL_ERROR; goto done; } #define ERRMSG2(msg1,msg2) { Tcl_AppendResult(interp,msg1,msg2,(char*)NULL); \ result = TCL_ERROR; goto done; } int GetGlVal (Tcl_Interp *interp, int argc, char* argv []) { int i, j, len; char buf [80]; GLfloat floatVal [16]; GLint intVal [16]; if (argc != 3) { Tcl_AppendResult (interp, "wrong # args", (char*) NULL); return TCL_ERROR; } len = (int)strlen (argv [2]); for (i = 0; i < sizeof(getTable)/sizeof(getStruct); i++) { if (strncmp (argv [2], getTable[i].name, len) == 0) goto found; } Tcl_AppendResult (interp, "not implemented", (char*) NULL); return TCL_ERROR; found: switch (getTable [i].code) { case GL_CURRENT_COLOR: glGetFloatv (GL_CURRENT_COLOR, floatVal); break; case GL_CURRENT_NORMAL: glGetFloatv (GL_CURRENT_NORMAL, floatVal); break; case GL_MODELVIEW_MATRIX: glGetFloatv (GL_MODELVIEW_MATRIX, floatVal); break; case GL_PROJECTION_MATRIX: glGetFloatv (GL_PROJECTION_MATRIX, floatVal); break; case GL_VIEWPORT: glGetIntegerv (GL_VIEWPORT, intVal); break; } switch (getTable [i].type) { case FLOATVAL: { for (j = 0; j < getTable [i].nVal; j++) { sprintf (buf, "%g", floatVal [j]); Tcl_AppendElement (interp, buf); } break; } case INTVAL: { for (j = 0; j < getTable [i].nVal; j++) { sprintf (buf, "%d", intVal [j]); Tcl_AppendElement (interp, buf); } break; } default: break; } return TCL_OK; } cgnslib_3.1.4/src/cgnstools/tkogl/Makefile.win0000664000076400007640000000221212160605670016333 00000000000000 include ..\make.win INCS = $(TKOGLINCS) $(TCLINC) OBJS = \ tkogl.obj \ get.obj \ gencyl.obj \ load3ds.obj \ nurbs.obj \ quadric.obj \ tess.obj \ printstr.obj \ feedback.obj \ tkoglparse.obj lib : tkogl.lib install : tkogl.lib clean: -$(RM) *.obj -$(RM) tkogl.lib tkogl.lib : $(OBJS) -$(RM) tkogl.lib link /lib /OUT:tkogl.lib $(OBJS) tkogl.obj: tkogl.h tkoglparse.h \ load3ds.h tess.h quadric.h nurbs.h get.h gencyl.h \ tkogl.c $(CC) $(CFLAGS) $(INCS) -c tkogl.c get.obj: get.h get.c $(CC) $(CFLAGS) $(INCS) -c get.c printstr.obj: printstr.c printstr.h $(CC) $(CFLAGS) $(INCS) -c printstr.c tess.obj: tkogl.h tess.h tess.c $(CC) $(CFLAGS) $(INCS) -c tess.c nurbs.obj: tkogl.h nurbs.h nurbs.c $(CC) $(CFLAGS) $(INCS) -c nurbs.c quadric.obj: tkogl.h quadric.h quadric.c $(CC) $(CFLAGS) $(INCS) -c quadric.c load3ds.obj: tkogl.h load3ds.h load3ds.c $(CC) $(CFLAGS) $(INCS) -c load3ds.c gencyl.obj: tkogl.h gencyl.h gencyl.c $(CC) $(CFLAGS) $(INCS) -c gencyl.c tkoglparse.obj: tkoglparse.h tkoglparse.c $(CC) $(CFLAGS) $(INCS) -c tkoglparse.c feedback.obj: feedback.h feedback.c $(CC) $(CFLAGS) $(INCS) -c feedback.c cgnslib_3.1.4/src/cgnstools/tkogl/Makefile.unix0000664000076400007640000000270712160605670016532 00000000000000# Makefile for Unix/Linux include ../make.defs COPTS = $(CFLAGS) $(TKOGLOPTS) OBJS = \ tkogl.$(O) \ get.$(O) \ gencyl.$(O) \ load3ds.$(O) \ nurbs.$(O) \ quadric.$(O) \ tess.$(O) \ printstr.$(O) \ feedback.$(O) \ tkoglparse.$(O) lib : libtkogl.$(A) install : libtkogl.$(A) clean: $(RM) *.$(O) *~ *.bak *.$(A) glwish$(EXE) #---------------------------------------------------------- libtkogl.$(A) : $(OBJS) $(AR) $@ $(OBJS) $(RANLIB) $@ tkogl.$(O): tkogl.h tkoglparse.h load3ds.h tess.h quadric.h nurbs.h \ get.h gencyl.h tkogl.c $(CC) $(COPTS) -c tkogl.c get.$(O): get.h get.c $(CC) $(COPTS) -c get.c printstr.$(O): printstr.c printstr.h $(CC) $(COPTS) -c printstr.c tess.$(O): tkogl.h tess.h tess.c $(CC) $(COPTS) -c tess.c nurbs.$(O): tkogl.h nurbs.h nurbs.c $(CC) $(COPTS) -c nurbs.c quadric.$(O): tkogl.h quadric.h quadric.c $(CC) $(COPTS) -c quadric.c load3ds.$(O): tkogl.h load3ds.h load3ds.c $(CC) $(COPTS) -c load3ds.c gencyl.$(O): tkogl.h gencyl.h gencyl.c $(CC) $(COPTS) -c gencyl.c tkoglparse.$(O): tkoglparse.h tkoglparse.c $(CC) $(COPTS) -c tkoglparse.c feedback.$(O): feedback.h feedback.c $(CC) $(COPTS) -c feedback.c #---------------------------------------------------------- LIBS = $(TKLIBS) $(OGLLIBS) $(TKOGLLIB) $(X11LIBS) $(TKOGLXLIB) glwish$(EXE) : tkAppInit.$(O) libtkogl.$(A) $(CC) -o $@ tkAppInit.$(O) libtkogl.$(A) $(LIBS) $(STRIP) $@ tkAppInit.$(O): tkogl.h tkAppInit.c $(CC) $(COPTS) -c tkAppInit.c cgnslib_3.1.4/src/cgnstools/tkogl/quadric.c0000664000076400007640000001127512160605670015704 00000000000000#include #include #include #include #include "tkogl.h" #include "quadric.h" #include "tkoglparse.h" /*-------------------------------------------------------------------------- * * Main Procedure for generating quadrics * *--------------------------------------------------------------------------*/ #define ERRMSG(msg) { Tcl_AppendResult(interp,msg,(char*)NULL); \ result = TCL_ERROR; goto done; } #define ERRMSG2(msg1,msg2) { Tcl_AppendResult(interp,msg1,msg2,(char*)NULL); \ result = TCL_ERROR; goto done; } int Quadric (Tcl_Interp *interp, int argc, char* argv []) { int result = TCL_OK; int icoord = 0; int iarg; GLUquadricObj* obj = gluNewQuadric(); int dlist = -1; GLdouble val [6]; for (iarg = 2; iarg < argc; iarg++) { int len = (int)strlen (argv [iarg]); if (strncmp (argv [iarg], "-normals", len) == 0) { iarg++; if (iarg == argc) ERRMSG ("No value for -normals"); if (strcmp (argv [iarg], "none") == 0) { gluQuadricNormals (obj, GLU_NONE); } else if (strcmp (argv [iarg], "flat") == 0) { gluQuadricNormals (obj, GLU_FLAT); } else if (strcmp (argv [iarg], "smooth") == 0) { gluQuadricNormals (obj, GLU_SMOOTH); } else ERRMSG2 ("should be 'none', 'flat' or 'smooth':", argv [iarg]); } else if (strncmp (argv [iarg], "-drawstyle", len) == 0) { iarg++; if (iarg == argc) ERRMSG ("No value for -drawstyle"); if (strcmp (argv [iarg], "point") == 0) { gluQuadricDrawStyle (obj, GLU_POINT); } else if (strcmp (argv [iarg], "line") == 0) { gluQuadricDrawStyle (obj, GLU_LINE); } else if (strcmp (argv [iarg], "fill") == 0) { gluQuadricDrawStyle (obj, GLU_FILL); } else if (strcmp (argv [iarg], "silhouette") == 0) { gluQuadricDrawStyle (obj, GLU_SILHOUETTE); } else ERRMSG2 ("should be 'point', 'line', 'silhouette' or 'fill':", argv [iarg]); } else if (strncmp (argv [iarg], "-orientation", len) == 0) { iarg++; if (iarg == argc) ERRMSG ("No value for -orientation"); if (strcmp (argv [iarg], "outside") == 0) { gluQuadricOrientation (obj, GLU_OUTSIDE); } else if (strcmp (argv [iarg], "inside") == 0) { gluQuadricOrientation (obj, GLU_INSIDE); } else ERRMSG2 ("should be 'outside' or 'inside':", argv [iarg]); } else if (strncmp (argv [iarg], "-texture", len) == 0) { int texture; iarg++; if (iarg == argc) ERRMSG ("No value for -texture"); result = Tcl_GetBoolean (interp, argv [iarg], &texture); if (result != TCL_OK) goto done; gluQuadricTexture (obj, (GLboolean) texture); } else if (strncmp (argv [iarg], "-displaylist", len) == 0) { iarg++; if (strcmp (argv [iarg], "none") == 0) { dlist = 0; } else { result = Tcl_GetInt (interp, argv [iarg], &dlist); if (result != TCL_OK) goto done; } } else if (argv [iarg][0] == '-' && isalpha (argv [iarg][1])) { ERRMSG2 ("Invalid option: ", argv [iarg]) } else break; } for (; iarg < argc && icoord < 6; iarg++) { if (Tcl_GetDouble (interp, argv [iarg], &val[icoord]) != TCL_OK) { ERRMSG2 ("\nInvalid value in ", argv [1]); } icoord++; } if (dlist == -1) dlist = glGenLists (1); if (dlist != 0) glNewList (dlist, GL_COMPILE); switch (argv [1][0]) { case 'c': { /* Cylinder */ if (iarg != argc || icoord > 5) ERRMSG ("too many values for cylinder"); if (icoord < 5) ERRMSG ("too few values for cylinder"); gluCylinder (obj, val [0], val [1], val [2], (GLint) val [3], (GLint) val [4]); break; } case 'd': { /* Disk */ if (iarg != argc || icoord > 4) ERRMSG ("too many values for disk"); if (icoord < 4) ERRMSG ("too few values for disk"); gluDisk (obj, val [0], val [1], (GLint) val [2], (GLint) val [3]); break; } case 'p': { /* PartialDisk */ if (iarg != argc || icoord > 6) ERRMSG ("too many values for partialdisk"); if (icoord < 6) ERRMSG ("too few values for partialdisk"); gluPartialDisk (obj, val [0], val [1], (GLint) val [2], (GLint) val [3], val [4], val [5]); break; } case 's': { /* Sphere */ if (iarg != argc || icoord > 3) ERRMSG ("too many values for sphere"); if (icoord < 3) ERRMSG ("too few values for sphere"); gluSphere (obj, val [0], (GLint) val [1], (GLint) val [2]); break; } } done: gluDeleteQuadric (obj); if (dlist != 0) glEndList(); else return result; if (result == TCL_OK) { char tmp[128]; sprintf (tmp, "%d", dlist); Tcl_SetResult(interp, tmp, TCL_VOLATILE); } else { glDeleteLists (dlist, 1); } return result; } cgnslib_3.1.4/src/cgnstools/tkogl/feedback.c0000664000076400007640000001357612160605670016006 00000000000000#include "tkogl.h" #include "tkoglparse.h" #include "feedback.h" #include #include #if defined(__WIN32__) || defined(_WIN32) # ifdef strncasecmp # undef strncasecmp # endif # if defined(__BORLANDC__) || defined(__CYGWIN__) # define strncasecmp(a,b,c) strnicmp(a,b,c) # else # define strncasecmp(a,b,c) _strnicmp(a,b,c) # endif #endif typedef int PrintVtx (Tcl_DString *, GLfloat* ); static int ProcessBuffer (Tcl_Interp *interp, int size, GLfloat* buffer, PrintVtx * proc) { Tcl_DString list; int i, j, n; char buf [80]; Tcl_DStringInit (&list); for (i = 0; i < size; i++) { int nvtx = 0; if (*buffer == GL_POINT_TOKEN) { Tcl_DStringAppendElement (&list, "-point"); nvtx = 1; } else if (*buffer == GL_BITMAP_TOKEN) { Tcl_DStringAppendElement (&list, "-bitmap"); nvtx = 1; } else if (*buffer == GL_DRAW_PIXEL_TOKEN) { Tcl_DStringAppendElement (&list, "-drawpixel"); nvtx = 1; } else if (*buffer == GL_COPY_PIXEL_TOKEN) { Tcl_DStringAppendElement (&list, "-copypixel"); nvtx = 1; } else if (*buffer == GL_LINE_TOKEN) { Tcl_DStringAppendElement (&list, "-line"); nvtx = 2; } else if (*buffer == GL_LINE_RESET_TOKEN) { Tcl_DStringAppendElement (&list, "-linereset"); nvtx = 2; } else if (*buffer == GL_POLYGON_TOKEN) { Tcl_DStringAppendElement (&list, "-polygon"); buffer++; i++; nvtx = (int) *buffer; } else if (*buffer == GL_PASS_THROUGH_TOKEN) { Tcl_DStringAppendElement (&list, "-passthrough"); buffer++; i++; sprintf (buf, "%d", (int) *buffer); Tcl_DStringAppendElement (&list, buf); } if (nvtx > 0) { ++buffer; for (j = 0; j < nvtx; j++) { n = (*proc) (&list, buffer); buffer += n; i += n; } } } Tcl_DStringResult (interp, &list); Tcl_DStringFree (&list); return TCL_OK; } static int PrintVtx2D (Tcl_DString *list, GLfloat* buffer) { char buf [80]; int i; Tcl_DStringAppendElement (list, "-vertex"); for (i = 0; i < 2; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } return 2; } static int PrintVtx3D (Tcl_DString *list, GLfloat* buffer) { char buf [80]; int i; Tcl_DStringAppendElement (list, "-vertex"); for (i = 0; i < 3; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } return 3; } static int PrintVtx3DColor (Tcl_DString *list, GLfloat* buffer) { char buf [80]; int i; Tcl_DStringAppendElement (list, "-vertex"); for (i = 0; i < 3; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } Tcl_DStringAppendElement (list, "-color"); for (i = 0; i < 4; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } return 7; } static int PrintVtx3DColorTexture (Tcl_DString *list, GLfloat* buffer) { char buf [80]; int i; Tcl_DStringAppendElement (list, "-vertex"); for (i = 0; i < 3; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } Tcl_DStringAppendElement (list, "-color"); for (i = 0; i < 4; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } Tcl_DStringAppendElement (list, "-texture"); for (i = 0; i < 4; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } return 11; } static int PrintVtx4DColorTexture (Tcl_DString *list, GLfloat* buffer) { char buf [80]; int i; Tcl_DStringAppendElement (list, "-vertex"); for (i = 0; i < 4; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } Tcl_DStringAppendElement (list, "-color"); for (i = 0; i < 4; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } Tcl_DStringAppendElement (list, "-texture"); for (i = 0; i < 4; i++) { sprintf (buf, "%g", *buffer++); Tcl_DStringAppendElement (list, buf); } return 12; } int Feedback (Tcl_Interp *interp, int argc, char* argv []) { int result = TCL_OK; int narg; int len; int size; PrintVtx * proc; GLenum type; GLfloat *buffer; if (argc < 4) { Tcl_AppendResult (interp, "Not enough args", (char*) NULL); return TCL_ERROR; } /* Parse 'size' */ if (Tcl_GetInt (interp, argv [2], &size) != TCL_OK || size <= 0) { Tcl_AppendResult (interp, "invalid hit buffer size", argv [2], NULL); return TCL_ERROR; } /* Parse 'type' */ len = (int)strlen (argv [3]); if (strncasecmp (argv [3], "2d", len) == 0) { type = GL_2D; proc = PrintVtx2D; } else if (strncasecmp (argv [3], "3d", len) == 0) { type = GL_3D; proc = PrintVtx3D; } else if (strncasecmp (argv [3], "3dColor", len) == 0) { type = GL_3D_COLOR; proc = PrintVtx3DColor; } else if (strncasecmp (argv [3], "3dColorTexture", len) == 0) { type = GL_3D_COLOR_TEXTURE; proc = PrintVtx3DColorTexture; } else if (strncasecmp (argv [3], "4dColorTexture", len) == 0) { type = GL_4D_COLOR_TEXTURE; proc = PrintVtx4DColorTexture; } else { Tcl_AppendResult (interp, "Unknown type:", argv [3]); return TCL_ERROR; } /* Allocate feedback 'buffer' */ buffer = (GLfloat*) malloc (sizeof (GLfloat)*size); assert (buffer != NULL); /* Render in feedback mode */ glFeedbackBuffer (size, type, buffer); (void) glRenderMode (GL_FEEDBACK); argc -= 4; argv += 4; while (result == TCL_OK && argc > 0) { result = ParseGLFunc (interp, argc, argv, &narg); argc -= narg; argv += narg; } glFlush (); /* Generate feedback string */ size = glRenderMode (GL_RENDER); if (result == TCL_OK) { result = ProcessBuffer (interp, size, buffer, proc); } free (buffer); return result; } cgnslib_3.1.4/src/cgnstools/tkogl/outline.c0000664000076400007640000000556612160605670015741 00000000000000#if defined(__WIN32__) || defined(_WIN32) # define strcasecmp(a,b) stricmp(a,b) #endif typedef struct { unsigned char x, y; } CPoint; typedef struct { int nPoint; cPoint * point; } Stroke; typedef struct { CPoint box; CPoint org; CPoint inc; int nStroke; Stroke stroke; } CDesc; typedef CDesc * StrokeFont [256]; static int LoadFont (Tcl_Interp * interp, char * filename, StrokeFont font) { int glyph x, y; CDesc *desc; int nstroke; int npoint; Stroke strokebuf [50]; CPoint pointbuf [1000]; char buf [80]; FILE *f; int ch; # define ERROR(s1,s2) { \ Tcl_AppendResult (interp, s1, s2, (char*) NULL); \ return TCL_ERROR; \ } # define STORESTROKES {\ desc->nStroke = nstroke; \ desc->stroke = (Stroke*) malloc (sizeof (Stroke) * nstroke); \ memcpy (desc->stroke, strokebuf, sizeof (Stroke) * nstroke); \ } if ((f = fopen (filename, "r")) == 0) ERROR("Can't open ", filename); for (glyph = 0; glyph < 256; glyph++) { font [glyph] = NULL; } nstroke = 0; glyph = -1; while (!feof (f)) { if (fscanf (f, "%79s", buf) != 1) ERROR("Error reading ", filename); if (strcasecmp (buf, "glyph") == 0) { if (glyph != -1) font [glyph] = desc; if (nstroke > 0) STORESTROKES; if (fscanf (f, "%d", &glyph)!= 1) ERROR ("Error in glyph ", filename); desc = (CDesc*) malloc (sizeof (CDesc)); desc->box.x = desc->box.y = 0; desc->org.x = desc->org.y = 0; desc->inc.x = desc->inc.y = 0; nstroke = 0; } else if (strcasecmp (buf, "blackbox") == 0) { if (fscanf (f, "%d %d", &x, &y) != 2) ERROR ("Error in blackbox", filename); desc->box.x = (unsigned char) x; desc->box.y = (unsigned char) y; } else if (strcasecmp (buf, "origin") == 0) { if (fscanf (f, "%d %d", &x, &y) != 2) ERROR ("Error in origin", filename); desc->org.x = (unsigned char) x; desc->org.y = (unsigned char) y; } else if (strcasecmp (buf, "cellinc") == 0) { if (fscanf (f, "%d %d", &x, &y) != 2) ERROR ("Error in cellinc", filename); desc->inc.x = (unsigned char) x; desc->inc.y = (unsigned char) y; } else if (strcasecmp (buf, "stroke") == 0) { npoint = 0; for (;;) { do { ch = getc (f); } while (!(feof (f) || isalpha (ch))); if (isalpha (ch)) { ungetc (ch, f); break; } if (fscanf (f, "%d %d", &x, &y) != 2) ERROR ("Error reading stroke in ", filename); pointbuf [npoint].x = (unsigned char) x; pointbuf [npoint].y = (unsigned char) y; npoint++; } strokebuf [nstroke].nPoint = npoint; strokebuf [nstroke].point = (CPoint*) malloc (sizeof (CPoint)*npoint); memcpy (strokebuf [nstroke].point, pointbuf, sizeof (CPoint)*npoint); nstroke++; } } if (glyph != -1) font [glyph] = desc; if (nstroke > 0) STORESTROKES; return TCL_OK; } cgnslib_3.1.4/src/cgnstools/tkogl/tess.h0000664000076400007640000000007712160605670015235 00000000000000int Tesselate (Tcl_Interp *interp, int argc, char* argv []); cgnslib_3.1.4/src/cgnstools/tkogl/gencyl.h0000664000076400007640000000012212160605670015527 00000000000000int GenericCylinder _ANSI_ARGS_((Tcl_Interp *interp, int argc, char* argv [])); cgnslib_3.1.4/src/cgnstools/tkogl/printstr.c0000664000076400007640000002167712160605670016150 00000000000000#include #if defined(__WIN32__) || defined(_WIN32) # define WIN32_LEAN_AND_MEAN # include # undef WIN32_LEAN_AND_MEAN #endif #include #include #include #include "printstr.h" #include "tkogl.h" static GLubyte rasters[][13] = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36}, {0x00, 0x00, 0x00, 0x66, 0x66, 0xff, 0x66, 0x66, 0xff, 0x66, 0x66, 0x00, 0x00}, {0x00, 0x00, 0x18, 0x7e, 0xff, 0x1b, 0x1f, 0x7e, 0xf8, 0xd8, 0xff, 0x7e, 0x18}, {0x00, 0x00, 0x0e, 0x1b, 0xdb, 0x6e, 0x30, 0x18, 0x0c, 0x76, 0xdb, 0xd8, 0x70}, {0x00, 0x00, 0x7f, 0xc6, 0xcf, 0xd8, 0x70, 0x70, 0xd8, 0xcc, 0xcc, 0x6c, 0x38}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1c, 0x0c, 0x0e}, {0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c}, {0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30}, {0x00, 0x00, 0x00, 0x00, 0x99, 0x5a, 0x3c, 0xff, 0x3c, 0x5a, 0x99, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x00, 0x00}, {0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x03, 0x03}, {0x00, 0x00, 0x3c, 0x66, 0xc3, 0xe3, 0xf3, 0xdb, 0xcf, 0xc7, 0xc3, 0x66, 0x3c}, {0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x38, 0x18}, {0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0xe7, 0x7e}, {0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0x07, 0x03, 0x03, 0xe7, 0x7e}, {0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xff, 0xcc, 0x6c, 0x3c, 0x1c, 0x0c}, {0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xff}, {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e}, {0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x03, 0x03, 0xff}, {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e}, {0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x03, 0x7f, 0xe7, 0xc3, 0xc3, 0xe7, 0x7e}, {0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x30, 0x18, 0x1c, 0x1c, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06}, {0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60}, {0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x18, 0x0c, 0x06, 0x03, 0xc3, 0xc3, 0x7e}, {0x00, 0x00, 0x3f, 0x60, 0xcf, 0xdb, 0xd3, 0xdd, 0xc3, 0x7e, 0x00, 0x00, 0x00}, {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18}, {0x00, 0x00, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe}, {0x00, 0x00, 0x7e, 0xe7, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e}, {0x00, 0x00, 0xfc, 0xce, 0xc7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc7, 0xce, 0xfc}, {0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xc0, 0xff}, {0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc0, 0xc0, 0xc0, 0xff}, {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xcf, 0xc0, 0xc0, 0xc0, 0xc0, 0xe7, 0x7e}, {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xff, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3}, {0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e}, {0x00, 0x00, 0x7c, 0xee, 0xc6, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06}, {0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xe0, 0xf0, 0xd8, 0xcc, 0xc6, 0xc3}, {0x00, 0x00, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0}, {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xff, 0xff, 0xe7, 0xc3}, {0x00, 0x00, 0xc7, 0xc7, 0xcf, 0xcf, 0xdf, 0xdb, 0xfb, 0xf3, 0xf3, 0xe3, 0xe3}, {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xe7, 0x7e}, {0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe}, {0x00, 0x00, 0x3f, 0x6e, 0xdf, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c}, {0x00, 0x00, 0xc3, 0xc6, 0xcc, 0xd8, 0xf0, 0xfe, 0xc7, 0xc3, 0xc3, 0xc7, 0xfe}, {0x00, 0x00, 0x7e, 0xe7, 0x03, 0x03, 0x07, 0x7e, 0xe0, 0xc0, 0xc0, 0xe7, 0x7e}, {0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff}, {0x00, 0x00, 0x7e, 0xe7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3}, {0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3}, {0x00, 0x00, 0xc3, 0xe7, 0xff, 0xff, 0xdb, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3}, {0x00, 0x00, 0xc3, 0x66, 0x66, 0x3c, 0x3c, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3}, {0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3}, {0x00, 0x00, 0xff, 0xc0, 0xc0, 0x60, 0x30, 0x7e, 0x0c, 0x06, 0x03, 0x03, 0xff}, {0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c}, {0x00, 0x03, 0x03, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60}, {0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18}, {0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x30, 0x70}, {0x00, 0x00, 0x7f, 0xc3, 0xc3, 0x7f, 0x03, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0}, {0x00, 0x00, 0x7e, 0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x7f, 0xc3, 0xc3, 0xc3, 0xc3, 0x7f, 0x03, 0x03, 0x03, 0x03, 0x03}, {0x00, 0x00, 0x7f, 0xc0, 0xc0, 0xfe, 0xc3, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x33, 0x1e}, {0x7e, 0xc3, 0x03, 0x03, 0x7f, 0xc3, 0xc3, 0xc3, 0x7e, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0}, {0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x18, 0x00}, {0x38, 0x6c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x0c, 0x00}, {0x00, 0x00, 0xc6, 0xcc, 0xf8, 0xf0, 0xd8, 0xcc, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0}, {0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78}, {0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xfe, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00}, {0xc0, 0xc0, 0xc0, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0xfe, 0x00, 0x00, 0x00, 0x00}, {0x03, 0x03, 0x03, 0x7f, 0xc3, 0xc3, 0xc3, 0xc3, 0x7f, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, 0xfe, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0xfe, 0x03, 0x03, 0x7e, 0xc0, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x1c, 0x36, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x00}, {0x00, 0x00, 0x7e, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x18, 0x3c, 0x3c, 0x66, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0xc3, 0xe7, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00}, {0xc0, 0x60, 0x60, 0x30, 0x18, 0x3c, 0x66, 0x66, 0xc3, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0xff, 0x60, 0x30, 0x18, 0x0c, 0x06, 0xff, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x0f, 0x18, 0x18, 0x18, 0x38, 0xf0, 0x38, 0x18, 0x18, 0x18, 0x0f}, {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, {0x00, 0x00, 0xf0, 0x18, 0x18, 0x18, 0x1c, 0x0f, 0x1c, 0x18, 0x18, 0x18, 0xf0}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x8f, 0xf1, 0x60, 0x00, 0x00, 0x00} }; int LoadBitmapFont(Tcl_Interp *interp, int argc, char* argv []) { GLuint fontOffset, i; char tmp[128]; glPixelStorei(GL_UNPACK_ALIGNMENT, 1); if (argc > 3) { Tcl_AppendResult (interp, "wrong # args", (char*) NULL); return TCL_ERROR; } if (argc == 2) { fontOffset = glGenLists (128-32); for (i = 32; i < 127; i++) { glNewList(i+fontOffset, GL_COMPILE); glBitmap(8, 13, 0.0, 2.0, 10.0, 0.0, rasters[i-32]); glEndList(); } } else { Tcl_AppendResult (interp, "Not Implemented yet", (char*) NULL); return TCL_ERROR; } sprintf (tmp, "%d", fontOffset); Tcl_SetResult(interp, tmp, TCL_VOLATILE); return TCL_OK; } int PrintString(Tcl_Interp *interp, int argc, char* argv []) { int fontOffset; if (argc != 4) { Tcl_AppendResult (interp, "wrong # args", (char*) NULL); return TCL_ERROR; } if (Tcl_GetInt (interp, argv [2], &fontOffset) != TCL_OK) return TCL_ERROR; glPushAttrib (GL_LIST_BIT); glListBase((GLuint)fontOffset); glCallLists((GLsizei)strlen(argv [3]), GL_UNSIGNED_BYTE, (GLubyte *) argv[3]); glPopAttrib (); return TCL_OK; } cgnslib_3.1.4/src/cgnstools/tkogl/strokefont.c0000664000076400007640000001222712160605670016450 00000000000000#include "tkogl.h" #if defined(__WIN32__) || defined(_WIN32) # if defined(__BORLANDC__) || defined(__CYGWIN__) # define strcasecmp(a,b) stricmp(a,b) # else # define strcasecmp(a,b) _stricmp(a,b) # endif #endif typedef struct { unsigned char x, y; } CPoint; typedef struct { int nPoint; CPoint * point; } Stroke; typedef struct { CPoint box; CPoint org; CPoint inc; int nStroke; Stroke * stroke; } CDesc; typedef CDesc * StrokeFont [256]; typedef StrokeFont* StrokeFontPtr; /*---------------------------------------------------------------------- * * NewFont * ======= * * Returns a pointer to a newly allocated empty font */ static StrokeFontPtr NewFont () { StrokeFontPtr fontPtr = (StrokeFontPtr) malloc (sizeof (StrokeFont)); int glyph; for (glyph = 0; glyph < 256; glyph++) { (*fontPtr) [glyph] = NULL; } return fontPtr; } /*---------------------------------------------------------------------- * * FreeFont * ======= * * Given a pointer to a font, deallocates it. */ static void FreeFont (StrokeFontPtr fontPtr) { int glyph; for (glyph = 0; glyph < 256; glyph++) { if ((*fontPtr) [glyph] != NULL) { Stroke * stroke = ((*fontPtr) [glyph]) -> stroke; int istroke = ((*fontPtr) [glyph]) -> nStroke; while (istroke--) { free (stroke->point); stroke++; } free (((*fontPtr) [glyph]) -> stroke); } } free (fontPtr); } /*---------------------------------------------------------------------- * * LoadFont * ======== * * Given the name of a text file containing a description of a stroke font, * loads it into the supplied (empty) font. Returns a standard Tcl * result indicating the success of the operation. */ static int LoadFont (Tcl_Interp * interp, char * filename, StrokeFont font) { int glyph, x, y; CDesc *desc; int nstroke; int npoint; Stroke strokebuf [50]; CPoint pointbuf [1000]; char buf [80]; FILE *f; int ch; # define ERROR(s1,s2) { \ Tcl_AppendResult (interp, s1, s2, (char*) NULL); \ return TCL_ERROR; \ } # define STORESTROKES {\ desc->nStroke = nstroke; \ desc->stroke = (Stroke*) malloc (sizeof (Stroke) * nstroke); \ memcpy (desc->stroke, strokebuf, sizeof (Stroke) * nstroke); \ } if ((f = fopen (filename, "r")) == 0) ERROR("Can't open ", filename); for (glyph = 0; glyph < 256; glyph++) { font [glyph] = NULL; } nstroke = 0; glyph = -1; while (!feof (f)) { if (fscanf (f, "%79s", buf) != 1) ERROR("Error reading ", filename); if (strcasecmp (buf, "glyph") == 0) { if (glyph != -1) font [glyph] = desc; if (nstroke > 0) STORESTROKES; if (fscanf (f, "%d", &glyph)!= 1) ERROR ("Error in glyph ", filename); desc = (CDesc*) malloc (sizeof (CDesc)); desc->box.x = desc->box.y = 0; desc->org.x = desc->org.y = 0; desc->inc.x = desc->inc.y = 0; desc->nStroke = nstroke = 0; desc->stroke = NULL; } else if (strcasecmp (buf, "blackbox") == 0) { if (fscanf (f, "%d %d", &x, &y) != 2) ERROR ("Error in blackbox", filename); desc->box.x = (unsigned char) x; desc->box.y = (unsigned char) y; } else if (strcasecmp (buf, "origin") == 0) { if (fscanf (f, "%d %d", &x, &y) != 2) ERROR ("Error in origin", filename); desc->org.x = (unsigned char) x; desc->org.y = (unsigned char) y; } else if (strcasecmp (buf, "cellinc") == 0) { if (fscanf (f, "%d %d", &x, &y) != 2) ERROR ("Error in cellinc", filename); desc->inc.x = (unsigned char) x; desc->inc.y = (unsigned char) y; } else if (strcasecmp (buf, "stroke") == 0) { npoint = 0; printf ("stroke\n"); for (;;) { do { ch = getc (f); } while (!feof (f) && isspace (ch)); ungetc (ch, f); if (isalpha (ch)) break; if (fscanf (f, "%d %d", &x, &y) != 2) ERROR ("Error reading stroke in ", filename); pointbuf [npoint].x = (unsigned char) x; pointbuf [npoint].y = (unsigned char) y; npoint++; printf ("%d %d\n", x, y); } strokebuf [nstroke].nPoint = npoint; strokebuf [nstroke].point = (CPoint*) malloc (sizeof (CPoint)*npoint); memcpy (strokebuf [nstroke].point, pointbuf, sizeof (CPoint)*npoint); nstroke++; } } if (glyph != -1) font [glyph] = desc; if (nstroke > 0) STORESTROKES; fclose (f); return TCL_OK; } /*---------------------------------------------------------------------- * * StrokeFontExt * ============= * * Main Tkogl extension command for handling stroked fonts. */ int StrokeFontExt (Tcl_Interp *interp, int argc, char* argv []) { int iarg; static StrokeFontPtr fontPtr = NULL; for (iarg = 2; iarg < argc; iarg++) { int len = strlen (argv [iarg]); if (strncmp (argv [iarg], "-load", len) == 0) { iarg++; if (iarg == argc) { Tcl_AppendResult (interp, "not enough arguments", (char*)NULL); return TCL_ERROR; } if (fontPtr != NULL) FreeFont (fontPtr); fontPtr = NewFont (); return LoadFont (interp, argv [iarg], *fontPtr); } else { Tcl_AppendResult (interp, "unknown font option: ", argv [iarg]); return TCL_ERROR; } } } cgnslib_3.1.4/src/cgnstools/tkogl/load3ds.h0000664000076400007640000000013412160605670015602 00000000000000int glLoad3DStudio _ANSI_ARGS_ ((Tcl_Interp *interp, int argc, char ** argv)); cgnslib_3.1.4/src/cgnstools/tkogl/tess.c0000664000076400007640000000660012160605670015226 00000000000000#include #include #include #include #include "tkogl.h" #include "tess.h" /*-------------------------------------------------------------------------- * * Main Procedure for generating tesselations * *--------------------------------------------------------------------------*/ static Tcl_Interp * globalinterp; static int globalresult; static void TessError (GLenum errno) { Tcl_AppendResult (globalinterp, "Tesselation error: ", gluErrorString(errno), " ", (char*) NULL); globalresult = TCL_ERROR; } #if defined(__WIN32__) || defined(_WIN32) typedef void (CALLBACK* TessCallback) (); #else typedef void (* TessCallback) (); #endif int Tesselate (Tcl_Interp *interp, int argc, char* argv []) { int result = TCL_OK; int icoord = 0; int edgeflags = 1; int iarg; GLUtriangulatorObj* obj; int dlist = -1; GLdouble coord [3]; GLfloat* vtx; GLfloat* vtxptr; globalinterp = interp; globalresult = TCL_OK; for (iarg = 2; iarg < argc; iarg++) { int len = (int)strlen (argv [iarg]); if (strncmp (argv [iarg], "-displaylist", len) == 0) { iarg++; if (iarg == argc) { Tcl_AppendResult (interp, "not enough arguments", (char*)NULL); return TCL_ERROR; } if (strcmp (argv [iarg], "none") == 0) { dlist = 0; } else if (Tcl_GetInt (interp, argv [iarg], &dlist) != TCL_OK) { Tcl_AppendResult (interp, "\nError parsing display list number", (char*) NULL); return TCL_ERROR; } } else if (strncmp (argv [iarg], "-noedgeflags", len) == 0) { edgeflags = 0; } else break; } if (argc - iarg < 9) { Tcl_AppendResult (interp, "Not enough vertices", (char*) NULL); return TCL_ERROR; } obj = gluNewTess(); vtx = (GLfloat*) malloc (sizeof (GLfloat) * (argc - iarg)); vtxptr = vtx; assert (vtx != NULL); gluTessCallback(obj, GLU_BEGIN, glBegin); gluTessCallback(obj, GLU_VERTEX, glVertex3fv); gluTessCallback(obj, GLU_END, glEnd); gluTessCallback(obj, GLU_ERROR, (TessCallback) TessError); if (edgeflags) gluTessCallback (obj, GLU_EDGE_FLAG, (TessCallback) glEdgeFlag); if (dlist == -1) dlist = glGenLists (1); if (dlist != 0) glNewList (dlist, GL_COMPILE); gluBeginPolygon (obj); for (; iarg < argc; iarg++) { int len = (int)strlen (argv [iarg]); if (strncmp (argv [iarg], "-contour", len) == 0) { gluNextContour (obj, GLU_UNKNOWN); } else { if (Tcl_GetDouble (interp, argv [iarg], &coord[icoord]) != TCL_OK) { Tcl_AppendResult (interp, "\nError parsing tesselation vertex coord", (char*) NULL); result = TCL_ERROR; break; } else { icoord = (icoord+1)%3; if (icoord == 0) { *(vtxptr) = (GLfloat)coord [0]; *(vtxptr+1) = (GLfloat)coord [1]; *(vtxptr+2) = (GLfloat)coord [2]; gluTessVertex (obj, coord, vtxptr); vtxptr += 3; } } } } gluEndPolygon (obj); gluDeleteTess (obj); free (vtx); if (dlist != 0) glEndList(); if (result != TCL_OK || globalresult != TCL_OK) { if (dlist != 0) glDeleteLists (dlist, 1); return TCL_ERROR; } if (dlist != 0) { char tmp[128]; sprintf (tmp, "%d", dlist); Tcl_SetResult(interp, tmp, TCL_VOLATILE); } return TCL_OK; } cgnslib_3.1.4/src/cgnstools/tkogl/tkoglparse.h0000664000076400007640000000050512160605670016426 00000000000000void InitHashTables (); int ParseGLFunc _ANSI_ARGS_((Tcl_Interp *interp, int argc, char *argv [], int *nArg)); int SearchEnumVal _ANSI_ARGS_((Tcl_Interp* interp, char * name, GLenum* val)); int SearchEnumName _ANSI_ARGS_((Tcl_Interp* interp, GLenum val, char ** name)); cgnslib_3.1.4/src/cgnstools/tkogl/gencyl.c0000664000076400007640000010060712160605670015533 00000000000000#include #if defined(__WIN32__) || defined(_WIN32) # define WIN32_LEAN_AND_MEAN # include # undef WIN32_LEAN_AND_MEAN #endif #include #include #include #include #include #include #include "gencyl.h" #include "tkogl.h" #ifndef PI /* The ubiquitous PI constant */ #define PI 3.14159265358979323846264338327950288 #endif /* Constants that define the various flags for rendering a generic * cylinder */ #define STITCH_ENDS 0x01 /* Stitch together the ends of the cyl */ #define STITCH_LOOPS 0x02 /* Close the cross-sections of the cyl */ #define SHADE_SMOOTH_ROWS 0x04 /* Average normals across rows */ #define SHADE_SMOOTH_COLS 0x08 /* Average normals across columns */ #define TEXTURE_GEN 0x10 /* Generate texture coordinates */ #define ADAPTIVE 0x20 /* Average only normals which form a small angle */ #define CLOSE_FIRST 0x40 /* Close first cross section */ #define CLOSE_LAST 0x80 /* Close last cross section */ /*--------------------------------------------------------------------------- * * General operations with vectors and transformation matrices * *---------------------------------------------------------------------------*/ typedef GLfloat Vector [3]; typedef GLfloat Matrix [4][4]; static void MatrixMult (Matrix m1, Matrix m2, Matrix result) { /* Multiplies m1 by m2 storing the result in result */ int i, j, k; Matrix tmp; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { tmp [i][j] = 0.0; for (k = 0; k < 4; k++) { tmp [i][j] += m1 [i][k] * m2 [k][j]; } } } for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { result [i][j] = tmp [i][j]; } } } static void TransformVector (const Vector v, Matrix m, Vector result) { /* Applies affine linear transformation m to v storing the result in * result */ int i, j; Vector tmp; for (i = 0; i < 3; i++) { tmp [i] = m [i][3]; for (j = 0; j < 3; j++) { tmp [i] += m [i][j] * v [j]; } } for (i = 0; i < 3; i++) { result [i] = tmp [i]; } } static void NormalizeVector (Vector v) { /* Makes v a unit vector */ GLfloat hypot = (GLfloat) sqrt (v [0] * v [0] + v [1] * v [1] + v [2] * v [2]); if (hypot == 0.0) { return; } v [0] /= hypot; v [1] /= hypot; v [2] /= hypot; } static void AddVector (const Vector v1, const Vector v2, Vector result) { /* Adds v1 to v2 and stores in result */ result [0] = v1 [0] + v2 [0]; result [1] = v1 [1] + v2 [1]; result [2] = v1 [2] + v2 [2]; } #define InitVector(v,a,b,c) {v[0]=a; v[1]=b; v[2]=c;} #define CopyVector(dst,src) {dst[0]=src[0];dst[1]=src[1];dst[2]=src[2];} #define DotProduct(a,b) (a[0]*b[0]+a[1]*b[1]+a[2]*b[2]) #if 0 static void ComputeTriangleNormal2 (const Vector v1, const Vector v2, const Vector v3, Vector normal) { /* Computes the normal of the triangle given by the three vertices v1, v2, v3 * and stores it in the vector given by normal */ Vector e1, e2; InitVector (e1, v2[0] - v1[0], v2[1] - v1[1], v2[2] - v1[2]); InitVector (e2, v3[0] - v2[0], v3[1] - v2[1], v3[2] - v2[2]); normal [0] = e1[1]*e2[2]-e1[2]*e2[1]; normal [1] = e2[0]*e1[2]-e2[2]*e1[0]; normal [2] = e1[0]*e2[1]-e1[1]*e2[0]; } static void ComputeQuadNormal (const Vector v1, const Vector v2, const Vector v3, const Vector v4, Vector normal) { /* Computes the normal at vertex v1 of the quadrilateral given * by v1-v2-v3-v4 and stores it in the vector given by normal */ Vector normal1, normal2; GLfloat size1, size2; ComputeTriangleNormal2 (v1, v2, v3, normal1); ComputeTriangleNormal2 (v3, v4, v1, normal2); size1 = normal1[0]*normal1[0]+normal1[1]*normal1[1]+normal1[2]*normal1[2]; size2 = normal2[0]*normal2[0]+normal2[1]*normal2[1]+normal2[2]*normal2[2]; if (size1 > 100*size2) { normal [0] = normal1 [0]/size1; normal [1] = normal1 [1]/size1; normal [2] = normal1 [1]/size1; } else if (size2 > 100*size1) { normal [0] = normal2 [0]/size2; normal [1] = normal2 [1]/size2; normal [2] = normal2 [1]/size2; } else { AddVector (normal1, normal2, normal); NormalizeVector (normal); } } #endif static void ComputeQuadNormal2 (const Vector v1, const Vector v2, const Vector v3, const Vector v4, Vector normal) { /* Computes the squared normal at vertex v1 of the quadrilateral given * by v1-v2-v3-v4 and stores it in the vector given by normal */ normal [0] = (v4 [1] - v1 [1]) * (v4 [2] + v1[2]); normal [1] = (v4 [2] - v1 [2]) * (v4 [0] + v1[0]); normal [2] = (v4 [0] - v1 [0]) * (v4 [1] + v1[1]); normal [0] += (v1 [1] - v2 [1]) * (v1 [2] + v2[2]); normal [1] += (v1 [2] - v2 [2]) * (v1 [0] + v2[0]); normal [2] += (v1 [0] - v2 [0]) * (v1 [1] + v2[1]); normal [0] += (v2 [1] - v3 [1]) * (v2 [2] + v3[2]); normal [1] += (v2 [2] - v3 [2]) * (v2 [0] + v3[0]); normal [2] += (v2 [0] - v3 [0]) * (v2 [1] + v3[1]); normal [0] += (v3 [1] - v4 [1]) * (v3 [2] + v4[2]); normal [1] += (v3 [2] - v4 [2]) * (v3 [0] + v4[0]); normal [2] += (v3 [0] - v4 [0]) * (v3 [1] + v4[1]); } /*--------------------------------------------------------------------------- * * Management of cross sections * *---------------------------------------------------------------------------*/ typedef struct { Vector * vtx; /* Vertex Coordinates */ Vector * normalUL, /* Normal to the Up Left Side of the vertex */ * normalUR, /* Normal to the Up Right Side of the vertex */ * normalDL, /* Normal to the Down Left Side of the vertex */ * normalDR ; /* Normal to the Down Right Side of the vertex */ int nvtx, /* Number of vertices in cross section */ vtxsize; /* Number of vertices allocated in vtx */ } CrossSection; static CrossSection* NewCrossSection () { /* Allocates a new cross section structure */ CrossSection * result = (CrossSection*) malloc (sizeof (CrossSection)); assert (result != NULL); result->nvtx = 0; result->vtxsize = 8; result->vtx = (Vector*) malloc (sizeof (Vector)*result->vtxsize); result->normalUL = result->normalUR = result->normalDL = result->normalDR = NULL; assert (result->vtx != NULL); return result; } static void FreeCrossSection (CrossSection * s) { /* Deallocates the memory associated with cross-section s */ assert (s != NULL); assert (s->vtx != NULL); if (s->normalUL != NULL) free(s->normalUL); if (s->normalUR != NULL) free(s->normalUR); if (s->normalDL != NULL) free(s->normalDL); if (s->normalDR != NULL) free(s->normalDR); free (s->vtx); free (s); } static void AddCrossSectionVtx (CrossSection * s, GLfloat x, GLfloat y, GLfloat z) { /* Stores another vertex with coords (x,y,0) as the next vertex in * cross section 's' */ assert (s != NULL); if (s->vtxsize == s->nvtx) { s->vtxsize *= 2; s->vtx = (Vector*) realloc (s->vtx, sizeof(Vector)*s->vtxsize); assert (s->vtx != NULL); } s->vtx [s->nvtx][0] = x; s->vtx [s->nvtx][1] = y; s->vtx [s->nvtx][2] = z; s->nvtx++; } static CrossSection* PolygonCrossSection (GLfloat radius, int nsides) { /* Returns a cross section which is a regular polygon with 'nsides' sides * and radius 'radius' */ GLfloat x, y, ang, incAng; int i; CrossSection *cross = NewCrossSection (); incAng = (GLfloat)(PI * 2 / nsides); ang = 0.0; for (i = 0; i < nsides; i++) { x = (GLfloat)(radius * sin (ang)); y = (GLfloat)(radius * cos (ang)); AddCrossSectionVtx (cross, x, y, 0.0); ang += incAng; } return cross; } static void TransformCrossSection (CrossSection* s, Matrix m) { /* Apply transformation m to cross section s */ int i; for (i = 0; i < s->nvtx; i++) { TransformVector (s->vtx [i], m, s->vtx [i]); } } static void DupCrossSection (const CrossSection* src, CrossSection* dst) { /* Make dst an exact copy of src */ if (dst->vtxsize < src->vtxsize) { dst->vtxsize = src->vtxsize; dst->vtx = (Vector*) realloc (dst->vtx, sizeof(Vector)*dst->vtxsize); assert (dst->vtx != NULL); } dst->nvtx = src->nvtx; memcpy (dst->vtx, src->vtx, sizeof (Vector)*dst->nvtx); } static void ExpandCrossSection (const CrossSection* src, CrossSection* dst, int ndst) { /* Make dst a copy of src expanded to have n vertices */ int i, nsrc; nsrc = src->nvtx; assert (nsrc < ndst); if (dst->vtxsize < ndst) { dst->vtxsize = ndst; dst->vtx = (Vector*) realloc (dst->vtx, sizeof (Vector)*ndst); } dst->nvtx = ndst; for (i = 0; i < ndst; i++) { memcpy (&(dst->vtx [i]), &(src->vtx [i*nsrc/ndst]), sizeof(Vector)); } } static void CrossSectionNormal2 (const CrossSection* cross, Vector normal) { /* Computes a non-normalized vector that is normal to the cross section */ int ivtx, prev; int nvtx = cross->nvtx; Vector * vtx = cross->vtx; prev = nvtx; normal [0] = normal [1] = normal [2] = 0.0; for (ivtx = 0; ivtx < cross->nvtx; ivtx++) { normal [0] += (vtx[prev] [1] - vtx[ivtx] [1]) * (vtx[prev] [2] + vtx[ivtx][2]); normal [1] += (vtx[prev] [2] - vtx[ivtx] [2]) * (vtx[prev] [0] + vtx[ivtx][0]); normal [2] += (vtx[prev] [0] - vtx[ivtx] [0]) * (vtx[prev] [1] + vtx[ivtx][1]); prev = ivtx; } } /*--------------------------------------------------------------------------- * * Model management * *---------------------------------------------------------------------------*/ typedef struct { double smin, smax, tmin, tmax; int flags; int ncross, sizecross; double adaptivethreshold; CrossSection** cross; } Model; static Model * NewModel () { /* Allocates a new model and returns a pointer to it */ Model* result; result = (Model*) malloc (sizeof (Model)); result->adaptivethreshold = 0; result->ncross = 0; result->sizecross = 8; result->cross = (CrossSection**) malloc (sizeof (CrossSection*) * result->sizecross); assert (result->cross != NULL); return result; } static void FreeModel (Model* model) { /* Deallocates all memory associated with model model */ int i; for (i = 0; i < model->ncross; i++) { FreeCrossSection (model->cross [i]); } free (model->cross); } static void AddModelCrossSection (Model* model, CrossSection* cross) { /* Adds another cross section to the model */ if (model->sizecross == model->ncross) { model->sizecross *= 2; model->cross = (CrossSection**) realloc (model->cross, sizeof (CrossSection*) * model->sizecross); } model->cross [model->ncross++] = cross; } static void UniformCrossSectionLengths (Model * model) { /* Force all CrossSections to be of uniform length */ int icross, maxlength; maxlength = 0; for (icross = 0; icross < model->ncross; icross++) { if (model->cross [icross]->nvtx > maxlength) { maxlength = model->cross [icross]->nvtx; } } for (icross = 0; icross < model->ncross; icross++) { if (model->cross [icross]->nvtx < maxlength) { CrossSection* tmp = NewCrossSection (); ExpandCrossSection (model->cross [icross], tmp, maxlength); FreeCrossSection (model->cross [icross]); model->cross [icross] = tmp; } } } static void ComputeModelNormals (Model* model) { /* Computes normals for each vertex of the model */ int icross, ivtx, prevvtx; int flags = model->flags; CrossSection *thisCross, *nextCross, *prevCross = NULL; Vector *a, *b, *c, *d; int nvtx = model->cross [0]->nvtx; /* Assume every cross section has the same number of vertices */ assert (model->ncross > 1); assert (nvtx > 1); /* First compute Up Right normals (face normals) */ for (icross = 0; icross < model->ncross; icross++) { thisCross = model->cross [icross]; assert (thisCross->nvtx == nvtx); thisCross->normalUR = (Vector*) malloc (sizeof (Vector) * nvtx); if (icross+1 == model->ncross) { if (flags&STITCH_ENDS) { /* Assume last cross section wraps with first cross section */ nextCross = model->cross [0]; } else { /* Last Cross section repeats normals at right from previous cross sections */ assert (prevCross != NULL); memcpy (thisCross->normalUR, prevCross->normalUR, sizeof (Vector) * nvtx); break; } } else { nextCross = model->cross [icross+1]; } for (ivtx = 0; ivtx < nvtx; ivtx++) { if (ivtx+1 == nvtx) { if (flags&STITCH_LOOPS) { /* Assume last vertex wraps with first */ b = &(thisCross->vtx [0]); c = &(nextCross->vtx [0]); } else { /* Last Vertex repeats normal above from previous vertex */ CopyVector (thisCross->normalUR[ivtx], thisCross->normalUR[ivtx-1]); break; } } else { b = &(thisCross->vtx [ivtx+1]); c = &(nextCross->vtx [ivtx+1]); } a = &(thisCross->vtx [ivtx]); d = &(nextCross->vtx [ivtx]); ComputeQuadNormal2 (*a, *d, *c, *b, thisCross->normalUR [ivtx]); NormalizeVector (thisCross->normalUR [ivtx]); } prevCross = thisCross; } /* If only face normals are needed, return here */ if ((flags&(SHADE_SMOOTH_ROWS | SHADE_SMOOTH_COLS)) == 0) return; /* Copy normals to the remaining 3 directions */ for (icross = 0; icross < model->ncross; icross++) { thisCross = model->cross [icross]; thisCross->normalUL = (Vector*) malloc (sizeof (Vector) * nvtx); thisCross->normalDR = (Vector*) malloc (sizeof (Vector) * nvtx); thisCross->normalDL = (Vector*) malloc (sizeof (Vector) * nvtx); if (icross == 0) { if (flags&STITCH_ENDS) { /* Assume first cross section wraps with last cross section */ prevCross = model->cross [model->ncross-1]; } else { /* First Cross section repeats normals at left from the right*/ prevCross = thisCross; } } else { prevCross = model->cross [icross-1]; } for (ivtx = 0; ivtx < nvtx; ivtx++) { if (ivtx == 0) { if (flags&STITCH_LOOPS) { /* Assume last vertex wraps with first */ prevvtx = nvtx-1; } else { /* First Vertex repeats normal below from above */ prevvtx = 0; } } else { prevvtx = ivtx-1; } CopyVector (thisCross->normalUL [ivtx], prevCross->normalUR [ivtx]); CopyVector (thisCross->normalDR [ivtx], thisCross->normalUR [prevvtx]); CopyVector (thisCross->normalDL [ivtx], prevCross->normalUR [prevvtx]); } } /* Smooth Normals */ for (icross = 0; icross < model->ncross; icross++) { thisCross = model->cross [icross]; for (ivtx = 0; ivtx < nvtx; ivtx++) { if ((flags & SHADE_SMOOTH_ROWS)) { Vector tmp; if (!(flags&ADAPTIVE)|| DotProduct(thisCross->normalUL [ivtx], thisCross->normalUR [ivtx]) > model->adaptivethreshold) { AddVector (thisCross->normalUL [ivtx], thisCross->normalUR [ivtx], tmp); NormalizeVector (tmp); CopyVector (thisCross->normalUL [ivtx], tmp); CopyVector (thisCross->normalUR [ivtx], tmp); } if (!(flags&ADAPTIVE)|| DotProduct(thisCross->normalDL [ivtx], thisCross->normalDR [ivtx]) > model->adaptivethreshold) { AddVector (thisCross->normalDL [ivtx], thisCross->normalDR [ivtx], tmp); NormalizeVector (tmp); CopyVector (thisCross->normalDL [ivtx], tmp); CopyVector (thisCross->normalDR [ivtx], tmp); } } if (flags & SHADE_SMOOTH_COLS) { Vector tmp; if (!(flags&ADAPTIVE)|| DotProduct(thisCross->normalUL [ivtx], thisCross->normalDL [ivtx]) > model->adaptivethreshold) { AddVector (thisCross->normalUL [ivtx], thisCross->normalDL [ivtx], tmp); NormalizeVector (tmp); CopyVector (thisCross->normalUL [ivtx], tmp); CopyVector (thisCross->normalDL [ivtx], tmp); } if (!(flags&ADAPTIVE)|| DotProduct(thisCross->normalUR [ivtx], thisCross->normalDR [ivtx]) > model->adaptivethreshold) { AddVector (thisCross->normalUR [ivtx], thisCross->normalDR [ivtx], tmp); NormalizeVector (tmp); CopyVector (thisCross->normalUR [ivtx], tmp); CopyVector (thisCross->normalDR [ivtx], tmp); } } } } } static void ComputeModelBBox (Tcl_Interp* interp, Model* model) { /* Computes the model's bounding box and stores it as two elements in the Interp's result: one for the minimum corner and another for the maximum corner */ Vector min; Vector max; char buf [200]; int icross, ivtx, icoord, ifirst = 1; for (icross = 0; icross < model->ncross; icross++) { CrossSection *cross = model->cross [icross]; for (ivtx = 0; ivtx < cross->nvtx; ivtx++) { if (ifirst) { for (icoord = 0; icoord < 3; icoord++) { min [icoord] = max [icoord] = cross->vtx [ivtx][icoord]; } ifirst = 0; } else { for (icoord = 0; icoord < 3; icoord++) { if (cross->vtx [ivtx][icoord] < min[icoord]) { min [icoord] = cross->vtx [ivtx][icoord]; } if (cross->vtx [ivtx][icoord] > max[icoord]) { max [icoord] = cross->vtx [ivtx][icoord]; } } } } } sprintf (buf, "min %f %f %f", min[0], min[1], min[2]); Tcl_AppendElement (interp, buf); sprintf (buf, "max %f %f %f", max[0], max[1], max[2]); Tcl_AppendElement (interp, buf); } static void RenderModel (Model* model) { /* Renders the surface between each pair of cross sections */ int icross, previcross, ivtx, previvtx; int ncross = model->ncross; int flags = model->flags; int nvtx = model->cross [0]->nvtx; int gentex = (flags & TEXTURE_GEN) != 0; GLfloat texcoord [2]; GLfloat texincr [2]; texcoord [0] = (GLfloat)model->tmin; if (flags&STITCH_ENDS) { icross = 0; previcross = ncross-1; texincr [0] = (GLfloat)((model->tmax-model->tmin) / ncross); } else { icross = 1; previcross = 0; texincr [0] = (GLfloat)((model->tmax-model->tmin) / (ncross-1)); } if (flags&STITCH_LOOPS) { texincr [1] = (GLfloat)((model->smax-model->smin) / nvtx); } else { texincr [1] = (GLfloat)((model->smax-model->smin) / (nvtx-1)); } while (icross < ncross) { CrossSection *a = model->cross [previcross]; CrossSection *b = model->cross [icross]; assert (a->nvtx == b->nvtx); if (flags & STITCH_LOOPS) { ivtx = 0; previvtx = nvtx-1; } else { ivtx = 1; previvtx = 0; } texcoord [1] = (GLfloat)model->smin; if (flags & (SHADE_SMOOTH_COLS|SHADE_SMOOTH_ROWS)) { /* One normal per vertex */ for (; ivtx < nvtx; ivtx++) { glBegin (GL_TRIANGLE_STRIP); if (gentex) glTexCoord2f (texcoord [0], texcoord [1]); glNormal3fv (a->normalUR [previvtx]); glVertex3fv (a->vtx [previvtx]); if (gentex) glTexCoord2f (texcoord [0]+texincr[0], texcoord [1]); glNormal3fv (b->normalUL [previvtx]); glVertex3fv (b->vtx [previvtx]); if (gentex) glTexCoord2f (texcoord [0], texcoord [1]+texincr[1]); glNormal3fv (a->normalDR [ivtx]); glVertex3fv (a->vtx [ivtx]); if (gentex) glTexCoord2f (texcoord [0]+texincr[0], texcoord [1]+texincr[1]); glNormal3fv (b->normalDL [ivtx]); glVertex3fv (b->vtx [ivtx]); previvtx = ivtx; if (gentex) texcoord [1] += texincr [1]; glEnd (); } } else { for (; ivtx < nvtx; ivtx++) { glBegin (GL_TRIANGLE_STRIP); if (gentex) glTexCoord2f (texcoord [0], texcoord [1]); glNormal3fv (a->normalUR [previvtx]); glVertex3fv (a->vtx [previvtx]); if (gentex) glTexCoord2f (texcoord [0]+texincr[0], texcoord [1]); glVertex3fv (b->vtx [previvtx]); if (gentex) glTexCoord2f (texcoord [0], texcoord [1]+texincr[1]); glVertex3fv (a->vtx [ivtx]); if (gentex) glTexCoord2f (texcoord [0]+texincr[0], texcoord [1]+texincr[1]); glVertex3fv (b->vtx [ivtx]); previvtx = ivtx; if (gentex) texcoord [1] += texincr [1]; glEnd(); } } previcross = icross; if (gentex) texcoord [0] += texincr [0]; icross++; } if (flags&(CLOSE_FIRST|CLOSE_LAST)) { GLUtriangulatorObj* obj; Vector normal; GLdouble v [3]; obj = gluNewTess(); gluTessCallback(obj, GLU_BEGIN, glBegin); gluTessCallback(obj, GLU_VERTEX, glVertex3fv); gluTessCallback(obj, GLU_END, glEnd); if (flags&CLOSE_FIRST) { CrossSection *a = model->cross [0]; CrossSectionNormal2 (a, normal); NormalizeVector (normal); glNormal3fv (normal); gluBeginPolygon (obj); for (ivtx = 0; ivtx < nvtx; ivtx++) { v [0] = a->vtx [ivtx][0]; v [1] = a->vtx [ivtx][1]; v [2] = a->vtx [ivtx][2]; gluTessVertex (obj, v, &(a->vtx [ivtx][0])); } gluEndPolygon (obj); } if (flags&CLOSE_LAST) { CrossSection *a = model->cross [model->ncross-1]; CrossSectionNormal2 (a, normal); NormalizeVector (normal); normal [0] = -normal [0]; normal [1] = -normal [1]; normal [2] = -normal [2]; glNormal3fv (normal); gluBeginPolygon (obj); for (ivtx = nvtx-1; ivtx >= 0; ivtx--) { v [0] = a->vtx [ivtx][0]; v [1] = a->vtx [ivtx][1]; v [2] = a->vtx [ivtx][2]; gluTessVertex (obj, v, &(a->vtx [ivtx][0])); } gluEndPolygon (obj); } gluDeleteTess (obj); } } /*-------------------------------------------------------------------------- * * Main Procedure for generating generic cylinders * *--------------------------------------------------------------------------*/ int GenericCylinder (Tcl_Interp *interp, int argc, char* argv []) { #define ERRMSG(msg) \ { Tcl_AppendResult (interp, (msg), (char*) NULL);\ result = TCL_ERROR;\ goto done; } #define ERRMSG2(msg1, msg2) \ { Tcl_AppendResult (interp, (msg1), (msg2), (char*) NULL);\ result = TCL_ERROR;\ goto done; } #define I { \ {1, 0, 0, 0}, \ {0, 1, 0, 0}, \ {0, 0, 1, 0}, \ {0, 0, 0, 1} \ } int result = TCL_OK; Matrix transf = I; CrossSection *currentCross = NewCrossSection (); Model* model = NewModel (); int iarg; int dlist = -1; model->flags = STITCH_LOOPS | SHADE_SMOOTH_ROWS | SHADE_SMOOTH_COLS; model->adaptivethreshold = 0; AddCrossSectionVtx (currentCross, -1.0, -1.0, 0.0); AddCrossSectionVtx (currentCross, -1.0, 1.0, 0.0); AddCrossSectionVtx (currentCross, 1.0, 1.0, 0.0); AddCrossSectionVtx (currentCross, 1.0, -1.0, 0.0); for (iarg = 2; iarg < argc; iarg++) { int len = (int)strlen (argv [iarg]); if (strncmp (argv [iarg], "-plot", len) == 0) { CrossSection* cross = NewCrossSection (); DupCrossSection (currentCross, cross); TransformCrossSection (cross, transf); AddModelCrossSection (model, cross); } else if (strncmp (argv [iarg], "-displaylist", len) == 0) { iarg++; if (strcmp (argv [iarg], "none") == 0) { dlist = 0; } else { result = Tcl_GetInt (interp, argv [iarg], &dlist); if (result != TCL_OK) goto done; } } else if (strncmp (argv [iarg], "-cross", len) == 0) { FreeCrossSection (currentCross); currentCross = NewCrossSection (); while (iarg+3 < argc && !isalpha (argv [iarg+1][1])) { double x, y, z; if (Tcl_GetDouble (interp, argv [iarg+1], &x) != TCL_OK || Tcl_GetDouble (interp, argv [iarg+2], &y) != TCL_OK || Tcl_GetDouble (interp, argv [iarg+3], &z) != TCL_OK) { ERRMSG ("\n error in -cross"); } AddCrossSectionVtx (currentCross, (GLfloat)x, (GLfloat)y, (GLfloat)z); iarg += 3; } } else if (strncmp (argv [iarg], "-polygon", len) == 0) { double radius; int nsides; if (iarg+2 >= argc || Tcl_GetDouble (interp, argv [iarg+1], &radius) != TCL_OK || Tcl_GetInt (interp, argv [iarg+2], &nsides) != TCL_OK) { ERRMSG ("\nError in -polygon"); } iarg += 2; FreeCrossSection (currentCross); currentCross = PolygonCrossSection ((GLfloat)radius, nsides); } else if (strncmp (argv [iarg], "-stitch", len) == 0) { if (iarg+1 >= argc) ERRMSG ("No value for -stitch"); iarg++; len = (int)strlen (argv [iarg]); if (strncmp (argv [iarg], "both", len) == 0) { model->flags |= STITCH_LOOPS | STITCH_ENDS; } else if (strncmp (argv [iarg], "none", len) == 0) { model->flags &= ~(STITCH_LOOPS | STITCH_ENDS); } else if (strncmp (argv [iarg], "ends", len) == 0) { model->flags |= STITCH_ENDS; model->flags &= ~STITCH_LOOPS; } else if (strncmp (argv [iarg], "loops", len) == 0) { model->flags &= ~STITCH_ENDS; model->flags |= STITCH_LOOPS; } else { ERRMSG2 ("Should be 'both', 'none', 'loops' or 'ends':", argv [iarg]); } } else if (strncmp (argv [iarg], "-close", len) == 0) { if (iarg+1 >= argc) ERRMSG ("No value for -close"); iarg++; len = (int)strlen (argv [iarg]); if (strncmp (argv [iarg], "both", len) == 0) { model->flags |= CLOSE_FIRST | CLOSE_LAST; } else if (strncmp (argv [iarg], "none", len) == 0) { model->flags &= ~(CLOSE_FIRST | CLOSE_LAST); } else if (strncmp (argv [iarg], "first", len) == 0) { model->flags |= CLOSE_FIRST; model->flags &= ~CLOSE_LAST; } else if (strncmp (argv [iarg], "last", len) == 0) { model->flags &= ~CLOSE_LAST; model->flags |= CLOSE_FIRST; } else { ERRMSG2 ("Should be 'both', 'none', 'first' or 'last':", argv [iarg]); } } else if (strncmp (argv [iarg], "-shade", len) == 0) { if (iarg+1 >= argc) ERRMSG ("No value for -shade"); iarg++; len = (int)strlen (argv [iarg]); if (strncmp (argv [iarg], "smooth", len) == 0) { model->flags |= SHADE_SMOOTH_COLS | SHADE_SMOOTH_ROWS; } else if (strncmp (argv [iarg], "flat", len) == 0) { model->flags &= ~(SHADE_SMOOTH_COLS | SHADE_SMOOTH_ROWS); } else if (strncmp (argv [iarg], "smoothrows", len) == 0) { model->flags &= ~SHADE_SMOOTH_COLS; model->flags |= SHADE_SMOOTH_ROWS; } else if (strncmp (argv [iarg], "smoothcols", len) == 0) { model->flags &= ~SHADE_SMOOTH_ROWS; model->flags |= SHADE_SMOOTH_COLS; } else { ERRMSG2 ("Should be 'flat', 'smooth', 'smoothrows' or 'smoothcols':", argv [iarg]); } } else if (strncmp (argv [iarg], "-adaptive", len) == 0) { double ang; model->flags |= ADAPTIVE; if (iarg+1 >= argc || Tcl_GetDouble (interp, argv [iarg+1], &ang) != TCL_OK) ERRMSG ("\nError in -adaptive"); model->adaptivethreshold = cos(ang*PI/180); iarg++; } else if (strncmp (argv [iarg], "-texgen", len) == 0) { double smin, smax, tmin, tmax; model->flags |= TEXTURE_GEN; if (iarg+4 >= argc || Tcl_GetDouble (interp, argv [iarg+1], &smin) != TCL_OK || Tcl_GetDouble (interp, argv [iarg+2], &smax) != TCL_OK || Tcl_GetDouble (interp, argv [iarg+3], &tmin) != TCL_OK || Tcl_GetDouble (interp, argv [iarg+4], &tmax) != TCL_OK) ERRMSG ("\nError in -rotate"); iarg += 4; model->smin = smin; model->smax = smax; model->tmin = tmin; model->tmax = tmax; } else if (strncmp (argv [iarg], "-identity", len) == 0) { Matrix ident = I; memcpy (transf, ident, sizeof (Matrix)); } else if (strncmp (argv [iarg], "-rotate", len) == 0) { double angle, x, y, z, norm, sint, cost; Matrix m = I; if (iarg+4 >= argc || Tcl_GetDouble (interp, argv [iarg+1], &angle) != TCL_OK || Tcl_GetDouble (interp, argv [iarg+2], &x) != TCL_OK || Tcl_GetDouble (interp, argv [iarg+3], &y) != TCL_OK || Tcl_GetDouble (interp, argv [iarg+4], &z) != TCL_OK) ERRMSG ("\nError in -rotate"); iarg += 4; norm = sqrt (x*x+y*y+z*z); if (norm == 0.0) ERRMSG ("Null Vector"); x /= norm; y /= norm; z /= norm; angle *= PI/180; sint = sin(angle); cost = cos(angle); m [0][0] = (GLfloat)(x*x + cost * (1 - x*x) + sint * 0); m [0][1] = (GLfloat)(x*y + cost * (0 - x*y) + sint * (-z)); m [0][2] = (GLfloat)(x*z + cost * (0 - x*z) + sint * (y)); m [1][0] = (GLfloat)(y*x + cost * (0 - y*x) + sint * (z)); m [1][1] = (GLfloat)(y*y + cost * (1 - y*y) + sint * 0); m [1][2] = (GLfloat)(y*z + cost * (0 - y*z) + sint * (-x)); m [2][0] = (GLfloat)(z*x + cost * (0 - z*x) + sint * (-y)); m [2][1] = (GLfloat)(z*y + cost * (0 - z*y) + sint * (x)); m [2][2] = (GLfloat)(z*z + cost * (1 - z*z) + sint * 0); MatrixMult (m, transf, transf); } else if (strncmp (argv [iarg], "-translate", len) == 0) { double x, y, z; Matrix m = I; if (iarg+3 >= argc || Tcl_GetDouble (interp, argv [iarg+1], &x) != TCL_OK || Tcl_GetDouble (interp, argv [iarg+2], &y) != TCL_OK || Tcl_GetDouble (interp, argv [iarg+3], &z) != TCL_OK) ERRMSG ("\nError in -translate"); iarg += 3; m [0][3] = (GLfloat)x; m [1][3] = (GLfloat)y; m [2][3] = (GLfloat)z; MatrixMult (m, transf, transf); } else if (strncmp (argv [iarg], "-scale", len) == 0) { double x, y, z; Matrix m = I; if (iarg+3 >= argc || Tcl_GetDouble (interp, argv [iarg+1], &x) != TCL_OK || Tcl_GetDouble (interp, argv [iarg+2], &y) != TCL_OK || Tcl_GetDouble (interp, argv [iarg+3], &z) != TCL_OK) ERRMSG ("\nError in -scale"); iarg += 3; m [0][0] = (GLfloat)x; m [1][1] = (GLfloat)y; m [2][2] = (GLfloat)z; MatrixMult (m, transf, transf); } else { ERRMSG2 ("No such option: ", argv [iarg]); } } done: if (result == TCL_OK) { char buf [100]; if (dlist == -1) dlist = glGenLists (1); if (dlist != 0) glNewList (dlist, GL_COMPILE); UniformCrossSectionLengths (model); ComputeModelNormals (model); RenderModel (model); if (dlist != 0) { glEndList (); sprintf (buf, "displaylist %d", dlist); } Tcl_AppendElement (interp, buf); ComputeModelBBox (interp, model); } FreeModel (model); return result; } cgnslib_3.1.4/src/cgnstools/tkogl/CMakeLists.txt0000664000076400007640000000040012160605670016634 00000000000000######### # tkogl # ######### include_directories(${TCL_INCLUDE_PATH} ${TK_INCLUDE_PATH}) set(tkogl_FILES tkogl.c get.c gencyl.c load3ds.c nurbs.c quadric.c tess.c printstr.c feedback.c tkoglparse.c) add_library(tkogl STATIC ${tkogl_FILES}) cgnslib_3.1.4/src/cgnstools/tkogl/tkAppInit.c0000664000076400007640000000171512160605670016155 00000000000000#include #include #include "tkogl.h" /* * The following variable is a special hack that is needed in order for * Sun shared libraries to be used for Tcl. */ #ifdef NEED_MATHERR extern int matherr(); int *tclDummyMathPtr = (int *) matherr; #endif int Tcl_AppInit(Tcl_Interp *interp) /* Interpreter for application. */ { if (Tcl_Init(interp) == TCL_ERROR) return TCL_ERROR; if (Tk_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_StaticPackage(interp, "Tk", Tk_Init, (Tcl_PackageInitProc *) NULL); if (Tkogl_Init(interp) == TCL_ERROR) return TCL_ERROR; Tcl_SetVar(interp, "tcl_rcFileName", "~/.wishrc", TCL_GLOBAL_ONLY); return TCL_OK; } int main (int argc, /* Number of command-line arguments. */ char **argv) /* Values of command-line arguments. */ { Tk_Main(argc, argv, Tcl_AppInit); return 0; /* Needed only to prevent compiler warning. */ } cgnslib_3.1.4/src/cgnstools/tkogl/get.h0000664000076400007640000000007612160605670015035 00000000000000int GetGlVal (Tcl_Interp *interp, int argc, char* argv []); cgnslib_3.1.4/src/cgnstools/utilities/0000775000076400007640000000000012167722166015064 500000000000000cgnslib_3.1.4/src/cgnstools/utilities/cgns_to_tecplot.c0000664000076400007640000003337712160605674020350 00000000000000#include #include #include #include #include #include "getargs.h" #include "cgnslib.h" #include "cgnsutil.h" static char options[] = "ab:B:S:w"; static char *usgmsg[] = { "usage: cgns_to_tecplot [options] CGNSfile Tecplotfile", " options are:", " -a = write ascii instead of binary format", " -b = use CGNS base number (default 1)", " -B = use CGNS base named ", " -S = solution to use, 0 for no solution (default 1)", " -w = use volume weighting", NULL }; static int weighting = 0; static int usesol = -1; static int ascii = 0; /*--------------------------------------------------------------------*/ static int check_solution (void) { int nz, nf, nvar = -1; if (!usesol) return 0; for (nz = 0; nz < nZones; nz++) { read_zone_solution (nz+1); if (usesol < 0) { if (Zones[nz].nsols == 0) { usesol = 0; return 0; } nf = Zones[nz].sols[0].nflds; } else { if (usesol > Zones[nz].nsols) FATAL (NULL, "solution index out of range"); nf = Zones[nz].sols[usesol-1].nflds; } if (nvar < 0) nvar = nf; else { if (nvar != nf) { if (usesol < 0) { usesol = 0; return 0; } FATAL (NULL, "number solution fields not the same for all zones"); } } } if (usesol < 0) usesol = 1; return nvar; } /*--------------------------------------------------------------------*/ static void write_string (FILE *fp, char *data) { int c; if (ascii) fprintf (fp, "\"%s\"\n", data); else { do { c = (int)*data; fwrite (&c, 4, 1, fp); } while (*data++); } } /*--------------------------------------------------------------------*/ static void write_ints (FILE *fp, int cnt, int *data) { if (ascii) { int nout = 0; while (cnt-- > 0) { if (nout == 10) { putc ('\n', fp); nout = 0; } if (nout++) putc (' ', fp); fprintf (fp, "%d", *data); data++; } putc ('\n', fp); } else { fwrite (data, sizeof(int), cnt, fp); } } /*--------------------------------------------------------------------*/ static void write_floats (FILE *fp, int cnt, float *data) { if (ascii) { int nout = 0; while (cnt-- > 0) { if (nout == 5) { putc ('\n', fp); nout = 0; } if (nout++) putc (' ', fp); fprintf (fp, "%#g", *data); data++; } putc ('\n', fp); } else fwrite (data, sizeof(float), cnt, fp); } /*--------------------------------------------------------------------*/ static void count_elements (int nz, cgsize_t *nelems, int *elemtype) { int ns, et; cgsize_t n, nn, ne, nb = 0, nt = 0; ZONE *z = &Zones[nz]; if (z->esets == NULL) read_zone_element (nz+1); for (ns = 0; ns < z->nesets; ns++) { ne = z->esets[ns].end - z->esets[ns].start + 1; et = z->esets[ns].type; if (et == CGNS_ENUMV(MIXED)) { for (n = 0, nn = 0; nn < ne; nn++) { et = (int)z->esets[ns].conn[n++]; if (et < CGNS_ENUMV(NODE) || et > CGNS_ENUMV(HEXA_27)) FATAL (NULL, "unrecognized element type"); if (et >= CGNS_ENUMV(TETRA_4)) { if (et > CGNS_ENUMV(TETRA_10)) nb++; else nt++; } n += element_node_counts[et]; } continue; } if (et >= CGNS_ENUMV(TETRA_4) && et <= CGNS_ENUMV(HEXA_27)) { if (et > CGNS_ENUMV(TETRA_10)) nb += ne; else nt += ne; } } if (nt + nb == 0) FATAL (NULL, "no volume elements in the zone"); *nelems = nt + nb; *elemtype = nb ? 3 : 2; } /*--------------------------------------------------------------------*/ static int *volume_elements (int nz, cgsize_t *nelems, int *elemtype) { int i, np, ns, nt, et; int *elems; cgsize_t n, nn, ne; ZONE *z = &Zones[nz]; count_elements (nz, &ne, &nt); *nelems = ne; *elemtype = nt; elems = (int *) malloc ((size_t)ne * (1 << nt) * sizeof(int)); if (NULL == elems) FATAL (NULL, "malloc failed for elements"); for (np = 0, ns = 0; ns < z->nesets; ns++) { ne = z->esets[ns].end - z->esets[ns].start + 1; et = z->esets[ns].type; if (et < CGNS_ENUMV(TETRA_4) || et > CGNS_ENUMV(MIXED)) continue; for (n = 0, nn = 0; nn < ne; nn++) { if (z->esets[ns].type == CGNS_ENUMV(MIXED)) et = (int)z->esets[ns].conn[n++]; switch (et) { case CGNS_ENUMV(TETRA_4): case CGNS_ENUMV(TETRA_10): if (nt == 2) { for (i = 0; i < 4; i++) elems[np++] = (int)z->esets[ns].conn[n+i]; } else { for (i = 0; i < 3; i++) elems[np++] = (int)z->esets[ns].conn[n+i]; elems[np++] = (int)z->esets[ns].conn[n+2]; for (i = 0; i < 4; i++) elems[np++] = (int)z->esets[ns].conn[n+3]; } break; case CGNS_ENUMV(PYRA_5): case CGNS_ENUMV(PYRA_14): for (i = 0; i < 4; i++) elems[np++] = (int)z->esets[ns].conn[n+i]; for (i = 0; i < 4; i++) elems[np++] = (int)z->esets[ns].conn[n+4]; break; case CGNS_ENUMV(PENTA_6): case CGNS_ENUMV(PENTA_15): case CGNS_ENUMV(PENTA_18): for (i = 0; i < 3; i++) elems[np++] = (int)z->esets[ns].conn[n+i]; elems[np++] = (int)z->esets[ns].conn[n+2]; for (i = 3; i < 6; i++) elems[np++] = (int)z->esets[ns].conn[n+i]; elems[np++] = (int)z->esets[ns].conn[n+5]; break; case CGNS_ENUMV(HEXA_8): case CGNS_ENUMV(HEXA_20): case CGNS_ENUMV(HEXA_27): for (i = 0; i < 8; i++) elems[np++] = (int)z->esets[ns].conn[n+i]; break; } n += element_node_counts[et]; } } return elems; } /*--------------------------------------------------------------------*/ int main (int argc, char *argv[]) { int i, n, ib, nb, nz, nv, celldim, phydim; int nn, type, *elems = 0, idata[5]; cgsize_t ne; char *p, basename[33], title[65]; float value, *var; SOLUTION *sol; FILE *fp; if (argc < 2) print_usage (usgmsg, NULL); ib = 0; basename[0] = 0; while ((n = getargs (argc, argv, options)) > 0) { switch (n) { case 'a': ascii = 1; break; case 'b': ib = atoi (argarg); break; case 'B': strncpy (basename, argarg, 32); basename[32] = 0; break; case 'w': weighting = 1; break; case 'S': usesol = atoi (argarg); break; } } if (argind > argc - 2) print_usage (usgmsg, "CGNSfile and/or Tecplotfile not given"); if (!file_exists (argv[argind])) FATAL (NULL, "CGNSfile does not exist or is not a file"); /* open CGNS file */ printf ("reading CGNS file from %s\n", argv[argind]); nb = open_cgns (argv[argind], 1); if (!nb) FATAL (NULL, "no bases found in CGNS file"); if (*basename && 0 == (ib = find_base (basename))) FATAL (NULL, "specified base not found"); if (ib > nb) FATAL (NULL, "base index out of range"); cgnsbase = ib ? ib : 1; if (cg_base_read (cgnsfn, cgnsbase, basename, &celldim, &phydim)) FATAL (NULL, NULL); if (celldim != 3 || phydim != 3) FATAL (NULL, "cell and physical dimension must be 3"); printf (" using base %d - %s\n", cgnsbase, basename); if (NULL == (p = strrchr (argv[argind], '/')) && NULL == (p = strrchr (argv[argind], '\\'))) strncpy (title, argv[argind], sizeof(title)); else strncpy (title, ++p, sizeof(title)); title[sizeof(title)-1] = 0; if ((p = strrchr (title, '.')) != NULL) *p = 0; read_zones (); if (!nZones) FATAL (NULL, "no zones in the CGNS file"); /* verify dimensions fit in an integer */ for (nz = 0; nz < nZones; nz++) { if (Zones[nz].nverts > CG_MAX_INT32) FATAL(NULL, "zone size too large to write with integers"); if (Zones[nz].type == CGNS_ENUMV(Unstructured)) { count_elements (nz, &ne, &type); if (ne > CG_MAX_INT32) FATAL(NULL, "too many elements to write with integers"); } } nv = 3 + check_solution (); /* open Tecplot file */ printf ("writing %s Tecplot data to <%s>\n", ascii ? "ASCII" : "binary", argv[++argind]); if (NULL == (fp = fopen (argv[argind], ascii ? "w+" : "w+b"))) FATAL (NULL, "couldn't open Tecplot output file"); /* write file header */ if (ascii) fprintf (fp, "TITLE = \"%s\"\n", title); else { fwrite ("#!TDV75 ", 1, 8, fp); i = 1; write_ints (fp, 1, &i); write_string (fp, title); } /* write variables */ if (ascii) { fprintf (fp, "VARIABLES = \"X\", \"Y\", \"Z\""); if (usesol) { sol = Zones->sols; for (n = 0; n < sol->nflds; n++) fprintf (fp, ",\n\"%s\"", sol->flds[n].name); } } else { write_ints (fp, 1, &nv); write_string (fp, "X"); write_string (fp, "Y"); write_string (fp, "Z"); if (usesol) { sol = Zones->sols; for (n = 0; n < sol->nflds; n++) write_string (fp, sol->flds[n].name); } } /* write zones */ if (!ascii) { for (nz = 0; nz < nZones; nz++) { if (Zones[nz].type == CGNS_ENUMV(Structured)) { idata[0] = 0; /* BLOCK */ idata[1] = -1; /* color not specified */ idata[2] = (int)Zones[nz].dim[0]; idata[3] = (int)Zones[nz].dim[1]; idata[4] = (int)Zones[nz].dim[2]; } else { count_elements (nz, &ne, &type); idata[0] = 2; /* FEBLOCK */ idata[1] = -1; /* color not specified */ idata[2] = (int)Zones[nz].dim[0]; idata[3] = (int)ne; idata[4] = type; } value = 299.0; write_floats (fp, 1, &value); write_string (fp, Zones[nz].name); write_ints (fp, 5, idata); } value = 357.0; write_floats (fp, 1, &value); } for (nz = 0; nz < nZones; nz++) { printf (" zone %d...", nz+1); fflush (stdout); read_zone_grid (nz+1); ne = 0; type = 2; nn = (int)Zones[nz].nverts; var = (float *) malloc (nn * sizeof(float)); if (NULL == var) FATAL (NULL, "malloc failed for temp float array"); if (Zones[nz].type == CGNS_ENUMV(Unstructured)) elems = volume_elements (nz, &ne, &type); if (ascii) { if (Zones[nz].type == CGNS_ENUMV(Structured)) fprintf (fp, "\nZONE T=\"%s\", I=%d, J=%d, K=%d, F=BLOCK\n", Zones[nz].name, (int)Zones[nz].dim[0], (int)Zones[nz].dim[1], (int)Zones[nz].dim[2]); else fprintf (fp, "\nZONE T=\"%s\", N=%d, E=%d, F=FEBLOCK, ET=%s\n", Zones[nz].name, nn, (int)ne, type == 2 ? "TETRAHEDRON" : "BRICK"); } else { value = 299.0; write_floats (fp, 1, &value); i = 0; write_ints (fp, 1, &i); i = 1; for (n = 0; n < nv; n++) write_ints (fp, 1, &i); } for (n = 0; n < nn; n++) var[n] = (float)Zones[nz].verts[n].x; write_floats (fp, nn, var); for (n = 0; n < nn; n++) var[n] = (float)Zones[nz].verts[n].y; write_floats (fp, nn, var); for (n = 0; n < nn; n++) var[n] = (float)Zones[nz].verts[n].z; write_floats (fp, nn, var); if (usesol) { read_solution_field (nz+1, usesol, 0); sol = &Zones[nz].sols[usesol-1]; if (sol->location != CGNS_ENUMV(Vertex)) cell_vertex_solution (nz+1, usesol, weighting); for (nv = 0; nv < sol->nflds; nv++) { for (n = 0; n < nn; n++) var[n] = (float)sol->flds[nv].data[n]; write_floats (fp, nn, var); } } free (var); if (Zones[nz].type == CGNS_ENUMV(Unstructured)) { if (!ascii) { i = 0; write_ints (fp, 1, &i); } nn = 1 << type; for (i = 0, n = 0; n < ne; n++, i += nn) write_ints (fp, nn, &elems[i]); free (elems); } puts ("done"); } fclose (fp); cg_close (cgnsfn); return 0; } cgnslib_3.1.4/src/cgnstools/utilities/patran.tcl0000664000076400007640000000303312160605674016771 00000000000000 array set Import { patfile "" distloads 0 } proc patran_import {w name exe} { global ProgData Font Import set cmd [get_executable $exe 1] if {$cmd == ""} return set Import(cgnsfile) $ProgData(file,name) toplevel $w wm title $w "Patran Neutral File Import" wm transient $w . wm protocol $w WM_DELETE_WINDOW {set Import(done) 0} import_input $w patfile Patran {.pat .neu .txt} import_output $w 1 FrameCreate $w.opts -text "Options" -font $Font(bold) pack $w.opts -side top -padx 5 -pady 2 -fill x set opts [FrameGet $w.opts] checkbutton $opts.dl -text "Include Distributed Loads" \ -variable Import(distloads) -onvalue 1 -offvalue 0 pack $opts.dl -side left frame $opts.dup pack $opts.dup -side right import_dup_check $opts.dup if {[import_buttons $w patran_check]} { if {$Import(distloads)} { lappend cmd -l } if {$Import(dupcheck,flag)} { lappend cmd -$Import(dupcheck) if {$Import(duptol) != ""} { lappend cmd -t$Import(duptol) } } if {$Import(basename) != ""} { lappend cmd -B$Import(basename) } lappend cmd $Import(patfile) $Import(cgnsfile) import_run "Patran Import" $cmd $Import(cgnsfile) } } proc patran_check {w} { global Import if {[string trim $Import(patfile)] == "" || [string trim $Import(cgnsfile)] == ""} { errormsg "must specify a Patran and a CGNS file" $w return } if {![file exists $Import(patfile)]} { errormsg "Patran Neutral file doesn't exist" $w return } set Import(done) 1 } cgnslib_3.1.4/src/cgnstools/utilities/p3dfout.c0000664000076400007640000000626312160605674016540 00000000000000#include #include #include #include #include "binaryio.h" static FILE *p3dout; void OPENF (int *read, char *fname, int length) { char *p, *buff; if (*read) { fprintf (stderr, "reading not supported\n"); exit (1); } #if MACH_LOCAL == MACH_CRAY || \ MACH_LOCAL == MACH_DOS16 || \ MACH_LOCAL == MACH_DOS32 || \ MACH_LOCAL == MACH_UNKNOWN fprintf (stderr, "Fortran unformatted output not supported for %s machine\n", bf_machname (MACH_LOCAL); exit (1); #else buff = (char *) malloc (length + 1); if (NULL == buff) { fprintf (stderr, "malloc failed for filename working buffer\n"); exit (1); } strncpy (buff, fname, length); buff[length] = 0; for (p = buff+strlen(buff)-1; p >= buff && isspace(*p); p--) ; *++p = 0; for (p = buff; *p && isspace(*p); p++) ; if (NULL == (p3dout = fopen (p, "w+b"))) { fprintf (stderr, "couldn't open <%s> for writing\n", fname); exit (1); } free (buff); #endif } void CLOSEF (void) { fclose (p3dout); } void WRITEIF (int *icnt, int *idata, int *ierr) { unsigned int reclen = (unsigned int)*icnt * sizeof(int); if (fwrite (&reclen, sizeof(int), 1, p3dout) != 1 || fwrite (idata, sizeof(int), *icnt, p3dout) != *icnt || fwrite (&reclen, sizeof(int), 1, p3dout) != 1) *ierr = 1; else *ierr = 0; return; } void WRITEFF (int *icnt, float *rdata, int *ierr) { unsigned int reclen = (unsigned int)*icnt * sizeof(float); if (fwrite (&reclen, sizeof(int), 1, p3dout) != 1 || fwrite (rdata, sizeof(float), *icnt, p3dout) != *icnt || fwrite (&reclen, sizeof(int), 1, p3dout) != 1) *ierr = 1; else *ierr = 0; return; } void WRITEDF (int *icnt, double *rdata, int *ierr) { unsigned int reclen = (unsigned int)*icnt * sizeof(double); if (fwrite (&reclen, sizeof(int), 1, p3dout) != 1 || fwrite (rdata, sizeof(double), *icnt, p3dout) != *icnt || fwrite (&reclen, sizeof(int), 1, p3dout) != 1) *ierr = 1; else *ierr = 0; return; } void WRITEGFF(int *icnt, float *rdata, int *idata, int *ierr) { unsigned int rcnt = 3 * (unsigned int)*icnt; unsigned int reclen = rcnt * sizeof(float) + (unsigned int)*icnt * sizeof(int); if (fwrite (&reclen, sizeof(int), 1, p3dout) != 1 || fwrite (rdata, sizeof(float), rcnt, p3dout) != rcnt || fwrite (idata, sizeof(int), *icnt, p3dout) != *icnt || fwrite (&reclen, sizeof(int), 1, p3dout) != 1) *ierr = 1; else *ierr = 0; return; } void WRITEGDF(int *icnt, double *rdata, int *idata, int *ierr) { unsigned int rcnt = 3 * (unsigned int)*icnt; unsigned int reclen = rcnt * sizeof(double) + (unsigned int)*icnt * sizeof(int); if (fwrite (&reclen, sizeof(int), 1, p3dout) != 1 || fwrite (rdata, sizeof(double), rcnt, p3dout) != rcnt || fwrite (idata, sizeof(int), *icnt, p3dout) != *icnt || fwrite (&reclen, sizeof(int), 1, p3dout) != 1) *ierr = 1; else *ierr = 0; return; } cgnslib_3.1.4/src/cgnstools/utilities/utilities.mnu0000664000076400007640000000170112160605674017534 00000000000000File:separator # File->Import menu File:Import:PLOT3D import plot3d_to_cgns plot3d_import plot3d.tcl File:Import:Tecplot import tecplot_to_cgns tecplot_import tecplot.tcl File:Import:Patran import patran_to_cgns patran_import patran.tcl File:Import:User import # File->Export menu File:Export:PLOT3D export cgns_to_plot3d plot3d_export plot3d.tcl File:Export:Tecplot export cgns_to_tecplot tecplot_export tecplot.tcl File:Export:VTK export cgns_to_vtk vtk_export vtk.tcl File:Export:User export # Utilities "Utilities:Solution Location" convert convert_location \ convert_location convert.tcl "Utilities:Solution Variables" convert convert_variables \ convert_variables convert.tcl Utilities:Dimensionalization convert convert_dataclass \ convert_dimensional convert.tcl Utilities:separator "Utilities:Extract Subset" convert extract_subset extract_subset util.tcl Utilities:Interpolation convert interpolate_cgns interpolate_cgns util.tcl cgnslib_3.1.4/src/cgnstools/utilities/cgns_to_vtk.c0000775000076400007640000007763012160605674017505 00000000000000/* * cgns_to_vtk - read CGNS file and write VTK file */ #include #include #include #include #include #include #include #ifdef _WIN32 # include # include # define chdir _chdir #else # include #endif #include "getargs.h" #include "cgnslib.h" #ifndef CG_MODE_READ # define CG_MODE_READ MODE_READ #endif #if defined(_WIN32) || defined(__CYGWIN__) || defined(__linux) || \ defined(__alpha) || defined(__ultrix) # ifndef BYTE_SWAPPED # define BYTE_SWAPPED # endif #endif static char options[] = "b:z:s:vea"; static char *usgmsg[] = { "usage : cgns_to_vtk [options] CGNSfile [outdir]", "options:", " -b = base number (default 1)", " -z = zone number (default 0 - all)", " -s = solution number (default 1)", " -v = verbose output", " -e = write element sets (unstructured zone)", " -a = write ascii instead of binary format", " is the output directory for the VTK files.", "If not specified, it defaults to the current directory.", NULL }; typedef float Node[3]; typedef struct { int cnt; char name[33]; } Variable; static int nzones; static int cgnsfn; static int cgnsbase = 1; static int cgnszone = 0; static int cgnssol = 1; static int CellDim, PhyDim; static int nnodes; static Node *nodes; static CGNS_ENUMT(GridLocation_t) varloc; static int nvars, ndata; static Variable *vars; static cgsize_t varrng[2][3]; static int verbose = 0; static int ascii = 0; /*---------- FATAL ---------------------------------------------------- * exit with error message *---------------------------------------------------------------------*/ static void FATAL (char *errmsg) { if (NULL == errmsg) fprintf (stderr, "CGNS error:%s\n", cg_get_error()); else fprintf (stderr, "%s\n", errmsg); exit (1); } /*---------- create_filename ----------------------------------------- * create valid filename *--------------------------------------------------------------------*/ static void create_filename (char *str, char *fname) { int n = 0; char *p; for (p = str; *p; p++) { #ifdef _WIN32 if (strchr ("\\/:*?\"<>|", *p) == NULL) #else if (isspace(*p)) continue; if (strchr ("\\/:*?\"<>|[]()", *p) == NULL) #endif fname[n++] = *p; else fname[n++] = '_'; } fname[n] = 0; } /*---------- fix_name ------------------------------------------------ * remove invalid characters from variable name *--------------------------------------------------------------------*/ static void fix_name (char *str, char *name) { int n = 0; char *p; for (p = str; *p; p++) { if (!isspace(*p)) name[n++] = *p; } name[n] = 0; } /*---------- swap_bytes ---------------------------------------------- * swap bytes *--------------------------------------------------------------------*/ #ifdef BYTE_SWAPPED static void *swap_bytes (int bytes, void *data) { static unsigned char buf[sizeof(double)]; unsigned char *p = (unsigned char *)data; int n; p += bytes; for (n = 0; n < bytes; n++) buf[n] = *--p; return ((void *)buf); } #endif /*---------- write_ints ---------------------------------------------- * write integers to VTK file *--------------------------------------------------------------------*/ static void write_ints (FILE *fp, int cnt, int *data) { if (ascii) { fprintf (fp, "%d", *data); while (--cnt > 0) { data++; fprintf (fp, " %d", *data); } putc ('\n', fp); } else { #ifdef BYTE_SWAPPED while (cnt-- > 0) { fwrite (swap_bytes (sizeof(int), (void *)data), sizeof(int), 1, fp); data++; } #else fwrite (data, sizeof(int), cnt, fp); #endif } } /*---------- write_floats -------------------------------------------- * write floats to VTK file *--------------------------------------------------------------------*/ static void write_floats (FILE *fp, int cnt, float *data) { if (ascii) { fprintf (fp, "%g", *data); while (--cnt > 0) { data++; fprintf (fp, " %g", *data); } putc ('\n', fp); } else { #ifdef BYTE_SWAPPED while (cnt-- > 0) { fwrite (swap_bytes (sizeof(float), (void *)data), sizeof(float), 1, fp); data++; } #else fwrite (data, sizeof(float), cnt, fp); #endif } } /*---------- get_nodes ------------------------------------------------ * read zone nodes *---------------------------------------------------------------------*/ static int get_nodes (int nz, CGNS_ENUMT(ZoneType_t) zonetype, cgsize_t *sizes) { int i, j, n, ncoords; int rind[6]; cgsize_t nn, rng[2][3]; CGNS_ENUMT(DataType_t) datatype; float *xyz; double rad, theta, phi; char name[33], coordtype[4]; /* get number of coordinates */ if (cg_ncoords (cgnsfn, cgnsbase, nz, &ncoords)) FATAL (NULL); if (ncoords < PhyDim) FATAL ("less than PhyDim coordinates"); /* check for rind */ if (cg_goto (cgnsfn, cgnsbase, "Zone_t", nz, "GridCoordinates_t", 1, "end")) FATAL (NULL); if ((i = cg_rind_read (rind)) != CG_OK) { if (i != CG_NODE_NOT_FOUND) FATAL (NULL); for (n = 0; n < 6; n++) rind[n] = 0; } /* get grid coordinate range */ if (zonetype == CGNS_ENUMV(Structured)) { for (n = 0; n < 3; n++) { rng[0][n] = 1; rng[1][n] = 1; } nn = 1; for (n = 0; n < CellDim; n++) { rng[0][n] = rind[2*n] + 1; rng[1][n] = rind[2*n] + sizes[n]; nn *= sizes[n]; } } else { nn = sizes[0] + rind[0] + rind[1]; rng[0][0] = 1; rng[1][0] = nn; } nnodes = (int)nn; /* read the nodes */ strcpy (coordtype, " "); xyz = (float *) malloc (nnodes * sizeof(float)); nodes = (Node *) malloc (nnodes * sizeof(Node)); if (xyz == NULL || nodes == NULL) FATAL ("malloc failed for nodes"); for (i = 1; i <= ncoords; i++) { if (cg_coord_info (cgnsfn, cgnsbase, nz, i, &datatype, name) || cg_coord_read (cgnsfn, cgnsbase, nz, name, CGNS_ENUMV(RealSingle), rng[0], rng[1], xyz)) FATAL (NULL); if (0 == strcmp (name, "CoordinateX") || 0 == strcmp (name, "CoordinateR")) j = 0; else if (0 == strcmp (name, "CoordinateY") || 0 == strcmp (name, "CoordinateTheta")) j = 1; else if (0 == strcmp (name, "CoordinateZ") || 0 == strcmp (name, "CoordinatePhi")) j = 2; else continue; if (coordtype[j] == ' ' || strchr ("XYZ", name[10]) != NULL) coordtype[j] = name[10]; for (n = 0; n < nnodes; n++) nodes[n][j] = xyz[n]; } free (xyz); /* change coordinate system to cartesian */ if (0 == strncmp (coordtype, "RTZ", PhyDim)) { for (n = 0; n < nnodes; n++) { rad = nodes[n][0]; theta = nodes[n][1]; nodes[n][0] = (float)(rad * cos (theta)); nodes[n][1] = (float)(rad * sin (theta)); } } else if (0 == strcmp (coordtype, "RTP")) { for (n = 0; n < nnodes; n++) { rad = nodes[n][0]; theta = nodes[n][1]; phi = nodes[n][2]; nodes[n][0] = (float)(rad * sin (theta) * cos (phi)); nodes[n][1] = (float)(rad * sin (theta) * sin (phi)); nodes[n][2] = (float)(rad * cos (theta)); } } else if (strncmp (coordtype, "XYZ", PhyDim)) FATAL ("unknown coordinate system"); return nnodes; } /*---------- sort_variables ----------------------------------------- * sort variables by name *-------------------------------------------------------------------*/ static int sort_variables (const void *v1, const void *v2) { Variable *var1 = (Variable *)v1; Variable *var2 = (Variable *)v2; return (strcmp (var1->name, var2->name)); } /*---------- get_variables -------------------------------------------- * get the solution vaiables *---------------------------------------------------------------------*/ static int get_variables (int nz, CGNS_ENUMT(ZoneType_t) zonetype, cgsize_t *sizes) { char name[33]; int n, len, nv, nsols; int rind[6]; CGNS_ENUMT(DataType_t) datatype; nvars = 0; if (cg_nsols (cgnsfn, cgnsbase, nz, &nsols)) FATAL (NULL); if (cgnssol < 1 || cgnssol > nsols) return 0; if (cg_sol_info (cgnsfn, cgnsbase, nz, cgnssol, name, &varloc) || cg_nfields (cgnsfn, cgnsbase, nz, cgnssol, &nv)) FATAL (NULL); if (nv < 1) return 0; if (varloc != CGNS_ENUMV(Vertex) && varloc != CGNS_ENUMV(CellCenter)) return 0; nvars = nv; /* check for rind */ if (cg_goto (cgnsfn, cgnsbase, "Zone_t", nz, "FlowSolution_t", cgnssol, "end")) FATAL (NULL); if ((n = cg_rind_read (rind)) != CG_OK) { if (n != CG_NODE_NOT_FOUND) FATAL (NULL); for (n = 0; n < 6; n++) rind[n] = 0; } /* get solution data range */ if (zonetype == CGNS_ENUMV(Structured)) { nv = varloc == CGNS_ENUMV(Vertex) ? 0 : CellDim; for (n = 0; n < 3; n++) { varrng[0][n] = 1; varrng[1][n] = 1; } ndata = 1; for (n = 0; n < CellDim; n++) { varrng[0][n] = rind[2*n] + 1; varrng[1][n] = rind[2*n] + sizes[n+nv]; ndata *= (int)sizes[n+nv]; } } else { nv = varloc == CGNS_ENUMV(Vertex) ? 0 : 1; ndata = (int)sizes[nv]; varrng[0][0] = rind[0] + 1; varrng[1][0] = rind[0] + ndata; } /* get variable names */ vars = (Variable *) malloc (nvars * sizeof(Variable)); if (vars == NULL) FATAL ("malloc failed for variable names"); for (nv = 0; nv < nvars; nv++) { if (cg_field_info (cgnsfn, cgnsbase, nz, cgnssol, nv+1, &datatype, name)) FATAL (NULL); vars[nv].cnt = 1; strcpy (vars[nv].name, name); } qsort (vars, nvars, sizeof(Variable), sort_variables); /* get number of scalars and vectors */ for (nv = 2; nv < nvars; nv++) { len = (int)strlen(vars[nv].name) - 1; if (vars[nv].name[len] == 'Z') { strcpy (name, vars[nv].name); name[len] = 'Y'; if (0 == strcmp (name, vars[nv-1].name)) { name[len] = 'X'; if (0 == strcmp (name, vars[nv-2].name)) { vars[nv-2].cnt = 3; vars[nv-1].cnt = 0; vars[nv].cnt = 0; } } } } return nvars; } /*---------- write_solution ------------------------------------------- * write solution to vtk file *---------------------------------------------------------------------*/ static void write_solution (FILE *fp, int nz, int *mask) { char name[33]; int n, nv, nd; int nscal, nvect; float *data, v[3]; nscal = nvect = 0; for (nv = 0; nv < nvars; nv++) { if (vars[nv].cnt == 1) nscal++; else if (vars[nv].cnt == 3) nvect++; } if (nvect) data = (float *) malloc (3 * ndata * sizeof(float)); else data = (float *) malloc (ndata * sizeof(float)); if (data == NULL) FATAL ("malloc failed for solution data"); if (mask == NULL) nd = ndata; else { for (nd = 0, n = 0; n < ndata; n++) { if (mask[n]) nd++; } } if (verbose) { printf (" writing %d scalars and %d vectors as %s data\n", nscal, nvect, varloc == CGNS_ENUMV(Vertex) ? "point" : "cell"); fflush (stdout); } fprintf (fp, "%s_DATA %d\n", varloc == CGNS_ENUMV(Vertex) ? "POINT" : "CELL", nd); if (nscal) { for (nv = 0; nv < nvars; nv++) { if (vars[nv].cnt != 1) continue; if (cg_field_read (cgnsfn, cgnsbase, nz, cgnssol, vars[nv].name, CGNS_ENUMV(RealSingle), varrng[0], varrng[1], data)) FATAL (NULL); fix_name (vars[nv].name, name); fprintf (fp, "SCALARS %s float\n", name); fprintf (fp, "LOOKUP_TABLE default\n"); for (n = 0; n < ndata; n++) { if (mask == NULL || mask[n]) write_floats (fp, 1, &data[n]); } } } if (nvect) { for (nv = 0; nv < nvars; nv++) { if (vars[nv].cnt != 3) continue; if (cg_field_read (cgnsfn, cgnsbase, nz, cgnssol, vars[nv].name, CGNS_ENUMV(RealSingle), varrng[0], varrng[1], data) || cg_field_read (cgnsfn, cgnsbase, nz, cgnssol, vars[nv+1].name, CGNS_ENUMV(RealSingle), varrng[0], varrng[1], &data[ndata]) || cg_field_read (cgnsfn, cgnsbase, nz, cgnssol, vars[nv+2].name, CGNS_ENUMV(RealSingle), varrng[0], varrng[1], &data[2*ndata])) FATAL (NULL); fix_name (vars[nv].name, name); name[strlen(name)-1] = 0; fprintf (fp, "VECTORS %s float\n", name); for (n = 0; n < ndata; n++) { if (mask == NULL || mask[n]) { v[0] = data[n]; v[1] = data[n+ndata]; v[2] = data[n+2*ndata]; write_floats (fp, 3, v); } } } } free (data); } /*---------- write_volume_cells --------------------------------------- * write volume cell data to vtk file *---------------------------------------------------------------------*/ static void write_volume_cells (FILE *fp, int nz) { int i, n, ns, nsect, nn, ip; int elemcnt, elemsize; int *types, cell[9]; cgsize_t is, ie, nelems, maxsize, maxelems; cgsize_t size, *conn; CGNS_ENUMT(ElementType_t) elemtype, et; char name[33]; if (cg_nsections (cgnsfn, cgnsbase, nz, &nsect)) FATAL (NULL); if (nsect < 1) FATAL ("no sections defined"); maxsize = maxelems = 0; for (ns = 1; ns <= nsect; ns++) { if (cg_section_read (cgnsfn, cgnsbase, nz, ns, name, &elemtype, &is, &ie, &nn, &ip) || cg_ElementDataSize (cgnsfn, cgnsbase, nz, ns, &size)) FATAL (NULL); nelems = ie - is + 1; if (maxelems < nelems) maxelems = nelems; if (maxsize < size) maxsize = size; } if (maxsize > CG_MAX_INT32) FATAL("too many elements for 32-bit integer"); conn = (cgsize_t *) malloc ((size_t)maxsize * sizeof(cgsize_t)); if (conn == NULL) FATAL ("malloc failed for element connectivity"); /* count volume cells */ elemcnt = elemsize = 0; for (ns = 1; ns <= nsect; ns++) { if (cg_section_read (cgnsfn, cgnsbase, nz, ns, name, &elemtype, &is, &ie, &nn, &ip)) FATAL (NULL); if (elemtype < CGNS_ENUMV(TETRA_4) || elemtype > CGNS_ENUMV(MIXED)) continue; nelems = ie - is + 1; if (elemtype == CGNS_ENUMV(MIXED)) { if (cg_elements_read (cgnsfn, cgnsbase, nz, ns, conn, NULL)) FATAL (NULL); for (i = 0, n = 0; n < nelems; n++) { et = (int)conn[i++]; switch (et) { case CGNS_ENUMV(TETRA_4): case CGNS_ENUMV(TETRA_10): elemcnt++; elemsize += 5; break; case CGNS_ENUMV(PYRA_5): case CGNS_ENUMV(PYRA_14): elemcnt++; elemsize += 6; break; case CGNS_ENUMV(PENTA_6): case CGNS_ENUMV(PENTA_15): case CGNS_ENUMV(PENTA_18): elemcnt++; elemsize += 7; break; case CGNS_ENUMV(HEXA_8): case CGNS_ENUMV(HEXA_20): case CGNS_ENUMV(HEXA_27): elemcnt++; elemsize += 9; break; default: break; } if (cg_npe (et, &nn) || nn == 0) FATAL ("invalid element type in MIXED"); i += nn; } } else { switch (elemtype) { case CGNS_ENUMV(TETRA_4): case CGNS_ENUMV(TETRA_10): nn = 5; break; case CGNS_ENUMV(PYRA_5): case CGNS_ENUMV(PYRA_14): nn = 6; break; case CGNS_ENUMV(PENTA_6): case CGNS_ENUMV(PENTA_15): case CGNS_ENUMV(PENTA_18): nn = 7; break; case CGNS_ENUMV(HEXA_8): case CGNS_ENUMV(HEXA_20): case CGNS_ENUMV(HEXA_27): nn = 9; break; default: nn = 0; break; } if (nn) { elemcnt += (int)nelems; elemsize += (nn * (int)nelems); } } } if (elemcnt == 0) { free (conn); return; } types = (int *) malloc (elemcnt * sizeof(int)); if (types == NULL) FATAL ("malloc failed for cell types"); /* write the elements */ if (verbose) { printf (" writing %d cells\n", elemcnt); fflush (stdout); } fprintf (fp, "CELLS %d %d\n", elemcnt, elemsize); elemcnt = 0; for (ns = 1; ns <= nsect; ns++) { if (cg_section_read (cgnsfn, cgnsbase, nz, ns, name, &elemtype, &is, &ie, &nn, &ip)) FATAL (NULL); if (elemtype < CGNS_ENUMV(TETRA_4) || elemtype > CGNS_ENUMV(MIXED)) continue; nelems = ie - is + 1; if (cg_elements_read (cgnsfn, cgnsbase, nz, ns, conn, NULL)) FATAL (NULL); et = elemtype; for (i = 0, n = 0; n < nelems; n++) { if (elemtype == CGNS_ENUMV(MIXED)) et = (int)conn[i++]; switch (et) { case CGNS_ENUMV(TETRA_4): case CGNS_ENUMV(TETRA_10): nn = 4; types[elemcnt++] = 10; break; case CGNS_ENUMV(PYRA_5): case CGNS_ENUMV(PYRA_14): nn = 5; types[elemcnt++] = 14; break; case CGNS_ENUMV(PENTA_6): case CGNS_ENUMV(PENTA_15): case CGNS_ENUMV(PENTA_18): nn = 6; types[elemcnt++] = 13; break; case CGNS_ENUMV(HEXA_8): case CGNS_ENUMV(HEXA_20): case CGNS_ENUMV(HEXA_27): nn = 8; types[elemcnt++] = 12; break; default: nn = 0; break; } if (nn) { cell[0] = nn; for (ip = 0; ip < nn; ip++) cell[ip+1] = (int)conn[i+ip] - 1; write_ints (fp, nn+1, cell); } if (cg_npe (et, &nn) || nn == 0) FATAL ("invalid element type"); i += nn; } } free (conn); /* write the element types */ fprintf (fp, "CELL_TYPES %d\n", elemcnt); write_ints (fp, elemcnt, types); free (types); } /*---------- write_element_sets --------------------------------------- * write element sets as vtk files *---------------------------------------------------------------------*/ static void write_element_sets (int nz, cgsize_t *sizes) { int i, n, ns, nsect, nn, ip; int elemcnt, elemsize, cell[9]; int *nodemap, *types; cgsize_t is, ie, nelems; cgsize_t size, *conn; CGNS_ENUMT(ElementType_t) elemtype, et; char name[33], outfile[65], buff[33]; FILE *fp; if (cg_nsections (cgnsfn, cgnsbase, nz, &nsect)) FATAL (NULL); if (nsect < 1) FATAL ("no sections defined"); nodemap = (int *) malloc (nnodes * sizeof(int)); if (nodemap == NULL) FATAL ("malloc failed for node mapping data"); for (ns = 1; ns <= nsect; ns++) { if (cg_section_read (cgnsfn, cgnsbase, nz, ns, name, &elemtype, &is, &ie, &nn, &ip) || cg_ElementDataSize (cgnsfn, cgnsbase, nz, ns, &size)) FATAL (NULL); if (size > CG_MAX_INT32) FATAL("element data too large for 32-bit integer"); nelems = ie - is + 1; conn = (cgsize_t *) malloc ((size_t)size * sizeof(cgsize_t)); if (conn == NULL) FATAL ("malloc failed for element connectivity"); if (cg_elements_read (cgnsfn, cgnsbase, nz, ns, conn, NULL)) FATAL (NULL); for (n = 0; n < nnodes; n++) nodemap[n] = 0; et = elemtype; elemcnt = elemsize = 0; for (is = 0, ie = 0; ie < nelems; ie++) { if (elemtype == CGNS_ENUMV(MIXED)) et = (int)conn[is++]; switch (et) { case CGNS_ENUMV(NODE): nn = 1; break; case CGNS_ENUMV(BAR_2): case CGNS_ENUMV(BAR_3): nn = 2; break; case CGNS_ENUMV(TRI_3): case CGNS_ENUMV(TRI_6): nn = 3; break; case CGNS_ENUMV(QUAD_4): case CGNS_ENUMV(QUAD_8): case CGNS_ENUMV(QUAD_9): case CGNS_ENUMV(TETRA_4): case CGNS_ENUMV(TETRA_10): nn = 4; break; case CGNS_ENUMV(PYRA_5): case CGNS_ENUMV(PYRA_14): nn = 5; break; case CGNS_ENUMV(PENTA_6): case CGNS_ENUMV(PENTA_15): case CGNS_ENUMV(PENTA_18): nn = 6; break; case CGNS_ENUMV(HEXA_8): case CGNS_ENUMV(HEXA_20): case CGNS_ENUMV(HEXA_27): nn = 8; break; default: nn = 0; break; } if (nn) { elemcnt++; elemsize += (nn + 1); for (i = 0; i < nn; i++) { n = (int)conn[is+i] - 1; (nodemap[n])++; } } if (cg_npe (et, &nn) || nn == 0) FATAL ("invalid element type"); is += nn; } if (elemcnt == 0) { free (conn); continue; } create_filename (name, outfile); if (nzones > 1) { sprintf (buff, ".%d", nz); strcat (outfile, buff); } strcat (outfile, ".vtk"); printf ("writing element set %d to \"%s\"\n", ns, outfile); fflush (stdout); if ((fp = fopen (outfile, "w+b")) == NULL) { fprintf (stderr, "couldn't open <%s> for output\n", outfile); exit (1); } fprintf (fp, "# vtk DataFile Version 2.0\n"); fprintf (fp, "zone %d, elemset %d - %s\n", nz, ns, name); fprintf (fp, "%s\n", ascii ? "ASCII" : "BINARY"); fprintf (fp, "DATASET UNSTRUCTURED_GRID\n"); /* write the points */ for (nn = 0, n = 0; n < nnodes; n++) { if (nodemap[n]) { nodemap[n] = ++nn; } } if (verbose) { printf (" writing %d points\n", nn); fflush (stdout); } fprintf (fp, "POINTS %d float\n", nn); for (n = 0; n < nnodes; n++) { if (nodemap[n]) { write_floats (fp, 3, nodes[n]); } } /* write the cells */ types = (int *) malloc (elemcnt * sizeof(int)); if (types == NULL) FATAL ("malloc failed for element types"); if (verbose) { printf (" writing %d cells\n", elemcnt); fflush (stdout); } fprintf (fp, "CELLS %d %d\n", elemcnt, elemsize); et = elemtype; elemcnt = 0; for (is = 0, ie = 0; ie < nelems; ie++) { if (elemtype == CGNS_ENUMV(MIXED)) et = (int)conn[is++]; switch (et) { case CGNS_ENUMV(NODE): nn = 1; types[elemcnt++] = 1; break; case CGNS_ENUMV(BAR_2): case CGNS_ENUMV(BAR_3): nn = 2; types[elemcnt++] = 3; break; case CGNS_ENUMV(TRI_3): case CGNS_ENUMV(TRI_6): nn = 3; types[elemcnt++] = 5; break; case CGNS_ENUMV(QUAD_4): case CGNS_ENUMV(QUAD_8): case CGNS_ENUMV(QUAD_9): nn = 4; types[elemcnt++] = 9; break; case CGNS_ENUMV(TETRA_4): case CGNS_ENUMV(TETRA_10): nn = 4; types[elemcnt++] = 10; break; case CGNS_ENUMV(PYRA_5): case CGNS_ENUMV(PYRA_14): nn = 5; types[elemcnt++] = 14; break; case CGNS_ENUMV(PENTA_6): case CGNS_ENUMV(PENTA_15): case CGNS_ENUMV(PENTA_18): nn = 6; types[elemcnt++] = 13; break; case CGNS_ENUMV(HEXA_8): case CGNS_ENUMV(HEXA_20): case CGNS_ENUMV(HEXA_27): nn = 8; types[elemcnt++] = 12; break; default: nn = 0; break; } if (nn) { cell[0] = nn; for (i = 0; i < nn; i++) cell[i+1] = nodemap[(int)conn[is+i]-1] - 1; write_ints (fp, nn+1, cell); } cg_npe (et, &nn); is += nn; } free (conn); /* write the cell types */ fprintf (fp, "CELL_TYPES %d\n", elemcnt); write_ints (fp, elemcnt, types); free (types); /* write solution if Vertex */ if (nvars) { if (varloc == CGNS_ENUMV(Vertex) && ndata == nnodes) write_solution (fp, nz, nodemap); else if (verbose) { printf (" skipping solution - not Vertex\n"); fflush (stdout); } } fclose (fp); } free (nodemap); } /*========== main =====================================================*/ int main (int argc, char *argv[]) { int n, nz; char name[33], outfile[37]; int elemsets = 0; cgsize_t sizes[9]; CGNS_ENUMT(ZoneType_t) zonetype; struct stat st; FILE *fp; if (argc < 2) print_usage (usgmsg, NULL); while ((n = getargs (argc, argv, options)) > 0) { switch (n) { case 'b': cgnsbase = atoi (argarg); break; case 'z': cgnszone = atoi (argarg); break; case 's': cgnssol = atoi (argarg); break; case 'e': elemsets = 1; break; case 'v': verbose = 1; break; case 'a': ascii = 1; break; } } if (argind >= argc) print_usage (usgmsg, "filename not specified"); if (stat (argv[argind], &st)) { fprintf (stderr, "can't stat <%s>\n", argv[argind]); exit (1); } if (S_IFREG != (st.st_mode & S_IFMT)) { fprintf (stderr, "<%s> is not a regular file\n", argv[argind]); exit (1); } /* open CGNS file */ printf ("reading CGNS file from \"%s\"\n", argv[argind]); fflush (stdout); if (cg_open (argv[argind], CG_MODE_READ, &cgnsfn)) FATAL (NULL); if (cg_base_read (cgnsfn, cgnsbase, name, &CellDim, &PhyDim)) FATAL (NULL); printf (" using base %d - %s\n", cgnsbase, name); fflush (stdout); if (PhyDim != 3 /*|| (CellDim != 1 && CellDim != 3)*/) FATAL ("cell and/or physical dimension invalid"); if (cg_nzones (cgnsfn, cgnsbase, &nzones)) FATAL (NULL); if (nzones == 0) FATAL ("no zones in the CGNS file"); if (cgnszone && cgnszone > nzones) FATAL ("zone number invalid"); /* file output directory */ if (++argind < argc) { if (stat (argv[argind], &st) && #ifdef _WIN32 _mkdir (argv[argind])) { #else mkdir (argv[argind], S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH)) { #endif cg_close (cgnsfn); fprintf (stderr, "couldn't create the directory <%s>\n", argv[argind]); exit (1); } if (chdir (argv[argind])) { cg_close (cgnsfn); fprintf (stderr, "couldn't chdir to <%s>\n", argv[argind]); exit (1); } printf ("writing %s VTK files to directory \"%s\"\n", ascii ? "ASCII" : "binary", argv[argind]); } else printf ("writing %s VTK files to current directory\n", ascii ? "ASCII" : "binary"); for (nz = 1; nz <= nzones; nz++) { if (cgnszone && nz != cgnszone) continue; if (cg_zone_type (cgnsfn, cgnsbase, nz, &zonetype) || cg_zone_read (cgnsfn, cgnsbase, nz, name, sizes)) FATAL (NULL); if (zonetype == CGNS_ENUMV(Structured)) { if (sizes[0]*sizes[1]*sizes[2] > CG_MAX_INT32) FATAL("too many coordinates for 32-bit integer"); } else if (zonetype == CGNS_ENUMV(Unstructured)) { if (sizes[0] > CG_MAX_INT32) FATAL("too many coordinates for 32-bit integer"); } else FATAL ("invalid zone type"); create_filename (name, outfile); strcat (outfile, ".vtk"); printf ("writing zone %d as %s to \"%s\"\n", nz, #if CGNS_VERSION >= 2500 cg_ZoneTypeName(zonetype), outfile); #else ZoneTypeName[zonetype], outfile); #endif fflush (stdout); if ((fp = fopen (outfile, "w+b")) == NULL) { fprintf (stderr, "couldn't open <%s> for output\n", outfile); exit (1); } fprintf (fp, "# vtk DataFile Version 2.0\n"); fprintf (fp, "zone %d - %s\n", nz, name); fprintf (fp, "%s\n", ascii ? "ASCII" : "BINARY"); if (zonetype == CGNS_ENUMV(Structured)) { fprintf (fp, "DATASET STRUCTURED_GRID\n"); fprintf (fp, "DIMENSIONS %d %d %d\n", (int)sizes[0], (int)sizes[1], (int)sizes[2]); } else fprintf (fp, "DATASET UNSTRUCTURED_GRID\n"); get_nodes (nz, zonetype, sizes); if (verbose) { printf (" writing %d points\n", nnodes); fflush (stdout); } fprintf (fp, "POINTS %d float\n", nnodes); for (n = 0; n < nnodes; n++) write_floats (fp, 3, nodes[n]); if (zonetype == CGNS_ENUMV(Unstructured)) write_volume_cells (fp, nz); if (get_variables (nz, zonetype, sizes)) write_solution (fp, nz, NULL); fclose (fp); if (elemsets && zonetype == CGNS_ENUMV(Unstructured)) write_element_sets (nz, sizes); free (nodes); if (nvars) free (vars); } cg_close (cgnsfn); return 0; } cgnslib_3.1.4/src/cgnstools/utilities/util.tcl0000664000076400007640000001677412160605674016501 00000000000000# util.tcl - CGNS utility routines array set Tools { subseti i subsetj j subsetk k cgnssol "" solbase "" solbase,flag 1 bboxpad "" bboxpad,flag 1 maxdepth "" maxdepth,flag 1 maxelem "" maxelem,flag 1 extrapolate 0 } proc interpolate_cgns {w name exe} { global ProgData Tools Font if {$ProgData(file,name) == ""} return set cmd [get_executable $exe 1] if {$cmd == ""} return set Tools(cgnsinput) $ProgData(file,name) if {$Tools(cgnsoutput) == ""} { set Tools(cgnsoutput) $ProgData(file,name) } toplevel $w wm title $w "Interpolate Solution" wm transient $w . wm protocol $w WM_DELETE_WINDOW {set Tools(done) 0} set labw 13 FrameCreate $w.cgnssol -text "CGNS Solution" -font $Font(bold) pack $w.cgnssol -side top -pady 2 -fill x set wf [FrameGet $w.cgnssol] set f [frame $wf.file] pack $f -side top -fill x label $f.lab -text Filename -width $labw -anchor w pack $f.lab -side left entry $f.ent -textvariable Tools(cgnssol) -width 30 pack $f.ent -side left -fill x -expand 1 button $f.but -text Browse -pady 0 -command "tools_browse $f.but cgnssol" pack $f.but -side right -fill y set f [frame $wf.basenum] pack $f -side top -fill x label $f.lab -text "Base Index" -width $labw -anchor w pack $f.lab -side left entry $f.ent -textvariable Tools(solbase) -width 10 pack $f.ent -side left checkbutton $f.but -text default \ -variable Tools(solbase,flag) -onvalue 1 -offvalue 0 \ -command "tools_state solbase $f.ent" pack $f.but -side left tools_state solbase $f.ent FrameCreate $w.cgnsinput -text "CGNS Grid" -font $Font(bold) pack $w.cgnsinput -side top -pady 2 -fill x set wf [FrameGet $w.cgnsinput] set f [frame $wf.file] pack $f -side top -fill x label $f.lab -text Filename -width $labw -anchor w pack $f.lab -side left entry $f.ent -textvariable Tools(cgnsinput) -width 30 pack $f.ent -side left -fill x -expand 1 button $f.but -text Browse -pady 0 -command "tools_browse $f.but cgnsinput" pack $f.but -side right -fill y set f [frame $wf.basenum] pack $f -side top -fill x label $f.lab -text "Base Index" -width $labw -anchor w pack $f.lab -side left entry $f.ent -textvariable Tools(basenum) -width 10 pack $f.ent -side left checkbutton $f.but -text default \ -variable Tools(basenum,flag) -onvalue 1 -offvalue 0 \ -command "tools_state basenum $f.ent" pack $f.but -side left tools_state basenum $f.ent FrameCreate $w.cgnsoutput -text "CGNS Output" -font $Font(bold) pack $w.cgnsoutput -side top -pady 2 -fill x set wf [FrameGet $w.cgnsoutput] set f [frame $wf.file] pack $f -side top -fill x label $f.lab -text Filename -width $labw -anchor w pack $f.lab -side left entry $f.ent -textvariable Tools(cgnsoutput) -width 30 pack $f.ent -side left -fill x -expand 1 button $f.but -text Browse -pady 0 -command "tools_browse $f.but cgnsoutput" pack $f.but -side right -fill y set f [frame $wf.basename] pack $f -side top -fill x label $f.lab -text "Base Name" -width $labw -anchor w pack $f.lab -side left entry $f.ent -textvariable Tools(basename) -width 30 pack $f.ent -side left -fill x -expand 1 checkbutton $f.but -text default \ -variable Tools(basename,flag) -onvalue 1 -offvalue 0 \ -command "tools_state basename $f.ent {}" pack $f.but -side left tools_state basename $f.ent "" set f [frame $wf.solname] pack $f -side top -fill x label $f.lab -text "Solution Name" -width $labw -anchor w pack $f.lab -side left entry $f.ent -textvariable Tools(solname) -width 30 pack $f.ent -side left -fill x -expand 1 checkbutton $f.but -text default \ -variable Tools(solname,flag) -onvalue 1 -offvalue 0 \ -command "tools_state solname $f.ent {}" pack $f.but -side left tools_state solname $f.ent "" tools_averaging $w FrameCreate $w.treeopts -text "Octtree Options" -font $Font(bold) pack $w.treeopts -side top -pady 2 -fill x set treeopts [FrameGet $w.treeopts] foreach opt {\ {bboxpad "Bounding Box Padding" 0.01} \ {maxdepth "Max Octtree Depth" 16} \ {maxelem "Max Octtree Elements" 256}} { set tag [lindex $opt 0] set f [frame $treeopts.$tag] pack $f -side top -anchor w label $f.lab -text [lindex $opt 1] -width 20 -anchor w entry $f.ent -textvariable Tools($tag) -width 15 checkbutton $f.but -text default \ -variable Tools($tag,flag) -onvalue 1 -offvalue 0 \ -command "tools_state $tag $f.ent [lindex $opt 2]" pack $f.lab $f.ent $f.but -side left tools_state $tag $f.ent [lindex $opt 2] } checkbutton $treeopts.extrap -text "Allow Extrapolation" \ -variable Tools(extrapolate) -onvalue 1 -offvalue 0 pack $treeopts.extrap -side top -anchor w if {![tools_interact $w check_interpolation]} return foreach i {{c solbase} {b basenum} {B basename} {S solname} \ {p bboxpad} {d maxdepth} {e maxelem}} { set opt $Tools([lindex $i 1]) if {$opt != ""} { lappend cmd "-[lindex $i 0]$opt" } } if {$Tools(weight) != ""} { lappend cmd -w } if {$Tools(extrapolate)} { lappend cmd -a } lappend cmd $Tools(cgnssol) $Tools(cgnsinput) if {$Tools(cgnsoutput) != ""} { lappend cmd $Tools(cgnsoutput) } tools_run "Solution Interpolation" $cmd $Tools(cgnsoutput) } proc check_interpolation {w} { global Tools if {$Tools(cgnssol) == "" || ![file exists $Tools(cgnssol)]} { errormsg "CGNS solution file not specified or does not exist" $w return 0 } if {$Tools(cgnsinput) == "" || ![file exists $Tools(cgnsinput)]} { errormsg "CGNS grid file not specified or does not exist" $w return 0 } if {$Tools(bboxpad) != "" && [catch {expr double($Tools(bboxpad))}]} { errormsg "invalid value for bounding box padding" $w return 0 } if {$Tools(maxdepth) != "" && [catch {expr int($Tools(maxdepth))}]} { errormsg "invalid value for max octtree depth" $w return 0 } if {$Tools(maxelem) != "" && [catch {expr int($Tools(maxelem))}]} { errormsg "invalid value for max octtree elements" $w return 0 } return 1 } proc extract_subset {w name exe} { global ProgData Tools Font if {$ProgData(file,name) == ""} return set cmd [get_executable $exe 1] if {$cmd == ""} return set Tools(cgnsinput) $ProgData(file,name) if {$Tools(cgnsoutput) == ""} { set Tools(cgnsoutput) $ProgData(file,name) } toplevel $w wm title $w "Extract Subset" wm transient $w . wm protocol $w WM_DELETE_WINDOW {set Tools(done) 0} FrameCreate $w.loc -text Directions -font $Font(bold) pack $w.loc -side top -pady 2 -fill x set f [FrameGet $w.loc] foreach n {i j k} { checkbutton $f.$n -text "[string toupper $n]-subset" \ -variable Tools(subset$n) -onvalue $n -offvalue "" pack $f.$n -side left -expand 1 } tools_cgnsinput $w 1 tools_cgnsoutput $w basename tools_averaging $w if {![tools_interact $w check_subset]} return set opts $Tools(weight) foreach i {i j k} { if {$Tools(subset$i) != ""} { append opts $Tools(subset$i) } } lappend cmd -$opts foreach i {basenum zonenum} { if {$Tools($i) != ""} { lappend cmd "-[string index $i 0]$Tools($i)" } } if {$Tools(basename) != ""} { lappend cmd "-B$Tools(basename)" } lappend cmd $Tools(cgnsinput) if {$Tools(cgnsoutput) != ""} { lappend cmd $Tools(cgnsoutput) } tools_run "Subset Extraction" $cmd $Tools(cgnsoutput) } proc check_subset {w} { global Tools foreach i {i j k} { if {$Tools(subset$i) != ""} { return [tools_check_input $w] } } errormsg "no subset directions selected" $w return 0 } cgnslib_3.1.4/src/cgnstools/utilities/patran_to_cgns.c0000664000076400007640000002046412160605674020154 00000000000000/* * patran_to_cgns - Patran Neutral File Import * reads packets 1 (nodes), 2 (elements) and 21 (named groups) * and optionally packet 6 (loads), and writes CGNS */ #include #include #include #include #include #include "cgnsImport.h" #include "getargs.h" #define getline() \ {if (NULL == fgets (buffer, sizeof(buffer), fp)) \ cgnsImportFatal ("premature EOF"); \ lineno++;} static char options[] = "ldDt:B:"; static char *usgmsg[] = { "usage : patran_to_cgns [options] Patranfile CGNSfile", "options:", " -l = process packet 6 - distributed loads", " -d = duplicate node checking with rel tol", " -D = duplicate node checking with abs tol", " -t = duplicate node checking tolerance", " -B = set CGNS base name to ", NULL }; /*---------- print_error ------------------------------------------- * print error message and line number *------------------------------------------------------------------*/ static int lineno = 0; static void print_error (char *errmsg) { fprintf (stderr, "%s on line %d\n", errmsg, lineno); } /*---------- add_face ----------------------------------------------- * add an element face to the region list *-------------------------------------------------------------------*/ static void add_face (int elemid, char *data) { int n, nodes[8], nnodes; int elemtype, faceid; cgsize_t elemnodes[8], nodeid[8]; char errmsg[81]; static int facemap[5][7] = { {0, 1, 2, 3, 4, 0, 0}, {0, 1, 2, 3, 4, 5, 0}, {0, 4, 5, 1, 3, 2, 0}, {0, 0, 0, 0, 0, 0, 0}, {0, 2, 4, 1, 3, 6, 5} }; /* check for node flags set */ for (nnodes = 0, n = 0; n < 8; n++) { if ('1' == data[n]) nodes[nnodes++] = n; } elemtype = cgnsImportGetElement (elemid, elemnodes); if (!elemtype) { sprintf (errmsg, "element %d not found for packet 6\n", elemid); cgnsImportFatal (errmsg); } /* if node flags set, use the node values */ if (nnodes) { for (n = 0; n < nnodes; n++) { if (nodes[n] >= elemtype) { sprintf (errmsg, "invalid node flags for element %d\n", elemid); cgnsImportFatal (errmsg); } nodeid[n] = elemnodes[nodes[n]]; } } /* else get nodes from face number */ else { faceid = atoi (&data[8]); if (faceid < 1 || faceid > 6) { sprintf (errmsg, "invalid faceid for element %d\n", elemid); cgnsImportFatal (errmsg); } faceid = facemap[elemtype-4][faceid]; nnodes = cgnsImportGetFace (elemid, faceid, nodeid); if (nnodes < 0) { sprintf (errmsg, "element %d not found for packet 6\n", elemid); cgnsImportFatal (errmsg); } if (0 == nnodes) { sprintf (errmsg, "invalid face number for element %d\n", elemid); cgnsImportFatal (errmsg); } } cgnsImportAddReg (nnodes, nodeid); } /*========== main ===================================================*/ int main (int argc, char *argv[]) { int n, packet, nlines, nodeid; int nnodes, elemid; cgsize_t nodes[8]; int lastid = -1, loadid; int do_loads = 0, do_chk = 0; double xyz[3]; char *p, buffer[256], *basename = NULL; FILE *fp; if (argc < 2) print_usage (usgmsg, NULL); while ((n = getargs (argc, argv, options)) > 0) { switch (n) { case 'l': do_loads = 1; break; case 'D': case 'd': do_chk = n; break; case 't': cgnsImportSetTol (atof (argarg)); break; case 'B': basename = argarg; break; } } if (argind + 1 >= argc) print_usage (usgmsg, "Patran and/or CGNS filename not specified\n"); if (NULL == (fp = fopen (argv[argind], "r"))) { sprintf (buffer, "can't open <%s> for reading", argv[argind]); cgnsImportFatal (buffer); } printf ("reading Patran Neutral file from %s\n", argv[argind]); cgnsImportError (print_error); getline (); /* header - packet 25 */ if ((packet = atoi (buffer)) == 25) { getline (); fputs (buffer, stdout); getline (); packet = atoi (buffer); } /* summary - packet 26 */ if (packet == 26) { getline (); getline (); packet = atoi (buffer); } /* get remaining packets */ while (packet != 99) { /* node */ if (packet == 1) { nodeid = atoi (&buffer[2]); getline (); p = buffer + 48; for (n = 2; n >= 0; n--) { *p = 0; p -= 16; xyz[n] = atof (p); } getline (); cgnsImportNode (nodeid, xyz[0], xyz[1], xyz[2]); } /* element */ else if (packet == 2) { elemid = atoi (&buffer[2]); n = atoi (&buffer[10]); nlines = atoi (&buffer[18]); if (n == 5 || n == 7 || n == 8) { getline (); nnodes = n == 8 ? n : n-1; lineno++; for (n = 0; n < nnodes; n++) { if (1 != fscanf (fp, "%d", &nodeid) || nodeid < 1) cgnsImportFatal ("missing or invalid node ID"); nodes[n] = nodeid; } while (getc (fp) != '\n') ; nlines -= 2; cgnsImportElement (elemid, nnodes, nodes); } while (nlines-- > 0) getline (); } /* distributed loads */ else if (packet == 6 && do_loads) { elemid = atoi (&buffer[2]); loadid = atoi (&buffer[10]); nlines = atoi (&buffer[18]); if (loadid != lastid) { sprintf (buffer, "PatranLoad%d", loadid); cgnsImportBegReg (buffer, cgnsREG_NODES); lastid = loadid; } getline (); /* add if element load flag is set */ if ('1' == buffer[0]) add_face (elemid, &buffer[9]); while (--nlines > 0) getline (); } /* named component */ else if (packet == 21) { int cnt, type, id; elemid = atoi (&buffer[2]); nnodes = atoi (&buffer[10]) / 2; getline (); /* strip leading and trailing spaces */ buffer[sizeof(buffer)-1] = 0; p = buffer + strlen (buffer); while (--p >= buffer && isspace(*p)) ; *++p = 0; for (p = buffer; *p && isspace(*p); p++) ; cgnsImportBegReg (p, cgnsREG_NODES); /* currently only handle type 5 (nodes) in groups */ for (n = 0, cnt = 0; n < nnodes; n++) { if (0 == (n % 5)) lineno++; fscanf (fp, "%d%d", &type, &id); if (5 == type) { nodes[cnt++] = id; if (8 == cnt) { cgnsImportAddReg (8, nodes); cnt = 0; } } } while (getc (fp) != '\n') ; if (cnt) cgnsImportAddReg (cnt, nodes); cgnsImportEndReg (); } /* all others */ else { nlines = atoi (&buffer[18]); while (nlines--) getline (); } if (NULL == fgets (buffer, sizeof(buffer), fp)) break; lineno++; packet = atoi (buffer); } fclose (fp); cgnsImportError (NULL); /* check for duplicate nodes */ if (do_chk) { printf ("checking for duplicate nodes...\n"); cgnsImportCheck (do_chk == 'd'); } /* output to CGNS file */ printf ("writing CGNS data to %s\n", argv[++argind]); cgnsImportOpen (argv[argind]); if (basename != NULL) cgnsImportBase (basename); cgnsImportWrite (); cgnsImportClose (); return 0; } cgnslib_3.1.4/src/cgnstools/utilities/cgns_info.c0000664000076400007640000001127012160605674017113 00000000000000/* * cgns_info.c - print CGNS information */ #include #include #include #include "getargs.h" #include "cgnslib.h" #include "cgnsutil.h" /* command line options */ static char options[] = "vb:"; static char *usgmsg[] = { "usage : cgns_info [options] CGNSfile", "options:", " -v = verbose output", " -b = use CGNS base number (default 1)", NULL }; static void print_interface (ZONE *zone) { int ni; INTERFACE *ints; read_zone_interface (zone->id); ints = zone->ints; for (ni = 0; ni < zone->nints; ni++) { printf (" interface %d - %s\n", ints[ni].id, ints[ni].name); printf (" range = %d %d %d %d %d %d\n", (int)ints[ni].range[0][0], (int)ints[ni].range[0][1], (int)ints[ni].range[1][0], (int)ints[ni].range[1][1], (int)ints[ni].range[2][0], (int)ints[ni].range[2][1]); printf (" donor name = %s\n", ints[ni].d_name); printf (" donor range = %d %d %d %d %d %d\n", (int)ints[ni].d_range[0][0], (int)ints[ni].d_range[0][1], (int)ints[ni].d_range[1][0], (int)ints[ni].d_range[1][1], (int)ints[ni].d_range[2][0], (int)ints[ni].d_range[2][1]); printf (" transform = %d %d %d\n", ints[ni].transform[0], ints[ni].transform[1], ints[ni].transform[2]); printf (" donor zone = %d\n", ints[ni].d_zone); } } static void print_connect (ZONE *zone) { int nc; CONNECT *conns; read_zone_connect (zone->id); conns = zone->conns; for (nc = 0; nc < zone->nconns; nc++) { printf (" connectivity %d - %s\n", conns[nc].id, conns[nc].name); printf (" type = %d\n", conns[nc].type); printf (" location = %d\n", conns[nc].location); printf (" pt type = %d\n", conns[nc].ptype); printf (" points = %d\n", (int)conns[nc].npnts); printf (" donor name = %s\n", conns[nc].d_name); printf (" donor pt type = %d\n", conns[nc].d_ptype); printf (" donor points = %d\n", (int)conns[nc].d_npnts); printf (" donor zone = %d\n", conns[nc].d_zone); } } static void print_solution (ZONE *zone) { int ns, nf; SOLUTION *sols; read_zone_solution (zone->id); sols = zone->sols; for (ns = 0; ns < zone->nsols; ns++) { printf (" solution %d - %s\n", sols[ns].id, sols[ns].name); printf (" location = %d\n", sols[ns].location); printf (" rind = %d %d %d %d %d %d\n", sols[ns].rind[0][0], sols[ns].rind[0][1], sols[ns].rind[1][0], sols[ns].rind[1][1], sols[ns].rind[2][0], sols[ns].rind[2][1]); printf (" size = %d\n", (int)sols[ns].size); printf (" fields = %d\n", sols[ns].nflds); for (nf = 0; nf < sols[ns].nflds; nf++) printf (" %s\n", sols[ns].flds[nf].name); } } int main (int argc, char *argv[]) { int n, nz, nbases, celldim, phydim; int verbose = 0; char basename[33]; ZONE *z; if (argc < 2) print_usage (usgmsg, NULL); while ((n = getargs (argc, argv, options)) > 0) { switch (n) { case 'v': verbose = 1; break; case 'b': cgnsbase = atoi (argarg); break; } } if (argind == argc) print_usage (usgmsg, "CGNSfile not given"); if (!file_exists (argv[argind])) FATAL (NULL, "CGNSfile does not exist or is not a file"); /* read CGNS file */ printf ("reading CGNS file from %s\n", argv[argind]); fflush (stdout); nbases = open_cgns (argv[argind], 1); if (!nbases) FATAL (NULL, "no bases in CGNS file"); if (cgnsbase < 1 || cgnsbase > nbases) FATAL (NULL, "invalid base index"); if (cg_base_read (cgnsfn, cgnsbase, basename, &celldim, &phydim)) FATAL (NULL, NULL); printf ("using base %d - %s\n", cgnsbase, basename); printf ("cell dimension = %d\n", celldim); printf ("physical dimension = %d\n", phydim); read_zones (); for (z = Zones, nz = 1; nz <= nZones; nz++, z++) { printf ("\nzone %d - %s\n", z->id, z->name); printf ("type = %d\n", z->type); printf ("dimension = %d x %d x %d\n", (int)z->dim[0], (int)z->dim[1], (int)z->dim[2]); printf ("1to1 = %d\n", z->nints); if (verbose) print_interface (z); printf ("connects = %d\n", z->nconns); if (verbose) print_connect (z); printf ("solutions = %d\n", z->nsols); if (verbose) print_solution (z); } if (cg_close (cgnsfn)) FATAL (NULL, NULL); return 0; } cgnslib_3.1.4/src/cgnstools/utilities/primitive.cnv0000664000076400007640000000104312160605674017517 00000000000000# convert conserved variables to primitive # Density -> Density # MomentumX -> VelocityX # MomentumY -> VelocityY # MomentumZ -> VelocityZ # EnergyStagnationDensity -> Pressure VelocityX = MomentumX / Density VelocityY = MomentumY / Density VelocityZ = MomentumZ / Density qq = VelocityX^2 + VelocityY^2 + VelocityZ^2 Pressure = (gamma-1) * (EnergyStagnationDensity - 0.5*Density*qq) # add primitive variables + VelocityX,VelocityY,VelocityZ,Pressure # remove conserved variables - MomentumX,MomentumY,MomentumZ,EnergyStagnationDensity cgnslib_3.1.4/src/cgnstools/utilities/binaryio.h0000664000076400007640000001446612160605674017001 00000000000000/* * binaryio.h - include for C and FORTRAN binary I/O */ #ifndef _BINARYIO_H_ #define _BINARYIO_H_ #include /*----- machines -----*/ #define MACH_DEFAULT 0x0000 #define MACH_SUN 0x0001 /* 32-bit Sun */ #define MACH_IRIS 0x0002 /* 32-bit SGI */ #define MACH_HP 0x0003 /* 32-bit HP */ #define MACH_IBM 0x0004 /* 32-bit IBM */ #define MACH_DEC 0x0005 /* 32-bit DEC */ #define MACH_ALPHA 0x0006 /* 64-bit DEC Alpha */ #define MACH_CRAY 0x0007 /* 64-bit Cray */ #define MACH_CONVEX 0x0008 /* 32-bit Convex (native fp) */ #define MACH_DOS16 0x0009 /* 16-bit DOS (real mode) */ #define MACH_DOS32 0x000A /* 32-bit DOS (protected mode) */ #define MACH_WIN32 0x000B /* 32-bit Windows */ #define MACH_LINUX 0x000C /* 32-bit Linux */ #define MACH_BSIEEE 0x000D /* 32-bit generic byteswapped IEEE */ #define MACH_IEEE 0x000E /* 32-bit generic IEEE */ #define MACH_UNKNOWN 0x00FF /* unkown machine */ /*----- architectures -----*/ #define ARCH_DEFAULT 0x0000 #define ARCH_BSIEEE 0x0100 /* byteswapped IEEE */ #define ARCH_CRAY 0x0200 /* 64-bit Cray */ #define ARCH_CONVEX 0x0300 /* native Convex */ #define ARCH_ALPHA 0x0400 /* 64-bit DEC Alpha */ #define ARCH_DOS 0x0500 /* 16-bit DOS */ #define ARCH_IEEE 0x0F00 /* IEEE */ /*----- determine local machine/architecture -----*/ #if defined(sun) || defined(sparc) # define MACH_LOCAL MACH_SUN # define ARCH_LOCAL ARCH_IEEE #endif #ifdef __sgi # define MACH_LOCAL MACH_IRIS # define ARCH_LOCAL ARCH_IEEE #endif #if defined(hpux) || defined(__hpux) # define MACH_LOCAL MACH_HP # define ARCH_LOCAL ARCH_IEEE #endif #ifdef _AIX # define MACH_LOCAL MACH_IBM # define ARCH_LOCAL ARCH_IEEE #endif #ifdef __ultrix # define MACH_LOCAL MACH_DEC # define ARCH_LOCAL ARCH_BSIEEE #endif #ifdef __alpha # define MACH_LOCAL MACH_ALPHA # define ARCH_LOCAL ARCH_ALPHA #endif #ifdef CRAY # define MACH_LOCAL MACH_CRAY # define ARCH_LOCAL ARCH_CRAY #endif #if defined(__convex__) || defined(__convexc__) # if defined(__convex__) || defined(_IEEE_FLOAT_) # define MACH_LOCAL MACH_IEEE # define ARCH_LOCAL ARCH_IEEE # else # define MACH_LOCAL MACH_CONVEX # define ARCH_LOCAL ARCH_CONVEX # endif #endif #if defined(MSDOS) || defined(__MSDOS__) # if defined(__GO32__) || defined(__WIN32__) # define MACH_LOCAL MACH_DOS32 # define ARCH_LOCAL ARCH_BSIEEE # else # define MACH_LOCAL MACH_DOS16 # define ARCH_LOCAL ARCH_DOS # endif #endif #ifdef _WIN32 # define ARCH_LOCAL ARCH_BSIEEE # define MACH_LOCAL MACH_WIN32 #endif #if defined(__linux) || defined(__CYGWIN__) # define ARCH_LOCAL ARCH_BSIEEE # define MACH_LOCAL MACH_LINUX #endif /* assume machine is 32-bit IEEE */ #ifndef MACH_LOCAL # define MACH_LOCAL MACH_UNKNOWN # define ARCH_LOCAL ARCH_IEEE #endif /*----- read/write flags -----*/ #define OPEN_READ 0x0000 /* open for reading */ #define OPEN_WRITE 0x1000 /* open for writing */ #define OPEN_FORTRAN 0x2000 /* FORTRAN reads */ #define OPEN_ASCII 0x4000 /* ASCII read/write */ /*----- file pointer structure -----*/ typedef struct binaryio { FILE *fp; /* file pointer from fopen() */ int flags; /* file I/O flags */ int arch; /* I/O file architecture */ int did_open; /* set if bf_open() called */ long rec_num; /* current record number */ long rec_size; /* current record size */ long rec_read; /* bytes read in current record */ /* data sizes */ int short_size; /* size of short in bytes */ int int_size; /* size of int in bytes */ int long_size; /* size of long in bytes */ int float_size; /* size of float in bytes */ int double_size; /* size of double in bytes */ /* conversion routines */ unsigned char *(*fromshort)(unsigned char *data); unsigned char *(*fromint)(unsigned char *data); unsigned char *(*fromlong)(unsigned char *data); unsigned char *(*fromfloat)(unsigned char *data); unsigned char *(*fromdouble)(unsigned char *data); unsigned char *(*toshort)(unsigned char *data); unsigned char *(*toint)(unsigned char *data); unsigned char *(*tolong)(unsigned char *data); unsigned char *(*tofloat)(unsigned char *data); unsigned char *(*todouble)(unsigned char *data); } BINARYIO; extern void (*binaryio_error)( /* error handler */ char *errmsg ); /*----- function prototypes -----*/ #ifdef __cplusplus extern "C" { #endif /* file manipulation */ BINARYIO *bf_open (char *filename, int flags); BINARYIO *bf_new (FILE *fp, int flags); void bf_close (BINARYIO *bf); void bf_rewind (BINARYIO *bf); long bf_tell (BINARYIO *bf); int bf_seek (BINARYIO *bf, long offset); int bf_unget (BINARYIO *bf, int c); int bf_nextrec (BINARYIO *bf); int bf_reclen (BINARYIO *bf); int bf_skipspace (BINARYIO *bf); /* information */ char *bf_machname (int mach); char *bf_archname (int mach); /* reads */ int bf_getbytes (BINARYIO *bf, int count, unsigned char *data); int bf_getstring (BINARYIO *bf, int count, char *data); int bf_getshorts (BINARYIO *bf, int count, short *data); int bf_getints (BINARYIO *bf, int count, int *data); int bf_getlongs (BINARYIO *bf, int count, long *data); int bf_getfloats (BINARYIO *bf, int count, float *data); int bf_getdoubles (BINARYIO *bf, int count, double *data); /* writes */ int bf_putbytes (BINARYIO *bf, int count, unsigned char *data); int bf_putshorts (BINARYIO *bf, int count, short *data); int bf_putints (BINARYIO *bf, int count, int *data); int bf_putlongs (BINARYIO *bf, int count, long *data); int bf_putfloats (BINARYIO *bf, int count, float *data); int bf_putdoubles (BINARYIO *bf, int count, double *data); #ifdef __cplusplus } #endif /*----- macros -----*/ #define bf_flags(BF) ((BF)->flags) #define bf_is_fortran(BF) (OPEN_FORTRAN == ((BF)->flags & OPEN_FORTRAN)) #define bf_is_ASCII(BF) (OPEN_ASCII == ((BF)->flags & OPEN_ASCII)) #define bf_machtype(BF) ((BF)->flags & MACH_IEEE) #define bf_archtype(BF) ((BF)->arch) #define bf_reccount(BF) ((BF)->rec_num) #define bf_is_eof(BF) (feof((BF)->fp)) #define bf_is_eor(BF) (OPEN_FORTRAN != ((BF)->flags & OPEN_FORTRAN) \ || (BF)->rec_read == (BF)->rec_size); #endif /* _BINARYIO_H_ */ cgnslib_3.1.4/src/cgnstools/utilities/convert_location.c0000664000076400007640000001777212160605674020533 00000000000000/* * convert_location.c - convert between vertex and cell-center */ #include #include #include #ifdef _WIN32 # define unlink _unlink #else # include #endif #include "getargs.h" #include "cgnslib.h" #include "cgnsutil.h" #ifndef CG_MODE_MODIFY # define CG_MODE_MODIFY MODE_MODIFY #endif /* command line options */ #if defined(CELL_TO_VERTEX) static char options[] = "wb:z:s:S:"; static char *usgmsg[] = { "usage : cell_to_vertex [options] CGNSfile [newCGNSfile]", "options:", " -w = use volume weighting", " -b = use CGNS base number (default 1)", " -z = read zone number (default all)", " -s = read solution number (default all)", " -S = write to solution (default same as read)", NULL }; #elif defined(VERTEX_TO_CELL) static char options[] = "wb:z:s:S:ijkIJK"; static char *usgmsg[] = { "usage : vertex_to_cell [options] CGNSfile [newCGNSfile]", "options:", " -w = use volume weighting", " -b = use CGNS base number (default 1)", " -z = read zone number (default all)", " -s = read solution number (default all)", " -S = write to solution (default same as read)", " -i = add rind cell at imin", " -I = add rind cell at imax", " -j = add rind cell at jmin", " -J = add rind cell at jmax", " -k = add rind cell at kmin", " -K = add rind cell at kmax", NULL }; #else static char options[] = "cvwb:z:s:S:ijkIJK"; static char *usgmsg[] = { "usage : convert_location [options] CGNSfile [newCGNSfile]", "options:", " -c = convert to cell-center", " -v = convert to vertex", " -w = use volume weighting", " -b = use CGNS base number (default 1)", " -z = read zone number (default all)", " -s = read solution number (default all)", " -S = write to solution (default same as read)", " for conversions to cell-center:", " -i = add rind cell at imin", " -I = add rind cell at imax", " -j = add rind cell at jmin", " -J = add rind cell at jmax", " -k = add rind cell at kmin", " -K = add rind cell at kmax", NULL }; #endif static int weighting = 0; static int izone = 0; static int isol = 0; /*-------------------------------------------------------------------*/ static void check_zones (int location) { int iz, nz, ns, icnt = 0; ZONE *z; SOLUTION *s; for (z = Zones, nz = 1; nz <= nZones; nz++, z++) { iz = 0; if (!izone || nz == izone) { read_zone_solution (nz); for (s = z->sols, ns = 1; ns <= z->nsols; ns++, s++) { if ((!isol || ns == isol) && s->location == location) { icnt += s->nflds; iz = z->id; } else s->id = 0; } } z->id = iz; } if (!icnt) { printf ("nothing to do\n"); exit (0); } } /*-------------------------------------------------------------------*/ int main (int argc, char *argv[]) { int i, j, n, nz, ns, celldim, phydim; int rind[3][2], location = 0; char basename[33], *solname = NULL, *tmpfile; ZONE *z; SOLUTION *s; if (argc < 2) print_usage (usgmsg, NULL); for (i = 0; i < 3; i++) for (j = 0; j < 2; j++) rind[i][j] = 0; while ((n = getargs (argc, argv, options)) > 0) { switch (n) { case 'c': location += CGNS_ENUMV(CellCenter); break; case 'v': location += CGNS_ENUMV(Vertex); break; case 'w': weighting = 1; break; case 'b': cgnsbase = atoi (argarg); break; case 'z': izone = atoi (argarg); break; case 's': isol = atoi (argarg); break; case 'S': solname = argarg; break; case 'i': case 'j': case 'k': rind[n-'i'][0] = 1; break; case 'I': case 'J': case 'K': rind[n-'I'][1] = 1; break; } } if (argind == argc) print_usage (usgmsg, "CGNSfile not given"); if (!file_exists (argv[argind])) FATAL (NULL, "CGNSfile does not exist or is not a file"); #if defined(CELL_TO_VERTEX) location = CGNS_ENUMV(Vertex); #elif defined(VERTEX_TO_CELL) location = CGNS_ENUMV(CellCenter); #else if (!location) print_usage (usgmsg, "please select either the -c or -v option"); if (location != CGNS_ENUMV(CellCenter) && location != CGNS_ENUMV(Vertex)) print_usage (usgmsg, "please select only one of -c or -v options"); #endif /* create a working copy */ printf ("creating a working copy of %s\n", argv[argind]); tmpfile = temporary_file (argv[argind]); copy_file (argv[argind], tmpfile); /* read CGNS file */ printf ("reading CGNS file from %s\n", tmpfile); if (cg_open (tmpfile, CG_MODE_MODIFY, &cgnsfn) || cg_base_read (cgnsfn, cgnsbase, basename, &celldim, &phydim)) FATAL (NULL, NULL); if (celldim != 3 || phydim != 3) FATAL (NULL, "cell and/or physical dimension must be 3"); printf ("reading zone information for base %d - %s\n", cgnsbase, basename); printf ("converting solution location to %s\n", location == CGNS_ENUMV(CellCenter) ? "CellCenter" : "Vertex"); read_zones (); check_zones (location == CGNS_ENUMV(CellCenter) ? CGNS_ENUMV(Vertex) : CGNS_ENUMV(CellCenter)); /* convert solution location */ for (z = Zones, nz = 1; nz <= nZones; nz++, z++) { if (z->id) { for (s = z->sols, ns = 1; ns <= z->nsols; ns++, s++) { if (s->id) { printf ("converting zone %d, solution %d ... ", nz, ns); fflush (stdout); read_solution_field (nz, ns, 0); if (location == CGNS_ENUMV(CellCenter)) { for (i = 0; i < 3; i++) for (j = 0; j < 2; j++) s->rind[i][j] = rind[i][j]; cell_center_solution (nz, ns, weighting); } else cell_vertex_solution (nz, ns, weighting); puts ("done"); } } } } /* write CGNS file */ for (z = Zones, nz = 1; nz <= nZones; nz++, z++) { if (z->id) { for (s = z->sols, ns = 1; ns <= z->nsols; ns++, s++) { if (s->id) { printf ("writing zone %d, solution %d ... ", nz, ns); fflush (stdout); if (solname != NULL) { if (z->nsols == 1) strncpy (s->name, solname, 32); else if (strlen (solname) > 30) sprintf (s->name, "%30.30s%d", solname, s->id); else sprintf (s->name, "%s%d", solname, s->id); s->name[32] = 0; } write_zone_solution (nz, ns); write_solution_field (nz, ns, 0); puts ("done"); } } } } cg_close (cgnsfn); if (argind + 1 < argc) argind++; printf ("renaming %s to %s\n", tmpfile, argv[argind]); unlink (argv[argind]); if (rename (tmpfile, argv[argind])) { char msg[512]; sprintf (msg, "rename %s -> %s failed", tmpfile, argv[argind]); FATAL (NULL, msg); exit (1); } free (tmpfile); return 0; } cgnslib_3.1.4/src/cgnstools/utilities/cgnsImport.h0000664000076400007640000001237412160605674017306 00000000000000/* include file for CGNS imports */ #ifndef _cgnsIMPORT_H_ #define _cgnsIMPORT_H_ #include "cgnslib.h" #ifndef CGNSTYPES_H # define cgsize_t int #endif #ifndef CGNS_ENUMT # define CGNS_ENUMT(e) e # define CGNS_ENUMV(e) e #endif /*--- allowable element types ---*/ #define cgnsELEM_TET 4 /* tet element (4 nodes ) */ #define cgnsELEM_PYR 5 /* pyramid element (5 nodes ) */ #define cgnsELEM_WDG 6 /* wedge element (6 nodes) */ #define cgnsELEM_HEX 8 /* hex element (8 nodes) */ /*--- allowable region types ---*/ #define cgnsREG_NODES 1 #define cgnsREG_FACES 2 #define cgnsREG_ELEMS 3 /*--- convert element ID/face number to face ID */ #define cgnsFACEID(elemid,facenum) ((elemid << 3) | (facenum & 7)) /*--- function prototypes ---*/ #ifdef __cplusplus extern "C" { #endif void cgnsImportError ( /* define callback for errors */ void (*callback)( /* user-supplied call back routine */ char *errmsg /* error message */ ) ); void cgnsImportFatal ( /* terminate with error message */ char *errmsg /* error message */ ); double cgnsImportSetTol (/* setup node checking tolerance */ double tol /* tolerance for comparisons */ ); double cgnsImportGetTol (/* get duplicate node tolerance */ int rel_tol /* 0 - absolute tol, else relative tol */ ); void cgnsImportSetCheck (/* set dup checking for new nodes */ int set /* 0 - allow dup checking, else disallow */ ); cgsize_t cgnsImportRange (/* returns bounding box of nodes */ double *xmin, /* lower x limit */ double *ymin, /* lower y limit */ double *zmin, /* lower z limit */ double *xmax, /* upper x limit */ double *ymax, /* upper y limit */ double *zmax /* upper z limit */ ); cgsize_t cgnsImportCheck (/* check for duplicate nodes */ int rel_tol /* 0 - absolute tol, else relative tol */ ); cgsize_t cgnsImportMap ( /* explicitly map 2 nodes */ cgsize_t nodeid, /* reference node id */ cgsize_t mapid /* node id to map */ ); cgsize_t cgnsImportNode (/* import a node */ cgsize_t nodeid, /* node number */ double x, /* x coordinate */ double y, /* y coordinate */ double z /* z coordinate */ ); cgsize_t cgnsImportSetNode (/* set node coordinates */ cgsize_t nodeid, /* node ID */ double x, /* coordinates */ double y, double z ); cgsize_t cgnsImportGetNode (/* get node coordinates */ cgsize_t nodeid, /* node ID */ double *x, /* returned coordinates */ double *y, double *z ); cgsize_t *cgnsImportNodeList (/* return list of all node ID's */ void ); int cgnsImportAddVariable (/*add a variable to the nodes */ char *varname /* name of the variable */ ); int cgnsImportGetVariable (/* return variable number */ char *varname /* name of the variable */ ); cgsize_t cgnsImportVariable (/* set variable value at node */ cgsize_t nodeid, /* node number */ int varnum, /* variable number */ double val /* variable value */ ); int cgnsImportElement ( /* import an element */ cgsize_t elemid, /* element number */ int elemtype, /* element type - tet,pyr,wdg or hex */ cgsize_t *nodelist /* node numbers defining element */ ); int cgnsImportGetElement (/* get element nodes */ cgsize_t elemid, /* element ID */ cgsize_t nodeid[] /* returned node IDs */ ); cgsize_t *cgnsImportElementList (/* return list of all element ID's */ void ); int cgnsImportGetFace ( /* get element face nodes */ cgsize_t elemid, /* element ID */ int facenum, /* element face number */ cgsize_t nodeid[] /* face nodes */ ); int cgnsImportFindFace ( /* get element face number */ cgsize_t elemid, /* element ID */ int nnodes, /* number of nodes */ cgsize_t nodeid[] /* face nodes */ ); cgsize_t cgnsImportBegReg (/* begin a region specification */ char *regname, /* region name */ int regtype /* type of region (nodes,faces or elements) */ ); cgsize_t cgnsImportAddReg (/* add nodes to a region specification */ cgsize_t numobjs, /* number of objects to add */ cgsize_t *objlist /* object list for region */ ); cgsize_t cgnsImportEndReg (/* end region specification */ void ); cgsize_t cgnsImportRegion (/* import region of nodes */ char *regname, /* region name */ int regtype, /* region type */ cgsize_t numobjs, /* number of objects in region */ cgsize_t *objlist /* object IDs in region */ ); char **cgnsImportRegionList (/* get list of region names */ void ); cgsize_t *cgnsImportGetRegion (/* get region object ID's */ char *regname /* region name */ ); int cgnsImportOpen ( /* open CGNS file */ char *filename /* name of the file */ ); int cgnsImportBase ( /* set CGNS base */ char *basename /* name for base */ ); void cgnsImportZone ( /* set CGNS zone */ char *zonename /* name for zone */ ); int cgnsImportWrite ( /* write data to CGNS file */ void ); void cgnsImportClose ( /* close the CGNS file */ void ); #ifdef __cplusplus } #endif #endif /* _cgnsIMPORT_H_ */ cgnslib_3.1.4/src/cgnstools/utilities/tecplot_to_cgns.c0000664000076400007640000003535312160605674020344 00000000000000/* * tecplot_to_cgns - convert Tecplot to CGNS */ #include #include #include #include #include #ifdef _WIN32 # define strcasecmp(A,B) _stricmp(A,B) # define strncasecmp(A,B,C) _strnicmp(A,B,C) #endif #include "cgnsImport.h" #include "getargs.h" static char options[] = "fdDt:B:"; static char *usgmsg[] = { "usage : tecplot_to_cgns [options] Tecplotfile CGNSfile", "options:", " -f = fix degenerate brick elements", " -d = duplicate node checking with rel tol", " -D = duplicate node checking with abs tol", " -t = duplicate node checking tolerance", " -B = set CGNS base name to ", NULL }; static int nvar = 3; static int xloc = 0; static int yloc = 1; static int zloc = 2; static char buffer[257], name[33]; /*---------- check_ascii -------------------------------------------- * check first 256 bytes for non-ascii characters *-------------------------------------------------------------------*/ static void check_ascii (char *fname) { int n, np; FILE *fp = fopen (fname, "rb"); if (fp == NULL) { fprintf (stderr, "can't open <%s> for reading\n", fname); exit (1); } np = (int)fread (buffer, 1, sizeof(buffer), fp); fclose (fp); for (n = 0; n < np; n++) { if (!buffer[n] || !isascii (buffer[n]) || (buffer[n] < ' ' && !isspace (buffer[n]))) { fprintf (stderr, "can only read ASCII Tecplot files\n"); exit (1); } } } /*---------- get_line ----------------------------------------------- * get next non-blank line *-------------------------------------------------------------------*/ static char *get_line (FILE *fp) { char *p; while (fgets (buffer, sizeof(buffer), fp) != NULL) { buffer[sizeof(buffer)-1] = 0; for (p = buffer+strlen(buffer)-1; p >= buffer && isspace(*p); p--) ; *++p = 0; for (p = buffer; *p && isspace (*p); p++) ; if (*p) return p; } return NULL; } /*---------- getvar ------------------------------------------------- * get the next variable name *-------------------------------------------------------------------*/ static char *getvar (char **pp) { int n = 0; char *p; for (p = *pp; *p && (isspace (*p) || *p == ','); p++) ; if (*p != '"') return NULL; for (++p; *p && *p != '"'; p++) { if (n < sizeof(name)) name[n++] = *p; } name[n] = 0; if (*p == '"') p++; *pp = p; return name; } /*---------- getzone ------------------------------------------------ * get zone description data *-------------------------------------------------------------------*/ static char *getzone (char **pp, int *tag) { int n, match; char *p, what[5]; for (p = *pp; *p && (isspace (*p) || *p == ','); p++) ; if (!*p) return NULL; for (n = 0; *p && !isspace(*p) && *p != '='; p++) { if (n < sizeof(what)) what[n++] = *p; } what[n] = 0; while (*p && isspace (*p)) p++; if (*p != '=') cgnsImportFatal ("zone specification error"); while (*++p && isspace (*p)) ; if (*p == '"' || *p == '(') { match = *p == '"' ? '"' : ')'; for (n = 0, ++p; *p && *p != match; p++) { if (n < sizeof(name)) name[n++] = *p; } if (*p == match) p++; } else if (*p) { for (n = 0; *p && !isspace (*p) && *p != ','; p++) { if (n < sizeof(name)) name[n++] = *p; } } else cgnsImportFatal ("zone specification error"); name[n] = 0; switch (tolower (what[0])) { case 't': *tag = 0; break; case 'f': *tag = 1; break; case 'i': *tag = 2; break; case 'j': *tag = 3; break; case 'k': *tag = 4; break; case 'n': *tag = 5; break; case 'e': *tag = tolower(what[1]) == 't' ? 7 : 6; break; default: *tag = -1; break; } *pp = p; return name; } /*---------- block_nodes -------------------------------------------- * read nodes in block format *-------------------------------------------------------------------*/ static void block_nodes (FILE *fp, int nnodes) { int nv, nn, vnum; double *x, *y, *z, v; for (nn = 0; nn < nnodes; nn++) cgnsImportNode (nn+1, 0.0, 0.0, 0.0); x = (double *) calloc (3 * nnodes, sizeof(double)); if (x == NULL) cgnsImportFatal ("malloc failed for variables"); y = x + nnodes; z = y + nnodes; for (vnum = 0, nv = 0; nv < nvar; nv++) { if (nv == xloc) { for (nn = 0; nn < nnodes; nn++) { if (1 != fscanf (fp, "%lf", &x[nn])) cgnsImportFatal ("error reading variables"); } } else if (nv == yloc) { for (nn = 0; nn < nnodes; nn++) { if (1 != fscanf (fp, "%lf", &y[nn])) cgnsImportFatal ("error reading variables"); } } else if (nv == zloc) { for (nn = 0; nn < nnodes; nn++) { if (1 != fscanf (fp, "%lf", &z[nn])) cgnsImportFatal ("error reading variables"); } } else { for (nn = 0; nn < nnodes; nn++) { if (1 != fscanf (fp, "%lf", &v)) cgnsImportFatal ("error reading variables"); cgnsImportVariable(nn+1, vnum++, v); } } } for (nn = 0; nn < nnodes; nn++) cgnsImportSetNode (nn+1, x[nn], y[nn], z[nn]); free (x); } /*---------- point_nodes -------------------------------------------- * read nodes in point format *-------------------------------------------------------------------*/ static void point_nodes (FILE *fp, int nnodes) { int nv, nn, vnum; double x = 0.0, y = 0.0, z = 0.0; double *v; v = (double *) malloc (nvar * sizeof(double)); if (v == NULL) cgnsImportFatal ("malloc failed for variables"); for (nn = 0; nn < nnodes; nn++) { for (nv = 0; nv < nvar; nv++) { if (1 != fscanf (fp, "%lf", &v[nv])) cgnsImportFatal ("error reading variables"); } if (xloc >= 0 && xloc < nvar) x = v[xloc]; if (yloc >= 0 && yloc < nvar) y = v[yloc]; if (zloc >= 0 && zloc < nvar) z = v[zloc]; cgnsImportNode (nn+1, x, y, z); for (vnum = 0, nv = 0; nv < nvar; nv++) { if (nv != xloc && nv != yloc && nv != zloc) cgnsImportVariable(nn+1, vnum++, v[nv]); } } free (v); } /*========== main ===================================================*/ int main (int argc, char *argv[]) { int n, i, j, k, ni, nj, nk; int nn, ne, et, nz, block; cgsize_t nodes[8]; int do_chk = 0, fix_bricks = 0; char elemname[33]; char zonename[33], *p, *s, *basename = NULL; FILE *fp; if (argc < 2) print_usage (usgmsg, NULL); while ((n = getargs (argc, argv, options)) > 0) { switch (n) { case 'f': fix_bricks = 1; break; case 'D': case 'd': do_chk = n; break; case 't': cgnsImportSetTol (atof (argarg)); break; case 'B': basename = argarg; break; } } if (argind + 1 >= argc) print_usage (usgmsg, "Tecplot and/or CGNS filename not specified\n"); check_ascii (argv[argind]); if (NULL == (fp = fopen (argv[argind], "r"))) { fprintf (stderr, "can't open <%s> for reading\n", argv[argind]); exit (1); } printf ("reading Tecplot file from %s\n", argv[argind++]); printf ("writing CGNS data to %s\n", argv[argind]); cgnsImportOpen (argv[argind]); if (basename != NULL) cgnsImportBase (basename); nz = 0; p = get_line (fp); while (p != NULL) { /* VARIABLES */ if (0 == strncasecmp (p, "variables", 9)) { for (p += 9; *p && isspace(*p); p++) ; if (*p++ != '=') { p = get_line (fp); continue; } nvar = 0; xloc = yloc = zloc = -1; while (1) { if ((s = getvar (&p)) == NULL) { p = get_line (fp); if (p == NULL || (s = getvar (&p)) == NULL) break; } if (0 == strcasecmp ("x", s)) xloc = nvar++; else if (0 == strcasecmp ("y", s)) yloc = nvar++; else if (0 == strcasecmp ("z", s)) zloc = nvar++; else { cgnsImportAddVariable(s); nvar++; } } if (xloc == -1 && yloc == -1 && zloc == -1) cgnsImportFatal("X, Y and Z variables missing"); continue; } /* ZONE */ if (0 == strncasecmp (p, "zone", 4)) { p += 4; ni = nj = nk = nn = ne = et = -1; block = 0; sprintf (zonename, "Zone%d", ++nz); while (1) { if ((s = getzone (&p, &n)) == NULL) { while ((n = fgetc (fp)) != EOF && (isspace(n) || n == ',')) ; if (n == EOF) cgnsImportFatal ("end of file while reading zone"); ungetc (n, fp); if (!isalpha (n)) break; p = get_line (fp); continue; } switch (n) { case 0: /* T */ strncpy (zonename, s, 32); zonename[32] = 0; break; case 1: /* F */ if (0 == strncasecmp (s, "block", 5) || 0 == strncasecmp (s, "feblock", 7)) block = 1; break; case 2: /* I */ ni = atoi (s); break; case 3: /* J */ nj = atoi (s); break; case 4: /* K */ nk = atoi (s); break; case 5: /* N */ nn = atoi (s); break; case 6: /* E */ ne = atoi (s); break; case 7: /* ET */ strncpy (elemname, s, 32); elemname[32] = 0; if (0 == strncasecmp (elemname, "tri", 3)) et = 0; else if (0 == strncasecmp (elemname, "qua", 3)) et = 1; else if (0 == strncasecmp (elemname, "tet", 3)) et = 2; else if (0 == strncasecmp (elemname, "bri", 3)) et = 3; else printf("unhandled element type %s", elemname); break; default: break; } } printf("zone %s:", zonename); if (nn == -1) { if (ni < 2 || nj < 2 || nk < 2) { printf("missing I, J and K - skipping zone\n"); p = get_line(fp); continue; } nn = ni * nj * nk; ne = (ni - 1) * (nj - 1) * (nk - 1); et = 5; } else { if (nn < 3 || ne < 1 || et < 0) { printf("%d nodes, %d %s elements - skipping zone\n", nn, ne, elemname); p = get_line(fp); continue; } if (et < 2) { printf ("%s elements - skipping zone\n", elemname); p = get_line (fp); continue; } } printf ("%d nodes...", nn); fflush (stdout); cgnsImportZone (zonename); if (block) block_nodes (fp, nn); else point_nodes (fp, nn); printf (" %d %s elements...", ne, elemname); fflush (stdout); if (et == 5) { for (n = 1, k = 1; k < nk; k++) { for (j = 1; j < nj; j++) { for (i = 1; i < ni; i++) { n = i + ni * ((j - 1) + nj * (k - 1)); nodes[0] = n; nodes[1] = n + 1; nodes[2] = n + 1 + ni; nodes[3] = n + ni; n = i + ni * ((j - 1) + nj * k); nodes[4] = n; nodes[5] = n + 1; nodes[6] = n + 1 + ni; nodes[7] = n + ni; cgnsImportElement (n++, 8, nodes); } } } } else { j = 1 << et; for (n = 1; n <= ne; n++) { for (i = 0; i < j; i++) { if (1 != fscanf (fp, "%d", &k)) cgnsImportFatal ("error reading elements"); nodes[i] = k; } k = j; if (fix_bricks && k == 8 && nodes[6] == nodes[7]) { if (nodes[4] == nodes[6] && nodes[5] == nodes[6]) { if (nodes[2] == nodes[3]) { k = 4; nodes[3] = nodes[4]; } else k = 5; } else if (nodes[2] == nodes[3]) { k = 6; nodes[3] = nodes[4]; nodes[4] = nodes[5]; nodes[5] = nodes[6]; } } cgnsImportElement (n, k, nodes); } } puts (" done"); if (do_chk) { printf ("checking for duplicate nodes...\n"); cgnsImportCheck (do_chk == 'd'); } cgnsImportWrite (); } p = get_line (fp); } fclose (fp); cgnsImportClose (); return 0; } cgnslib_3.1.4/src/cgnstools/utilities/cgnsutil.h0000664000076400007640000001132712160605674017006 00000000000000/* * cgnsutil.h - CGNS utility header */ #ifndef _CGNSUTIL_H_ #define _CGNSUTIL_H_ #include "cgnslib.h" #ifndef CGNSTYPES_H # define cgsize_t int # define CG_MAX_INT32 0x7FFFFFFF #endif #ifndef CGNS_ENUMT # define CGNS_ENUMT(e) e # define CGNS_ENUMV(e) e #endif typedef struct _DESC { int id; char name[33]; char *desc; } DESC; typedef struct _VERTEX { cgsize_t id; double x, y, z, w; } VERTEX; typedef struct _ELEMSET { int id; char name[33]; int type; cgsize_t start; cgsize_t end; int nbndry; cgsize_t *conn; cgsize_t *parent; } ELEMSET; typedef struct _INTERFACE { int id; char name[33]; cgsize_t range[3][2]; char d_name[33]; cgsize_t d_range[3][2]; int transform[3]; int d_zone; } INTERFACE; typedef struct _CONNECT { int id; char name[33]; int type; int location; int ptype; cgsize_t npnts; cgsize_t *pnts; char d_name[33]; int d_ztype; int d_ptype; cgsize_t d_npnts; cgsize_t *d_pnts; int d_zone; } CONNECT; typedef struct _BOCO { int id; char name[33]; int type; int ptype; cgsize_t npnts; cgsize_t *pnts; int n_index[3]; cgsize_t n_cnt; int n_type; double *n_list; } BOCO; typedef struct _FIELD { int id; char name[33]; int datatype; int units[5]; int dataclass; int convtype; double dataconv[2]; int exptype; double exponent[5]; double *data; } FIELD; typedef struct _SOLUTION { int id; char name[33]; int location; int rind[3][2]; cgsize_t size; int units[5]; int dataclass; int nflds; FIELD *flds; int ndesc; DESC *desc; } SOLUTION; typedef struct _ZONE { int id; char name[33]; int type; int idim; cgsize_t dim[3]; int units[5]; int dataclass; int datatype; int vertflags; cgsize_t nverts; VERTEX *verts; int nesets; ELEMSET *esets; int nints; INTERFACE *ints; int nconns; CONNECT *conns; int nbocos; BOCO *bocos; int nsols; SOLUTION *sols; void *user; int ndesc; DESC *desc; } ZONE; extern int nZones; extern ZONE *Zones; extern int baseunits[5]; extern int baseclass; extern int cgnsfn; extern int cgnsbase; extern int element_node_counts[]; #ifdef __cplusplus extern "C" { #endif void FATAL (char *procname, char *errmsg); ZONE *new_zone (int count); VERTEX *new_vertex (cgsize_t nverts); ELEMSET *new_elemset (int nsets); INTERFACE *new_interface (int nints); CONNECT *new_connect (int nconns); BOCO *new_boco (int nbocos); DESC *new_desc (int ndesc); SOLUTION *new_solution (int nsols); FIELD *new_field (int nfields, cgsize_t size); cgsize_t vertex_index (ZONE *z, cgsize_t i, cgsize_t j, cgsize_t k); cgsize_t cell_index (ZONE *z, cgsize_t i, cgsize_t j, cgsize_t k); cgsize_t solution_index (ZONE *z, SOLUTION *s, cgsize_t i, cgsize_t j, cgsize_t k); int file_exists (char *file); int is_executable (char *file); char *find_executable (char *exename); char *find_file (char *filename, char *exename); int same_file (char *file1, char *file2); char *temporary_file (char *basename); void copy_file (char *oldfile, char *newfile); int open_cgns (char *cgnsfile, int read_only); int find_base (char *basename); void read_cgns (void); int read_zones (void); void read_zone_data (int izone); cgsize_t read_zone_grid (int izone); int read_zone_element (int izone); int structured_elements (int izone); int read_zone_interface (int izone); int read_zone_connect (int izone); int read_zone_boco (int izone); int read_zone_solution (int izone); cgsize_t read_solution_field (int izone, int isol, int ifld); int read_units (int units[5]); void write_cgns (void); void write_zones (void); void write_zone_data (int izone); void write_zone_grid (int izone); void write_zone_element (int izone); void write_zone_interface (int izone); void write_zone_connect (int izone); void write_zone_boco (int izone); void write_zone_solution (int izone, int isol); void write_solution_field (int izone, int isol, int ifld); double volume_tet (VERTEX *v1, VERTEX *v2, VERTEX *v3, VERTEX *v4); double volume_pyr (VERTEX *v1, VERTEX *v2, VERTEX *v3, VERTEX *v4, VERTEX *v5); double volume_wdg (VERTEX *v1, VERTEX *v2, VERTEX *v3, VERTEX *v4, VERTEX *v5, VERTEX *v6); double volume_hex (VERTEX *v1, VERTEX *v2, VERTEX *v3, VERTEX *v4, VERTEX *v5, VERTEX *v6, VERTEX *v7, VERTEX *v8); double volume_element (int nnodes, VERTEX *v[]); double cell_volume (ZONE *z, cgsize_t i, cgsize_t j, cgsize_t k); void vertex_volumes (int izone); void cell_vertex_solution (int izone, int isol, int weight); void cell_center_solution (int izone, int isol, int weight); #ifdef __cplusplus } #endif #endif cgnslib_3.1.4/src/cgnstools/utilities/interpolate_cgns.c0000664000076400007640000011374212160605674020515 00000000000000/* * interpolate_cgns.c - solution interpolation */ #include #include #include #include #include #ifdef _WIN32 # define unlink _unlink #else # include #endif #include "getargs.h" #include "cgnslib.h" #include "cgnsutil.h" #ifndef CG_MODE_READ # define CG_MODE_READ MODE_READ # define CG_MODE_MODIFY MODE_MODIFY #endif #define BBOX_PADDING 0.01 #define MAX_ELEMENTS 256 #define MAX_DEPTH 16 #define MAX_ITER 20 #define TOLERANCE 0.00001 /* command line options */ static char options[] = "c:b:B:S:wand:e:p:i:t:"; static char *usgmsg[] = { "usage : interpolate_cgns [options] CGNSsol CGNSgrid [CGNSnew]", " reads solution from CGNSsol and interpolates the", " solution onto the grid from CGNSgrid.", "options:", " -c = use CGNS base number for CGNSsol (default 1)", " -b = use CGNS base number for CGNSgrid (default 1)", " -B = write results to base (default same as read)", " -S = write results to solution ", " -w = use volume weighting", " -a = allow element extrapolation", " -n = use nearest point values", " -d = max depth for octtree (default 16)", " -e = max number of elements in octtree branch (default 256)", " -p = bounding box padding fraction (default 0.01)", " -i = max newton iterations (default 20)", " -t = u,v,w tolerance (default 0.00001)", NULL }; typedef struct _Element { int flag; int zone; int nnodes; cgsize_t nodes[8]; double bbox[3][2]; } Element; static cgsize_t num_elements; static Element *elements; typedef struct _OctTree { int depth; int subflag; struct _OctTree *parent; struct _OctTree *tree[8]; double bbox[3][2]; cgsize_t nelem; Element **elem; } OctTree; static OctTree root; static int depths[3]; static cgsize_t counts[4]; static int nbasezones; static ZONE *basezones; static char *solname = NULL; static int weighting = 0; static int extrapolate = 0; static int nearestpt = 0; static int numout = 0; static int numextrap = 0; static int numconv = 0; static int max_elements = MAX_ELEMENTS; static int max_depth = MAX_DEPTH; static float bbox_padding = (float)BBOX_PADDING; static int max_iter = MAX_ITER; static double tolerance = TOLERANCE; static char buff[1024]; /*-------------------------------------------------------------------*/ static int sort_name (const void *v1, const void *v2) { return strcmp (((FIELD *)v1)->name, ((FIELD *)v2)->name); } /*-------------------------------------------------------------------*/ static void check_solution (void) { int nz, nf; ZONE *z; for (z = Zones, nz = 1; nz <= nZones; nz++, z++) { read_solution_field (nz, 1, 0); if (z->sols->nflds == 0) { sprintf (buff, "missing solution for zone %d", nz); FATAL ("check_solution", buff); } if (z->sols->location == CGNS_ENUMV(CellCenter)) cell_vertex_solution (nz, 1, weighting); if (z->sols->nflds > 1) qsort (z->sols->flds, z->sols->nflds, sizeof(FIELD), sort_name); if (nz > 1) { if (z->sols->nflds != Zones->sols->nflds) FATAL ("check_solution", "solution inconsistant between zones"); for (nf = 0; nf < z->sols->nflds; nf++) { if (strcmp (z->sols->flds[nf].name, Zones->sols->flds[nf].name)) FATAL ("check_solution", "solution inconsistant between zones"); } } } } /*-------------------------------------------------------------------*/ static cgsize_t count_elements (int nz) { int ns, et; cgsize_t n, nn, ne, nelem = 0; ZONE *z = &Zones[nz]; for (ns = 0; ns < z->nesets; ns++) { ne = z->esets[ns].end - z->esets[ns].start + 1; et = z->esets[ns].type; if (et == CGNS_ENUMV(MIXED)) { for (n = 0, nn = 0; nn < ne; nn++) { et = (int)z->esets[ns].conn[n++]; if (et < CGNS_ENUMV(NODE) || et > CGNS_ENUMV(HEXA_27)) FATAL ("count_elements", "unrecognized element type"); if (et >= CGNS_ENUMV(TETRA_4) && et <= CGNS_ENUMV(HEXA_27)) nelem++; n += element_node_counts[et]; } } else { if (et >= CGNS_ENUMV(TETRA_4) && et <= CGNS_ENUMV(HEXA_27)) nelem += ne; } } return nelem; } /*-------------------------------------------------------------------*/ static void add_elements (int nz) { int i, nn, ns, et; cgsize_t n, j, ne, iv, nelem = 0; ZONE *z = &Zones[nz]; VERTEX *v; Element *e = &elements[num_elements]; for (ns = 0; ns < z->nesets; ns++) { ne = z->esets[ns].end - z->esets[ns].start + 1; et = z->esets[ns].type; if (et < CGNS_ENUMV(TETRA_4) || et > CGNS_ENUMV(MIXED)) continue; for (n = 0, j = 0; j < ne; j++) { if (z->esets[ns].type == CGNS_ENUMV(MIXED)) et = (int)z->esets[ns].conn[n++]; switch (et) { case CGNS_ENUMV(TETRA_4): case CGNS_ENUMV(TETRA_10): nn = 4; break; case CGNS_ENUMV(PYRA_5): case CGNS_ENUMV(PYRA_14): nn = 5; break; case CGNS_ENUMV(PENTA_6): case CGNS_ENUMV(PENTA_15): case CGNS_ENUMV(PENTA_18): nn = 6; break; case CGNS_ENUMV(HEXA_8): case CGNS_ENUMV(HEXA_20): case CGNS_ENUMV(HEXA_27): nn = 8; break; default: nn = 0; break; } if (nn) { e[nelem].zone = nz; e[nelem].nnodes = nn; for (i = 0; i < nn; i++) { iv = z->esets[ns].conn[n+i] - 1; e[nelem].nodes[i] = iv; v = &z->verts[iv]; if (i) { if (e[nelem].bbox[0][0] > v->x) e[nelem].bbox[0][0] = v->x; if (e[nelem].bbox[0][1] < v->x) e[nelem].bbox[0][1] = v->x; if (e[nelem].bbox[1][0] > v->y) e[nelem].bbox[1][0] = v->y; if (e[nelem].bbox[1][1] < v->y) e[nelem].bbox[1][1] = v->y; if (e[nelem].bbox[2][0] > v->z) e[nelem].bbox[2][0] = v->z; if (e[nelem].bbox[2][1] < v->z) e[nelem].bbox[2][1] = v->z; } else { e[nelem].bbox[0][0] = e[nelem].bbox[0][1] = v->x; e[nelem].bbox[1][0] = e[nelem].bbox[1][1] = v->y; e[nelem].bbox[2][0] = e[nelem].bbox[2][1] = v->z; } } nelem++; } n += element_node_counts[et]; } } num_elements += nelem; } /*-------------------------------------------------------------------*/ static int contains_point (OctTree *tree, VERTEX *vert) { if (vert->x < tree->bbox[0][0] || vert->x > tree->bbox[0][1] || vert->y < tree->bbox[1][0] || vert->y > tree->bbox[1][1] || vert->z < tree->bbox[2][0] || vert->z > tree->bbox[2][1]) return 0; return 1; } #if 0 /*-------------------------------------------------------------------*/ static int contains_edge (OctTree *tree, VERTEX *v1, VERTEX *v2) { int n; double s, x, y, z; if ((v1->x < tree->bbox[0][0] && v2->x < tree->bbox[0][0]) || (v1->x > tree->bbox[0][1] && v2->x > tree->bbox[0][1]) || (v1->y < tree->bbox[1][0] && v2->y < tree->bbox[1][0]) || (v1->y > tree->bbox[1][1] && v2->y > tree->bbox[1][1]) || (v1->z < tree->bbox[2][0] && v2->z < tree->bbox[2][0]) || (v1->z > tree->bbox[2][1] && v2->z > tree->bbox[2][1])) return 0; if (v1->x != v2->x) { for (n = 0; n < 2; n++) { s = (tree->bbox[0][n] - v1->x) / (v2->x - v1->x); if (s >= 0.0 && s <= 1.0) { y = v1->y + s * (v2->y - v1->y); z = v1->z + s * (v2->z - v1->z); if (y >= tree->bbox[1][0] && y <= tree->bbox[1][1] && z >= tree->bbox[2][0] && z <= tree->bbox[2][1]) return 1; } } } if (v1->y != v2->y) { for (n = 0; n < 2; n++) { s = (tree->bbox[1][n] - v1->y) / (v2->y - v1->y); if (s >= 0.0 && s <= 1.0) { x = v1->x + s * (v2->x - v1->x); z = v1->z + s * (v2->z - v1->z); if (x >= tree->bbox[0][0] && x <= tree->bbox[0][1] && z >= tree->bbox[2][0] && z <= tree->bbox[2][1]) return 1; } } } if (v1->z != v2->z) { for (n = 0; n < 2; n++) { s = (tree->bbox[2][n] - v1->z) / (v2->z - v1->z); if (s >= 0.0 && s <= 1.0) { x = v1->x + s * (v2->x - v1->x); y = v1->y + s * (v2->y - v1->y); if (x >= tree->bbox[0][0] && x <= tree->bbox[0][1] && y >= tree->bbox[1][0] && y <= tree->bbox[1][1]) return 1; } } } return 0; } #endif /*-------------------------------------------------------------------*/ static int contains_element (OctTree *tree, Element *elem) { int n; #if 0 ZONE *z = &Zones[elem->zone]; VERTEX *v[8]; #endif for (n = 0; n < 3; n++) { if (elem->bbox[n][0] > tree->bbox[n][1] || elem->bbox[n][1] < tree->bbox[n][0]) return 0; } #if 0 for (n = 0; n < elem->nnodes; n++) { v[n] = &z->verts[elem->nodes[n]]; if (contains_point (tree, v[n])) return 1; } if (elem->nnodes == 4) { return (contains_edge (tree, v[0], v[1]) || contains_edge (tree, v[0], v[2]) || contains_edge (tree, v[0], v[3]) || contains_edge (tree, v[1], v[2]) || contains_edge (tree, v[1], v[3]) || contains_edge (tree, v[2], v[3])); } if (elem->nnodes == 5) { return (contains_edge (tree, v[0], v[1]) || contains_edge (tree, v[0], v[3]) || contains_edge (tree, v[0], v[4]) || contains_edge (tree, v[1], v[2]) || contains_edge (tree, v[1], v[4]) || contains_edge (tree, v[2], v[3]) || contains_edge (tree, v[2], v[4]) || contains_edge (tree, v[3], v[4])); } if (elem->nnodes == 6) { return (contains_edge (tree, v[0], v[1]) || contains_edge (tree, v[0], v[2]) || contains_edge (tree, v[0], v[3]) || contains_edge (tree, v[1], v[2]) || contains_edge (tree, v[1], v[4]) || contains_edge (tree, v[2], v[5]) || contains_edge (tree, v[3], v[4]) || contains_edge (tree, v[3], v[5]) || contains_edge (tree, v[4], v[5])); } return (contains_edge (tree, v[0], v[1]) || contains_edge (tree, v[0], v[3]) || contains_edge (tree, v[0], v[4]) || contains_edge (tree, v[1], v[2]) || contains_edge (tree, v[1], v[5]) || contains_edge (tree, v[2], v[3]) || contains_edge (tree, v[2], v[6]) || contains_edge (tree, v[3], v[7]) || contains_edge (tree, v[4], v[5]) || contains_edge (tree, v[4], v[7]) || contains_edge (tree, v[5], v[6]) || contains_edge (tree, v[6], v[7])); #endif /* * add if bounding boxes overlap - this does not imply that * the element is actually contained in the tree bounding box * and may result in additional elements that must be searched. * This does, however, guarantee that all possible elements * will be included in the tree branch. */ return 1; } /*-------------------------------------------------------------------*/ static void subdivide (OctTree *parent) { int i, j, k, n, ne; double bbox[3][3]; OctTree *tree; if (parent->nelem <= max_elements || parent->depth >= max_depth) { if (depths[0] > parent->depth) depths[0] = parent->depth; if (depths[1] < parent->depth) depths[1] = parent->depth; depths[2] += parent->depth; if (counts[0] > parent->nelem) counts[0] = parent->nelem; if (counts[1] < parent->nelem) counts[1] = parent->nelem; counts[2] += parent->nelem; (counts[3])++; return; } parent->subflag = 1; for (n = 0; n < 3; n++) { bbox[n][0] = parent->bbox[n][0]; bbox[n][1] = 0.5 * (parent->bbox[n][0] + parent->bbox[n][1]); bbox[n][2] = parent->bbox[n][1]; } for (n = 0; n < 8; n++) { parent->tree[n] = tree = (OctTree *) malloc (sizeof(OctTree)); if (NULL == tree) FATAL ("subdivide", "malloc failed for octtree branch"); i = (n & 1); j = (n & 2) >> 1; k = (n & 4) >> 2; tree->bbox[0][0] = bbox[0][i]; tree->bbox[0][1] = bbox[0][i+1]; tree->bbox[1][0] = bbox[1][j]; tree->bbox[1][1] = bbox[1][j+1]; tree->bbox[2][0] = bbox[2][k]; tree->bbox[2][1] = bbox[2][k+1]; tree->depth = parent->depth + 1; tree->subflag = 0; tree->parent = parent; for (ne = 0, i = 0; i < parent->nelem; i++) { if (contains_element (tree, parent->elem[i])) { parent->elem[i]->flag = 1; ne++; } else parent->elem[i]->flag = 0; } tree->nelem = ne; if (ne) { tree->elem = (Element **) malloc (ne * sizeof(Element *)); if (NULL == tree->elem) FATAL ("subdivide", "malloc failed for octtree elements"); for (ne = 0, i = 0; i < parent->nelem; i++) { if (parent->elem[i]->flag) tree->elem[ne++] = parent->elem[i]; } } } free (parent->elem); parent->nelem = 0; for (n = 0; n < 8; n++) subdivide (parent->tree[n]); } /*-------------------------------------------------------------------*/ static void build_octree (void) { int i, nz; cgsize_t n, ne; double diff; ZONE *z = Zones; root.depth = 0; root.subflag = 0; root.parent = NULL; root.bbox[0][0] = root.bbox[0][1] = z->verts->x; root.bbox[1][0] = root.bbox[1][1] = z->verts->y; root.bbox[2][0] = root.bbox[2][1] = z->verts->z; for (ne = 0, nz = 0; nz < nZones; nz++, z++) { for (n = 0; n < z->nverts; n++) { if (root.bbox[0][0] > z->verts[n].x) root.bbox[0][0] = z->verts[n].x; if (root.bbox[0][1] < z->verts[n].x) root.bbox[0][1] = z->verts[n].x; if (root.bbox[1][0] > z->verts[n].y) root.bbox[1][0] = z->verts[n].y; if (root.bbox[1][1] < z->verts[n].y) root.bbox[1][1] = z->verts[n].y; if (root.bbox[2][0] > z->verts[n].z) root.bbox[2][0] = z->verts[n].z; if (root.bbox[2][1] < z->verts[n].z) root.bbox[2][1] = z->verts[n].z; } ne += count_elements (nz); } if (!ne) FATAL ("build_octree", "no volume elements found"); /* add buffer around bounding box */ for (i = 0; i < 3; i++) { diff = bbox_padding * (root.bbox[i][1] - root.bbox[i][0]); root.bbox[i][0] -= diff; root.bbox[i][1] += diff; } /* build element list */ elements = (Element *) malloc ((size_t)ne * sizeof(Element)); if (NULL == elements) FATAL ("build_octree", "malloc failed for elements"); num_elements = 0; for (nz = 0; nz < nZones; nz++) add_elements (nz); if (num_elements != ne) FATAL ("build_octree", "mismatch in element count"); root.nelem = num_elements; root.elem = (Element **) malloc ((size_t)num_elements * sizeof(Element *)); if (NULL == root.elem) FATAL ("build_octree", "malloc failed for element pointers"); for (ne = 0; ne < num_elements; ne++) root.elem[ne] = &elements[ne]; depths[0] = max_depth; counts[0] = num_elements; for (i = 1; i < 3; i++) { depths[i] = 0; counts[i] = 0; } counts[3] = 0; subdivide (&root); } /*-------------------------------------------------------------------*/ #define SWAP(A,B) {temp=(A);(A)=(B);(B)=temp;} static int invert3x3 (double a[3][3], double b[3]) { int i, j, k, irow = 0, icol = 0; int indxc[3], indxr[3], ipiv[3]; double big, temp, pivinv; for (j = 0; j < 3; j++) ipiv[j] = 0; for (i = 0; i < 3; i++) { big = 0.0; for (j = 0; j < 3; j++) { if (ipiv[j] != 1) { for (k = 0; k < 3; k++) { if (ipiv[k] == 0) { if (fabs (a[j][k]) >= big) { big = fabs (a[j][k]); irow = j; icol = k; } } else { if (ipiv[k] > 1) return 1; } } } } ++(ipiv[icol]); if (irow != icol) { for (j = 0; j < 3; j++) SWAP (a[irow][j], a[icol][j]); SWAP (b[irow], b[icol]); } indxr[i] = irow; indxc[i] = icol; if (a[icol][icol] == 0.0) return 2; pivinv = 1.0 / a[icol][icol]; a[icol][icol] = 1.0; for (j = 0; j < 3; j++) a[icol][j] *= pivinv; b[icol] *= pivinv; for (k = 0; k < 3; k++) { if (k != icol) { temp = a[k][icol]; a[k][icol] = 0.0; for (j = 0; j < 3; j++) a[k][j] -= (a[icol][j] * temp); b[k] -= (b[icol] * temp); } } } for (j = 2; j >= 0; j--) { if (indxr[j] != indxc[j]) { for (k = 0; k < 3; k++) SWAP (a[k][indxr[j]], a[k][indxc[j]]); } } return 0; } /*-------------------------------------------------------------------*/ static void compute_shapef (int nnodes, double uvw[3], double shapef[8], double deriv[8][3]) { if (nnodes == 4) { shapef[0] = 1.0 - uvw[0] - uvw[1] - uvw[2]; shapef[1] = uvw[0]; shapef[2] = uvw[1]; shapef[3] = uvw[2]; } else if (nnodes == 5) { shapef[0] = (1.0 - uvw[0]) * (1.0 - uvw[1]) * (1.0 - uvw[2]); shapef[1] = uvw[0] * (1.0 - uvw[1]) * (1.0 - uvw[2]); shapef[2] = uvw[0] * uvw[1] * (1.0 - uvw[2]); shapef[3] = (1.0 - uvw[0]) * uvw[1] * (1.0 - uvw[2]); shapef[4] = uvw[2]; } else if (nnodes == 6) { shapef[0] = (1.0 - uvw[0] - uvw[1]) * (1.0 - uvw[2]); shapef[1] = uvw[0] * (1.0 - uvw[2]); shapef[2] = uvw[1] * (1.0 - uvw[2]); shapef[3] = (1.0 - uvw[0] - uvw[1]) * uvw[2]; shapef[4] = uvw[0] * uvw[2]; shapef[5] = uvw[1] * uvw[2]; } else if (nnodes == 8) { shapef[0] = (1.0 - uvw[0]) * (1.0 - uvw[1]) * (1.0 - uvw[2]); shapef[1] = uvw[0] * (1.0 - uvw[1]) * (1.0 - uvw[2]); shapef[2] = uvw[0] * uvw[1] * (1.0 - uvw[2]); shapef[3] = (1.0 - uvw[0]) * uvw[1] * (1.0 - uvw[2]); shapef[4] = (1.0 - uvw[0]) * (1.0 - uvw[1]) * uvw[2]; shapef[5] = uvw[0] * (1.0 - uvw[1]) * uvw[2]; shapef[6] = uvw[0] * uvw[1] * uvw[2]; shapef[7] = (1.0 - uvw[0]) * uvw[1] * uvw[2]; } else FATAL ("compute_shapef", "invalid number of nodes for element"); if (deriv != NULL) { if (nnodes == 4) { deriv[0][0] = -1.0; deriv[0][1] = -1.0; deriv[0][2] = -1.0; deriv[1][0] = 1.0; deriv[1][1] = 0.0; deriv[1][2] = 0.0; deriv[2][0] = 0.0; deriv[2][1] = 1.0; deriv[2][2] = 0.0; deriv[3][0] = 0.0; deriv[3][1] = 0.0; deriv[3][2] = 1.0; } else if (nnodes == 5) { deriv[0][0] = -(1.0 - uvw[1]) * (1.0 - uvw[2]); deriv[0][1] = -(1.0 - uvw[0]) * (1.0 - uvw[2]); deriv[0][2] = -(1.0 - uvw[0]) * (1.0 - uvw[1]); deriv[1][0] = (1.0 - uvw[1]) * (1.0 - uvw[2]); deriv[1][1] = -uvw[0] * (1.0 - uvw[2]); deriv[1][2] = -uvw[0] * (1.0 - uvw[1]); deriv[2][0] = uvw[1] * (1.0 - uvw[2]); deriv[2][1] = uvw[0] * (1.0 - uvw[2]); deriv[2][2] = -uvw[0] * uvw[1]; deriv[3][0] = -uvw[1] * (1.0 - uvw[2]); deriv[3][1] = (1.0 - uvw[0]) * (1.0 - uvw[2]); deriv[3][2] = -(1.0 - uvw[0]) * uvw[1]; deriv[4][0] = 0.0; deriv[4][1] = 0.0; deriv[4][2] = 1.0; } else if (nnodes == 6) { deriv[0][0] = -(1.0 - uvw[2]); deriv[0][1] = -(1.0 - uvw[2]); deriv[0][2] = -(1.0 - uvw[0] - uvw[1]); deriv[1][0] = (1.0 - uvw[2]); deriv[1][1] = 0.0; deriv[1][2] = -uvw[0]; deriv[2][0] = 0.0; deriv[2][1] = (1.0 - uvw[2]); deriv[2][2] = -uvw[1]; deriv[3][0] = -uvw[2]; deriv[3][1] = -uvw[2]; deriv[3][2] = (1.0 - uvw[0] - uvw[1]); deriv[4][0] = uvw[2]; deriv[4][1] = 0.0; deriv[4][2] = uvw[0]; deriv[5][0] = 0.0; deriv[5][1] = uvw[2]; deriv[5][2] = uvw[1]; } else { deriv[0][0] = -(1.0 - uvw[1]) * (1.0 - uvw[2]); deriv[0][1] = -(1.0 - uvw[0]) * (1.0 - uvw[2]); deriv[0][2] = -(1.0 - uvw[0]) * (1.0 - uvw[1]); deriv[1][0] = (1.0 - uvw[1]) * (1.0 - uvw[2]); deriv[1][1] = -uvw[0] * (1.0 - uvw[2]); deriv[1][2] = -uvw[0] * (1.0 - uvw[1]); deriv[2][0] = uvw[1] * (1.0 - uvw[2]); deriv[2][1] = uvw[0] * (1.0 - uvw[2]); deriv[2][2] = -uvw[0] * uvw[1]; deriv[3][0] = -uvw[1] * (1.0 - uvw[2]); deriv[3][1] = (1.0 - uvw[0]) * (1.0 - uvw[2]); deriv[3][2] = -(1.0 - uvw[0]) * uvw[1]; deriv[4][0] = -(1.0 - uvw[1]) * uvw[2]; deriv[4][1] = -(1.0 - uvw[0]) * uvw[2]; deriv[4][2] = (1.0 - uvw[0]) * (1.0 - uvw[1]); deriv[5][0] = (1.0 - uvw[1]) * uvw[2]; deriv[5][1] = -uvw[0] * uvw[2]; deriv[5][2] = uvw[0] * (1.0 - uvw[1]); deriv[6][0] = uvw[1] * uvw[2]; deriv[6][1] = uvw[0] * uvw[2]; deriv[6][2] = uvw[0] * uvw[1]; deriv[7][0] = -uvw[1] * uvw[2]; deriv[7][1] = (1.0 - uvw[0]) * uvw[2]; deriv[7][2] = (1.0 - uvw[0]) * uvw[1]; } } } /*-------------------------------------------------------------------*/ static int compute_uvw (Element *elem, VERTEX *pt, double uvw[3]) { int i, j, n; double dist; double a[3][3], b[3], shapef[8], dw[8][3]; VERTEX *v[8]; ZONE *z = &basezones[elem->zone]; /* check if point is within element bounding box */ if (!extrapolate) { if (pt->x < elem->bbox[0][0] || pt->x > elem->bbox[0][1] || pt->y < elem->bbox[1][0] || pt->y > elem->bbox[1][1] || pt->z < elem->bbox[2][0] || pt->z > elem->bbox[2][1]) return 0; } for (n = 0; n < elem->nnodes; n++) v[n] = &z->verts[elem->nodes[n]]; /* for tetrahedron, direct solution */ if (elem->nnodes == 4) { for (i = 0; i < 3; i++) { a[0][i] = v[i+1]->x - v[0]->x; a[1][i] = v[i+1]->y - v[0]->y; a[2][i] = v[i+1]->z - v[0]->z; } b[0] = pt->x - v[0]->x; b[1] = pt->y - v[0]->y; b[2] = pt->z - v[0]->z; if (invert3x3 (a, b)) return 0; for (n = 0; n < 3; n++) uvw[n] = b[n]; if (!extrapolate) { for (n = 0; n < 3; n++) { if (uvw[n] < 0.0) { if (uvw[n] < -tolerance) return 0; uvw[n] = 0.0; } else if (uvw[n] > 1.0) { if (uvw[n] > 1.0+tolerance) return 0; uvw[n] = 1.0; } } } return 1; } /* all other elements, use Newton iteration */ for (n = 0; n < 3; n++) uvw[n] = 0.5; for (n = 0; n < max_iter; n++) { compute_shapef (elem->nnodes, uvw, shapef, dw); b[0] = -pt->x; b[1] = -pt->y; b[2] = -pt->z; for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { a[i][j] = 0.0; } } for (i = 0; i < elem->nnodes; i++) { b[0] += (shapef[i] * v[i]->x); b[1] += (shapef[i] * v[i]->y); b[2] += (shapef[i] * v[i]->z); for (j = 0; j < 3; j++) { a[0][j] -= (dw[i][j] * v[i]->x); a[1][j] -= (dw[i][j] * v[i]->y); a[2][j] -= (dw[i][j] * v[i]->z); } } if (invert3x3 (a, b)) return 0; for (dist = 0.0, i = 0; i < 3; i++) { dist += b[i] * b[i]; uvw[i] += b[i]; } if (dist <= tolerance * tolerance) { if (!extrapolate) { for (i = 0; i < 3; i++) { if (uvw[i] < 0.0) { if (uvw[i] < -tolerance) return 0; uvw[i] = 0.0; } else if (uvw[i] > 1.0) { if (uvw[i] > 1.0+tolerance) return 0; uvw[i] = 1.0; } } } return 1; } } #if 0 printf ("%g (%g,%g,%g) (%g,%g,%g)\n", dist, b[0], b[1], b[2], uvw[0], uvw[1], uvw[2]); #endif numconv++; return 0; } /*-------------------------------------------------------------------*/ static Element *closest_point (OctTree *tree, VERTEX *pt, double shapef[8]) { int ne, nn, index = 0, nt, ntree; double dist, min_dist = 1.0e32; OctTree **tp; Element *e, *elem = NULL; VERTEX *v; ZONE *z; if (tree->nelem == 0) { tp = tree->parent->tree; ntree = 8; } else { tp = &tree; ntree = 1; } for (nt = 0; nt < ntree; nt++) { for (ne = 0; ne < tp[nt]->nelem; ne++) { e = tp[nt]->elem[ne]; z = &basezones[e->zone]; for (nn = 0; nn < e->nnodes; nn++) { v = &z->verts[e->nodes[nn]]; v->id = 0; } } } for (nt = 0; nt < ntree; nt++) { for (ne = 0; ne < tp[nt]->nelem; ne++) { e = tp[nt]->elem[ne]; z = &basezones[e->zone]; for (nn = 0; nn < e->nnodes; nn++) { v = &z->verts[e->nodes[nn]]; if (!v->id) { v->id = 1; dist = (pt->x - v->x) * (pt->x - v->x) + (pt->y - v->y) * (pt->y - v->y) + (pt->z - v->z) * (pt->z - v->z); if (elem == NULL || dist < min_dist) { elem = e; min_dist = dist; index = nn; } } } } } for (nn = 0; nn < elem->nnodes; nn++) shapef[nn] = 0.0; shapef[index] = 1.0; numout++; return elem; } /*-------------------------------------------------------------------*/ static Element *find_element (VERTEX *pt, double shapef[8]) { int n, ne, nt, ntree; double xm, ym, zm, dist, min_dist; double uvw[3], min_uvw[3]; OctTree **tp, *tree = &root; Element *elem = NULL; /* find branch containing point */ if (!contains_point (tree, pt)) { sprintf (buff, "vertex %g,%g,%g outside bounds", pt->x, pt->y, pt->z); FATAL ("find_element", buff); } while (tree->subflag) { xm = 0.5 * (tree->bbox[0][0] + tree->bbox[0][1]); ym = 0.5 * (tree->bbox[1][0] + tree->bbox[1][1]); zm = 0.5 * (tree->bbox[2][0] + tree->bbox[2][1]); n = (pt->x < xm ? 0 : 1) | (pt->y < ym ? 0 : 2) | (pt->z < zm ? 0 : 4); tree = tree->tree[n]; } if (nearestpt) return closest_point (tree, pt, shapef); /* find element containing point */ if (tree->nelem == 0 && extrapolate) { tp = tree->parent->tree; ntree = 8; } else { tp = &tree; ntree = 1; } for (nt = 0; nt < ntree; nt++) { for (ne = 0; ne < tp[nt]->nelem; ne++) { if (compute_uvw (tp[nt]->elem[ne], pt, uvw)) { for (dist = 0.0, n = 0; n < 3; n++) dist += (uvw[n] - 0.5) * (uvw[n] - 0.5); if (elem == NULL || dist < min_dist) { elem = tp[nt]->elem[ne]; min_dist = dist; for (n = 0; n < 3; n++) min_uvw[n] = uvw[n]; } } } } /* if no element was found use nearest point */ if (elem == NULL) elem = closest_point (tree, pt, shapef); else compute_shapef (elem->nnodes, min_uvw, shapef, NULL); return elem; } /*-------------------------------------------------------------------*/ static void build_solution (int nz) { int n, ns, nv, nf; SOLUTION *sol = NULL; ZONE *bz, *z = &Zones[nz]; Element *elem; double wsum, fsum, shapef[8]; if (z->nsols) { if (solname == NULL) sol = z->sols; else { for (ns = 0; ns < z->nsols; ns++) { if (!strcmp (solname, z->sols[ns].name)) { sol = &z->sols[ns]; break; } } if (sol == NULL) { z->sols = (SOLUTION *) realloc (z->sols, (z->nsols + 1) * sizeof(SOLUTION)); if (NULL == z->sols) FATAL ("build_solution", "realloc failed for a new solution"); sol = &z->sols[(z->nsols)++]; } } } else { z->nsols = 1; z->sols = sol = new_solution (1); } if (solname != NULL) { strncpy (sol->name, solname, 32); sol->name[32] = 0; } sol->location = CGNS_ENUMV(Vertex); sol->size = z->nverts; for (n = 0; n < 5; n++) sol->units[n] = basezones->sols->units[n]; sol->dataclass = basezones->sols->dataclass; sol->nflds = basezones->sols->nflds; sol->flds = new_field (sol->nflds, z->nverts); for (nf = 0; nf < sol->nflds; nf++) { strcpy (sol->flds[nf].name, basezones->sols->flds[nf].name); sol->flds[nf].datatype = basezones->sols->flds[nf].datatype; for (n = 0; n < 5; n++) sol->flds[nf].units[n] = basezones->sols->flds[nf].units[n]; sol->flds[nf].dataclass = basezones->sols->flds[nf].dataclass; sol->flds[nf].convtype = basezones->sols->flds[nf].convtype; for (n = 0; n < 2; n++) sol->flds[nf].dataconv[n] = basezones->sols->flds[nf].dataconv[n]; sol->flds[nf].exptype = basezones->sols->flds[nf].exptype; for (n = 0; n < 5; n++) sol->flds[nf].exponent[n] = basezones->sols->flds[nf].exponent[n]; } for (nv = 0; nv < z->nverts; nv++) { elem = find_element (&z->verts[nv], shapef); for (n = 0; n < elem->nnodes; n++) { if (shapef[n] < 0.0 || shapef[n] > 1.0) { numextrap++; break; } } bz = &basezones[elem->zone]; for (wsum = 0.0, n = 0; n < elem->nnodes; n++) { shapef[n] *= bz->verts[elem->nodes[n]].w; wsum += shapef[n]; } if (wsum == 0.0) wsum = 1.0; for (nf = 0; nf < sol->nflds; nf++) { for (fsum = 0.0, n = 0; n < elem->nnodes; n++) fsum += shapef[n] * bz->sols->flds[nf].data[elem->nodes[n]]; sol->flds[nf].data[nv] = fsum / wsum; } } } /*-------------------------------------------------------------------*/ #if 0 /* this is for debugging - solution and grid files must have same nodes */ static void compare_solution () { int nz, nf, n; double f, diff, fmax, favg, fsum; for (nz = 0; nz < nZones; nz++) { for (nf = 0; nf < Zones[nz].sols->nflds; nf++) { f = basezones[nz].sols->flds[nf].data[0]; favg = fmax = fabs (Zones[nz].sols->flds[nf].data[0] - f); fsum = fabs (f); for (n = 1; n < Zones[nz].sols->size; n++) { f = basezones[nz].sols->flds[nf].data[n]; diff = fabs (Zones[nz].sols->flds[nf].data[n] - f); if (fmax < diff) fmax = diff; favg += diff; fsum += fabs (f); } favg /= (double)n; fsum /= (double)n; printf ("%d %s %g %g %g\n", nz+1, Zones[nz].sols->flds[nf].name, fsum, favg, fmax); } } } #endif /*-------------------------------------------------------------------*/ int main (int argc, char *argv[]) { int n, nz, dim; int base1 = 1, base2 = 1; char *tmpfile, *newbase = NULL, basename[33]; if (argc < 2) print_usage (usgmsg, NULL); while ((n = getargs (argc, argv, options)) > 0) { switch (n) { case 'c': base1 = atoi (argarg); break; case 'b': base2 = atoi (argarg); break; case 'B': newbase = argarg; break; case 'S': solname = argarg; break; case 'a': extrapolate = 1; break; case 'w': weighting = 1; break; case 'n': nearestpt = 1; break; case 'd': max_depth = atoi (argarg); break; case 'e': max_elements = atoi (argarg); break; case 'p': bbox_padding = (float)atof (argarg); break; case 'i': max_iter = atoi (argarg); break; case 't': tolerance = atof (argarg); break; } } if (argind >= argc + 1) print_usage (usgmsg, "CGNSbase and/or CGNSfile not given"); if (!file_exists (argv[argind]) || !file_exists (argv[argind+1])) FATAL (NULL, "CGNSbase and/or CGNSfile do not exist or is not a file"); /* read solution CGNS file */ printf ("reading CGNS solution file from %s\n", argv[argind]); if (cg_open (argv[argind], CG_MODE_READ, &cgnsfn) || cg_base_read (cgnsfn, base1, basename, &dim, &dim)) FATAL (NULL, NULL); cgnsbase = base1; printf ("reading zone information for base %d - %s\n", cgnsbase, basename); read_zones (); for (nz = 1; nz <= nZones; nz++) { read_zone_grid (nz); if (Zones[nz-1].type == CGNS_ENUMV(Structured)) structured_elements (nz); else read_zone_element (nz); if (weighting) vertex_volumes (nz); read_zone_solution (nz); if (!Zones[nz-1].nsols) { sprintf (buff, "zone %d does not contain a solution", nz); FATAL (NULL, buff); } } puts ("checking zone solutions..."); fflush (stdout); check_solution (); puts ("building octtree..."); fflush (stdout); build_octree (); printf (" min max avg\n"); printf (" depth: %8d%8d%8d\n", depths[0], depths[1], depths[2] / (int)counts[3]); printf (" elements:%8ld%8ld%8ld\n", (long)counts[0], (long)counts[1], (long)(counts[2] / counts[3])); /* save zone information */ nbasezones = nZones; basezones = Zones; cg_close (cgnsfn); /* create a working copy */ printf ("\ncreating a working copy of %s\n", argv[++argind]); tmpfile = temporary_file (argv[argind]); copy_file (argv[argind], tmpfile); printf ("reading CGNS file from %s\n", tmpfile); if (cg_open (tmpfile, CG_MODE_MODIFY, &cgnsfn) || cg_base_read (cgnsfn, base2, basename, &dim, &dim)) FATAL (NULL, NULL); cgnsbase = base2; /* conversion may leave temp file (older CGNS versions) */ sprintf (buff, "%s.temp", tmpfile); unlink (buff); printf ("reading zone information for base %d - %s\n", cgnsbase, basename); read_cgns (); printf ("interpolating solution using %s averaging...\n", weighting ? "volume" : "simple"); for (nz = 0; nz < nZones; nz++) { printf (" zone %d, %ld vertices...\n", nz+1, (long)Zones[nz].nverts); fflush (stdout); build_solution (nz); } #if 0 if (numconv) printf ("Newton iteration failed for %d points\n", numconv); #endif if (numout) printf ("%d points were set to the nearest existing point\n", numout); if (numextrap) printf ("%d points were extrapolated from element values\n", numextrap); if (newbase != NULL) { strncpy (basename, newbase, 32); basename[32] = 0; if (cg_base_write (cgnsfn, basename, 3, 3, &cgnsbase)) FATAL (NULL, NULL); } printf ("writing data to base %d - %s...\n", cgnsbase, basename); fflush (stdout); write_cgns (); cg_close (cgnsfn); if (argind + 1 < argc) argind++; printf ("renaming %s to %s\n", tmpfile, argv[argind]); unlink (argv[argind]); if (rename (tmpfile, argv[argind])) { char msg[512]; sprintf (msg, "rename %s -> %s failed", tmpfile, argv[argind]); FATAL (NULL, msg); exit (1); } free (tmpfile); return 0; } cgnslib_3.1.4/src/cgnstools/utilities/binaryio.c0000664000076400007640000016670212160605674016775 00000000000000/* * binaryio.c - reads C or FORTRAN binary files */ #include #include /* for malloc */ #include /* for memcpy, etc */ #include #include /* for atof() */ #include "binaryio.h" #ifdef _WIN32 #include /* for O_BINARY */ #include /* for setmode() */ # define setmode _setmode # define fileno _fileno #endif /*define STRING_SKIP_SPACE*/ /*----- forward references -----*/ static void swapbytes(unsigned char *, int); static unsigned char *copy2(unsigned char *); static unsigned char *copy4(unsigned char *); static unsigned char *copy8(unsigned char *); static unsigned char *swap2(unsigned char *); static unsigned char *swap4(unsigned char *); static unsigned char *swap8(unsigned char *); static unsigned char *swap2to4(unsigned char *); static unsigned char *swap4to2(unsigned char *); static unsigned char *swap4to8(unsigned char *); static unsigned char *swap8to4(unsigned char *); static unsigned char *cray_short(unsigned char *); static unsigned char *cray_long(unsigned char *); static unsigned char *cray_float(unsigned char *); static unsigned char *cray_double(unsigned char *); static unsigned char *short_cray(unsigned char *); static unsigned char *long_cray(unsigned char *); static unsigned char *float_cray(unsigned char *); static unsigned char *double_cray(unsigned char *); static unsigned char *convex_float(unsigned char *); static unsigned char *convex_double(unsigned char *); static unsigned char *float_convex(unsigned char *); static unsigned char *double_convex(unsigned char *); static int rdlongs(BINARYIO *,int,long *); /*----- error codes and messages -----*/ enum ERRCODES { BIOERR_WRITE = 1, BIOERR_READ, BIOERR_NOEOR, BIOERR_BADEOR }; static char *errmsg[] = { "tried to read from file opened for write", "tried to write to file opened for read", "Fortran EOR mark not found", "misplaced Fortran EOR mark" }; void (*binaryio_error)(char *msg) = NULL; /*----- macros for local data conversions -----*/ #if ARCH_LOCAL == ARCH_IEEE # define ieee2short(S) *((short *)(S)) # define ieee2int(I) *((int *)(I)) # define ieee2long(L) *((long *)(L)) # define ieee2float(F) *((float *)(F)) # define ieee2double(D) *((double *)(D)) # define short2ieee(S) (unsigned char *)(S) # define int2ieee(I) (unsigned char *)(I) # define long2ieee(L) (unsigned char *)(L) # define float2ieee(F) (unsigned char *)(F) # define double2ieee(D) (unsigned char *)(D) #endif #if ARCH_LOCAL == ARCH_BSIEEE # define ieee2short(S) *((short *)swap2((unsigned char *)(S))) # define ieee2int(I) *((int *)swap4((unsigned char *)(I))) # define ieee2long(L) *((long *)swap4((unsigned char *)(L))) # define ieee2float(F) *((float *)swap4((unsigned char *)(F))) # define ieee2double(D) *((double *)swap8((unsigned char *)(D))) # define short2ieee(S) swap2((unsigned char *)(S)) # define int2ieee(I) swap4((unsigned char *)(I)) # define long2ieee(L) swap4((unsigned char *)(L)) # define float2ieee(F) swap4((unsigned char *)(F)) # define double2ieee(D) swap8((unsigned char *)(D)) #endif #if ARCH_LOCAL == ARCH_CRAY # define ieee2short(S) *((short *)short_cray((unsigned char *)(S))) # define ieee2int(I) *((int *)long_cray((unsigned char *)(I))) # define ieee2long(L) *((long *)long_cray((unsigned char *)(L))) # define ieee2float(F) *((float *)float_cray((unsigned char *)(F))) # define ieee2double(D) *((double *)double_cray((unsigned char *)(D))) # define short2ieee(S) cray_short((unsigned char *)(S)) # define int2ieee(I) cray_long((unsigned char *)(I)) # define long2ieee(L) cray_long((unsigned char *)(L)) # define float2ieee(F) cray_float((unsigned char *)(F)) # define double2ieee(D) cray_double((unsigned char *)(D)) #endif #if ARCH_LOCAL == ARCH_CONVEX # define ieee2short(S) *((short *)(S)) # define ieee2int(I) *((int *)(I)) # define ieee2long(L) *((long *)(L)) # define ieee2float(F) *((float *)float_convex((unsigned char *)(F))) # define ieee2double(D) *((double *)double_convex((unsigned char *)(D))) # define short2ieee(S) (unsigned char *)(S) # define int2ieee(I) (unsigned char *)(I) # define long2ieee(L) (unsigned char *)(L) # define float2ieee(F) convex_float((unsigned char *)(F)) # define double2ieee(D) convex_double((unsigned char *)(D)) #endif #if ARCH_LOCAL == ARCH_ALPHA # define ieee2short(S) *((short *)swap2((unsigned char *)(S))) # define ieee2int(I) *((int *)swap4((unsigned char *)(I))) # define ieee2long(L) *((long *)swap4to8((unsigned char *)(L))) # define ieee2float(F) *((float *)swap4((unsigned char *)(F))) # define ieee2double(D) *((double *)swap8((unsigned char *)(D))) # define short2ieee(S) swap2((unsigned char *)(S)) # define int2ieee(I) swap4((unsigned char *)(I)) # define long2ieee(L) swap8to4((unsigned char *)(L)) # define float2ieee(F) swap4((unsigned char *)(F)) # define double2ieee(D) swap8((unsigned char *)(D)) #endif #if ARCH_LOCAL == ARCH_DOS # define ieee2short(S) *((short *)swap2((unsigned char *)(S))) # define ieee2int(I) *((int *)swap4to2((unsigned char *)(I))) # define ieee2long(L) *((long *)swap4((unsigned char *)(L))) # define ieee2float(F) *((float *)swap4((unsigned char *)(F))) # define ieee2double(D) *((double *)swap8((unsigned char *)(D))) # define short2ieee(S) swap2((unsigned char *)(S)) # define int2ieee(I) swap2to4((unsigned char *)(I)) # define long2ieee(L) swap4((unsigned char *)(L)) # define float2ieee(F) swap4((unsigned char *)(F)) # define double2ieee(D) swap8((unsigned char *)(D)) #endif #ifdef NO_MEMCPY /*---------- memcpy ------------------------------------------------ * copys memory buffers *------------------------------------------------------------------*/ char *memcpy (dest, s, cnt) char *dest; register char *s; register int cnt; { register char *d = dest; if (d != NULL) { while (cnt--) *d++ = *s++; } return (dest); } #endif /* NO_MEMCPY */ #ifdef NO_MEMSET /*---------- memset ------------------------------------------------ * sets memory to a given character *------------------------------------------------------------------*/ char *memset (dest, c, cnt) char *dest; register int c; register int cnt; { register char *d = dest; if (d != NULL) { while (cnt--) *d++ = c; } return (dest); } #endif /* NO_MEMSET */ /*=================================================================== * utility routines *===================================================================*/ /*---------- set_flags ---------------------------------------------- * set up I/O flags and conversion routines *-------------------------------------------------------------------*/ static int set_flags (BINARYIO *bf, int flags) { /* can't write fortran */ if ((OPEN_WRITE|OPEN_FORTRAN) == (flags & (OPEN_WRITE|OPEN_FORTRAN))) return (0); /* initialize */ if (MACH_DEFAULT == (flags & MACH_UNKNOWN)) { switch (flags & ARCH_IEEE) { case ARCH_IEEE: flags |= MACH_IEEE; break; case ARCH_BSIEEE: flags |= MACH_BSIEEE; break; case ARCH_CRAY: flags |= MACH_CRAY; break; case ARCH_CONVEX: flags |= MACH_CONVEX; break; case ARCH_ALPHA: flags |= MACH_ALPHA; break; case ARCH_DOS: if (OPEN_FORTRAN == (flags & OPEN_FORTRAN)) flags |= MACH_DOS32; else flags |= MACH_DOS16; break; default: flags |= MACH_LOCAL; break; } } bf->short_size = 2; bf->int_size = 4; bf->long_size = 4; bf->float_size = 4; bf->double_size = 8; bf->rec_num = 0L; bf->rec_size = 0L; bf->rec_read = 0L; /* set values based on machine type */ switch (flags & MACH_UNKNOWN) { case MACH_SUN: case MACH_IRIS: case MACH_HP: case MACH_IBM: case MACH_IEEE: case MACH_UNKNOWN: bf->arch = ARCH_IEEE; bf->fromshort = copy2; bf->fromint = copy4; bf->fromlong = copy4; bf->fromfloat = copy4; bf->fromdouble = copy8; bf->toshort = copy2; bf->toint = copy4; bf->tolong = copy4; bf->tofloat = copy4; bf->todouble = copy8; break; case MACH_DOS32: case MACH_DEC: case MACH_BSIEEE: case MACH_WIN32: case MACH_LINUX: bf->arch = ARCH_BSIEEE; bf->fromshort = swap2; bf->fromint = swap4; bf->fromlong = swap4; bf->fromfloat = swap4; bf->fromdouble = swap8; bf->toshort = swap2; bf->toint = swap4; bf->tolong = swap4; bf->tofloat = swap4; bf->todouble = swap8; break; case MACH_CRAY: bf->arch = ARCH_CRAY; bf->short_size = 8; bf->int_size = 8; bf->long_size = 8; bf->float_size = 8; bf->double_size = 8; bf->fromshort = cray_short; bf->fromint = cray_long; bf->fromlong = cray_long; bf->fromfloat = cray_float; bf->fromdouble = cray_double; bf->toshort = short_cray; bf->toint = long_cray; bf->tolong = long_cray; bf->tofloat = float_cray; bf->todouble = double_cray; break; case MACH_CONVEX: bf->arch = ARCH_CONVEX; bf->fromshort = copy2; bf->fromint = copy4; bf->fromlong = copy4; bf->fromfloat = convex_float; bf->fromdouble = convex_double; bf->toshort = copy2; bf->toint = copy4; bf->tolong = copy4; bf->tofloat = float_convex; bf->todouble = double_convex; break; case MACH_ALPHA: bf->arch = ARCH_ALPHA; bf->long_size = 8; bf->fromshort = swap2; bf->fromint = swap4; bf->fromlong = swap8to4; bf->fromfloat = swap4; bf->fromdouble = swap8; bf->toshort = swap2; bf->toint = swap4; bf->tolong = swap4to8; bf->tofloat = swap4; bf->todouble = swap8; break; case MACH_DOS16: bf->arch = ARCH_DOS; bf->int_size = 2; bf->fromshort = swap2; bf->fromint = swap2to4; bf->fromlong = swap4; bf->fromfloat = swap4; bf->fromdouble = swap8; bf->toshort = swap2; bf->toint = swap4to2; bf->tolong = swap4; bf->tofloat = swap4; bf->todouble = swap8; break; default: return (0); } bf->flags = flags & (OPEN_WRITE|OPEN_FORTRAN|OPEN_ASCII|MACH_UNKNOWN); return (bf->flags); } /*---------- fatal_error -------------------------------------------- * default fatal error handler *-------------------------------------------------------------------*/ static int fatal_error (char *funcname, int errcode) { char msg[81]; sprintf (msg, "%s: %s", funcname, errmsg[errcode-1]); if (NULL == binaryio_error) { fprintf (stderr, "%s\n", msg); exit (errcode); } (*binaryio_error) (msg); return (-1); } /*---------- beg_record ---------------------------------------------- * reads record size in bytes for FORTRAN data *--------------------------------------------------------------------*/ static int beg_record (BINARYIO *bf) { long rec_size; switch (bf->flags & MACH_UNKNOWN) { /* * most machines - integer byte count with * begin and end records marks */ case MACH_SUN: case MACH_IRIS: case MACH_HP: case MACH_IBM: case MACH_DEC: case MACH_ALPHA: case MACH_CONVEX: case MACH_WIN32: case MACH_LINUX: case MACH_IEEE: case MACH_BSIEEE: case MACH_UNKNOWN: if (1 != rdlongs (bf, 1, &rec_size)) return (0); bf->rec_size = rec_size; break; /* * Cray FORTRAN - record count is given in words (64-bit) * and needs to be masked by 0x1FFF. No end record mark */ case MACH_CRAY: if (1 != rdlongs (bf, 1, &rec_size)) return (0); rec_size &= 0x01FF; bf->rec_size = rec_size << 3; break; /* * Microsoft FORTRAN - first byte of file is 0x4B * each record is 128 bytes or less, with a byte for * the count at beginning and end of record * It also appears that a record mark of 129 indicates * a partial record, and 130 indicates EOF. */ case MACH_DOS16: case MACH_DOS32: if (0L == bf->rec_num) (void) getc (bf->fp); rec_size = (long) getc (bf->fp); if ((long)EOF == rec_size || 130L == rec_size) return (0); bf->rec_size = rec_size > 128L ? 128L : rec_size; break; default: return (0); } bf->rec_num++; bf->rec_read = 0L; return (1); } /*---------- end_record --------------------------------------------- * read end of record mark *-------------------------------------------------------------------*/ static int end_record (BINARYIO *bf) { long rec_size; switch (bf->flags & MACH_UNKNOWN) { case MACH_SUN: case MACH_IRIS: case MACH_HP: case MACH_IBM: case MACH_DEC: case MACH_ALPHA: case MACH_CONVEX: case MACH_WIN32: case MACH_LINUX: case MACH_IEEE: case MACH_BSIEEE: case MACH_UNKNOWN: if (1 != rdlongs (bf, 1, &rec_size) || bf->rec_size != rec_size) return (0); break; case MACH_CRAY: break; case MACH_DOS16: case MACH_DOS32: rec_size = (long) getc (bf->fp); if (rec_size > 128L) rec_size = 128L; if (bf->rec_size != rec_size) return (0); break; default: return (0); } bf->rec_size = 0L; bf->rec_read = 0L; return (1); } /*---------- skip_space --------------------------------------------- * skip over white space and commas *-------------------------------------------------------------------*/ static int skip_space (BINARYIO *bf) { int c; while (EOF != (c = getc (bf->fp))) { if (!isspace (c) && ',' != c) return (EOF == ungetc (c, bf->fp)); if ('\n' == c) { bf->rec_num++; bf->rec_read = 0L; } else bf->rec_read++; } return (EOF); } /*---------- read_double -------------------------------------------- * reads a floating point number from ASCII stream *-------------------------------------------------------------------*/ static int read_double (BINARYIO *bf, double *dval) { int c, n = 0, point = 0; char str[128]; *dval = 0.0; if (skip_space (bf)) return (-1); /* get to first digit */ if (EOF == (c = getc (bf->fp))) return (EOF); if ('-' == c || '+' == c) { str[n++] = c; bf->rec_read++; if (EOF == (c = getc (bf->fp))) return (EOF); } if ('.' == c) { str[n++] = c; bf->rec_read++; point = 1; if (EOF == (c = getc (bf->fp))) return (EOF); } /* next character needs to be a digit */ if (!isdigit (c)) return (EOF == ungetc (c, bf->fp)); /* get the number */ do { str[n++] = c; bf->rec_read++; if (EOF == (c = getc (bf->fp))) return (EOF); if (point && '.' == c) { str[n] = 0; *dval = atof (str); return (EOF == ungetc (c, bf->fp)); } } while (isdigit (c) || '.' == c); /* check for an exponent */ if (NULL != strchr ("DEde", c)) { str[n++] = 'e'; bf->rec_read++; if (EOF == (c = getc (bf->fp))) return (EOF); if ('-' == c || '+' == c) { str[n++] = c; bf->rec_read++; if (EOF == (c = getc (bf->fp))) return (EOF); } if (isdigit (c)) { do { str[n++] = c; bf->rec_read++; if (EOF == (c = getc (bf->fp))) return (EOF); } while (isdigit (c)); } } /* convert number */ str[n] = 0; *dval = atof (str); return (EOF == ungetc (c, bf->fp)); } /*=================================================================== * C binary reads *===================================================================*/ /*---------- rdshorts ----------------------------------------------- * read 16-bit integers from a file with data conversions *-------------------------------------------------------------------*/ static int rdshorts (BINARYIO *bf, int count, short *data) { int n; if (ARCH_LOCAL == bf->arch && sizeof(short) == bf->short_size) n = (int)fread (data, sizeof(short), count, bf->fp); else { unsigned char buf[8]; for (n = 0; n < count; n++, data++) { if (1 != fread (buf, bf->short_size, 1, bf->fp)) break; *data = ieee2short ((*bf->fromshort) (buf)); } } return (n); } /*---------- rdints ------------------------------------------------- * read integers from a file with data conversions *-------------------------------------------------------------------*/ static int rdints (BINARYIO *bf, int count, int *data) { int n; if (ARCH_LOCAL == bf->arch && sizeof(int) == bf->int_size) n = (int)fread (data, sizeof(int), count, bf->fp); else { unsigned char buf[8]; for (n = 0; n < count; n++, data++) { if (1 != fread (buf, bf->int_size, 1, bf->fp)) break; *data = ieee2int ((*bf->fromint) (buf)); } } return (n); } /*---------- rdINTS ------------------------------------------------- * read Fortran INTEGER*4 integers from a file with data conversions *-------------------------------------------------------------------*/ static int rdINTS (BINARYIO *bf, int count, int *data) { int n; #if ARCH_LOCAL == ARCH_DOS unsigned char buf[4]; for (n = 0; n < count; n++, data++) { if (1 != fread (buf, 4, 1, bf->fp)) break; *data = ieee2int ((*bf->fromint) (buf)); } #else n = rdints (bf, count, data); #endif return (n); } /*---------- rdlongs ------------------------------------------------ * read 32-bit integers from a file with data conversions *-------------------------------------------------------------------*/ static int rdlongs (BINARYIO *bf, int count, long *data) { int n; if (ARCH_LOCAL == bf->arch && sizeof(long) == bf->long_size) n = (int)fread (data, sizeof(long), count, bf->fp); else { unsigned char buf[8]; for (n = 0; n < count; n++, data++) { if (1 != fread (buf, bf->long_size, 1, bf->fp)) break; *data = ieee2long ((*bf->fromlong) (buf)); } } return (n); } /*---------- rdLONGS ------------------------------------------------ * read Fortran INTEGER*8 integers from a file with data conversions *-------------------------------------------------------------------*/ static int rdLONGS (BINARYIO *bf, int count, long *data) { int n; unsigned char buf[8]; for (n = 0; n < count; n++, data++) { if (1 != fread (buf, 8, 1, bf->fp)) break; if (ARCH_BSIEEE == bf->arch) *data = ieee2long ((*bf->fromlong) (buf)); else *data = ieee2long ((*bf->fromlong) (&buf[4])); } return (n); } /*---------- rdfloats ----------------------------------------------- * read 32-bit floats from a file with data conversions *-------------------------------------------------------------------*/ static int rdfloats (BINARYIO *bf, int count, float *data) { int n; if (ARCH_LOCAL == bf->arch && sizeof(float) == bf->float_size) n = (int)fread (data, sizeof(float), count, bf->fp); else { unsigned char buf[8]; for (n = 0; n < count; n++, data++) { if (1 != fread (buf, bf->float_size, 1, bf->fp)) break; *data = ieee2float ((*bf->fromfloat) (buf)); } } return (n); } /*---------- rddoubles ---------------------------------------------- * read 64-bit floats from a file with data conversions *-------------------------------------------------------------------*/ static int rddoubles (BINARYIO *bf, int count, double *data) { int n; if (ARCH_LOCAL == bf->arch && sizeof(double) == bf->double_size) n = (int)fread (data, sizeof(double), count, bf->fp); else { unsigned char buf[8]; for (n = 0; n < count; n++, data++) { if (1 != fread (buf, bf->double_size, 1, bf->fp)) break; *data = ieee2double ((*bf->fromdouble) (buf)); } } return (n); } /*=================================================================== * C binary writes *===================================================================*/ /*---------- wrtshorts ---------------------------------------------- * write 16-bit integers to a file with data conversions *-------------------------------------------------------------------*/ static int wrtshorts (BINARYIO *bf, int count, short *data) { int n; if (ARCH_LOCAL == bf->arch && sizeof(short) == bf->short_size) n = (int)fwrite (data, sizeof(short), count, bf->fp); else { unsigned char *buf; for (n = 0; n < count; n++, data++) { buf = (*bf->toshort) (short2ieee (data)); if (1 != fwrite (buf, bf->short_size, 1, bf->fp)) break; } } return (n); } /*---------- wrtints ------------------------------------------------ * write integers to a file with data conversions *-------------------------------------------------------------------*/ static int wrtints (BINARYIO *bf, int count, int *data) { int n; if (ARCH_LOCAL == bf->arch && sizeof(int) == bf->int_size) n = (int)fwrite (data, sizeof(int), count, bf->fp); else { unsigned char *buf; for (n = 0; n < count; n++, data++) { buf = (*bf->toint) (int2ieee (data)); if (1 != fwrite (buf, bf->int_size, 1, bf->fp)) break; } } return (n); } /*---------- wrtlongs ----------------------------------------------- * write 32-bit integers to a file with data conversions *-------------------------------------------------------------------*/ static int wrtlongs (BINARYIO *bf, int count, long *data) { int n; if (ARCH_LOCAL == bf->arch && sizeof(long) == bf->long_size) n = (int)fwrite (data, sizeof(long), count, bf->fp); else { unsigned char *buf; for (n = 0; n < count; n++, data++) { buf = (*bf->tolong) (long2ieee (data)); if (1 != fwrite (buf, bf->long_size, 1, bf->fp)) break; } } return (n); } /*---------- wrtfloats ---------------------------------------------- * write 32-bit floats to a file with data conversions *-------------------------------------------------------------------*/ static int wrtfloats (BINARYIO *bf, int count, float *data) { int n; if (ARCH_LOCAL == bf->arch && sizeof(float) == bf->float_size) n = (int)fwrite (data, sizeof(float), count, bf->fp); else { unsigned char *buf; for (n = 0; n < count; n++, data++) { buf = (*bf->tofloat) (float2ieee (data)); if (1 != fwrite (buf, bf->float_size, 1, bf->fp)) break; } } return (n); } /*---------- wrtdoubles --------------------------------------------- * write 64-bit floats to a file with data conversions *-------------------------------------------------------------------*/ static int wrtdoubles (BINARYIO *bf, int count, double *data) { int n; if (ARCH_LOCAL == bf->arch && sizeof(double) == bf->double_size) n = (int)fwrite (data, sizeof(double), count, bf->fp); else { unsigned char *buf; for (n = 0; n < count; n++, data++) { buf = (*bf->todouble) (double2ieee (data)); if (1 != fwrite (buf, bf->double_size, 1, bf->fp)) break; } } return (n); } /*=================================================================== * file manipulation *===================================================================*/ /*---------- bf_new ------------------------------------------------- * create the BINARYIO structure and set flags *-------------------------------------------------------------------*/ BINARYIO *bf_new (FILE *fp, int flags) { BINARYIO *bf; if (NULL == (bf = (BINARYIO *) malloc (sizeof(BINARYIO)))) return (NULL); if (!set_flags (bf, flags)) { free (bf); return (NULL); } bf->fp = fp; bf->did_open = 0; #if defined(MSDOS) || defined(__MSDOS__) || defined(_WIN32) if (OPEN_ASCII != (bf->flags & OPEN_ASCII)) setmode (fileno (bf->fp), O_BINARY); #endif return (bf); } /*---------- bf_open ------------------------------------------------ * open binary file *-------------------------------------------------------------------*/ BINARYIO *bf_open (char *fname, int flags) { BINARYIO *bf; if (NULL == fname || !*fname || NULL == (bf = (BINARYIO *) malloc (sizeof(BINARYIO)))) return (NULL); if (!set_flags (bf, flags)) { free (bf); return (NULL); } #if defined(MSDOS) || defined(__MSDOS__) || defined(_WIN32) if (OPEN_ASCII == (bf->flags & OPEN_ASCII)) bf->fp = fopen (fname, bf->flags & OPEN_WRITE ? "w+" : "r"); else bf->fp = fopen (fname, bf->flags & OPEN_WRITE ? "w+b" : "rb"); #else bf->fp = fopen (fname, bf->flags & OPEN_WRITE ? "w+" : "r"); #endif if (NULL == bf->fp) { free (bf); return (NULL); } bf->did_open = 1; return (bf); } /*---------- bf_close ----------------------------------------------- * close the file *-------------------------------------------------------------------*/ void bf_close (BINARYIO *bf) { if (bf->did_open) fclose (bf->fp); free (bf); } /*---------- bf_rewind ---------------------------------------------- * rewind the file *-------------------------------------------------------------------*/ void bf_rewind (BINARYIO *bf) { rewind (bf->fp); bf->rec_num = 0L; bf->rec_size = 0L; bf->rec_read = 0L; } /*---------- bf_tell ------------------------------------------------ * get current file offset *-------------------------------------------------------------------*/ long bf_tell (BINARYIO *bf) { long offset = ftell (bf->fp); if (0L < offset && OPEN_FORTRAN == (bf->flags & (OPEN_FORTRAN|OPEN_ASCII))) { int mach = bf->flags & MACH_UNKNOWN; /* Microsoft FORTRAN */ if (MACH_DOS16 == mach || MACH_DOS32 == mach) { offset -= (bf->rec_num << 1) + 1L; if (bf->rec_size) offset--; } /* Cray FORTRAN */ else if (MACH_CRAY == mach) offset -= (bf->rec_num << 3); /* most everybody else */ else { offset -= (bf->rec_num << 2); if (bf->rec_size) offset -= 4L; } } return (offset); } /*---------- bf_seek ------------------------------------------------ * set position in file *-------------------------------------------------------------------*/ int bf_seek (BINARYIO *bf, long offset) { long cur_off = 0L; if (0L > offset) return (-1); if (0L == offset) { bf_rewind (bf); return (0); } if (OPEN_ASCII == (bf->flags & OPEN_ASCII)) { int c; bf_rewind (bf); while (EOF != (c = getc (bf->fp))) { if ('\n' == c) { bf->rec_num++; bf->rec_read = 0L; } else bf->rec_read++; if (++cur_off == offset) return (0); } return (-1); } if (OPEN_FORTRAN == (bf->flags & OPEN_FORTRAN)) { bf_rewind (bf); while (1) { if (!beg_record (bf)) return (-1); if (offset < cur_off + bf->rec_size) break; if (fseek (bf->fp, bf->rec_size, 1)) return (-1); cur_off += bf->rec_size; if (!end_record (bf)) return (-1); } offset -= cur_off; bf->rec_read = offset; return (fseek (bf->fp, offset, 1)); } return (fseek (bf->fp, offset, 0)); } /*---------- bf_unget ------------------------------------------------ * unget last byte *--------------------------------------------------------------------*/ int bf_unget (BINARYIO *bf, int c) { if (EOF == ungetc (c, bf->fp)) return (0); if (bf->rec_read) bf->rec_read--; return (1); } /*---------- bf_nextrec ---------------------------------------------- * seek to start of next record *--------------------------------------------------------------------*/ int bf_nextrec (BINARYIO *bf) { int cnt = 0; if (OPEN_ASCII == (bf->flags & OPEN_ASCII)) { int c; while (EOF != (c = getc (bf->fp))) { cnt++; if ('\n' == c) { bf->rec_num++; bf->rec_read = 0L; return (cnt); } } return (0); } if (OPEN_FORTRAN == (bf->flags & OPEN_FORTRAN)) { if (0L == bf->rec_size) beg_record (bf); cnt = bf->rec_size - bf->rec_read; if (bf->rec_read < bf->rec_size) fseek (bf->fp, bf->rec_size - bf->rec_read, 1); end_record (bf); beg_record (bf); } return (cnt); } /*---------- bf_reclen ----------------------------------------------- * return the current record len *--------------------------------------------------------------------*/ int bf_reclen (BINARYIO *bf) { if (OPEN_ASCII == (bf->flags & OPEN_ASCII)) { int c; long len = bf->rec_read; while (EOF != (c = getc (bf->fp))) { len++; if ('\n' == c) break; } fseek (bf->fp, bf->rec_read - len, 1); return ('\n' == c ? (int)(len - 1L) : (int)len); } if (OPEN_FORTRAN == (bf->flags & OPEN_FORTRAN)) { if (0L == bf->rec_size) beg_record (bf); return ((int)bf->rec_size); } return (0); } /*---------- bf_skipspace -------------------------------------------- * skips white space and commas for ASCII file *--------------------------------------------------------------------*/ int bf_skipspace (BINARYIO *bf) { if (OPEN_ASCII == (bf->flags & OPEN_ASCII)) return (skip_space (bf)); return (0); } /*===================================================================== * information *=====================================================================*/ /*---------- bf_machname ---------------------------------------------- * return machine name for given type *---------------------------------------------------------------------*/ static char *machnames[] = { "unknown", "Sun", "Iris", "HP", "IBM", "DEC", "Alpha", "Cray", "Convex", "DOS16", "DOS32", "Win32", "Linux", "generic BSIEEE", "generic IEEE" }; #define NUM_MACH (sizeof(machnames)/sizeof(char *)) char *bf_machname (int mach) { if (MACH_DEFAULT == mach) mach = MACH_LOCAL; if (mach < 0 || mach > NUM_MACH) mach = 0; return (machnames[mach]); } /*---------- bf_archname --------------------------------------------- * return the architecture name *--------------------------------------------------------------------*/ static char *arch_name[] = { "32-bit IEEE", "32-bit byteswapped IEEE", "64-bit Cray", "32-bit native Convex", "64-bit DEC Alpha", "16-bit DOS", }; char *bf_archname (int mach) { int arch; if (MACH_DEFAULT == mach) mach = MACH_LOCAL; switch (mach) { case MACH_SUN: case MACH_IRIS: case MACH_HP: case MACH_IBM: case MACH_IEEE: case MACH_UNKNOWN: default: arch = 0; break; case MACH_DOS32: case MACH_DEC: case MACH_WIN32: case MACH_LINUX: case MACH_BSIEEE: arch = 1; break; case MACH_CRAY: arch = 2; break; case MACH_CONVEX: arch = 3; break; case MACH_ALPHA: arch = 4; break; case MACH_DOS16: arch = 5; break; } return (arch_name[arch]); } /*=================================================================== * reads *===================================================================*/ /*---------- bf_getbytes -------------------------------------------- * read bytes from a file *-------------------------------------------------------------------*/ int bf_getbytes (BINARYIO *bf, int count, unsigned char *data) { int n = 0; static char *fname = "bf_getbytes"; if (OPEN_WRITE == (bf->flags & OPEN_WRITE)) return (fatal_error (fname, BIOERR_WRITE)); /* ASCII read */ if (OPEN_ASCII == (bf->flags & OPEN_ASCII)) { n = (int)fread (data, 1, count, bf->fp); for (count = 0; count < n; count++, data++) { if ('\n' == *data) { bf->rec_num++; bf->rec_read = 0L; } else bf->rec_read++; } } /* Fortran binary read */ else if (OPEN_FORTRAN == (bf->flags & OPEN_FORTRAN)) { int nread; while (n < count) { if (0L == bf->rec_size) { if (!beg_record (bf)) return (n); continue; } if (bf->rec_read == bf->rec_size) { if (!end_record (bf)) return (fatal_error (fname, BIOERR_NOEOR)); continue; } nread = (int)(bf->rec_size - bf->rec_read); if (nread > count - n) nread = count - n; if (nread != fread (data, 1, nread, bf->fp)) return (n + nread); bf->rec_read += (long)nread; data += nread; n += nread; } } /* C binary read */ else n = (int)fread (data, 1, count, bf->fp); return (n); } /*---------- bf_getstring ------------------------------------------- * read bytes from a file up to len or end of record *-------------------------------------------------------------------*/ int bf_getstring (BINARYIO *bf, int count, char *data) { int n = 0; static char *fname = "bf_getstring"; if (OPEN_WRITE == (bf->flags & OPEN_WRITE)) return (fatal_error (fname, BIOERR_WRITE)); /* ASCII read */ if (OPEN_ASCII == (bf->flags & OPEN_ASCII)) { int c; #ifdef STRING_SKIP_SPACE if (skip_space (bf)) return (n); #endif for (n = 0; n < count; n++) { if (EOF == (c = getc (bf->fp))) return (EOF); if ('\n' == c) { bf->rec_num++; bf->rec_read = 0; return (n); } bf->rec_read++; *data++ = c; } } /* Fortran binary read */ else if (OPEN_FORTRAN == (bf->flags & OPEN_FORTRAN)) { if (0L == bf->rec_size) { if (!beg_record (bf)) return (EOF); } if (bf->rec_read == bf->rec_size) { if (!end_record (bf)) return (fatal_error (fname, BIOERR_NOEOR)); if (!beg_record (bf)) return (EOF); } n = (int)(bf->rec_size - bf->rec_read); if (n > count) n = count; n = (int)fread (data, 1, n, bf->fp); bf->rec_read += (long)n; } /* C binary read */ else { int c; for (n = 0; n < count; n++) { if (EOF == (c = getc (bf->fp))) return (EOF); if ('\0' == c) return (n); *data++ = c; } } return (n); } /*---------- bf_getshorts ------------------------------------------- * read 16-bit integers from a file *-------------------------------------------------------------------*/ int bf_getshorts (BINARYIO *bf, int count, short *data) { int n = 0, cnt; static char *fname = "bf_getshorts"; if (OPEN_WRITE == (bf->flags & OPEN_WRITE)) return (fatal_error (fname, BIOERR_WRITE)); /* ASCII read */ if (OPEN_ASCII == (bf->flags & OPEN_ASCII)) { for (n = 0; n < count; n++, data++) { if (skip_space(bf) || 1 != fscanf (bf->fp, "%hd%n", data, &cnt)) break; bf->rec_read += (long)cnt; } } /* Fortran binary read of INTEGER*2 */ else if (OPEN_FORTRAN == (bf->flags & OPEN_FORTRAN)) { int nread, shift = (ARCH_CRAY == bf->arch ? 3 : 1); long nleft; while (n < count) { if (0L == bf->rec_size) { if (!beg_record (bf)) return (n); continue; } if (bf->rec_read == bf->rec_size) { if (!end_record (bf)) return (fatal_error (fname, BIOERR_NOEOR)); continue; } nleft = bf->rec_size - bf->rec_read; nread = (int)(nleft >> shift); if (nread >= count - n) { nread = count - n; nleft = (long)nread << shift; } else if (nleft != ((long)nread << shift)) return (fatal_error (fname, BIOERR_BADEOR)); if (nread != rdshorts (bf, nread, data)) return (n + nread); bf->rec_read += nleft; data += nread; n += nread; } } /* C binary read */ else n = rdshorts (bf, count, data); return (n); } /*---------- bf_getints --------------------------------------------- * read integers from a file *-------------------------------------------------------------------*/ int bf_getints (BINARYIO *bf, int count, int *data) { int n = 0, cnt; static char *fname = "bf_getints"; if (OPEN_WRITE == (bf->flags & OPEN_WRITE)) return (fatal_error (fname, BIOERR_WRITE)); /* ASCII read */ if (OPEN_ASCII == (bf->flags & OPEN_ASCII)) { for (n = 0; n < count; n++, data++) { if (skip_space(bf) || 1 != fscanf (bf->fp, "%d%n", data, &cnt)) break; bf->rec_read += (long)cnt; } } /* Fortran binary read of INTEGER*4 */ else if (OPEN_FORTRAN == (bf->flags & OPEN_FORTRAN)) { int nread, shift = (ARCH_CRAY == bf->arch ? 3 : 2); long nleft; while (n < count) { if (0L == bf->rec_size) { if (!beg_record (bf)) return (n); continue; } if (bf->rec_read == bf->rec_size) { if (!end_record (bf)) return (fatal_error (fname, BIOERR_NOEOR)); continue; } nleft = bf->rec_size - bf->rec_read; nread = (int)(nleft >> shift); if (nread >= count - n) { nread = count - n; nleft = (long)nread << shift; } else if (nleft != ((long)nread << shift)) return (fatal_error (fname, BIOERR_BADEOR)); if (nread != rdINTS (bf, nread, data)) return (n + nread); bf->rec_read += nleft; data += nread; n += nread; } } /* C binary read */ else n = rdints (bf, count, data); return (n); } /*---------- bf_getlongs -------------------------------------------- * read 32/64-bit integers from a file *-------------------------------------------------------------------*/ int bf_getlongs (BINARYIO *bf, int count, long *data) { int n = 0, cnt; static char *fname = "bf_getlongs"; if (OPEN_WRITE == (bf->flags & OPEN_WRITE)) return (fatal_error (fname, BIOERR_WRITE)); /* ASCII read */ if (OPEN_ASCII == (bf->flags & OPEN_ASCII)) { for (n = 0; n < count; n++, data++) { if (skip_space(bf) || 1 != fscanf (bf->fp, "%ld%n", data, &cnt)) break; bf->rec_read += (long)cnt; } } /* Fortran binary read of INTEGER*8 */ else if (OPEN_FORTRAN == (bf->flags & OPEN_FORTRAN)) { int nread; long nleft; while (n < count) { if (0L == bf->rec_size) { if (!beg_record (bf)) return (n); continue; } if (bf->rec_read == bf->rec_size) { if (!end_record (bf)) return (fatal_error (fname, BIOERR_NOEOR)); continue; } nleft = bf->rec_size - bf->rec_read; nread = (int)(nleft >> 3); if (nread >= count - n) { nread = count - n; nleft = (long)nread << 3; } else if (nleft != ((long)nread << 3)) return (fatal_error (fname, BIOERR_BADEOR)); if (nread != rdLONGS (bf, nread, data)) return (n + nread); bf->rec_read += nleft; data += nread; n += nread; } } /* C binary read */ else n = rdlongs (bf, count, data); return (n); } /*---------- bf_getfloats ------------------------------------------- * read 32-bit floats from a file *-------------------------------------------------------------------*/ int bf_getfloats (BINARYIO *bf, int count, float *data) { int n = 0; double dval; static char *fname = "bf_getfloats"; if (OPEN_WRITE == (bf->flags & OPEN_WRITE)) return (fatal_error (fname, BIOERR_WRITE)); /* ASCII read */ if (OPEN_ASCII == (bf->flags & OPEN_ASCII)) { for (n = 0; n < count; n++) { if (read_double (bf, &dval)) break; *data++ = (float)dval; } } /* Fortran binary read of REAL*4 */ else if (OPEN_FORTRAN == (bf->flags & OPEN_FORTRAN)) { int nread, shift = (ARCH_CRAY == bf->arch ? 3 : 2); long nleft; while (n < count) { if (0L == bf->rec_size) { if (!beg_record (bf)) return (n); continue; } if (bf->rec_read == bf->rec_size) { if (!end_record (bf)) return (fatal_error (fname, BIOERR_NOEOR)); continue; } nleft = bf->rec_size - bf->rec_read; nread = (int)(nleft >> shift); if (nread >= count - n) { nread = count - n; nleft = (long)nread << shift; } else if (nleft != ((long)nread << shift)) return (fatal_error (fname, BIOERR_BADEOR)); if (nread != rdfloats (bf, nread, data)) return (n + nread); bf->rec_read += nleft; data += nread; n += nread; } } /* C binary read */ else n = rdfloats (bf, count, data); return (n); } /*---------- bf_getdoubles ------------------------------------------ * read 64-bit floats from a file *-------------------------------------------------------------------*/ int bf_getdoubles (BINARYIO *bf, int count, double *data) { int n = 0; static char *fname = "bf_getdoubles"; if (OPEN_WRITE == (bf->flags & OPEN_WRITE)) return (fatal_error (fname, BIOERR_WRITE)); /* ASCII read */ if (OPEN_ASCII == (bf->flags & OPEN_ASCII)) { for (n = 0; n < count; n++, data++) { if (read_double (bf, data)) break; } } /* Fortran binary read of REAL*8 */ else if (OPEN_FORTRAN == (bf->flags & OPEN_FORTRAN)) { int nread; long nleft; while (n < count) { if (0L == bf->rec_size) { if (!beg_record (bf)) return (n); continue; } if (bf->rec_read == bf->rec_size) { if (!end_record (bf)) return (fatal_error (fname, BIOERR_NOEOR)); continue; } nleft = bf->rec_size - bf->rec_read; nread = (int)(nleft >> 3); if (nread >= count - n) { nread = count - n; nleft = (long)nread << 3; } else if (nleft != ((long)nread << 3)) return (fatal_error (fname, BIOERR_BADEOR)); if (nread != rddoubles (bf, nread, data)) return (n + nread); bf->rec_read += nleft; data += nread; n += nread; } } /* C binary read */ else n = rddoubles (bf, count, data); return (n); } /*=================================================================== * writes *===================================================================*/ /*---------- bf_putbytes -------------------------------------------- * write bytes to a file *-------------------------------------------------------------------*/ int bf_putbytes (BINARYIO *bf, int count, unsigned char *data) { if (OPEN_WRITE != (bf->flags & OPEN_WRITE)) return (fatal_error ("bf_putbytes", BIOERR_READ)); return ((int)fwrite (data, 1, count, bf->fp)); } /*---------- bf_putshorts ------------------------------------------- * write 16-bit integers to a file *-------------------------------------------------------------------*/ int bf_putshorts (BINARYIO *bf, int count, short *data) { if (OPEN_WRITE != (bf->flags & OPEN_WRITE)) return (fatal_error ("bf_putshorts", BIOERR_READ)); if (OPEN_ASCII == (bf->flags & OPEN_ASCII)) { int n; for (n = 0; n < count; n++, data++) { if (-1 == fprintf (bf->fp, " %hd", *data)) break; } putc ('\n', bf->fp); return (n); } return (wrtshorts (bf, count, data)); } /*---------- bf_putints --------------------------------------------- * write integers to a file *-------------------------------------------------------------------*/ int bf_putints (BINARYIO *bf, int count, int *data) { if (OPEN_WRITE != (bf->flags & OPEN_WRITE)) return (fatal_error ("bf_putints", BIOERR_READ)); if (OPEN_ASCII == (bf->flags & OPEN_ASCII)) { int n; for (n = 0; n < count; n++, data++) { if (-1 == fprintf (bf->fp, " %d", *data)) break; } putc ('\n', bf->fp); return (n); } return (wrtints (bf, count, data)); } /*---------- bf_putlongs -------------------------------------------- * write 32-bit integers to a file *-------------------------------------------------------------------*/ int bf_putlongs (BINARYIO *bf, int count, long *data) { if (OPEN_WRITE != (bf->flags & OPEN_WRITE)) return (fatal_error ("bf_putlongs", BIOERR_READ)); if (OPEN_ASCII == (bf->flags & OPEN_ASCII)) { int n; for (n = 0; n < count; n++, data++) { if (-1 == fprintf (bf->fp, " %ld", *data)) break; } putc ('\n', bf->fp); return (n); } return (wrtlongs (bf, count, data)); } /*---------- bf_putfloats ------------------------------------------- * write 32-bit floats to a file *-------------------------------------------------------------------*/ int bf_putfloats (BINARYIO *bf, int count, float *data) { if (OPEN_WRITE != (bf->flags & OPEN_WRITE)) return (fatal_error ("bf_putfloats", BIOERR_READ)); if (OPEN_ASCII == (bf->flags & OPEN_ASCII)) { int n; for (n = 0; n < count; n++, data++) { if (-1 == fprintf (bf->fp, " %#g", *data)) break; } putc ('\n', bf->fp); return (n); } return (wrtfloats (bf, count, data)); } /*---------- bf_putdoubles ------------------------------------------ * write 64-bit floats to a file *-------------------------------------------------------------------*/ int bf_putdoubles (BINARYIO *bf, int count, double *data) { if (OPEN_WRITE != (bf->flags & OPEN_WRITE)) return (fatal_error ("bf_putdoubles", BIOERR_READ)); if (OPEN_ASCII == (bf->flags & OPEN_ASCII)) { int n; for (n = 0; n < count; n++, data++) { if (-1 == fprintf (bf->fp, " %#lg", *data)) break; } putc ('\n', bf->fp); return (n); } return (wrtdoubles (bf, count, data)); } /*=================================================================== * data conversion to and from 32-bit IEEE * * byte ordering used is MSB first * byte structure of floating point data types * * short - 2 bytes * int - 4 bytes * long - 4 bytes * * float - 4 bytes exp bias = 127 * 1 8 23 * double - 8 bytes exp bias = 1023 * 1 11 52 * * both floats and doubles are normalized to a value between 1 and 2, thus * the high order bit of the mantissa is always 1, and is not stored. *===================================================================*/ /*------------------------------------------------------------------- * IEEE to IEEE, just do copy *-------------------------------------------------------------------*/ static unsigned char *copy2 (unsigned char *bytes) { static unsigned char val[2]; if (bytes != val) memcpy (val, bytes, 2); return (val); } static unsigned char *copy4 (unsigned char *bytes) { static unsigned char val[4]; if (bytes != val) memcpy (val, bytes, 4); return (val); } static unsigned char *copy8 (unsigned char *bytes) { static unsigned char val[8]; if (bytes != val) memcpy (val, bytes, 8); return (val); } /*------------------------------------------------------------------- * byte-swapped IEEE *-------------------------------------------------------------------*/ static void swapbytes (unsigned char *bytes, int nbytes) { int i = 0, j = nbytes - 1; unsigned char tmp; while (i < j) { tmp = bytes[i]; bytes[i++] = bytes[j]; bytes[j--] = tmp; } } static unsigned char *swap2 (unsigned char *bytes) { static unsigned char val[2]; if (bytes == val) swapbytes (val, 2); else { val[1] = *bytes++; val[0] = *bytes; } return (val); } static unsigned char *swap4 (unsigned char *bytes) { static unsigned char val[4]; if (bytes == val) swapbytes (val, 4); else { int n; for (n = 3; n >= 0; n--) val[n] = *bytes++; } return (val); } static unsigned char *swap8 (unsigned char *bytes) { static unsigned char val[8]; if (bytes == val) swapbytes (val, 8); else { int n; for (n = 7; n >= 0; n--) val[n] = *bytes++; } return (val); } /*----------------------------------------------------------------------- * conversions for 16-bit DOS - ints are 2 bytes *-----------------------------------------------------------------------*/ static unsigned char *swap2to4 (unsigned char *bytes) { static unsigned char val[4]; if (bytes == val) swapbytes (val, 4); else { val[3] = *bytes++; val[2] = *bytes; if (0 == (*bytes & 0x80)) val[1] = val[0] = 0; else val[1] = val[0] = 0xFF; } return (val); } static unsigned char *swap4to2 (unsigned char *bytes) { static unsigned char val[2]; if (bytes == val) swapbytes (val, 2); else { bytes += 2; val[1] = *bytes++; val[0] = *bytes; } return (val); } /*----------------------------------------------------------------------- * conversions for DEC Alpha - longs are 8 bytes *-----------------------------------------------------------------------*/ static unsigned char *swap4to8 (unsigned char *bytes) { static unsigned char val[8]; if (bytes == val) swapbytes (val, 8); else { int n; for (n = 3; n >= 0; n--) val[n] = *bytes++; if (0 == (val[3] & 0x80)) { for (n = 4; n < 8 ; n++) val[n] = 0; } else { for (n = 4; n < 8 ; n++) val[n] = 0xFF; } } return (val); } static unsigned char *swap8to4 (unsigned char *bytes) { static unsigned char val[4]; if (bytes == val) swapbytes (val, 4); else { int n; for (n = 3; n >= 0; n--) val[n] = *bytes++; } return (val); } /*----------------------------------------------------------------------- * data conversions for Cray * * all data types on the Cray, except for char, are 64 bit quantities * * floating point values are stored as: * * * 1 15 1 47 *-----------------------------------------------------------------------*/ /*----- IEEE short -> Cray short -----*/ static unsigned char *short_cray (unsigned char *bytes) { static unsigned char val[8]; memset (val, *bytes & 0x80 ? 0xFF : 0, 8); memcpy (&val[6], bytes, 2); return (val); } /*----- IEEE long -> Cray long -----*/ static unsigned char *long_cray (unsigned char *bytes) { static unsigned char val[8]; memset (val, *bytes & 0x80 ? 0xFF : 0, 8); memcpy (&val[4], bytes, 4); return (val); } /*----- IEEE float -> Cray float -----*/ static unsigned char *float_cray (unsigned char *bytes) { unsigned exp; static unsigned char val[8]; memset (val, 0, 8); exp = ((unsigned)(bytes[0] & 0x7F) << 1) | ((unsigned)(bytes[1] & 0x80) >> 7); if (exp) { exp += 0x3F82; val[0] = (bytes[0] & 0x80) | ((exp >> 8) & 0x7F); val[1] = exp & 0xFF; val[2] = (bytes[1] & 0x7F) | 0x80; memcpy (&val[3], &bytes[2], 2); } return (val); } /*----- IEEE double -> Cray double -----*/ static unsigned char *double_cray (unsigned char *bytes) { unsigned exp; static unsigned char val[8]; memset (val, 0, 8); exp = ((unsigned)(bytes[0] & 0x7F) << 4) | ((unsigned)(bytes[1] & 0xF0) >> 4); if (exp) { int n; exp += 0x3C02; val[0] = (bytes[0] & 0x80) | ((exp >> 8) & 0x7F); val[1] = exp & 0xFF; val[2] = ((bytes[1] & 0x0F) << 3) | ((bytes[2] & 0xE0) >> 5) | 0x80; for (n = 3; n < 8; n++) val[n] = ((bytes[n-1] & 0x1F) << 3) | ((bytes[n] & 0xE0) >> 5); } return (val); } /*----- Cray short -> IEEE short -----*/ static unsigned char *cray_short (unsigned char *bytes) { static unsigned char val[2]; memcpy (val, bytes + 6, 2); return (val); } /*----- Cray long -> IEEE long -----*/ static unsigned char *cray_long (unsigned char *bytes) { static unsigned char val[4]; memcpy (val, bytes + 4, 4); return (val); } /*----- Cray float -> IEEE float -----*/ static unsigned char *cray_float (unsigned char *bytes) { unsigned exp; static unsigned char val[4]; exp = ((unsigned)(bytes[0] & 0x7F) << 8) | (unsigned)bytes[1]; if (exp < 0x3F82 || exp > 0x4081) memset (val, exp < 0x3F82 ? 0 : 0xFF, 4); else { exp -= 0x3F82; val[0] = (bytes[0] & 0x80) | ((exp & 0xFF) >> 1); val[1] = (bytes[2] & 0x7F) | ((exp & 0x01) << 7); memcpy (&val[2], &bytes[3], 2); } return (val); } /*----- Cray double -> IEEE double -----*/ static unsigned char *cray_double (unsigned char *bytes) { unsigned exp; static unsigned char val[8]; exp = ((unsigned)(bytes[0] & 0x7F) << 8) | (unsigned)bytes[1]; if (exp < 0x3C02 || exp > 0x4401) memset (val, exp < 0x3C02 ? 0 : 0xFF, 8); else { int n; exp -= 0x3C02; val[0] = (bytes[0] & 0x80) | ((exp >> 4) & 0x7F); val[1] = ((bytes[2] & 0x78) >> 3) | ((exp & 0x0F) << 4); for (n = 2; n < 7; n++) val[n] = ((bytes[n] & 0x07) << 5) | ((bytes[n+1] & 0xF8) >> 3); val[7] = (bytes[7] & 0x07) << 5; } return (val); } /*------------------------------------------------------------------------ * floating point data conversions for Convex * * native Convex floating point representation is basically * IEEE with an exponent bias of 129 instead of 127 *------------------------------------------------------------------------*/ /*----- IEEE float -> Convex float -----*/ static unsigned char *float_convex (unsigned char *bytes) { unsigned exp; static unsigned char val[4]; exp = ((unsigned)(bytes[0] & 0x7F) << 8) | (bytes[1] & 0x80); if (exp == 0) memset (val, 0, 4); else if (exp < 0x7E80) { exp += 0x0100; val[0] = (bytes[0] & 0x80) | (exp >> 8); val[1] = (bytes[1] & 0x7F) | (exp & 0x80); memcpy (&val[2], &bytes[2], 2); } else { val[0] = (bytes[0] & 0x80) | 0x7F; val[1] = 0x80; memset (&val[2], 0, 2); } return (val); } /*----- IEEE double -> Convex double -----*/ static unsigned char *double_convex (unsigned char *bytes) { unsigned exp; static unsigned char val[8]; exp = ((unsigned)(bytes[0] & 0x7F) << 8) | (bytes[1] & 0xF0); if (exp == 0) memset (val, 0, 8); else if (exp < 0x7FD0) { exp += 0x0020; val[0] = (bytes[0] & 0x80) | (exp >> 8); val[1] = (bytes[1] & 0x0F) | (exp & 0xF0); memcpy (&val[2], &bytes[2], 6); } else { val[0] = (bytes[0] & 0x80) | 0x7F; val[1] = 0xF0; memset (&val[2], 0, 6); } return (val); } /*----- Convex float -> IEEE float -----*/ static unsigned char *convex_float (unsigned char *bytes) { unsigned exp; static unsigned char val[4]; exp = ((unsigned)(bytes[0] & 0x7F) << 8) | (bytes[1] & 0x80); if (exp < 0x0100) memset (val, 0, 4); else if (exp < 0x7F80) { exp -= 0x0100; val[0] = (bytes[0] & 0x80) | (exp >> 8); val[1] = (bytes[1] & 0x7F) | (exp & 0x80); memcpy (&val[2], &bytes[2], 2); } else { val[0] = (bytes[0] & 0x80) | 0x7F; val[1] = 0x80; memset (&val[2], 0, 2); } return (val); } /*----- Convex double -> IEEE double -----*/ static unsigned char *convex_double (unsigned char *bytes) { unsigned exp; static unsigned char val[8]; exp = ((unsigned)(bytes[0] & 0x7F) << 8) | (bytes[1] & 0xF0); if (exp < 0x0200) memset (val, 0, 8); else if (exp < 0x7FF0) { exp -= 0x0020; val[0] = (bytes[0] & 0x80) | (exp >> 8); val[1] = (bytes[1] & 0x0F) | (exp & 0xF0); memcpy (&val[2], &bytes[2], 6); } else { val[0] = (bytes[0] & 0x80) | 0x7F; val[1] = 0xF0; memset (&val[2], 0, 6); } return (val); } cgnslib_3.1.4/src/cgnstools/utilities/plot3d.tcl0000664000076400007640000002413312160605674016715 00000000000000# plot3d.tcl - PLOT3D import/export array set Plot3d { mode "" cgns "" xyz "" q "" basenum "" basename "" solnum "" basenum,flag 1 solnum,flag 1 block "" format "" iblank "" type u mach "" ignore "" double "" base "" convert "" weight "" gamma 1.4 } proc plot3d_import {w name exe} { global ProgData Plot3d Import set cmd [get_executable $exe 1] if {$cmd == ""} return set Plot3d(mode) import set Plot3d(cgns) $ProgData(file,name) if ![plot3d_panel $w] return update idletasks set opts $Plot3d(block)$Plot3d(format)$Plot3d(type) if {$Plot3d(ignore) != ""} { append opts $Plot3d(ignore) } else { append opts $Plot3d(iblank) } append opts $Plot3d(double)$Plot3d(convert) if {$Plot3d(mach) != ""} { append opts M$Plot3d(mach) } if {$opts != ""} { lappend cmd -$opts } if {$Plot3d(basenum) != ""} { lappend cmd -b$Plot3d(basenum) } if {$Plot3d(basename) != ""} { lappend cmd -B$Plot3d(basename) } if {$Plot3d(gamma) != ""} { lappend cmd -g$Plot3d(gamma) } lappend cmd $Plot3d(xyz) if {$Plot3d(q) != ""} { lappend cmd $Plot3d(q) } lappend cmd $Plot3d(cgns) import_run "PLOT3D Import" $cmd $Plot3d(cgns) } proc plot3d_export {w name exe} { global ProgData Plot3d set cmd [get_executable $exe 1] if {$cmd == ""} return set Plot3d(mode) export set Plot3d(cgns) $ProgData(file,name) set Plot3d(xyz) [file rootname $ProgData(file,name)].xyz set Plot3d(q) [file rootname $ProgData(file,name)].q if ![plot3d_panel $w] return update idletasks set opts $Plot3d(block)$Plot3d(format)$Plot3d(type) append opts $Plot3d(ignore)$Plot3d(double)$Plot3d(weight) if {$opts != ""} { lappend cmd -$opts } if {$Plot3d(basenum) != ""} { lappend cmd -b$Plot3d(basenum) } if {$Plot3d(solnum) != ""} { lappend cmd -S$Plot3d(solnum) } if {$Plot3d(gamma) != ""} { lappend cmd -g$Plot3d(gamma) } lappend cmd $Plot3d(cgns) $Plot3d(xyz) if {$Plot3d(q) != ""} { lappend cmd $Plot3d(q) } update run_command "PLOT3D Export" $cmd } proc plot3d_panel {w} { global ProgData Font Plot3d toplevel $w wm title $w "Plot3d $Plot3d(mode)" wm transient $w . wm protocol $w WM_DELETE_WINDOW {set Plot3d(done) 0} FrameCreate $w.file -text "Files" -font $Font(bold) pack $w.file -side top -pady 2 -fill x set file [FrameGet $w.file] foreach i {cgns xyz q} { set f [frame $file.$i] pack $f -side top -fill x label $f.lab -text [string toupper $i] -width 6 -anchor w pack $f.lab -side left entry $f.ent -textvariable Plot3d($i) -width 30 pack $f.ent -side left -fill x -expand 1 button $f.but -text Browse -pady 0 -command "plot3d_browse_$i $w" pack $f.but -side right -fill y } FrameCreate $w.base -text "CGNS Location" -font $Font(bold) pack $w.base -side top -pady 2 -fill x set base [FrameGet $w.base] set labw 12 set f [frame $base.num] pack $f -side top -anchor w label $f.lab -text "Base Index" -width $labw -anchor w entry $f.ent -textvariable Plot3d(basenum) -width 10 checkbutton $f.but -text default \ -variable Plot3d(basenum,flag) -onvalue 1 -offvalue 0 \ -command "plot3d_state basenum $f.ent" pack $f.lab $f.ent $f.but -side left plot3d_state basenum $f.ent set f [frame $base.name] if {$Plot3d(mode) == "import"} { pack $f -side top -anchor w } label $f.lab -text "Base Name" -width $labw -anchor w entry $f.ent -textvariable Plot3d(basename) -width 30 pack $f.lab $f.ent -side left set f [frame $base.sol] if {$Plot3d(mode) == "export"} { pack $f -side top -anchor w } label $f.lab -text "Solution Index" -width $labw -anchor w entry $f.ent -textvariable Plot3d(solnum) -width 10 checkbutton $f.but -text default \ -variable Plot3d(solnum,flag) -onvalue 1 -offvalue 0 \ -command "plot3d_state solnum $f.ent" pack $f.lab $f.ent $f.but -side left plot3d_state solnum $f.ent FrameCreate $w.format -text "Plot3d File Format" -font $Font(bold) pack $w.format -side top -pady 2 -fill x set fmt [FrameGet $w.format] set f [frame $fmt.block] pack $f -side left -expand 1 radiobutton $f.m -text "Multi-Block" \ -variable Plot3d(block) -value "" radiobutton $f.s -text "Single-Block" \ -variable Plot3d(block) -value s pack $f.m $f.s -side top -anchor w set f [frame $fmt.format] pack $f -side left -expand 1 radiobutton $f.w -text "Whole Format" \ -variable Plot3d(format) -value "" radiobutton $f.p -text "Planar Format" \ -variable Plot3d(format) -value p pack $f.w $f.p -side top -anchor w set f [frame $fmt.iblank] if {$Plot3d(mode) == "import"} { pack $f -side left -expand 1 } radiobutton $f.n -text "No iblank" \ -variable Plot3d(iblank) -value "" radiobutton $f.y -text "Has iblank" \ -variable Plot3d(iblank) -value i pack $f.n $f.y -side top -anchor w FrameCreate $w.type -text "Plot3d File Type" -font $Font(bold) pack $w.type -side top -pady 2 -fill x set type [FrameGet $w.type] radiobutton $type.b -text binary \ -variable Plot3d(type) -value "" radiobutton $type.u -text unformatted \ -variable Plot3d(type) -value u radiobutton $type.f -text formatted \ -variable Plot3d(type) -value f checkbutton $type.d -text "64-bit" \ -variable Plot3d(double) -onvalue d -offvalue "" pack $type.b $type.u $type.f $type.d -side left -expand 1 FrameCreate $w.mach -text "Plot3d Machine Type" -font $Font(bold) if {$Plot3d(mode) == "import"} { pack $w.mach -side top -pady 2 -fill x } set mach [FrameGet $w.mach] set n 1 foreach type {\ {default IEEE BSIEEE} \ {Iris Sun HP} \ {Alpha DEC IBM} \ {Cray Convex NT}} { set f [frame $mach.f$n] pack $f -side left -expand 1 foreach i $type { set j [string tolower $i] radiobutton $f.$j -text $i \ -variable Plot3d(mach) -value $j if {$i == "default"} { $f.$j configure -value "" } pack $f.$j -side top -anchor w } incr n } FrameCreate $w.opts -text "Options" -font $Font(bold) pack $w.opts -side top -pady 2 -fill x set opts [FrameGet $w.opts] set f [frame $opts.f1] pack $f -side left -expand 1 if {$Plot3d(mode) == "import"} { checkbutton $f.i -text "Don't use iblank" \ -variable Plot3d(ignore) -onvalue n -offvalue "" checkbutton $f.c -text "Write primitive variables" \ -variable Plot3d(convert) -onvalue c -offvalue "" } else { checkbutton $f.i -text "Don't write iblank" \ -variable Plot3d(ignore) -onvalue n -offvalue "" checkbutton $f.c -text "Use volume weighting" \ -variable Plot3d(weight) -onvalue w -offvalue "" } pack $f.i $f.c -side top -anchor w set f [frame $opts.gamma] pack $f -side left -expand 1 label $f.lab -text gamma entry $f.ent -textvariable Plot3d(gamma) -width 10 pack $f.lab $f.ent -side left set f [frame $w.but] pack $f -side top -pady 5 button $f.accept -text Accept -width 6 -default active \ -command "plot3d_check $w" button $f.cancel -text Cancel -width 6 -command {set Plot3d(done) 0} pack $f.accept $f.cancel -side left -padx 5 bind $w "plot3d_check $w" center_window $w . set oldFocus [focus] set oldGrab [grab current $w] if {$oldGrab != ""} { set grabStatus [grab status $oldGrab] } catch {grab $w} tkwait visibility $w focus $w tkwait variable Plot3d(done) catch {focus $oldFocus} destroy $w if {$oldGrab != ""} { if {$grabStatus == "global"} { grab -global $oldGrab } else { grab $oldGrab } } return $Plot3d(done) } proc plot3d_state {what ent {def 1}} { global Plot3d if {$Plot3d($what,flag)} { set Plot3d($what) "" $ent configure -state disabled -cursor {} } else { if {$Plot3d($what) == ""} { set Plot3d($what) $def } $ent configure -state normal -cursor xterm } } proc plot3d_check {w} { global Plot3d if {[string trim $Plot3d(cgns)] == "" || [string trim $Plot3d(xyz)] == ""} { errormsg "must specify a CGNS and a Plot3d XYZ file" $w return } if {$Plot3d(mode) == "import"} { if {![file exists $Plot3d(xyz)]} { errormsg "Plot3d XYZ file doesn't exist" $w return } if {$Plot3d(q) != "" && ![file exists $Plot3d(q)]} { errormsg "Plot3d Q file doesn't exist" $w return } } else { if {![file exists $Plot3d(cgns)]} { errormsg "CGNS file doesn't exist" $w return } } if {$Plot3d(gamma) != ""} { if {[catch {expr $Plot3d(gamma) <= 1.0} nogood] || $nogood} { errormsg "invalid value for gamma" $w return } } set Plot3d(done) 1 } proc plot3d_browse_cgns {w} { global Plot3d tcl_platform if {$Plot3d(mode) == "import"} { set fname [FileSave "CGNS Output File" $Plot3d(cgns) $w \ {{{CGNS Files} {.cgns .cgn .adf}} {{All Files} {*}}} cgns] } else { set fname [FileOpen "CGNS Input File" $Plot3d(cgns) $w \ {{{CGNS Files} {.cgns .cgn .adf}} {{All Files} {*}}}] } if {$fname != ""} { if {$tcl_platform(platform) == "windows"} { set Plot3d(cgns) [join [split $fname /] \\] } else { set Plot3d(cgns) $fname } } } proc plot3d_browse_xyz {w} { global Plot3d tcl_platform if {$Plot3d(mode) == "import"} { set fname [FileOpen "Plot3d XYZ Input File" $Plot3d(xyz) $w \ {{{Plot3d Files} {.bin .dat .fmt .xyz}} {{All Files} {*}}}] } else { set fname [FileSave "Plot3d XYZ Output File" $Plot3d(xyz) $w \ {{{Plot3d Files} {.bin .dat .fmt .xyz}} {{All Files} {*}}}] } if {$fname != ""} { if {$tcl_platform(platform) == "windows"} { set Plot3d(xyz) [join [split $fname /] \\] } else { set Plot3d(xyz) $fname } } } proc plot3d_browse_q {w} { global Plot3d tcl_platform if {$Plot3d(mode) == "import"} { set fname [FileOpen "Plot3d Q Input File" $Plot3d(q) $w \ {{{Plot3d Files} {.bin .dat .fmt .q}} {{All Files} {*}}}] } else { set fname [FileSave "Plot3d Q Output File" $Plot3d(q) $w \ {{{Plot3d Files} {.bin .dat .fmt .q}} {{All Files} {*}}}] } if {$fname != ""} { if {$tcl_platform(platform) == "windows"} { set Plot3d(q) [join [split $fname /] \\] } else { set Plot3d(q) $fname } } } cgnslib_3.1.4/src/cgnstools/utilities/p3dfint.f0000664000076400007640000000406412160605674016523 00000000000000 subroutine openf (iread,fname) integer iread character *(*) fname if (iread .eq. 0) then open (2,file=fname,form='unformatted',status='new') else open (2,file=fname,form='unformatted',status='old') endif end c subroutine closef close (2) end c subroutine readif (icnt,idata,ierr) integer icnt,idata(*) read (2,end=10) (idata(i),i=1,icnt) ierr = 0 return 10 ierr = 1 end c subroutine readff (icnt,rdata,ierr) integer icnt real*4 rdata(*) read (2,end=10) (rdata(i),i=1,icnt) ierr = 0 return 10 ierr = 1 end c subroutine readdf (icnt,rdata,ierr) integer icnt real*8 rdata(*) read (2,end=10) (rdata(i),i=1,icnt) ierr = 0 return 10 ierr = 1 end c subroutine readgff (icnt,rdata,idata,ierr) integer icnt,idata(*),ierr real*4 rdata(*) read (2,end=10) (rdata(i),i=1,3*icnt),(idata(i),i=1,icnt) ierr = 0 return 10 ierr = 1 end c subroutine readgdf (icnt,rdata,idata,ierr) integer icnt,idata(*),ierr real*8 rdata(*) read (2,end=10) (rdata(i),i=1,3*icnt),(idata(i),i=1,icnt) ierr = 0 return 10 ierr = 1 end c subroutine writeif (icnt,idata,ierr) integer icnt,idata(*) write (2) (idata(i),i=1,icnt) ierr = 0 end c subroutine writeff (icnt,rdata,ierr) integer icnt real*4 rdata(*) write (2) (rdata(i),i=1,icnt) ierr = 0 end c subroutine writedf (icnt,rdata,ierr) integer icnt real*8 rdata(*) write (2) (rdata(i),i=1,icnt) ierr = 0 end c subroutine writegff (icnt,rdata,idata,ierr) integer icnt,idata(*),ierr real*4 rdata(*) write (2) (rdata(i),i=1,3*icnt),(idata(i),i=1,icnt) ierr = 0 end c subroutine writegdf (icnt,rdata,idata,ierr) integer icnt,idata(*),ierr real*8 rdata(*) write (2) (rdata(i),i=1,3*icnt),(idata(i),i=1,icnt) ierr = 0 end cgnslib_3.1.4/src/cgnstools/utilities/vtk.tcl0000775000076400007640000000511112160605674016312 00000000000000# VTK.tcl - VTK import/export array set Export { vtkdir "" elemset 0 } proc vtk_outdir {w} { global Export set dir [GetDirectory "VTK Output Directory" $Export(vtkdir) $w] if {$dir != ""} { set Export(vtkdir) $dir } } proc vtk_export {w name exe} { global ProgData Font Export set cmd [get_executable $exe 1] if {$cmd == ""} return toplevel $w wm title $w "VTK Export" wm transient $w . wm protocol $w WM_DELETE_WINDOW {set Export(done) 0} export_input $w 1 1 1 FrameCreate $w.output -text "VTK Output Directory" -font $Font(bold) pack $w.output -side top -padx 5 -pady 2 -fill x set f [FrameGet $w.output] label $f.lab -text Directory -anchor w pack $f.lab -side left entry $f.ent -textvariable Export(vtkdir) -width 30 pack $f.ent -side left -fill x -expand 1 button $f.but -text Browse -pady 0 -command "vtk_outdir $w" pack $f.but -side right -fill y FrameCreate $w.opts -text "Options" -font $Font(bold) pack $w.opts -side top -pady 2 -fill x set opts [FrameGet $w.opts] checkbutton $opts.fmt -text "ASCII VTK Output" \ -variable Export(ascii) -onvalue 1 -offvalue 0 \ -command tecplot_extension pack $opts.fmt -side top -anchor w checkbutton $opts.sol -text "Write Element Sets" \ -variable Export(elemset) -onvalue 1 -offvalue 0 pack $opts.sol -side top -anchor w set Export(cgnsfile) $ProgData(file,name) set dir $ProgData(file,dir) if {$dir == "" || $dir == "."} { set dir [pwd] } set prefix [file rootname $ProgData(file,name)] set Export(vtkdir) "${prefix}_vtk" if {[export_buttons $w vtk_export_check]} { update idletasks if {$Export(basenum) != ""} { lappend cmd -b$Export(basenum) } if {$Export(zonenum) != ""} { lappend cmd -z$Export(basenum) } if {$Export(solution)} { if {$Export(solnum) != ""} { lappend cmd -s$Export(solnum) } } else { lappend cmd -s0 } if {$Export(elemset)} { lappend cmd -e } lappend cmd $Export(cgnsfile) if {$Export(vtkdir) != ""} { lappend cmd $Export(vtkdir) } update run_command "VTK Export" $cmd } } proc vtk_export_check {w} { global Export if {[string trim $Export(cgnsfile)] == ""} { errormsg "must specify a CGNS file" $w return } if {![file exists $Export(cgnsfile)]} { errormsg "CGNS input file doesn't exist" $w return } set dir [string trim $Export(vtkdir)] if {$dir != "" && [file exists $dir] && ![file isdirectory $dir]} { errormsg "Output directory $dir exists and is not a directory" $w return } set Export(done) 1 } cgnslib_3.1.4/src/cgnstools/utilities/convert_dataclass.c0000664000076400007640000003206112160605674020646 00000000000000/* * convert_dataclass.c - convert between dimensional/nondimensional variables */ #include #include #include #include #include #ifdef _WIN32 # include # define access _access # define unlink _unlink #else # include #endif #include "getargs.h" #include "cgnslib.h" #include "cgnsutil.h" #include "calc.h" /* command line options */ static char options[] = "b:z:s:f:dnuhv"; static char *usgmsg[] = { "usage : convert_dataclass [options] CGNSfile [newCGNSfile]", "options:", " -b = use CGNS base number (default 1)", " -z = read zone number (default all)", " -s = read solution number (default all)", " -f = read conversion expressions from ", " -d = convert to Dimensional (default)", " -n = convert to NormalizedByDimensional", " -u = convert to NormalizedByUnknownDimensional", " -v = verbose (show expression parsing errors)", NULL }; static int verbose = 0; static CGNS_ENUMT(DataClass_t) dataclass = CGNS_ENUMV(DataClassNull); static char buff[1024]; static char cgnstemp[17] = ""; static int unconverted = 0; static int expressions = 0; static int conversions = 0; /*-------------------------------------------------------------------*/ static void get_error (int errnum, char *errmsg, int pos, char *str) { /* fatal error */ if (errnum < 0) { if (cgnsFile) cg_close (cgnsFile); if (*cgnstemp) unlink (cgnstemp); fprintf (stderr, "%s\n", errmsg); exit (-1); } /* parsing error */ if (verbose) { printf ("ERROR:"); if (NULL != str) { printf ("%s\n ", str); while (pos-- > 0) putchar ('-'); putchar ('^'); } printf ("%s\n", errmsg); } } /*-------------------------------------------------------------------*/ static void write_units (Units *units) { int n; for (n = 0; n < 5; n++) { if (units->units[n]) { if (cg_units_write ( (CGNS_ENUMT(MassUnits_t))units->units[0], (CGNS_ENUMT(LengthUnits_t))units->units[1], (CGNS_ENUMT(TimeUnits_t))units->units[2], (CGNS_ENUMT(TemperatureUnits_t))units->units[3], (CGNS_ENUMT(AngleUnits_t))units->units[4])) cgnsCalcFatal ((char *)cg_get_error()); break; } } #ifdef NofValidWallFunctionTypes if (n == 5) cg_delete_node ("DimensionalUnits"); #endif for (n = 0; n < 5; n++) { if (units->exps[n]) { if (cg_exponents_write (CGNS_ENUMV(RealSingle), units->exps)) cgnsCalcFatal ((char *)cg_get_error()); break; } } #ifdef NofValidWallFunctionTypes if (n == 5) cg_delete_node ("DimensionalExponents"); #endif } /*-------------------------------------------------------------------*/ static void update_zone (void) { int n, i, len; Variable *var = coordinates; VECSYM *sym; VECFLOAT *vf; float *f = NULL; Units *units; printf (" coordinates...\n"); for (n = 0; n < NumCoordinates; n++, var++) { len = var->len; printf (" %s -> ", var->name); if (var->dataclass == dataclass) { puts ("OK"); continue; } if ((sym = find_symbol (var->name, 0)) != NULL) { expressions++; printf ("expression\n"); fflush (stdout); if (vecsym_type(sym) != VECSYM_VECTOR || vecsym_veclen(sym) != len) cgnsCalcFatal ("result is not a vector of the right length"); vf = vecsym_vector(sym); units = vecsym_user(sym); } else if (var->hasconv) { conversions++; printf ("conversion\n"); fflush (stdout); sym = cgnsCalcCommand (var->name); vf = vecsym_vector(sym); if (dataclass == CGNS_ENUMV(Dimensional)) { for (i = 0; i < len; i++) vf[i] = vf[i] * var->dataconv[0] + var->dataconv[1]; } else { for (i = 0; i < len; i++) vf[i] = (vf[i] - var->dataconv[1]) / var->dataconv[0]; } units = NULL; } else { unconverted++; puts ("???"); continue; } if (var->datatype == CGNS_ENUMV(RealSingle)) { if (f == NULL) { f = (float *) malloc (len * sizeof(float)); if (f == NULL) cgnsCalcFatal ("malloc failed for coordinate data"); } for (i = 0; i < len; i++) f[i] = (float)vf[i]; if (cg_coord_write (cgnsFile, cgnsBase, cgnsZone, CGNS_ENUMV(RealSingle), var->name, f, &i)) cgnsCalcFatal ((char *)cg_get_error()); } else { if (cg_coord_write (cgnsFile, cgnsBase, cgnsZone, CGNS_ENUMV(RealDouble), var->name, vf, &i)) cgnsCalcFatal ((char *)cg_get_error()); } if (cg_goto (cgnsFile, cgnsBase, "Zone_t", cgnsZone, "GridCoordinates_t", 1, "DataArray_t", n+1, "end") || cg_dataclass_write (dataclass)) cgnsCalcFatal ((char *)cg_get_error()); if (units != NULL) write_units (units); } if (f != NULL) free (f); } /*-------------------------------------------------------------------*/ static void update_solution (void) { int n, i, len; Variable *var = variables; VECSYM *sym; VECFLOAT *vf; float *f = NULL; Units *units; printf (" solution %d - %s...\n", cgnsSoln, SolnName); for (n = 0; n < NumVariables; n++, var++) { len = var->len; printf (" %s -> ", var->name); if (var->dataclass == dataclass) { puts ("OK"); continue; } if ((sym = find_symbol (var->name, 0)) != NULL) { expressions++; printf ("expression\n"); fflush (stdout); if (vecsym_type(sym) != VECSYM_VECTOR || vecsym_veclen(sym) != len) cgnsCalcFatal ("result is not a vector of the right length"); vf = vecsym_vector(sym); units = vecsym_user(sym); } else if (var->hasconv) { conversions++; printf ("conversion\n"); fflush (stdout); sym = cgnsCalcCommand (var->name); vf = vecsym_vector(sym); if (dataclass == CGNS_ENUMV(Dimensional)) { for (i = 0; i < len; i++) vf[i] = vf[i] * var->dataconv[0] + var->dataconv[1]; } else { for (i = 0; i < len; i++) vf[i] = (vf[i] - var->dataconv[1]) / var->dataconv[0]; } units = NULL; } else { unconverted++; puts ("???"); continue; } if (var->datatype == CGNS_ENUMV(RealSingle)) { if (f == NULL) { f = (float *) malloc (len * sizeof(float)); if (f == NULL) cgnsCalcFatal ("malloc failed for coordinate data"); } for (i = 0; i < len; i++) f[i] = (float)vf[i]; if (cg_field_write (cgnsFile, cgnsBase, cgnsZone, cgnsSoln, CGNS_ENUMV(RealSingle), var->name, f, &i)) cgnsCalcFatal ((char *)cg_get_error()); } else { if (cg_field_write (cgnsFile, cgnsBase, cgnsZone, cgnsSoln, CGNS_ENUMV(RealDouble), var->name, vf, &i)) cgnsCalcFatal ((char *)cg_get_error()); } if (cg_goto (cgnsFile, cgnsBase, "Zone_t", cgnsZone, "FlowSolution_t", cgnsSoln, "DataArray_t", n+1, "end") || cg_dataclass_write (dataclass)) cgnsCalcFatal ((char *)cg_get_error()); if (units != NULL) write_units (units); } if (f != NULL) free (f); } /*-------------------------------------------------------------------*/ char *next_line (FILE *fp) { int n = 0, len; char *p, line[257]; while (fgets (line, sizeof(line), fp) != NULL) { line[sizeof(line)-1] = 0; p = line + strlen(line); while (--p >= line && isspace(*p)) ; *++p = 0; for (p = line; *p && isspace(*p); p++) ; if (!*p) continue; strcpy (buff, p); n = (int)strlen (buff); while (buff[n-1] == '\\') { for (n -= 2; n >= 0 && isspace(buff[n]); n--) ; buff[++n] = 0; if (fgets (line, sizeof(line), fp) == NULL) break; line[sizeof(line)-1] = 0; p = line + strlen(line); while (--p >= line && isspace(*p)) ; *++p = 0; for (p = line; *p && isspace(*p); p++) ; if (!*p) break; len = (int)strlen (p); if (n + len >= sizeof(buff)) cgnsCalcFatal ("internal command buffer length exceeded"); strcpy (&buff[n], p); n += len; } if ((p = strchr (buff, '#')) != NULL) *p = 0; for (p = buff+strlen(buff)-1; p >= buff && isspace(*p); p--) ; *++p = 0; for (p = buff; *p && isspace(*p); p++) ; if (*p) return (p); } return (NULL); } /*-------------------------------------------------------------------*/ static void parse_convfile (char *cnvfile) { char *cmd; FILE *fp = fopen (cnvfile, "r"); printf (" parsing conversion file...\n"); if (fp == NULL) { sprintf (buff, "couldn't open <%s> for reading", cnvfile); cgnsCalcFatal (buff); } cgnsCalcReset (); while ((cmd = next_line (fp)) != NULL) cgnsCalcCommand (cmd); fclose (fp); } /*-------------------------------------------------------------------*/ int main (int argc, char *argv[]) { int n, nz, ns, scnt; int ibase = 1, izone = 0, isol = 0; char *convfile = NULL, *tmpfile; if (argc < 2) print_usage (usgmsg, NULL); while ((n = getargs (argc, argv, options)) > 0) { switch (n) { case 'b': ibase = atoi (argarg); break; case 'z': izone = atoi (argarg); break; case 's': isol = atoi (argarg); break; case 'f': convfile = argarg; break; case 'd': dataclass = CGNS_ENUMV(Dimensional); break; case 'n': dataclass = CGNS_ENUMV(NormalizedByDimensional); break; case 'u': dataclass = CGNS_ENUMV(NormalizedByUnknownDimensional); break; case 'v': verbose = 1; break; } } if (dataclass == CGNS_ENUMV(DataClassNull)) print_usage (usgmsg, "need to select one of -d, -n or -u"); if (argind == argc) print_usage (usgmsg, "CGNSfile not given"); if (access (argv[argind], 0)) cgnsCalcFatal ("CGNSfile does not exist"); /* create a working copy */ printf ("creating a working copy of %s\n", argv[argind]); tmpfile = temporary_file (argv[argind]); copy_file (argv[argind], tmpfile); /* read CGNS file */ printf ("reading CGNS file from %s\n", tmpfile); cgnsCalcInit (tmpfile, 1, get_error); if (ibase != 1) cgnsCalcBase (ibase); printf ("reading base %d - %s\n", cgnsBase, BaseName); for (nz = 1; nz <= NumZones; nz++) { if (!izone || nz == izone) { scnt = 0; cgnsCalcZone (nz); printf ("\nupdating zone %d - %s\n", cgnsZone, ZoneName); for (ns = 1; ns <= NumSolns; ns++) { if (!isol || ns == isol) { cgnsCalcSoln (ns); if (convfile != NULL) parse_convfile (convfile); if (!scnt++) update_zone (); update_solution (); } } if (!scnt) { if (convfile != NULL) parse_convfile (convfile); update_zone (); } } } cgnsCalcDone (); if (expressions + conversions == 0) cgnsCalcFatal ("no variables were converted"); if (argind + 1 < argc) argind++; printf ("\nrenaming %s to %s\n", tmpfile, argv[argind]); unlink (argv[argind]); if (rename (tmpfile, argv[argind])) { char msg[512]; sprintf (msg, "rename %s -> %s failed", tmpfile, argv[argind]); cgnsCalcFatal (msg); exit (1); } free (tmpfile); printf ("%d variables converted using expressions\n", expressions); printf ("%d variables converted using conversion factors\n", conversions); printf ("%d variables were unchanged\n", unconverted); return 0; } cgnslib_3.1.4/src/cgnstools/utilities/cgns_to_plot3d.c0000664000076400007640000007210712160605674020075 00000000000000/* * cgns_to_plot3d.c - read CGNS file and write Plot3d file */ #include #include #include #ifdef _WIN32 # define unlink _unlink #else # include #endif #include "getargs.h" #include "cgnslib.h" #include "cgnsutil.h" #ifdef USE_FORTRAN #include "pd3fint.h" #else extern void OPENF (int *,char *,int); extern void CLOSEF (void); extern void WRITEIF (int *,int *,int *); extern void WRITEFF (int *,float *,int *); extern void WRITEDF (int *,double *,int *); extern void WRITEGFF(int *,float *,int *,int *); extern void WRITEGDF(int *,double *,int *,int *); #endif /* command line options */ static char options[] = "spnfudb:B:g:wS:"; static char *usgmsg[] = { "usage : cgns_to_plot3d [options] CGNSfile XYZfile [Qfile]", "options:", " -s = write Plot3d as single block", " -p = write Plot3d as planar format", " -n = don't write iblank array", " -f = write formatted (ASCII) Plot3d file", " -u = write Fortran unformatted Plot3d file", " -d = use double-precision (64-bit)", " -b = use CGNS base number (default 1)", " -B = use CGNS base named ", " -S = solution to use if multiple (default 1)", " -w = use volume weighting", " -g= gamma for data conversions (default 1.4)", "Default is multi-block binary format with iblank data.", NULL }; static int format = 'b'; static int mblock = 1; static int whole = 1; static int use_iblank = 1; static int weighting = 0; static int usesol = 1; static int use_double = 0; static double reference[4]; static double gamma = 1.4; static int nblocks = 0; static int *iblank; static double *q[5]; /*---------- compute_iblank ------------------------------------------- * fill in iblank values for a zone *---------------------------------------------------------------------*/ static void compute_iblank (int nz) { cgsize_t n, ni, i, j, k, nk, nj, nn; cgsize_t ns[3], ne[3]; ZONE *zone = &Zones[nz]; INTERFACE *ints = zone->ints; for (n = 0; n < zone->nverts; n++) iblank[n] = 1; nj = zone->dim[0]; nk = zone->dim[1] * nj; for (ni = 0; ni < zone->nints; ni++, ints++) { if (ints->d_zone) { for (n = 0; n < 3; n++) { if (ints->range[n][1] < ints->range[n][0]) { ns[n] = ints->range[n][1] - 1; ne[n] = ints->range[n][0] - 1; } else { ns[n] = ints->range[n][0] - 1; ne[n] = ints->range[n][1] - 1; } } for (k = ns[2]; k <= ne[2]; k++) { for (j = ns[1]; j <= ne[1]; j++) { nn = k * nk + j * nj + ns[0]; for (i = ns[0]; i <= ne[0]; i++) iblank[nn++] = -ints->d_zone; } } } } } /*---------- write_xyz_binary ----------------------------------------- * write binary Plot3d file *---------------------------------------------------------------------*/ static void write_xyz_binary (char *xyzfile) { int nz, i, dims[3]; int n, k, nk, np; VERTEX *verts; void *xyz; float *xyzf; double *xyzd; FILE *fp; printf ("\nwriting binary XYZ file to %s\n", xyzfile); printf (" in %s-precision", use_double ? "double" : "single"); if (use_iblank) printf (" with iblank array"); putchar ('\n'); for (np = 0, nz = 0; nz < nZones; nz++) { if (Zones[nz].type == CGNS_ENUMV(Structured)) { nk = whole ? (int)Zones[nz].nverts : (int)(Zones[nz].dim[0] * Zones[nz].dim[1]); if (np < nk) np = nk; } } if (use_double) { xyz = (void *) malloc (np * sizeof(double)); xyzd = (double *)xyz; } else { xyz = (void *) malloc (np * sizeof(float)); xyzf = (float *)xyz; } if (NULL == xyz) FATAL ("write_xyx_binary", "malloc failed for working arrays"); if (NULL == (fp = fopen (xyzfile, "w+b"))) { fprintf (stderr, "couldn't open <%s> for writing\n", xyzfile); exit (1); } if (mblock || nblocks > 1) fwrite (&nblocks, sizeof(int), 1, fp); for (nz = 0; nz < nZones; nz++) { if (Zones[nz].type == CGNS_ENUMV(Structured)) { for (i = 0; i < 3; i++) dims[i] = (int)Zones[nz].dim[i]; fwrite (dims, sizeof(int), 3, fp); } } for (nz = 0; nz < nZones; nz++) { if (Zones[nz].type == CGNS_ENUMV(Structured)) { printf (" zone %d - %d x %d x %d ... ", nz+1, (int)Zones[nz].dim[0], (int)Zones[nz].dim[1], (int)Zones[nz].dim[2]); fflush (stdout); if (use_iblank) compute_iblank (nz); if (whole) { np = (int)Zones[nz].nverts; nk = 1; } else { np = (int)(Zones[nz].dim[0] * Zones[nz].dim[1]); nk = (int)Zones[nz].dim[2]; } for (k = 0; k < nk; k++) { verts = &Zones[nz].verts[k*np]; if (use_double) { for (n = 0; n < np; n++) xyzd[n] = verts[n].x; fwrite (xyzd, sizeof(double), np, fp); for (n = 0; n < np; n++) xyzd[n] = verts[n].y; fwrite (xyzd, sizeof(double), np, fp); for (n = 0; n < np; n++) xyzd[n] = verts[n].z; fwrite (xyzd, sizeof(double), np, fp); } else { for (n = 0; n < np; n++) xyzf[n] = (float)verts[n].x; fwrite (xyzf, sizeof(float), np, fp); for (n = 0; n < np; n++) xyzf[n] = (float)verts[n].y; fwrite (xyzf, sizeof(float), np, fp); for (n = 0; n < np; n++) xyzf[n] = (float)verts[n].z; fwrite (xyzf, sizeof(float), np, fp); } if (use_iblank) fwrite (&iblank[k*np], sizeof(int), np, fp); } puts ("done"); } } fclose (fp); free (xyz); } /*---------- write_xyz_unformatted ------------------------------------ * write unformatted Plot3d file *---------------------------------------------------------------------*/ static void write_xyz_unformatted (char *xyzfile) { int n, i, ierr, *indices; int nz, k, nk, np; char buff[129]; VERTEX *verts; void *xyz; float *xyzf; double *xyzd; printf ("\nwriting unformatted XYZ file to %s\n", xyzfile); printf (" in %s-precision", use_double ? "double" : "single"); if (use_iblank) printf (" with iblank array"); putchar ('\n'); for (np = 0, nz = 0; nz < nZones; nz++) { if (Zones[nz].type == CGNS_ENUMV(Structured)) { nk = whole ? (int)Zones[nz].nverts : (int)(Zones[nz].dim[0] * Zones[nz].dim[1]); if (np < nk) np = nk; } } indices = (int *) malloc (3 * nblocks * sizeof(int)); if (use_double) { xyz = (void *) malloc (3 * np * sizeof(double)); xyzd = (double *)xyz; } else { xyz = (void *) malloc (3 * np * sizeof(float)); xyzf = (float *)xyz; } if (NULL == indices || NULL == xyz) FATAL ("write_xyx_unformatted", "malloc failed for working arrays"); unlink (xyzfile); strcpy (buff, xyzfile); for (n = (int)strlen(buff); n < 128; n++) buff[n] = ' '; buff[128] = 0; n = 0; OPENF (&n, buff, 128); if (mblock || nblocks > 1) { n = 1; WRITEIF (&n, &nblocks, &ierr); } for (n = 0, nz = 0; nz < nZones; nz++) { if (Zones[nz].type == CGNS_ENUMV(Structured)) { for (i = 0; i < 3; i++) indices[n++] = (int)Zones[nz].dim[i]; } } WRITEIF (&n, indices, &ierr); for (nz = 0; nz < nZones; nz++) { if (Zones[nz].type == CGNS_ENUMV(Structured)) { printf (" zone %d - %d x %d x %d ... ", nz+1, (int)Zones[nz].dim[0], (int)Zones[nz].dim[1], (int)Zones[nz].dim[2]); fflush (stdout); if (use_iblank) compute_iblank (nz); if (whole) { np = (int)Zones[nz].nverts; nk = 1; } else { np = (int)(Zones[nz].dim[0] * Zones[nz].dim[1]); nk = (int)Zones[nz].dim[2]; } for (k = 0; k < nk; k++) { verts = &Zones[nz].verts[k*np]; if (use_double) { for (i = 0, n = 0; n < np; n++) xyzd[i++] = verts[n].x; for (n = 0; n < np; n++) xyzd[i++] = verts[n].y; for (n = 0; n < np; n++) xyzd[i++] = verts[n].z; if (use_iblank) WRITEGDF (&np, xyzd, &iblank[k*np], &ierr); else WRITEDF (&i, xyzd, &ierr); } else { for (i = 0, n = 0; n < np; n++) xyzf[i++] = (float)verts[n].x; for (n = 0; n < np; n++) xyzf[i++] = (float)verts[n].y; for (n = 0; n < np; n++) xyzf[i++] = (float)verts[n].z; if (use_iblank) WRITEGFF (&np, xyzf, &iblank[k*np], &ierr); else WRITEFF (&i, xyzf, &ierr); } } puts ("done"); } } CLOSEF (); free (indices); free (xyz); } /*---------- write_xyz_formatted -------------------------------------- * write formatted Plot3d file *---------------------------------------------------------------------*/ static void write_xyz_formatted (char *xyzfile) { int n, k, nk, nz, np, *ib; VERTEX *verts; FILE *fp; printf ("\nwriting formatted XYZ file to %s\n", xyzfile); if (use_iblank) printf (" with iblank array\n"); if (NULL == (fp = fopen (xyzfile, "w+"))) { fprintf (stderr, "couldn't open <%s> for writing\n", xyzfile); exit (1); } if (mblock || nblocks > 1) fprintf (fp, "%d\n", nblocks); for (nz = 0; nz < nZones; nz++) { if (Zones[nz].type == CGNS_ENUMV(Structured)) fprintf (fp, "%d %d %d\n", (int)Zones[nz].dim[0], (int)Zones[nz].dim[1], (int)Zones[nz].dim[2]); } for (nz = 0; nz < nZones; nz++) { if (Zones[nz].type == CGNS_ENUMV(Structured)) { printf (" zone %d - %d x %d x %d ... ", nz+1, (int)Zones[nz].dim[0], (int)Zones[nz].dim[1], (int)Zones[nz].dim[2]); fflush (stdout); if (use_iblank) compute_iblank (nz); if (whole) { np = (int)Zones[nz].nverts; nk = 1; } else { np = (int)(Zones[nz].dim[0] * Zones[nz].dim[1]); nk = (int)Zones[nz].dim[2]; } for (k = 0; k < nk; k++) { verts = &Zones[nz].verts[k*np]; for (n = 0; n < np; n++) { if (n) putc ((n % 5) == 0 ? '\n' : ' ', fp); fprintf (fp, "%#g", verts[n].x); } putc ('\n', fp); for (n = 0; n < np; n++) { if (n) putc ((n % 5) == 0 ? '\n' : ' ', fp); fprintf (fp, "%#g", verts[n].y); } putc ('\n', fp); for (n = 0; n < np; n++) { if (n) putc ((n % 5) == 0 ? '\n' : ' ', fp); fprintf (fp, "%#g", verts[n].z); } putc ('\n', fp); if (use_iblank) { ib = &iblank[k*np]; for (n = 0; n < np; n++, ib++) { if (n && (n % 10) == 0) putc ('\n', fp); fprintf (fp, "%5d", *ib); } putc ('\n', fp); } } puts ("done"); } } fclose (fp); } /*---------- check_solution ------------------------------------------- * check zone for a complete solution *---------------------------------------------------------------------*/ static int check_solution (int nz) { int nf, flags = 0; SOLUTION *sol; if (!read_zone_solution (nz+1) || usesol > Zones[nz].nsols) return 0; sol = &Zones[nz].sols[usesol-1]; if (sol->nflds < 5 || (sol->location != CGNS_ENUMV(Vertex) && sol->location != CGNS_ENUMV(CellCenter))) return 0; for (nf = 0; nf < sol->nflds; nf++) { if (!strcmp (sol->flds[nf].name, "Density")) { flags |= 0x01; continue; } if (!strcmp (sol->flds[nf].name, "VelocityX") || !strcmp (sol->flds[nf].name, "MomentumX")) { flags |= 0x02; continue; } if (!strcmp (sol->flds[nf].name, "VelocityY") || !strcmp (sol->flds[nf].name, "MomentumY")) { flags |= 0x04; continue; } if (!strcmp (sol->flds[nf].name, "VelocityZ") || !strcmp (sol->flds[nf].name, "MomentumZ")) { flags |= 0x08; continue; } if (!strcmp (sol->flds[nf].name, "Pressure") || !strcmp (sol->flds[nf].name, "EnergyStagnationDensity")) { flags |= 0x10; continue; } } return (flags & 0x1f) == 0x1f ? 1 : 0; } /*---------- get_reference -------------------------------------------- * get the reference conditions *---------------------------------------------------------------------*/ static void get_reference (void) { int n, narrays, na, dim; cgsize_t vec[12]; CGNS_ENUMT(DataType_t) datatype; CGNS_ENUMT(AngleUnits_t) angle; int aloc = 0, units[5]; char name[33]; static char *refnames[4] = { "Mach", "AngleofAttack", "Reynolds", "TimeLatest" }; reference[0] = 0.5; /* Mach Number */ reference[1] = 0.0; /* angle of attack */ reference[2] = 1.0e6; /* Reynolds Number */ reference[3] = 0.0; /* time */ if (cg_goto (cgnsfn, cgnsbase, "ReferenceState_t", 1, "end") || cg_narrays (&narrays) || narrays < 1) return; for (na = 1; na <= narrays; na++) { if (cg_array_info (na, name, &datatype, &dim, vec)) FATAL ("get_reference", NULL); if (dim != 1 || vec[0] != 1) continue; for (n = 0; n < 4; n++) { if (!strcmp (refnames[n], name)) { if (cg_array_read_as (na, CGNS_ENUMV(RealDouble), &reference[n])) FATAL ("get_reference", NULL); if (n == 1) aloc = na; break; } } } /* angle of attack units */ if (aloc) { if (cg_goto (cgnsfn, cgnsbase, "ReferenceState_t", 1, "DataArray_t", aloc, "end")) FATAL ("get_reference", NULL); if (read_units (units)) angle = (CGNS_ENUMT(AngleUnits_t))units[4]; else angle = (CGNS_ENUMT(AngleUnits_t))baseunits[4]; if (angle == CGNS_ENUMV(Radian)) reference[1] *= 57.29578; } } /*---------- compute_solution ----------------------------------------- * compute solution for a zone *---------------------------------------------------------------------*/ static void compute_solution (int nz) { int n, nf, loc[5], con[5]; double vel2; SOLUTION *sol = &Zones[nz].sols[usesol-1]; for (n = 0; n < 5; n++) loc[n] = -1; for (nf = 0; nf < sol->nflds; nf++) { if (!strcmp (sol->flds[nf].name, "Density")) { loc[0] = nf; con[0] = 0; } else if (!strcmp (sol->flds[nf].name, "VelocityX")) { if (loc[1] >= 0) continue; loc[1] = nf; con[1] = 1; } else if (!strcmp (sol->flds[nf].name, "MomentumX")) { loc[1] = nf; con[1] = 0; } else if (!strcmp (sol->flds[nf].name, "VelocityY")) { if (loc[2] >= 0) continue; loc[2] = nf; con[2] = 1; } else if (!strcmp (sol->flds[nf].name, "MomentumY")) { loc[2] = nf; con[2] = 0; } else if (!strcmp (sol->flds[nf].name, "VelocityZ")) { if (loc[3] >= 0) continue; loc[3] = nf; con[3] = 1; } else if (!strcmp (sol->flds[nf].name, "MomentumZ")) { loc[3] = nf; con[3] = 0; } else if (!strcmp (sol->flds[nf].name, "Pressure")) { if (loc[4] >= 0) continue; loc[4] = nf; con[4] = 1; } else if (!strcmp (sol->flds[nf].name, "EnergyStagnationDensity")) { loc[4] = nf; con[4] = 0; } else continue; read_solution_field (nz+1, usesol, nf+1); } if (sol->location != CGNS_ENUMV(Vertex)) cell_vertex_solution (nz+1, usesol, weighting); for (nf = 0; nf < 5; nf++) { for (n = 0; n < sol->size; n++) q[nf][n] = sol->flds[loc[nf]].data[n]; } for (nf = 1; nf <= 3; nf++) { if (con[nf]) { for (n = 0; n < sol->size; n++) q[nf][n] *= q[0][n]; } } if (con[4]) { for (n = 0; n < sol->size; n++) { vel2 = 0.0; for (nf = 1; nf <= 3; nf++) vel2 += (q[nf][n] * q[nf][n]); q[4][n] = q[4][n] / (gamma - 1.0) + 0.5 * vel2 / q[0][n]; } } } /*---------- write_q_binary ------------------------------------------- * write binary Plot3d file *---------------------------------------------------------------------*/ static void write_q_binary (char *qfile) { int i, j, n, k, nk, nz, np, dim[3]; float qf[4]; FILE *fp; printf ("\nwriting binary Q file to %s\n", qfile); printf (" in %s-precision\n", use_double ? "double" : "single"); if (NULL == (fp = fopen (qfile, "w+b"))) { fprintf (stderr, "couldn't open <%s> for writing\n", qfile); exit (1); } if (mblock || nblocks > 1) fwrite (&nblocks, sizeof(int), 1, fp); for (nz = 0; nz < nZones; nz++) { if (Zones[nz].type == CGNS_ENUMV(Structured)) { for (i = 0; i < 3; i++) dim[i] = (int)Zones[nz].dim[i]; fwrite (dim, sizeof(int), 3, fp); } } for (nz = 0; nz < nZones; nz++) { if (Zones[nz].type == CGNS_ENUMV(Structured)) { printf (" zone %d ... ", nz+1); fflush (stdout); compute_solution (nz); if (whole) { np = (int)Zones[nz].nverts; nk = 1; } else { np = (int)(Zones[nz].dim[0] * Zones[nz].dim[1]); nk = (int)Zones[nz].dim[2]; } if (use_double) { fwrite (reference, sizeof(double), 4, fp); for (k = 0; k < nk; k++) { for (i = 0; i < 5; i++) fwrite (&q[i][k*np], sizeof(double), np, fp); } } else { for (n = 0; n < 4; n++) qf[n] = (float)reference[n]; fwrite (qf, sizeof(float), 4, fp); for (k = 0; k < nk; k++) { for (i = 0; i < 5; i++) { j = k * np; for (n = 0; n < np; n++, j++) { qf[0] = (float)q[i][j]; fwrite (qf, sizeof(float), 1, fp); } } } } puts ("done"); } } fclose (fp); } /*---------- write_q_unformatted -------------------------------------- * write unformatted Plot3d file *---------------------------------------------------------------------*/ static void write_q_unformatted (char *qfile) { int np, nk, nz, nq, ierr; int i, j, k, n, *indices; char buff[129]; void *qdata; float *qf = 0; double *qd = 0; printf ("\nwriting unformatted Q file to %s\n", qfile); printf (" in %s-precision\n", use_double ? "double" : "single"); for (np = 0, nz = 0; nz < nZones; nz++) { if (Zones[nz].type == CGNS_ENUMV(Structured)) { nk = whole ? (int)Zones[nz].nverts : (int)(Zones[nz].dim[0] * Zones[nz].dim[1]); if (np < nk) np = nk; } } indices = (int *) malloc (3 * nblocks * sizeof(int)); if (use_double) { qdata = (void *) malloc (5 * np * sizeof(double)); qd = (double *)qdata; } else { qdata = (void *) malloc (5 * np * sizeof(float)); qf = (float *)qdata; } if (NULL == indices || NULL == qdata) FATAL ("write_q_unformatted", "malloc failed for working arrays"); unlink (qfile); strcpy (buff, qfile); for (n = (int)strlen(buff); n < 128; n++) buff[n] = ' '; buff[128] = 0; n = 0; OPENF (&n, buff, 128); if (mblock || nblocks > 1) { n = 1; WRITEIF (&n, &nblocks, &ierr); } for (np = 0, nz = 0; nz < nZones; nz++) { if (Zones[nz].type == CGNS_ENUMV(Structured)) { for (n = 0; n < 3; n++) indices[np++] = (int)Zones[nz].dim[n]; } } WRITEIF (&np, indices, &ierr); for (nz = 0; nz < nZones; nz++) { if (Zones[nz].type == CGNS_ENUMV(Structured)) { printf (" zone %d ... ", nz+1); fflush (stdout); compute_solution (nz); if (whole) { np = (int)Zones[nz].nverts; nk = 1; } else { np = (int)(Zones[nz].dim[0] * Zones[nz].dim[1]); nk = (int)Zones[nz].dim[2]; } if (use_double) { n = 4; WRITEDF (&n, reference, &ierr); for (k = 0; k < nk; k++) { for (nq = 0, j = 0; j < 5; j++) { i = k * np; for (n = 0; n < np; n++, i++) qd[nq++] = q[j][i]; } WRITEDF (&nq, qd, &ierr); } } else { for (n = 0; n < 4; n++) qf[n] = (float)reference[n]; WRITEFF (&n, qf, &ierr); for (k = 0; k < nk; k++) { for (nq = 0, j = 0; j < 5; j++) { i = k * np; for (n = 0; n < np; n++, i++) qf[nq++] = (float)q[j][i]; } WRITEFF (&nq, qf, &ierr); } } puts ("done"); } } CLOSEF (); free (indices); free (qdata); } /*---------- write_q_formatted ---------------------------------------- * write formatted Plot3d file *---------------------------------------------------------------------*/ static void write_q_formatted (char *qfile) { int nz, i, j, n, k, nk, np; FILE *fp; printf ("\nwriting formatted Q file to %s\n", qfile); if (NULL == (fp = fopen (qfile, "w+"))) { fprintf (stderr, "couldn't open <%s> for writing\n", qfile); exit (1); } if (mblock || nblocks > 1) fprintf (fp, "%d\n", nblocks); for (nz = 0; nz < nZones; nz++) { if (Zones[nz].type == CGNS_ENUMV(Structured)) fprintf (fp, "%d %d %d\n", (int)Zones[nz].dim[0], (int)Zones[nz].dim[1], (int)Zones[nz].dim[2]); } for (nz = 0; nz < nZones; nz++) { if (Zones[nz].type == CGNS_ENUMV(Structured)) { printf (" zone %d ... ", nz+1); fflush (stdout); fprintf (fp, "%#g %#g %#g %#g\n", reference[0], reference[1], reference[2], reference[3]); compute_solution (nz); if (whole) { np = (int)Zones[nz].nverts; nk = 1; } else { np = (int)(Zones[nz].dim[0] * Zones[nz].dim[1]); nk = (int)Zones[nz].dim[2]; } for (k = 0; k < nk; k++) { i = k * np; for (j = 0; j < 5; j++) { for (n = 0; n < np; n++) { if (n) putc ((n % 5) == 0 ? '\n' : ' ', fp); fprintf (fp, "%#g", q[j][i+n]); } putc ('\n', fp); } } puts ("done"); } } fclose (fp); } /*========== main =====================================================*/ int main (int argc, char *argv[]) { int n, ib, nb, is, nz, celldim, phydim; cgsize_t imax; char basename[33]; if (argc < 2) print_usage (usgmsg, NULL); ib = 0; basename[0] = 0; while ((n = getargs (argc, argv, options)) > 0) { switch (n) { case 's': mblock = 0; break; case 'p': whole = 0; break; case 'n': use_iblank = 0; break; case 'f': case 'u': format = n; break; case 'd': use_double = 1; break; case 'b': ib = atoi (argarg); break; case 'B': strncpy (basename, argarg, 32); basename[32] = 0; break; case 'g': gamma = atof (argarg); if (gamma <= 1.0) FATAL (NULL, "invalid value for gamma"); break; case 'w': weighting = 1; break; case 'S': usesol = atoi (argarg); break; } } if (argind > argc - 2) print_usage (usgmsg, "CGNSfile and/or XYZfile not given"); if (!file_exists (argv[argind])) FATAL (NULL, "CGNSfile does not exist or is not a file"); /* open CGNS file */ printf ("reading CGNS file from %s\n", argv[argind]); nb = open_cgns (argv[argind], 1); if (!nb) FATAL (NULL, "no bases found in CGNS file"); if (*basename && 0 == (ib = find_base (basename))) FATAL (NULL, "specified base not found"); if (ib > nb) FATAL (NULL, "base index out of range"); cgnsbase = ib ? ib : 1; if (cg_base_read (cgnsfn, cgnsbase, basename, &celldim, &phydim)) FATAL (NULL, NULL); if (celldim != 3 || phydim != 3) FATAL (NULL, "cell and/or physical dimension must be 3"); printf (" using base %d - %s\n", cgnsbase, basename); read_zones (); for (nz = 0; nz < nZones; nz++) { if (Zones[nz].type == CGNS_ENUMV(Structured)) { /* verify we can write out using ints */ for (n = 0; n < 3; n++) { if (Zones[nz].dim[n] > CG_MAX_INT32) FATAL(NULL, "zone dimensions too large for integer"); } if (whole) { if (Zones[nz].nverts > CG_MAX_INT32) FATAL(NULL, "zone too large to write as whole using an integer"); } else { if (Zones[nz].dim[0]*Zones[nz].dim[1] > CG_MAX_INT32) FATAL(NULL, "zone too large to write using an integer"); } nblocks++; } } if (!nblocks) FATAL (NULL, "no structured zones found"); /* read the nodes */ printf ("reading %d zones\n", nblocks); ib = is = 0; imax = 0; for (nz = 0; nz < nZones; nz++) { if (Zones[nz].type == CGNS_ENUMV(Structured)) { printf (" zone %d - %s ... ", nz+1, Zones[nz].name); fflush (stdout); read_zone_grid (nz+1); ib += read_zone_interface (nz+1); is += check_solution (nz); if (imax < Zones[nz].nverts) imax = Zones[nz].nverts; puts ("done"); } } if (!ib) use_iblank = 0; if (use_iblank) { iblank = (int *) malloc ((size_t)imax * sizeof(int)); if (NULL == iblank) FATAL (NULL, "malloc failed for iblank array"); } /* write Plot3d XYZ file */ if (format == 'f') write_xyz_formatted (argv[++argind]); else if (format == 'u') write_xyz_unformatted (argv[++argind]); else write_xyz_binary (argv[++argind]); if (use_iblank) free (iblank); /* write solution file */ if (++argind < argc) { if (is != nblocks) { fprintf (stderr, "solution file is not being written since not\n"); fprintf (stderr, "all the blocks contain a complete solution\n"); cg_close (cgnsfn); exit (1); } for (n = 0; n < 5; n++) { q[n] = (double *) malloc ((size_t)imax * sizeof(double)); if (NULL == q[n]) FATAL (NULL, "malloc failed for solution working array"); } get_reference (); if (format == 'f') write_q_formatted (argv[argind]); else if (format == 'u') write_q_unformatted (argv[argind]); else write_q_binary (argv[argind]); } cg_close (cgnsfn); return 0; } cgnslib_3.1.4/src/cgnstools/utilities/Makefile.win0000664000076400007640000001562612160605674017247 00000000000000include ..\make.win CALCDIR = ..\calclib CALCLIB = $(CALCDIR)\cgnscalc.lib COPTS = $(CFLAGS) -I..\common -I$(CGNSDIR) #-------------------------------------------------- ALL = \ plot3d_to_cgns.exe \ cgns_to_plot3d.exe \ patran_to_cgns.exe \ tecplot_to_cgns.exe \ cgns_to_tecplot.exe \ cgns_to_vtk.exe \ convert_location.exe \ convert_variables.exe \ convert_dataclass.exe \ extract_subset.exe \ interpolate_cgns.exe OTHERS = \ cgns_info.exe \ fieldview_to_cgns.exe \ cgns_to_fieldview.exe \ vextex_to_cell.exe \ cell_to_vertex.exe SCRIPTS = \ utilities.mnu \ plot3d.tcl \ patran.tcl \ tecplot.tcl \ vtk.tcl \ convert.tcl \ util.tcl CNVFILES = \ primitive.cnv \ conserved.cnv \ dimensional.cnv all : $(ALL) others : $(OTHERS) #-------------------------------------------------- cgns_info : cgns_info.exe cgns_info.exe : cgns_info.obj cgnsutil.obj getargs.obj $(LINK) $(LFLAGS) cgns_info.obj cgnsutil.obj getargs.obj \ $(CGNSLIB) $(BUILDLIBS) $(CLIBS) cgns_info.obj : cgns_info.c cgnsutil.h #-------------------------------------------------- plot3d_to_cgns : plot3d_to_cgns.exe plot3d_to_cgns.exe : plot3d_to_cgns.obj cgnsutil.obj binaryio.obj getargs.obj $(LINK) $(LFLAGS) plot3d_to_cgns.obj cgnsutil.obj binaryio.obj \ getargs.obj $(CGNSLIB) $(BUILDLIBS) $(CLIBS) plot3d_to_cgns.obj : plot3d_to_cgns.c cgnsutil.h binaryio.h #-------------------------------------------------- cgns_to_plot3d : cgns_to_plot3d.exe cgns_to_plot3d.exe : cgns_to_plot3d.obj cgnsutil.obj getargs.obj p3dfout.obj $(LINK) $(LFLAGS) cgns_to_plot3d.obj cgnsutil.obj \ getargs.obj p3dfout.obj $(CGNSLIB) $(BUILDLIBS) $(CLIBS) cgns_to_plot3d.obj : cgns_to_plot3d.c cgnsutil.h p3dfout.obj : p3dfout.c #-------------------------------------------------- patran_to_cgns : patran_to_cgns.exe patran_to_cgns.exe : patran_to_cgns.obj cgnsImport.obj getargs.obj hash.obj $(LINK) $(LFLAGS) patran_to_cgns.obj cgnsImport.obj getargs.obj \ hash.obj $(CGNSLIB) $(BUILDLIBS) $(CLIBS) patran_to_cgns.obj : patran_to_cgns.c cgnsImport.h #-------------------------------------------------- tecplot_to_cgns : tecplot_to_cgns.exe tecplot_to_cgns.exe : tecplot_to_cgns.obj cgnsImport.obj getargs.obj hash.obj $(LINK) $(LFLAGS) tecplot_to_cgns.obj cgnsImport.obj getargs.obj \ hash.obj $(CGNSLIB) $(BUILDLIBS) $(CLIBS) tecplot_to_cgns.obj : tecplot_to_cgns.c cgnsImport.h #-------------------------------------------------- cgns_to_tecplot : cgns_to_tecplot.exe cgns_to_tecplot.exe : cgns_to_tecplot.obj cgnsutil.obj getargs.obj $(LINK) $(LFLAGS) cgns_to_tecplot.obj cgnsutil.obj \ getargs.obj $(CGNSLIB) $(BUILDLIBS) $(CLIBS) cgns_to_tecplot.obj : cgns_to_tecplot.c cgnsutil.h #-------------------------------------------------- cgns_to_vtk : cgns_to_vtk.exe cgns_to_vtk.exe : cgns_to_vtk.obj getargs.obj $(LINK) $(LFLAGS) cgns_to_vtk.obj getargs.obj \ $(CGNSLIB) $(BUILDLIBS) $(CLIBS) cgns_to_vtk.obj : cgns_to_vtk.c #-------------------------------------------------- fieldview_to_cgns : fieldview_to_cgns.exe fieldview_to_cgns.exe : fieldview_to_cgns.obj cgnsImport.obj getargs.obj hash.obj $(LINK) $(LFLAGS) fieldview_to_cgns.obj cgnsImport.obj getargs.obj \ hash.obj $(CGNSLIB) $(BUILDLIBS) $(CLIBS) fieldview_to_cgns.obj : fieldview_to_cgns.c cgnsImport.h #-------------------------------------------------- cgns_to_fieldview : cgns_to_fieldview.exe cgns_to_fieldview.exe : cgns_to_fieldview.obj cgnsutil.obj getargs.obj $(LINK) $(LFLAGS) cgns_to_fieldview.obj cgnsutil.obj \ getargs.obj $(CGNSLIB) $(BUILDLIBS) $(CLIBS) cgns_to_fieldview.obj : cgns_to_fieldview.c cgnsutil.h #-------------------------------------------------- convert_location : convert_location.exe convert_location.exe : convert_location.obj cgnsutil.obj getargs.obj $(LINK) $(LFLAGS) convert_location.obj cgnsutil.obj getargs.obj \ $(CGNSLIB) $(BUILDLIBS) $(CLIBS) convert_location.obj : convert_location.c cgnsutil.h #-------------------------------------------------- convert_variables : convert_variables.exe convert_variables.exe : convert_variables.obj cgnsutil.obj getargs.obj $(CALCLIB) $(LINK) $(LFLAGS) convert_variables.obj cgnsutil.obj getargs.obj \ $(CALCLIB) $(CGNSLIB) $(BUILDLIBS) $(CLIBS) convert_variables.obj : convert_variables.c cgnsutil.h $(CC) $(COPTS) -I$(CALCDIR) -Fo$@ -c convert_variables.c #-------------------------------------------------- convert_dataclass : convert_dataclass.exe convert_dataclass.exe : convert_dataclass.obj cgnsutil.obj getargs.obj $(CALCLIB) $(LINK) $(LFLAGS) convert_dataclass.obj cgnsutil.obj getargs.obj \ $(CALCLIB) $(CGNSLIB) $(BUILDLIBS) $(CLIBS) convert_dataclass.obj : convert_dataclass.c $(CC) $(COPTS) -I$(CALCDIR) -Fo$@ -c convert_dataclass.c #-------------------------------------------------- extract_subset : extract_subset.exe extract_subset.exe : extract_subset.obj cgnsutil.obj getargs.obj $(LINK) $(LFLAGS) extract_subset.obj cgnsutil.obj getargs.obj \ $(CGNSLIB) $(BUILDLIBS) $(CLIBS) extract_subset.obj : extract_subset.c cgnsutil.h #-------------------------------------------------- vertex_to_cell : vertex_to_cell.exe vertex_to_cell.exe : vertex_to_cell.obj cgnsutil.obj getargs.obj $(LINK) $(LFLAGS) vertex_to_cell.obj cgnsutil.obj getargs.obj \ $(CGNSLIB) $(BUILDLIBS) $(CLIBS) vertex_to_cell.obj : convert_location.c cgnsutil.h $(CC) $(COPTS) -DVERTEX_TO_CELL -Fovertex_to_cell.obj \ -c convert_location.c #-------------------------------------------------- cell_to_vertex : cell_to_vertex.exe cell_to_vertex.exe : cell_to_vertex.obj cgnsutil.obj getargs.obj $(LINK) $(LFLAGS) cell_to_vertex.obj cgnsutil.obj getargs.obj \ $(CGNSLIB) $(BUILDLIBS) $(CLIBS) cell_to_vertex.obj : convert_location.c cgnsutil.h $(CC) $(COPTS) -DCELL_TO_VERTEX -Focell_to_vertex.obj \ -c convert_location.c #-------------------------------------------------- interpolate_cgns : interpolate_cgns.exe interpolate_cgns.exe : interpolate_cgns.obj cgnsutil.obj getargs.obj $(LINK) $(LFLAGS) interpolate_cgns.obj cgnsutil.obj getargs.obj \ $(CGNSLIB) $(BUILDLIBS) $(CLIBS) interpolate_cgns.obj : interpolate_cgns.c cgnsutil.h #-------------------------------------------------- cgnsImport.obj : cgnsImport.c cgnsImport.h cgnsutil.obj : cgnsutil.c cgnsutil.h binaryio.obj : binaryio.c binaryio.h getargs.obj : ..\common\getargs.c ..\common\getargs.h $(CC) $(COPTS) -Fogetargs.obj -c ..\common\getargs.c hash.obj : ..\common\hash.c ..\common\hash.h $(CC) $(COPTS) -Fohash.obj -c ..\common\hash.c p3dfint.obj : p3dfint.f #-------------------------------------------------- install : $(ALL) $(BINDIR) $(SHAREDIR) -$(INSTALL) *.exe $(BINDIR) -$(INSTALL) utilities.mnu $(SHAREDIR) -$(INSTALL) *.tcl $(SHAREDIR) -$(INSTALL) *.cnv $(SHAREDIR) $(BINDIR) : $(INSTALLDIR) -mkdir $(BINDIR) $(SHAREDIR) : $(INSTALLDIR) -mkdir $(SHAREDIR) $(INSTALLDIR) : -mkdir $(INSTALLDIR) .c.obj : $(CC) $(COPTS) -Fo$@ -c $< .f.obj : $(F77) $(FFLAGS) -Fo$@ -c $< clean: -$(RM) *.obj -$(RM) *.pdb -$(RM) *.ilk -$(RM) *.exe -$(RM) *.bak cgnslib_3.1.4/src/cgnstools/utilities/Makefile.unix0000664000076400007640000001617312160605674017433 00000000000000# set path to CGNS library include ../make.defs CALCDIR = ../calclib CALCLIB = $(CALCDIR)/libcgnscalc.$(A) COPTS = $(CFLAGS) -I../common -I$(CGNSDIR) LDLIST = $(CGNSLIB) $(BUILDLIBS) $(CLIBS) #-------------------------------------------------- ALL = \ plot3d_to_cgns$(EXE) \ cgns_to_plot3d$(EXE) \ patran_to_cgns$(EXE) \ tecplot_to_cgns$(EXE) \ cgns_to_tecplot$(EXE) \ cgns_to_vtk$(EXE) \ convert_location$(EXE) \ convert_variables$(EXE) \ convert_dataclass$(EXE) \ extract_subset$(EXE) \ interpolate_cgns$(EXE) OTHERS = \ cgns_info$(EXE) \ vertex_to_cell$(EXE) \ cell_to_vertex$(EXE) SCRIPTS = \ utilities.mnu \ plot3d.tcl \ patran.tcl \ tecplot.tcl \ vtk.tcl \ convert.tcl \ util.tcl CNVFILES = \ primitive.cnv \ conserved.cnv \ dimensional.cnv all : $(ALL) others : $(OTHERS) everything : $(ALL) $(OTHERS) #-------------------------------------------------- cgns_info$(EXE) : cgns_info.$(O) cgnsutil.$(O) getargs.$(O) $(CC) $(LDFLAGS) -o $@ cgns_info.$(O) cgnsutil.$(O) \ getargs.$(O) $(LDLIST) $(STRIP) $@ cgns_info.$(O) : cgns_info.c cgnsutil.h #-------------------------------------------------- plot3d_to_cgns$(EXE) : plot3d_to_cgns.$(O) cgnsutil.$(O) binaryio.$(O) \ getargs.$(O) $(CC) $(LDFLAGS) -o $@ plot3d_to_cgns.$(O) cgnsutil.$(O) \ binaryio.$(O) getargs.$(O) $(LDLIST) $(STRIP) $@ plot3d_to_cgns.$(O) : plot3d_to_cgns.c cgnsutil.h binaryio.h #-------------------------------------------------- cgns_to_plot3d$(EXE) : cgns_to_plot3d.$(O) cgnsutil.$(O) getargs.$(O) \ p3dfout.$(O) $(CC) $(LDFLAGS) -o $@ cgns_to_plot3d.$(O) cgnsutil.$(O) \ getargs.$(O) p3dfout.$(O) $(LDLIST) $(STRIP) $@ cgns_to_plot3d.$(O) : cgns_to_plot3d.c cgnsutil.h p3dfout.$(O) : p3dfout.c binaryio.h #-------------------------------------------------- patran_to_cgns$(EXE) : patran_to_cgns.$(O) cgnsImport.$(O) getargs.$(O) \ hash.$(O) $(CC) $(LDFLAGS) -o $@ patran_to_cgns.$(O) cgnsImport.$(O) \ getargs.$(O) hash.$(O) $(LDLIST) $(STRIP) $@ patran_to_cgns.$(O) : patran_to_cgns.c cgnsImport.h #-------------------------------------------------- tecplot_to_cgns$(EXE) : tecplot_to_cgns.$(O) cgnsImport.$(O) getargs.$(O) \ hash.$(O) $(CC) $(LDFLAGS) -o $@ tecplot_to_cgns.$(O) cgnsImport.$(O) \ getargs.$(O) hash.$(O) $(LDLIST) $(STRIP) $@ tecplot_to_cgns.$(O) : tecplot_to_cgns.c cgnsImport.h #-------------------------------------------------- cgns_to_tecplot$(EXE) : cgns_to_tecplot.$(O) cgnsutil.$(O) getargs.$(O) $(CC) $(LDFLAGS) -o $@ cgns_to_tecplot.$(O) cgnsutil.$(O) \ getargs.$(O) $(LDLIST) $(STRIP) $@ cgns_to_tecplot.$(O) : cgns_to_tecplot.c cgnsutil.h #-------------------------------------------------- cgns_to_vtk$(EXE) : cgns_to_vtk.$(O) getargs.$(O) $(CC) $(LDFLAGS) -o $@ cgns_to_vtk.$(O) getargs.$(O) $(LDLIST) $(STRIP) $@ cgns_to_vtk.$(O) : cgns_to_vtk.c #-------------------------------------------------- fieldview_to_cgns$(EXE) : fieldview_to_cgns.$(O) cgnsImport.$(O) getargs.$(O) \ hash.$(O) $(CC) $(LDFLAGS) -o $@ fieldview_to_cgns.$(O) cgnsImport.$(O) \ getargs.$(O) hash.$(O) $(LDLIST) $(STRIP) $@ fieldview_to_cgns.$(O) : fieldview_to_cgns.c cgnsImport.h #-------------------------------------------------- cgns_to_fieldview$(EXE) : cgns_to_fieldview.$(O) cgnsutil.$(O) getargs.$(O) $(CC) $(LDFLAGS) -o $@ cgns_to_fieldview.$(O) cgnsutil.$(O) \ getargs.$(O) $(LDLIST) $(STRIP) $@ cgns_to_fieldview.$(O) : cgns_to_fieldview.c cgnsutil.h #-------------------------------------------------- convert_location$(EXE) : convert_location.$(O) cgnsutil.$(O) getargs.$(O) $(CC) $(LDFLAGS) -o $@ convert_location.$(O) cgnsutil.$(O) \ getargs.$(O) $(LDLIST) $(STRIP) $@ convert_location.$(O) : convert_location.c cgnsutil.h #-------------------------------------------------- vertex_to_cell$(EXE) : vertex_to_cell.$(O) cgnsutil.$(O) getargs.$(O) $(CC) $(LDFLAGS) -o $@ vertex_to_cell.$(O) cgnsutil.$(O) \ getargs.$(O) $(LDLIST) $(STRIP) $@ vertex_to_cell.$(O) : convert_location.c cgnsutil.h $(CC) $(COPTS) -DVERTEX_TO_CELL -o vertex_to_cell.$(O) \ -c convert_location.c #-------------------------------------------------- cell_to_vertex$(EXE) : cell_to_vertex.$(O) cgnsutil.$(O) getargs.$(O) $(CC) $(LDFLAGS) -o $@ cell_to_vertex.$(O) cgnsutil.$(O) \ getargs.$(O) $(LDLIST) $(STRIP) $@ cell_to_vertex.$(O) : convert_location.c cgnsutil.h $(CC) $(COPTS) -DCELL_TO_VERTEX -o cell_to_vertex.$(O) \ -c convert_location.c #-------------------------------------------------- convert_variables$(EXE) : convert_variables.$(O) cgnsutil.$(O) getargs.$(O) \ $(CALCLIB) $(CC) $(LDFLAGS) -o $@ convert_variables.$(O) cgnsutil.$(O) \ getargs.$(O) $(CALCLIB) $(LDLIST) $(STRIP) $@ convert_variables.$(O) : convert_variables.c cgnsutil.h $(CC) $(COPTS) -I$(CALCDIR) -c convert_variables.c #-------------------------------------------------- convert_dataclass$(EXE) : convert_dataclass.$(O) cgnsutil.$(O) getargs.$(O) \ $(CALCLIB) $(CC) $(LDFLAGS) -o $@ convert_dataclass.$(O) cgnsutil.$(O) \ getargs.$(O) $(CALCLIB) $(LDLIST) $(STRIP) $@ convert_dataclass.$(O) : convert_dataclass.c $(CC) $(COPTS) -I$(CALCDIR) -c convert_dataclass.c #-------------------------------------------------- extract_subset$(EXE) : extract_subset.$(O) cgnsutil.$(O) getargs.$(O) $(CC) $(LDFLAGS) -o $@ extract_subset.$(O) cgnsutil.$(O) \ getargs.$(O) $(LDLIST) $(STRIP) $@ extract_subset.$(O) : extract_subset.c cgnsutil.h #-------------------------------------------------- interpolate_cgns$(EXE) : interpolate_cgns.$(O) cgnsutil.$(O) getargs.$(O) $(CC) $(LDFLAGS) -o $@ interpolate_cgns.$(O) cgnsutil.$(O) \ getargs.$(O) $(LDLIST) $(STRIP) $@ interpolate_cgns.$(O) : interpolate_cgns.c cgnsutil.h #-------------------------------------------------- cgnsImport.$(O) : cgnsImport.c cgnsImport.h cgnsutil.$(O) : cgnsutil.c cgnsutil.h binaryio.$(O) : binaryio.c binaryio.h getargs.$(O) : ../common/getargs.c ../common/getargs.h $(CC) $(COPTS) -o getargs.$(O) -c ../common/getargs.c hash.$(O) : ../common/hash.c ../common/hash.h $(CC) $(COPTS) -o hash.$(O) -c ../common/hash.c $(CALCLIB) : cd $(CALCDIR) && $(MAKE) #-------------------------------------------------- install : install-dirs install-prog install-script install-dirs : @for d in \ $(EXE_INSTALL_DIR) \ $(LIB_INSTALL_DIR) ; do \ if [ ! -d $$d ] ; then \ echo "Making directory $$d"; \ mkdir -p $$d; \ chmod 755 $$d; \ fi; \ done; install-prog : $(ALL) @echo "installing utility executables to $(EXE_INSTALL_DIR)" @for i in $(ALL) ; do \ if [ -f $$i ]; then \ $(INSTALL_PROG) $$i $(EXE_INSTALL_DIR); \ fi; \ done; install-script : @echo "installing utility tcl scripts to $(LIB_INSTALL_DIR)" @for i in $(CNVFILES) $(SCRIPTS) ; do \ $(INSTALL_DATA) $$i $(LIB_INSTALL_DIR); \ done; uninstall : @echo "uninstalling utility executables" @for i in $(ALL) ; do \ if [ -f $(EXE_INSTALL_DIR)/$$i ] ; then \ /bin/rm -f $(EXE_INSTALL_DIR)/$$i; \ fi; \ done; @echo "uninstalling utility tcl scripts" @for i in $(CNVFILES) $(SCRIPTS) ; do \ if [ -f $(LIB_INSTALL_DIR)/$$i ] ; then \ /bin/rm -f $(LIB_INSTALL_DIR)/$$i; \ fi; \ done; .c.$(O) : $(CC) $(COPTS) -c $< clean: $(RM) *.$(O) *~ *.bak $(ALL) cgnslib_3.1.4/src/cgnstools/utilities/cgnsutil.c0000664000076400007640000030050212160605674016775 00000000000000/* * cgnsutil.c - CGNS utility routines */ #include #include #include #include #include #include #ifdef _WIN32 # include # include # define access _access # define unlink _unlink # define getcwd _getcwd #else # include #endif #include "cgnslib.h" #include "cgnsutil.h" #define MAXDIRLEN 256 #ifdef _WIN32 # define PATH_DELIM ';' # include # include #else # define PATH_DELIM ':' # include #endif #ifndef CG_MODE_READ # define CG_MODE_READ MODE_READ # define CG_MODE_WRITE MODE_WRITE # define CG_MODE_MODIFY MODE_MODIFY #endif int nZones = 0; ZONE *Zones; int baseclass = 0; int baseunits[5] = {0, 0, 0, 0, 0}; int cgnsbase = 1; int cgnsfn = 0; int element_node_counts[] = { 0, 0, /* ElementTypeNull, ElementTypeUserDefined */ 1, 2, 3, /* NODE, BAR_2, BAR_3 */ 3, 6, /* TRI_3, TRI_6 */ 4, 8, 9, /* QUAD_4, QUAD_8, QUAD_9 */ 4, 10, /* TETRA_4, TETRA_10 */ 5, 14, /* PYRA_5, PYRA_14 */ 6, 15, 18, /* PENTA_6, PENTA_15, PENTA_18 */ 8, 20, 27, /* HEXA_8, HEXA_20, HEXA_27 */ 0, 0 /* MIXED, NGON_n */ }; static char cgnstemp[16] = ""; /*---------- FATAL ---------------------------------------------------- * exit with error message *---------------------------------------------------------------------*/ void FATAL (char *procname, char *errmsg) { char *msg = errmsg; if (NULL == msg) { msg = (char *)cg_get_error (); if (NULL == msg || !*msg) msg = "unknown error"; } fflush (stdout); if (NULL == procname || !*procname) fprintf (stderr, "%s\n", msg); else fprintf (stderr, "%s:%s\n", procname, msg); if (cgnsfn) cg_close (cgnsfn); if (cgnstemp[0]) unlink (cgnstemp); exit (1); } /*---------- new_zone ------------------------------------------------- * create new zone(s) *---------------------------------------------------------------------*/ ZONE *new_zone (int count) { int n; ZONE *z; z = (ZONE *) calloc (count, sizeof(ZONE)); if (NULL == z) FATAL ("new_zone", "calloc failed for new zones"); for (n = 0; n < count; n++) { z[n].id = n + 1; sprintf (z[n].name, "Zone%d", n + 1); z[n].type = CGNS_ENUMV(Structured); z[n].vertflags = 0; z[n].datatype = CGNS_ENUMV(RealDouble); } return z; } /*---------- new_vertex ----------------------------------------------- * create coordinate array for a zone *---------------------------------------------------------------------*/ VERTEX *new_vertex (cgsize_t nverts) { cgsize_t n; VERTEX *verts; verts = (VERTEX *) calloc ((size_t)nverts, sizeof(VERTEX)); if (NULL == verts) FATAL ("new_vertex", "calloc failed for new vertex array"); for (n = 0; n < nverts; n++) { verts[n].id = n + 1; verts[n].w = 1.0; } return verts; } /*---------- new_elemset ---------------------------------------------- * create element set array *---------------------------------------------------------------------*/ ELEMSET *new_elemset (int nesets) { int n; ELEMSET *esets; esets = (ELEMSET *) calloc (nesets, sizeof(ELEMSET)); if (NULL == esets) FATAL ("new_elemset", "calloc failed for new element set array"); for (n = 0; n < nesets; n++) { esets[n].id = n + 1; sprintf (esets[n].name, "ElemSet%d", n + 1); } return esets; } /*---------- new_interface -------------------------------------------- * create grid 1to1 interface array for a zone *---------------------------------------------------------------------*/ INTERFACE *new_interface (int nints) { int n; INTERFACE *ints; ints = (INTERFACE *) calloc (nints, sizeof(INTERFACE)); if (NULL == ints) FATAL ("new_interface", "calloc failed for new interface array"); for (n = 0; n < nints; n++) { ints[n].id = n + 1; sprintf (ints[n].name, "Interface%d", n + 1); } return ints; } /*---------- new_connect ---------------------------------------------- * create grid connectivity array for a zone *---------------------------------------------------------------------*/ CONNECT *new_connect (int nconns) { int n; CONNECT *conns; conns = (CONNECT *) calloc (nconns, sizeof(CONNECT)); if (NULL == conns) FATAL ("new_connect", "calloc failed for new connectivity array"); for (n = 0; n < nconns; n++) { conns[n].id = n + 1; sprintf (conns[n].name, "Connectivity%d", n + 1); } return conns; } /*---------- new_boco ------------------------------------------------- * create boundary condition array *---------------------------------------------------------------------*/ BOCO *new_boco (int nbocos) { int n; BOCO *bocos; bocos = (BOCO *) calloc (nbocos, sizeof(BOCO)); if (NULL == bocos) FATAL ("new_boco", "calloc failed for new boco array"); for (n = 0; n < nbocos; n++) { bocos[n].id = n + 1; sprintf (bocos[n].name, "Boco%d", n + 1); } return bocos; } /*---------- new_solution --------------------------------------------- * create solution array for a zone *---------------------------------------------------------------------*/ SOLUTION *new_solution (int nsols) { int n; SOLUTION *sols; sols = (SOLUTION *) calloc (nsols, sizeof(SOLUTION)); if (NULL == sols) FATAL ("new_solution", "calloc failed for new solution array"); for (n = 0; n < nsols; n++) { sols[n].id = n + 1; sprintf (sols[n].name, "FlowSolution%d", n + 1); } return sols; } /*---------- new_field ------------------------------------------------ * create solution variable array for a zone *---------------------------------------------------------------------*/ FIELD *new_field (int nflds, cgsize_t size) { int n; FIELD *flds; flds = (FIELD *) calloc (nflds, sizeof(FIELD)); if (NULL == flds) FATAL ("new_field", "calloc failed for new field array"); for (n = 0; n < nflds; n++) { flds[n].id = n + 1; sprintf (flds[n].name, "Field%d", n+1); flds[n].datatype = CGNS_ENUMV(RealDouble); if (size > 0) { flds[n].data = (double *) calloc ((size_t)size, sizeof(double)); if (NULL == flds[n].data) FATAL ("new_field", "calloc failed for field data array"); } } return flds; } /*---------- new_desc ------------------------------------------------- * create descriptor array *---------------------------------------------------------------------*/ DESC *new_desc (int ndesc) { int n; DESC *desc; desc = (DESC *) calloc (ndesc, sizeof(DESC)); if (NULL == desc) FATAL ("new_desc", "calloc failed for new descriptor array"); for (n = 0; n < ndesc; n++) { desc[n].id = n + 1; sprintf (desc[n].name, "Descriptor%d", n + 1); } return desc; } /*---------- vertex_index --------------------------------------------- * get index in vertex array for structured grid *---------------------------------------------------------------------*/ cgsize_t vertex_index (ZONE *z, cgsize_t i, cgsize_t j, cgsize_t k) { return i - 1 + z->dim[0] * ((j - 1) + z->dim[1] * (k - 1)); } /*---------- cell_index ----------------------------------------------- * get index in cell array for structured grid *---------------------------------------------------------------------*/ cgsize_t cell_index (ZONE *z, cgsize_t i, cgsize_t j, cgsize_t k) { return i - 1 + (z->dim[0] - 1) * ((j - 1) + (z->dim[1] - 1) * (k - 1)); } /*---------- solution_index ------------------------------------------- * get index in solution array for structured grid *---------------------------------------------------------------------*/ cgsize_t solution_index (ZONE *z, SOLUTION *s, cgsize_t i, cgsize_t j, cgsize_t k) { cgsize_t ni, nj; ni = z->dim[0] - 1 + s->rind[0][0] + s->rind[0][1]; nj = z->dim[1] - 1 + s->rind[1][0] + s->rind[1][1]; i += s->rind[0][0]; j += s->rind[1][0]; k += s->rind[2][0]; return i - 1 + ni * ((j - 1) + nj * (k - 1)); } /*---------- file_exists ---------------------------------------------- * check if a file exists *---------------------------------------------------------------------*/ int file_exists (char *file) { struct stat st; if (access (file, 0) || stat (file, &st) || S_IFREG != (st.st_mode & S_IFMT)) return 0; return 1; } /*---------- is_executable ----------------------------------------------- * checks if pathname exists and is executable *------------------------------------------------------------------------*/ int is_executable (char *file) { struct stat st; /* needs to be executable and not a directory */ if (access (file, 1) || stat (file, &st) || S_IFDIR == (st.st_mode & S_IFMT)) return (0); return (1); } #ifdef _WIN32 /*---------- check_extensions ------------------------------------------- * check for DOS/Windows executable *-----------------------------------------------------------------------*/ static int check_extensions (char *pathname) { int n; char *p; static char *exts[] = {".com", ".exe", ".bat"}; /* fix path */ for (p = pathname; *p; p++) { if (*p == '/') *p = '\\'; } if (is_executable (pathname)) return (1); for (n = 0; n < 3; n++) { strcpy (p, exts[n]); if (is_executable (pathname)) return (1); } *p = 0; return (0); } #endif /*---------- find_executable -------------------------------------------- * locate and build pathname to executable *-----------------------------------------------------------------------*/ char *find_executable (char *exename) { int n; char *p, *s; static char exepath[MAXDIRLEN+1]; if (exename == NULL || !*exename) return (NULL); #ifdef _WIN32 /* full path */ if (*exename == '/' || *exename == '\\' || *(exename+1) == ':') { strcpy (exepath, exename); return (check_extensions (exepath) ? exepath : NULL); } /* get current directory */ if (NULL == getcwd (exepath, MAXDIRLEN)) FATAL ("find_executable", "couldn't get working directory"); p = exepath + strlen(exepath); if (*(p-1) == '\\') *--p = 0; /* relative path */ if (0 == strncmp (exename, ".\\", 2) || 0 == strncmp (exename, "..\\", 3) || 0 == strncmp (exename, "./", 2) || 0 == strncmp (exename, "../", 3)) { if (exename[1] != '.') strcpy (p, &exename[1]); else { if (NULL == (p = strrchr (exepath, '\\'))) p = exepath; strcpy (p, &exename[2]); } return (check_extensions (exepath) ? exepath : NULL); } /* current directory */ *p++ = '\\'; strcpy (p, exename); if (check_extensions (exepath)) return (exepath); #else /* full path */ if (*exename == '/') { if (is_executable (exename)) return (strcpy (exepath, exename)); return (NULL); } /* relative path */ if (0 == strncmp (exename, "./", 2) || 0 == strncmp (exename, "../", 3)) { if (NULL == getcwd (exepath, MAXDIRLEN)) FATAL ("find_executable", "couldn't get working directory"); p = exepath + strlen(exepath); if (*(p-1) == '/') *--p = 0; if (exename[1] != '.') strcpy (p, &exename[1]); else { if (NULL == (p = strrchr (exepath, '/'))) p = exepath; strcpy (p, &exename[2]); } return (is_executable (exepath) ? exepath : NULL); } #endif /* scan $PATH environment variable */ if (NULL == (p = getenv ("PATH"))) return (NULL); while (*p) { if (NULL == (s = strchr (p, PATH_DELIM))) { strcpy (exepath, p); n = (int)strlen (exepath); } else { n = (int)(s++ - p); strncpy (exepath, p, n); exepath[n] = 0; } if (n) { p = exepath + n; #ifdef _WIN32 if (*(p-1) != '\\') *p++ = '\\'; strcpy (p, exename); if (check_extensions (exepath)) return (exepath); #else if (*(p-1) != '/') *p++ = '/'; strcpy (p, exename); if (is_executable (exepath)) return (exepath); #endif } if (NULL == (p = s)) break; } return (NULL); } /*---------- find_file ------------------------------------------------ * get pathname to a file *---------------------------------------------------------------------*/ char *find_file (char *filename, char *exename) { char *p; static char pathname[MAXDIRLEN+1]; if (file_exists (filename)) return strcpy (pathname, filename); if ((p = find_executable (exename)) == NULL) return NULL; strcpy (pathname, p); while ((p = strrchr (pathname, '/')) != NULL || (p = strrchr (pathname, '\\')) != NULL) { strcpy (p+1, filename); if (file_exists (pathname)) return pathname; *p = 0; } return NULL; } /*---------- same_file ------------------------------------------------ * check if 2 files are the same *---------------------------------------------------------------------*/ int same_file (char *file1, char *file2) { int n = file_exists (file1) | (file_exists (file2) << 1); #ifdef _WIN32 char path1[257], path2[257]; if (n == 1 || n == 2) return 0; if (_fullpath (path1, file1, 256) != NULL && _fullpath (path2, file2, 256) != NULL) return (_stricmp (path1, path2) == 0); return (_stricmp (file1, file2) == 0); #else if (n == 3) { struct stat st1, st2; stat (file1, &st1); stat (file2, &st2); return (st1.st_ino == st2.st_ino); } if (n == 0) return (strcmp (file1, file2) == 0); return 0; #endif } /*---------- temporary_file ------------------------------------------- * create a temporary file *---------------------------------------------------------------------*/ char *temporary_file (char *basename) { char *p, *temp; int n; if (basename == NULL || !*basename) basename = "cgnstmpfile"; n = (int)strlen (basename); temp = (char *) malloc (n + 10); if (temp == NULL) FATAL ("temporary_file", "malloc failed for temp filename"); sprintf (temp, "%s.tmp", basename); p = temp + strlen(temp); for (n = 0; n < 1000; n++) { sprintf (p, "%3.3d~", n); if (access (temp, 0)) return temp; } FATAL ("temporary_file", "failed to create temporary filename"); return 0; } /*---------- copy_file ------------------------------------------------ * make a copy of a file *---------------------------------------------------------------------*/ void copy_file (char *oldfile, char *newfile) { int c; FILE *oldfp, *newfp; if (NULL == (oldfp = fopen (oldfile, "rb"))) FATAL ("copy_file", "error opening input file for reading"); if (NULL == (newfp = fopen (newfile, "w+b"))) { fclose (oldfp); FATAL ("copy_file", "error opening output file for writing"); } while (EOF != (c = getc (oldfp))) putc (c, newfp); fclose (oldfp); fclose (newfp); } /*---------- open_cgns ------------------------------------------------ * open a CGNS file *---------------------------------------------------------------------*/ int open_cgns (char *cgnsfile, int read_only) { int nbases; if (read_only) { if (cg_open (cgnsfile, CG_MODE_READ, &cgnsfn) || cg_nbases (cgnsfn, &nbases)) FATAL ("open_cgns", NULL); return nbases; } if (cg_open (cgnsfile, CG_MODE_MODIFY, &cgnsfn)) { if (cg_open (cgnsfile, CG_MODE_WRITE, &cgnsfn)) FATAL ("open_cgns", NULL); return 0; } if (cg_nbases (cgnsfn, &nbases)) FATAL ("open_cgns", NULL); return nbases; } /*---------- find_base ------------------------------------------------ * find base id from base name *---------------------------------------------------------------------*/ int find_base (char *basename) { int nbases, nb, idum; char buff[33]; if (cg_nbases (cgnsfn, &nbases)) FATAL ("find_base", NULL); for (nb = 1; nb <= nbases; nb++) { if (cg_base_read (cgnsfn, nb, buff, &idum, &idum)) FATAL ("find_base", NULL); if (!strcmp (buff, basename)) return nb; } return 0; } /*---------- read_cgns ------------------------------------------------ * read the CGNS file *---------------------------------------------------------------------*/ void read_cgns (void) { int nz, ns; read_zones (); for (nz = 1; nz <= nZones; nz++) { read_zone_grid (nz); read_zone_element (nz); read_zone_interface (nz); read_zone_connect (nz); read_zone_boco (nz); read_zone_solution (nz); for (ns = 1; ns <= Zones[nz-1].nsols; ns++) read_solution_field (nz, ns, 0); } } /*---------- read_zones ----------------------------------------------- * read zone information from CGNS file *---------------------------------------------------------------------*/ int read_zones (void) { int n, nz, nd, celldim; cgsize_t sizes[9]; CGNS_ENUMT(ZoneType_t) zonetype; char buff[33]; if (cg_goto (cgnsfn, cgnsbase, "end")) FATAL ("read_zones", NULL); read_units (baseunits); if (cg_dataclass_read ((CGNS_ENUMT(DataClass_t) *)&baseclass)) baseclass = 0; if (cg_base_read (cgnsfn, cgnsbase, buff, &celldim, &nd) || cg_nzones (cgnsfn, cgnsbase, &nZones)) FATAL ("read_zones", NULL); Zones = new_zone (nZones); /* read the zone information */ for (nz = 0; nz < nZones; nz++) { if (cg_zone_read (cgnsfn, cgnsbase, nz+1, buff, sizes) || cg_zone_type (cgnsfn, cgnsbase, nz+1, &zonetype)) FATAL ("read_zones", NULL); if (zonetype != CGNS_ENUMV(Structured) && zonetype != CGNS_ENUMV(Unstructured)) FATAL ("read_zones", "invalid zone type"); Zones[nz].id = nz + 1; strcpy (Zones[nz].name, buff); Zones[nz].type = zonetype; Zones[nz].idim = zonetype == CGNS_ENUMV(Structured) ? celldim : 1; for (n = 0; n < 3; n++) Zones[nz].dim[n] = sizes[n]; /* get units */ if (cg_goto (cgnsfn, cgnsbase, "Zone_t", nz+1, "end")) FATAL ("read_zones", NULL); if (!read_units (Zones[nz].units)) { for (n = 0; n < 5; n++) Zones[nz].units[n] = baseunits[n]; } if (cg_dataclass_read ((CGNS_ENUMT(DataClass_t) *)&Zones[nz].dataclass)) Zones[nz].dataclass = baseclass; /* get descriptors */ if (cg_ndescriptors (&nd)) FATAL ("cg_ndescriptors", NULL); if (nd) { Zones[nz].ndesc = nd; Zones[nz].desc = new_desc (nd); for (n = 0; n < nd; n++) { if (cg_descriptor_read (n+1, Zones[nz].desc[n].name, &Zones[nz].desc[n].desc)) FATAL ("cg_descriptor_read", NULL); } } /* get zone counts */ if (cg_nsections (cgnsfn, cgnsbase, nz+1, &Zones[nz].nesets) || cg_n1to1 (cgnsfn, cgnsbase, nz+1, &Zones[nz].nints) || cg_nconns (cgnsfn, cgnsbase, nz+1, &Zones[nz].nconns) || cg_nbocos (cgnsfn, cgnsbase, nz+1, &Zones[nz].nbocos) || cg_nsols (cgnsfn, cgnsbase, nz+1, &Zones[nz].nsols)) FATAL ("read_zones", NULL); } return nZones; } /*---------- read_zone_data ------------------------------------------- * read all zone data *---------------------------------------------------------------------*/ void read_zone_data (int nz) { int ns, nsols; read_zone_grid (nz); read_zone_element (nz); read_zone_interface (nz); read_zone_connect (nz); read_zone_boco (nz); nsols = read_zone_solution (nz); for (ns = 1; ns <= nsols; ns++) read_solution_field (nz, ns, 0); } /*---------- read_zone_grid ------------------------------------------- * read zone grid coordinates *---------------------------------------------------------------------*/ cgsize_t read_zone_grid (int nz) { int n, nc, ncoords; int rind[6]; cgsize_t nn, nverts, rng[2][3]; CGNS_ENUMT(DataType_t) datatype; char buff[33]; double *xyz; ZONE *z = &Zones[nz-1]; if (cg_goto (cgnsfn, cgnsbase, "Zone_t", nz, "GridCoordinates_t", 1, NULL)) FATAL ("read_zone_grid", NULL); if (cg_rind_read (rind) == CG_OK) { for (n = 0; n < 2 * z->idim; n++) { if (rind[n]) FATAL ("read_zone_grid", "currently can't handle coordinate rind"); } } if (z->type == CGNS_ENUMV(Structured)) { nverts = z->dim[0] * z->dim[1] * z->dim[2]; for (n = 0; n < 3; n++) { rng[0][n] = 1; rng[1][n] = z->dim[n]; } } else { nverts = z->dim[0]; for (n = 0; n < 3; n++) { rng[0][n] = 1; rng[1][n] = nverts; } } xyz = (double *) malloc ((size_t)nverts * sizeof(double)); if (NULL == xyz) FATAL ("read_zone_grid", "malloc failed for coordinate working array"); z->vertflags = 0; z->datatype = 0; z->nverts = nverts; z->verts = new_vertex (nverts); /* read the nodes */ if (cg_ncoords (cgnsfn, cgnsbase, nz, &ncoords)) FATAL ("read_zone_grid", NULL); for (nc = 1; nc <= ncoords; nc++) { if (cg_coord_info (cgnsfn, cgnsbase, nz, nc, &datatype, buff) || cg_coord_read (cgnsfn, cgnsbase, nz, buff, CGNS_ENUMV(RealDouble), rng[0], rng[1], xyz)) FATAL ("read_zone_grid", NULL); if (z->datatype < datatype) z->datatype = datatype; if (0 == strcmp (buff, "CoordinateX")) { z->vertflags |= 1; for (nn = 0; nn < nverts; nn++) z->verts[nn].x = xyz[nn]; } else if (0 == strcmp (buff, "CoordinateY")) { z->vertflags |= 2; for (nn = 0; nn < nverts; nn++) z->verts[nn].y = xyz[nn]; } else if (0 == strcmp (buff, "CoordinateZ")) { z->vertflags |= 4; for (nn = 0; nn < nverts; nn++) z->verts[nn].z = xyz[nn]; } else if (0 == strcmp (buff, "CoordinateR")) { z->vertflags |= 8; for (nn = 0; nn < nverts; nn++) z->verts[nn].z = xyz[nn]; } else if (0 == strcmp (buff, "CoordinateTheta")) { z->vertflags |= 16; for (nn = 0; nn < nverts; nn++) z->verts[nn].z = xyz[nn]; } else if (0 == strcmp (buff, "CoordinatePhi")) { z->vertflags |= 32; for (nn = 0; nn < nverts; nn++) z->verts[nn].z = xyz[nn]; } else { FATAL ("read_zone_grid", "unknown coordinate type"); } } free (xyz); /* cylindrical coordinates */ if (z->vertflags == 24 || z->vertflags == 28) { double r, t; for (nn = 0; nn < nverts; nn++) { r = z->verts[nn].x; t = z->verts[nn].y; z->verts[nn].x = r * cos (t); z->verts[nn].y = r * sin (t); } z->vertflags |= 3; } else if (z->vertflags == 56) { /* spherical coordinates */ double r, t, p; for (nn = 0; nn < nverts; nn++) { r = z->verts[nn].x; t = z->verts[nn].y; p = z->verts[nn].z; z->verts[nn].x = r * sin (t) * cos (p); z->verts[nn].y = r * sin (t) * sin (p); z->verts[nn].z = r * cos (t); } z->vertflags |= 7; } else { if (z->vertflags < 1 || z->vertflags > 7) FATAL ("read_zone_grid", "unknown coordinate system"); } return nverts; } /*---------- read_zone_element ---------------------------------------- * read zone element sets and elements *---------------------------------------------------------------------*/ int read_zone_element (int nz) { int ns, iparent; cgsize_t size; int rind[6]; ZONE *z = &Zones[nz-1]; ELEMSET *eset; if (cg_nsections (cgnsfn, cgnsbase, nz, &z->nesets)) FATAL ("read_zone_element", NULL); if (z->nesets) { z->esets = eset = new_elemset (z->nesets); for (ns = 1; ns <= z->nesets; ns++, eset++) { if (cg_goto (cgnsfn, cgnsbase, "Zone_t", nz, "Elements_t", ns, NULL)) FATAL ("read_zone_element", NULL); if (cg_rind_read (rind) == CG_OK && (rind[0] || rind[1])) FATAL ("read_zone_element", "currently can't handle element set rind"); if (cg_section_read (cgnsfn, cgnsbase, nz, ns, eset->name, (CGNS_ENUMT(ElementType_t) *)&eset->type, &eset->start, &eset->end, &eset->nbndry, &iparent) || cg_ElementDataSize (cgnsfn, cgnsbase, nz, ns, &size)) FATAL ("read_zone_element", NULL); eset->conn = (cgsize_t *) malloc ((size_t)size * sizeof(cgsize_t)); if (NULL == eset->conn) FATAL ("read_zone_element", "malloc failed for element connectivity"); if (iparent) { size = 4 * (eset->end - eset->start + 1); eset->parent = (cgsize_t *) malloc ((size_t)size * sizeof(cgsize_t)); if (NULL == eset->conn) FATAL ("read_zone_element","malloc failed for parent data"); } if (cg_elements_read (cgnsfn, cgnsbase, nz, ns, eset->conn, eset->parent)) FATAL ("read_zone_element", NULL); } } return z->nesets; } /*---------- structured_elements -------------------------------------- * build elements from structured zone *---------------------------------------------------------------------*/ int structured_elements (int nz) { cgsize_t i, j, k, n, nelems; ZONE *z = &Zones[nz-1]; ELEMSET *eset; if (z->type != CGNS_ENUMV(Structured)) return 0; nelems = (z->dim[0] - 1) * (z->dim[1] - 1) * (z->dim[2] - 1); if (nelems == 0) return 0; z->nesets = 1; z->esets = eset = new_elemset (1); strcpy (eset->name, "StructuredGridElements"); eset->type = CGNS_ENUMV(HEXA_8); eset->start = 1; eset->end = nelems; eset->nbndry = 0; eset->conn = (cgsize_t *) malloc ((size_t)(8 * nelems) * sizeof(cgsize_t)); if (NULL == eset->conn) FATAL ("structured_elements", "malloc failed for element connectivity"); eset->parent = NULL; for (n = 0, k = 1; k < z->dim[2]; k++) { for (j = 1; j < z->dim[1]; j++) { for (i = 1; i < z->dim[0]; i++) { eset->conn[n++] = vertex_index (z, i, j, k) + 1; eset->conn[n++] = vertex_index (z, i+1, j, k) + 1; eset->conn[n++] = vertex_index (z, i+1, j+1, k) + 1; eset->conn[n++] = vertex_index (z, i, j+1, k) + 1; eset->conn[n++] = vertex_index (z, i, j, k+1) + 1; eset->conn[n++] = vertex_index (z, i+1, j, k+1) + 1; eset->conn[n++] = vertex_index (z, i+1, j+1, k+1) + 1; eset->conn[n++] = vertex_index (z, i, j+1, k+1) + 1; } } } return 1; } /*---------- read_zone_interface -------------------------------------- * read zone 1 to 1 interfaces *---------------------------------------------------------------------*/ int read_zone_interface (int nz) { int i, j, n, ni; cgsize_t range[2][3], d_range[2][3]; ZONE *z = &Zones[nz-1]; INTERFACE *ints; if (cg_n1to1 (cgnsfn, cgnsbase, nz, &z->nints)) FATAL ("read_zone_interface", NULL); if (z->nints) { z->ints = ints = new_interface (z->nints); for (ni = 1; ni <= z->nints; ni++, ints++) { if (cg_1to1_read (cgnsfn, cgnsbase, nz, ni, ints->name, ints->d_name, (cgsize_t *)range, (cgsize_t *)d_range, (int *)ints->transform)) FATAL ("read_zone_interface", NULL); for (j = 0; j < 2; j++) { for (i = 0; i < 3; i++) { ints->range[i][j] = range[j][i]; ints->d_range[i][j] = d_range[j][i]; } } for (n = 0; n < nZones; n++) { if (!strcmp (Zones[n].name, ints->d_name)) { ints->d_zone = n + 1; break; } } } } return z->nints; } /*---------- read_zone_connect ---------------------------------------- * read zone connectivities *---------------------------------------------------------------------*/ int read_zone_connect (int nz) { int n, nc; cgsize_t npnts; CGNS_ENUMT(GridLocation_t) location; CGNS_ENUMT(GridConnectivityType_t) type; CGNS_ENUMT(PointSetType_t) ptype, d_ptype; CGNS_ENUMT(ZoneType_t) d_ztype; CGNS_ENUMT(DataType_t) d_datatype; ZONE *z = &Zones[nz-1]; CONNECT *conns; if (cg_nconns (cgnsfn, cgnsbase, nz, &z->nconns)) FATAL ("read_zone_connect", NULL); if (z->nconns) { z->conns = conns = new_connect (z->nconns); for (nc = 1; nc <= z->nconns; nc++, conns++) { if (cg_conn_info (cgnsfn, cgnsbase, nz, nc, conns->name, &location, &type, &ptype, &conns->npnts, conns->d_name, &d_ztype, &d_ptype, &d_datatype, &conns->d_npnts)) FATAL ("read_zone_connect", NULL); conns->location = location; conns->type = type; conns->ptype = ptype; conns->d_ztype = d_ztype; conns->d_ptype = d_ptype; npnts = conns->npnts * z->idim; conns->pnts = (cgsize_t *) calloc ((size_t)npnts, sizeof(cgsize_t)); npnts = conns->d_npnts * z->idim; conns->d_pnts = (cgsize_t *) calloc ((size_t)npnts, sizeof(cgsize_t)); if (NULL == conns->pnts || NULL == conns->d_pnts) FATAL ("read_zone_connect", "malloc failed for connectivity point arrays"); if (cg_conn_read (cgnsfn, cgnsbase, nz, nc, conns->pnts, CGNS_ENUMV(Integer), conns->d_pnts)) FATAL ("read_zone_connect", NULL); for (n = 0; n < nZones; n++) { if (!strcmp (Zones[n].name, conns->d_name)) { conns->d_zone = n + 1; break; } } } } return z->nconns; } /*---------- read_zone_boco ------------------------------------------ * read zone boundary conditions *---------------------------------------------------------------------*/ int read_zone_boco (int nz) { int nb, ndatasets; cgsize_t npnts; CGNS_ENUMT(BCType_t) bctype; CGNS_ENUMT(PointSetType_t) ptype; CGNS_ENUMT(DataType_t) datatype; ZONE *z = &Zones[nz-1]; BOCO *bocos; if (cg_nbocos (cgnsfn, cgnsbase, nz, &z->nbocos)) FATAL ("read_zone_boco", NULL); if (z->nbocos) { z->bocos = bocos = new_boco (z->nbocos); for (nb = 1; nb <= z->nbocos; nb++, bocos++) { if (cg_boco_info (cgnsfn, cgnsbase, nz, nb, bocos->name, &bctype, &ptype, &bocos->npnts, bocos->n_index, &bocos->n_cnt, &datatype, &ndatasets)) FATAL ("read_zone_boco", NULL); bocos->type = bctype; bocos->ptype = ptype; bocos->n_type = datatype; npnts = bocos->npnts * z->idim; bocos->pnts = (cgsize_t *) calloc ((size_t)npnts, sizeof(cgsize_t)); if (NULL == bocos->pnts) FATAL ("read_zone_boco", "calloc failed for boco point arrays"); if (bocos->n_cnt) { bocos->n_list = (double *) calloc ((size_t)bocos->n_cnt, sizeof(double)); if (NULL == bocos->n_list) FATAL ("read_zone_boco", "calloc failed for boco normal list"); } if (cg_boco_read (cgnsfn, cgnsbase, nz, nb, bocos->pnts, bocos->n_list)) FATAL ("read_zone_boco", NULL); } } return z->nbocos; } /*---------- read_zone_solution --------------------------------------- * read zone solution *---------------------------------------------------------------------*/ int read_zone_solution (int nz) { int i, j, ns, nd; CGNS_ENUMT(DataType_t) datatype; CGNS_ENUMT(GridLocation_t) location; ZONE *z = &Zones[nz-1]; SOLUTION *sols; if (cg_nsols (cgnsfn, cgnsbase, nz, &z->nsols)) FATAL ("read_zone_solution", NULL); if (z->nsols) { z->sols = sols = new_solution (z->nsols); for (ns = 1; ns <= z->nsols; ns++, sols++) { if (cg_sol_info (cgnsfn, cgnsbase, nz, ns, sols->name, &location)) FATAL ("read_zone_solution", NULL); sols->location = location; if (z->type == CGNS_ENUMV(Structured)) { if (sols->location == CGNS_ENUMV(Vertex)) { for (i = 0; i < 3; i++) for (j = 0; j < 2; j++) sols->rind[i][j] = 0; sols->size = z->dim[0] * z->dim[1] * z->dim[2]; } else if (sols->location == CGNS_ENUMV(CellCenter)) { if (cg_goto (cgnsfn, cgnsbase, "Zone_t", nz, "FlowSolution_t", ns, "end")) FATAL ("read_zone_solution", NULL); if (cg_rind_read ((int *)sols->rind)) { for (i = 0; i < 3; i++) for (j = 0; j < 2; j++) sols->rind[i][j] = 0; } sols->size = 1; for (i = 0; i < 3; i++) { sols->size *= (z->dim[i] - 1 + sols->rind[i][0] + sols->rind[i][1]); } } else FATAL ("read_zone_solution", "solution location not Vertex or CellCenter"); } else { sols->size = sols->location == CGNS_ENUMV(Vertex) ? z->dim[0] : z->dim[1]; for (i = 0; i < 3; i++) for (j = 0; j < 2; j++) sols->rind[i][j] = 0; } if (cg_nfields (cgnsfn, cgnsbase, nz, ns, &sols->nflds)) FATAL ("read_zone_solution", NULL); if (sols->nflds) { sols->flds = new_field (sols->nflds, 0); for (i = 0; i < sols->nflds; i++) { if (cg_field_info (cgnsfn, cgnsbase, nz, ns, i+1, &datatype, sols->flds[i].name)) FATAL ("read_zone_solution", NULL); } } /* get units */ if (cg_goto (cgnsfn, cgnsbase, "Zone_t", nz, "FlowSolution_t", ns, "end")) FATAL ("read_zone_solution", NULL); if (!read_units (sols->units)) { for (i = 0; i < 5; i++) sols->units[i] = z->units[i]; } if (cg_dataclass_read ((CGNS_ENUMT(DataClass_t) *)&sols->dataclass)) sols->dataclass = z->dataclass; /* get descriptors */ if (cg_ndescriptors (&nd)) FATAL ("cg_ndescriptors", NULL); if (nd) { sols->ndesc = nd; sols->desc = new_desc (nd); for (i = 0; i < nd; i++) { if (cg_descriptor_read (i+1, sols->desc[i].name, &sols->desc[i].desc)) FATAL ("cg_descriptor_read", NULL); } } } } return z->nsols; } /*---------- read_solution_field -------------------------------------- * read solution field data for a zone *---------------------------------------------------------------------*/ cgsize_t read_solution_field (int nz, int ns, int nf) { int n, is, ie; cgsize_t min[3], max[3]; CGNS_ENUMT(DataType_t) datatype; ZONE *z = &Zones[nz-1]; SOLUTION *s = &z->sols[ns-1]; FIELD *f; if (z->type == CGNS_ENUMV(Structured)) { for (n = 0; n < 3; n++) { min[n] = 1; max[n] = z->dim[n]; } if (s->location == CGNS_ENUMV(CellCenter)) { for (n = 0; n < 3; n++) max[n] += s->rind[n][0] + s->rind[n][1] - 1; } } else { for (n = 0; n < 3; n++) { min[n] = 1; max[n] = s->size; } } if (nf) { is = ie = nf; } else { is = 1; ie = s->nflds; } f = &s->flds[is-1]; for (nf = is; nf <= ie; nf++, f++) { if (cg_field_info (cgnsfn, cgnsbase, nz, ns, nf, &datatype, f->name)) FATAL ("read_solution_field", NULL); f->id = nf; f->datatype = datatype; f->data = (double *) malloc ((size_t)s->size * sizeof(double)); if (NULL == f->data) FATAL ("read_solution_field", "malloc failed for solution field data"); if (cg_field_read (cgnsfn, cgnsbase, nz, ns, f->name, CGNS_ENUMV(RealDouble), min, max, f->data)) FATAL ("read_solution_field", NULL); if (cg_goto (cgnsfn, cgnsbase, "Zone_t", nz, "FlowSolution_t", ns, "DataArray_t", nf, "end")) FATAL ("read_solution_field", NULL); if (!read_units (f->units)) { for (n = 0; n < 5; n++) f->units[n] = s->units[n]; } /* read data class, conversion and exponents */ if (cg_dataclass_read ((CGNS_ENUMT(DataClass_t) *)&f->dataclass)) f->dataclass = s->dataclass; if (cg_conversion_info (&datatype)) f->dataconv[0] = 1.0; else { f->convtype = datatype; if (datatype == CGNS_ENUMV(RealSingle)) { float conv[2]; if (cg_conversion_read (conv)) FATAL ("read_solution_field", NULL); for (n = 0; n < 2; n++) f->dataconv[n] = conv[n]; } else if (datatype == CGNS_ENUMV(RealDouble)) { if (cg_conversion_read (f->dataconv)) FATAL ("read_solution_field", NULL); } else FATAL ("cg_conversion_info", "invalid data type"); } if (!cg_exponents_info (&datatype)) { f->exptype = datatype; if (datatype == CGNS_ENUMV(RealSingle)) { float exp[5]; if (cg_exponents_read (exp)) FATAL ("read_solution_field", NULL); for (n = 0; n < 5; n++) f->exponent[n] = exp[n]; } else if (datatype == CGNS_ENUMV(RealDouble)) { if (cg_exponents_read (f->exponent)) FATAL ("read_solution_field", NULL); } else FATAL ("cg_exponents_info", "invalid data type"); } } return s->size; } /*---------- read_units ----------------------------------------------- * read unit specifications *---------------------------------------------------------------------*/ int read_units (int units[5]) { int n; CGNS_ENUMT(MassUnits_t) mass; CGNS_ENUMT(LengthUnits_t) length; CGNS_ENUMT(TimeUnits_t) time; CGNS_ENUMT(TemperatureUnits_t) temp; CGNS_ENUMT(AngleUnits_t) angle; if (cg_units_read (&mass, &length, &time, &temp, &angle)) { for (n = 0; n < 5; n++) units[n] = 0; return 0; } units[0] = mass; units[1] = length; units[2] = time; units[3] = temp; units[4] = angle; return 1; } /*---------- write_cgns ----------------------------------------------- * write the CGNS file *---------------------------------------------------------------------*/ void write_cgns (void) { int nz, ns; write_zones (); for (nz = 1; nz <= nZones; nz++) { write_zone_grid (nz); write_zone_element (nz); write_zone_interface (nz); write_zone_connect (nz); write_zone_boco (nz); for (ns = 1; ns <= Zones[nz-1].nsols; ns++) { write_zone_solution (nz, ns); write_solution_field (nz, ns, 0); } } } /*---------- write_zones ---------------------------------------------- * write zone information to CGNS file *---------------------------------------------------------------------*/ void write_zones (void) { int n, nz; cgsize_t sizes[3][3]; ZONE *z = Zones; for (n = 0; n < 5; n++) { if (baseunits[n]) { if (cg_goto (cgnsfn, cgnsbase, "end") || cg_units_write ((CGNS_ENUMT(MassUnits_t))baseunits[0], (CGNS_ENUMT(LengthUnits_t))baseunits[1], (CGNS_ENUMT(TimeUnits_t))baseunits[2], (CGNS_ENUMT(TemperatureUnits_t))baseunits[3], (CGNS_ENUMT(AngleUnits_t))baseunits[4])) FATAL ("write_zones", NULL); break; } } if (baseclass) { if (cg_goto (cgnsfn, cgnsbase, "end") || cg_dataclass_write ((CGNS_ENUMT(DataClass_t))baseclass)) FATAL ("write_zones", NULL); } /* write the zone information */ for (nz = 0; nz < nZones; nz++, z++) { if (!z->id) continue; for (n = 0; n < 3; n++) { sizes[0][n] = z->dim[n]; sizes[1][n] = z->dim[n] - 1; sizes[2][n] = 0; } if (cg_zone_write (cgnsfn, cgnsbase, z->name, (cgsize_t *)sizes, (CGNS_ENUMT(ZoneType_t))z->type, &z->id)) FATAL ("write_zones", NULL); for (n = 0; n < 5; n++) { if (z->units[n] && z->units[n] != baseunits[n]) { if (cg_goto (cgnsfn, cgnsbase, "Zone_t", z->id, "end") || cg_units_write ((CGNS_ENUMT(MassUnits_t))z->units[0], (CGNS_ENUMT(LengthUnits_t))z->units[1], (CGNS_ENUMT(TimeUnits_t))z->units[2], (CGNS_ENUMT(TemperatureUnits_t))z->units[3], (CGNS_ENUMT(AngleUnits_t))z->units[4])) FATAL ("write_zones", NULL); break; } } if (z->dataclass && z->dataclass != baseclass) { if (cg_goto (cgnsfn, cgnsbase, "Zone_t", z->id, "end") || cg_dataclass_write ((CGNS_ENUMT(DataClass_t))z->dataclass)) FATAL ("write_zones", NULL); } if (z->ndesc) { if (cg_goto (cgnsfn, cgnsbase, "Zone_t", z->id, "end")) FATAL ("write_zones", NULL); for (n = 0; n < z->ndesc; n++) { if (cg_descriptor_write (z->desc[n].name, z->desc[n].desc)) FATAL ("cg_descriptor_write", NULL); } } } } /*---------- write_zone_data ------------------------------------------ * write all zone data *---------------------------------------------------------------------*/ void write_zone_data (int nz) { int n, ns; cgsize_t sizes[3][3]; ZONE *z = &Zones[nz-1]; /* write the zone information */ for (n = 0; n < 3; n++) { sizes[0][n] = z->dim[n]; sizes[1][n] = z->dim[n] - 1; sizes[2][n] = 0; } if (cg_zone_write (cgnsfn, cgnsbase, z->name, (cgsize_t *)sizes, (CGNS_ENUMT(ZoneType_t))z->type, &z->id)) FATAL ("write_zone_data", NULL); for (n = 0; n < 5; n++) { if (z->units[n] && z->units[n] != baseunits[n]) { if (cg_goto (cgnsfn, cgnsbase, "Zone_t", z->id, "end") || cg_units_write ((CGNS_ENUMT(MassUnits_t))z->units[0], (CGNS_ENUMT(LengthUnits_t))z->units[1], (CGNS_ENUMT(TimeUnits_t))z->units[2], (CGNS_ENUMT(TemperatureUnits_t))z->units[3], (CGNS_ENUMT(AngleUnits_t))z->units[4])) FATAL ("write_zone_data", NULL); break; } } write_zone_grid (nz); write_zone_element (nz); write_zone_interface (nz); write_zone_connect (nz); write_zone_boco (nz); for (ns = 1; ns <= Zones[nz-1].nsols; ns++) { write_zone_solution (nz, ns); write_solution_field (nz, ns, 0); } } /*---------- write_zone_grid ------------------------------------------ * write zone grid coordinates *---------------------------------------------------------------------*/ void write_zone_grid (int nz) { int nc; cgsize_t n; ZONE *z = &Zones[nz-1]; if (z->verts == NULL || (z->vertflags & 7) == 0) return; if (z->datatype == CGNS_ENUMV(RealSingle)) { float *xyz = (float *) malloc ((size_t)z->nverts * sizeof(float)); if (NULL == xyz) FATAL ("write_zone_grid", "malloc failed for coordinate working array"); if ((z->vertflags & 1) == 1) { for (n = 0; n < z->nverts; n++) xyz[n] = (float)z->verts[n].x; if (cg_coord_write (cgnsfn, cgnsbase, z->id, CGNS_ENUMV(RealSingle), "CoordinateX", xyz, &nc)) FATAL ("write_zone_grid", NULL); } if ((z->vertflags & 2) == 2) { for (n = 0; n < z->nverts; n++) xyz[n] = (float)z->verts[n].y; if (cg_coord_write (cgnsfn, cgnsbase, z->id, CGNS_ENUMV(RealSingle), "CoordinateY", xyz, &nc)) FATAL ("write_zone_grid", NULL); } if ((z->vertflags & 4) == 4) { for (n = 0; n < z->nverts; n++) xyz[n] = (float)z->verts[n].z; if (cg_coord_write (cgnsfn, cgnsbase, z->id, CGNS_ENUMV(RealSingle), "CoordinateZ", xyz, &nc)) FATAL ("write_zone_grid", NULL); } free (xyz); } else { double *xyz = (double *) malloc ((size_t)z->nverts * sizeof(double)); if (NULL == xyz) FATAL ("write_zone_grid", "malloc failed for coordinate working array"); if ((z->vertflags & 1) == 1) { for (n = 0; n < z->nverts; n++) xyz[n] = z->verts[n].x; if (cg_coord_write (cgnsfn, cgnsbase, z->id, CGNS_ENUMV(RealDouble), "CoordinateX", xyz, &nc)) FATAL ("write_zone_grid", NULL); } if ((z->vertflags & 2) == 2) { for (n = 0; n < z->nverts; n++) xyz[n] = z->verts[n].y; if (cg_coord_write (cgnsfn, cgnsbase, z->id, CGNS_ENUMV(RealDouble), "CoordinateY", xyz, &nc)) FATAL ("write_zone_grid", NULL); } if ((z->vertflags & 4) == 4) { for (n = 0; n < z->nverts; n++) xyz[n] = z->verts[n].z; if (cg_coord_write (cgnsfn, cgnsbase, z->id, CGNS_ENUMV(RealDouble), "CoordinateZ", xyz, &nc)) FATAL ("write_zone_grid", NULL); } free (xyz); } } /*---------- write_zone_element --------------------------------------- * write zone element sets and elements *---------------------------------------------------------------------*/ void write_zone_element (int nz) { int ns; ZONE *z = &Zones[nz-1]; ELEMSET *eset = z->esets; if (eset == NULL || z->type == CGNS_ENUMV(Structured)) return; for (ns = 1; ns <= z->nesets; ns++, eset++) { if (eset->id) { if (cg_section_write (cgnsfn, cgnsbase, z->id, eset->name, (CGNS_ENUMT(ElementType_t))eset->type, eset->start, eset->end, eset->nbndry, eset->conn, &eset->id)) FATAL ("write_zone_element", NULL); if (eset->parent != NULL && cg_parent_data_write (cgnsfn, cgnsbase, z->id, eset->id, eset->parent)) FATAL ("write_zone_element", NULL); } } } /*---------- write_zone_interface ------------------------------------- * write zone 1 to 1 interfaces *---------------------------------------------------------------------*/ void write_zone_interface (int nz) { int i, j, ni; cgsize_t range[2][3], d_range[2][3]; ZONE *z = &Zones[nz-1]; INTERFACE *ints = z->ints; if (ints == NULL) return; for (ni = 1; ni <= z->nints; ni++, ints++) { if (ints->id) { for (j = 0; j < 2; j++) { for (i = 0; i < 3; i++) { range[j][i] = ints->range[i][j]; d_range[j][i] = ints->d_range[i][j]; } } if (cg_1to1_write (cgnsfn, cgnsbase, z->id, ints->name, ints->d_name, (cgsize_t *)range, (cgsize_t *)d_range, ints->transform, &ints->id)) FATAL ("write_zone_interface", NULL); } } } /*---------- write_zone_connect --------------------------------------- * write zone connectivities *---------------------------------------------------------------------*/ void write_zone_connect (int nz) { int nc; ZONE *z = &Zones[nz-1]; CONNECT *conns = z->conns; if (conns == NULL) return; for (nc = 1; nc <= z->nconns; nc++, conns++) { if (conns->id && cg_conn_write (cgnsfn, cgnsbase, z->id, conns->name, (CGNS_ENUMT(GridLocation_t))conns->location, (CGNS_ENUMT(GridConnectivityType_t))conns->type, (CGNS_ENUMT(PointSetType_t))conns->ptype, conns->npnts, conns->pnts, conns->d_name, (CGNS_ENUMT(ZoneType_t))conns->d_ztype, (CGNS_ENUMT(PointSetType_t))conns->d_ptype, CGNS_ENUMV(Integer), conns->d_npnts, conns->d_pnts, &conns->id)) FATAL ("write_zone_connect", NULL); } } /*---------- write_zone_bocos ----------------------------------------- * write zone boundary conditions *---------------------------------------------------------------------*/ void write_zone_boco (int nz) { int nb; ZONE *z = &Zones[nz-1]; BOCO *bocos = z->bocos; if (bocos == NULL) return; for (nb = 1; nb <= z->nbocos; nb++, bocos++) { if (bocos->id && (cg_boco_write (cgnsfn, cgnsbase, z->id, bocos->name, (CGNS_ENUMT(BCType_t))bocos->type, (CGNS_ENUMT(PointSetType_t))bocos->ptype, bocos->npnts, bocos->pnts, &bocos->id) || cg_boco_normal_write (cgnsfn, cgnsbase, z->id, bocos->id, bocos->n_index, (int)bocos->n_cnt, (CGNS_ENUMT(DataType_t))bocos->n_type, bocos->n_list))) FATAL ("write_zone_boco", NULL); } } /*---------- write_zone_solution -------------------------------------- * write zone solution *---------------------------------------------------------------------*/ void write_zone_solution (int nz, int ns) { int n; ZONE *z = &Zones[nz-1]; SOLUTION *s; if (z->sols == NULL || ns < 1 || ns > z->nsols) return; s = &z->sols[ns-1]; if (cg_sol_write (cgnsfn, cgnsbase, z->id, s->name, (CGNS_ENUMT(GridLocation_t))s->location, &s->id)) FATAL ("write_zone_solution", NULL); if (z->type == CGNS_ENUMV(Structured) && s->location == CGNS_ENUMV(CellCenter)) { if (cg_goto (cgnsfn, cgnsbase, "Zone_t", z->id, "FlowSolution_t", s->id, "end") || cg_rind_write ((int *)s->rind)) FATAL ("write_zone_solution", NULL); } for (n = 0; n < 5; n++) { if (s->units[n] && s->units[n] != z->units[n]) { if (cg_goto (cgnsfn, cgnsbase, "Zone_t", z->id, "FlowSolution_t", s->id, "end") || cg_units_write ((CGNS_ENUMT(MassUnits_t))s->units[0], (CGNS_ENUMT(LengthUnits_t))s->units[1], (CGNS_ENUMT(TimeUnits_t))s->units[2], (CGNS_ENUMT(TemperatureUnits_t))s->units[3], (CGNS_ENUMT(AngleUnits_t))s->units[4])) FATAL ("write_zone_solution", NULL); break; } } if (s->dataclass && s->dataclass != z->dataclass) { if (cg_goto (cgnsfn, cgnsbase, "Zone_t", z->id, "FlowSolution_t", s->id, "end") || cg_dataclass_write ((CGNS_ENUMT(DataClass_t))s->dataclass)) FATAL ("write_zone_solution", NULL); } if (s->ndesc) { if (cg_goto (cgnsfn, cgnsbase, "Zone_t", z->id, "FlowSolution_t", s->id, "end")) FATAL ("write_zone_solution", NULL); for (n = 0; n < s->ndesc; n++) { if (cg_descriptor_write (s->desc[n].name, s->desc[n].desc)) FATAL ("cg_descriptor_write", NULL); } } } /*---------- write_solution_field ------------------------------------- * write solution field data for a zone *---------------------------------------------------------------------*/ void write_solution_field (int nz, int ns, int nf) { int n, is, ie; float *data = NULL; ZONE *z = &Zones[nz-1]; SOLUTION *s = &z->sols[ns-1]; FIELD *f; if (nf) { is = ie = nf; } else { is = 1; ie = s->nflds; } f = &s->flds[is-1]; for (nf = is; nf <= ie; nf++, f++) { if (f->data == NULL) continue; if (f->datatype == CGNS_ENUMV(RealSingle)) { if (data == NULL) { data = (float *) malloc ((size_t)s->size * sizeof(float)); if (NULL == data) FATAL ("write_solution_field", "malloc failed for working array"); } for (n = 0; n < s->size; n++) data[n] = (float)f->data[n]; if (cg_field_write (cgnsfn, cgnsbase, z->id, s->id, CGNS_ENUMV(RealSingle), f->name, data, &f->id)) FATAL ("write_solution_field", NULL); } else { if (cg_field_write (cgnsfn, cgnsbase, z->id, s->id, CGNS_ENUMV(RealDouble), f->name, f->data, &f->id)) FATAL ("write_solution_field", NULL); } for (n = 0; n < 5; n++) { if (f->units[n] && f->units[n] != s->units[n]) { if (cg_goto (cgnsfn, cgnsbase, "Zone_t", z->id, "FlowSolution_t", s->id, "DataArray_t", f->id, "end") || cg_units_write ((CGNS_ENUMT(MassUnits_t))f->units[0], (CGNS_ENUMT(LengthUnits_t))f->units[1], (CGNS_ENUMT(TimeUnits_t))f->units[2], (CGNS_ENUMT(TemperatureUnits_t))f->units[3], (CGNS_ENUMT(AngleUnits_t))f->units[4])) FATAL ("write_solution_field", NULL); break; } } if (f->dataclass && f->dataclass != s->dataclass) { if (cg_goto (cgnsfn, cgnsbase, "Zone_t", z->id, "FlowSolution_t", s->id, "DataArray_t", f->id, "end") || cg_dataclass_write ((CGNS_ENUMT(DataClass_t))f->dataclass)) FATAL ("write_solution_field", NULL); } if (f->convtype == CGNS_ENUMV(RealSingle)) { float conv[2]; for (n = 0; n < 2; n++) conv[n] = (float)f->dataconv[n]; if (cg_goto (cgnsfn, cgnsbase, "Zone_t", z->id, "FlowSolution_t", s->id, "DataArray_t", f->id, "end") || cg_conversion_write (CGNS_ENUMV(RealSingle), conv)) FATAL ("write_solution_field", NULL); } else if (f->convtype == CGNS_ENUMV(RealDouble)) { if (cg_goto (cgnsfn, cgnsbase, "Zone_t", z->id, "FlowSolution_t", s->id, "DataArray_t", f->id, "end") || cg_conversion_write (CGNS_ENUMV(RealDouble), f->dataconv)) FATAL ("write_solution_field", NULL); } else {} if (f->exptype == CGNS_ENUMV(RealSingle)) { float exp[5]; for (n = 0; n < 5; n++) exp[n] = (float)f->dataconv[n]; if (cg_goto (cgnsfn, cgnsbase, "Zone_t", z->id, "FlowSolution_t", s->id, "DataArray_t", f->id, "end") || cg_exponents_write (CGNS_ENUMV(RealSingle), exp)) FATAL ("write_solution_field", NULL); } else if (f->exptype == CGNS_ENUMV(RealDouble)) { if (cg_goto (cgnsfn, cgnsbase, "Zone_t", z->id, "FlowSolution_t", s->id, "DataArray_t", f->id, "end") || cg_exponents_write (CGNS_ENUMV(RealDouble), f->exponent)) FATAL ("write_solution_field", NULL); } else {} } if (data != NULL) free (data); } /*---------- volume_tet ----------------------------------------------- * compute volume of a tetrahedron *---------------------------------------------------------------------*/ double volume_tet (VERTEX *v1, VERTEX *v2, VERTEX *v3, VERTEX *v4) { double vol = ((v4->x - v1->x) * ((v2->y - v1->y) * (v3->z - v1->z) - (v2->z - v1->z) * (v3->y - v1->y)) + (v4->y - v1->y) * ((v2->z - v1->z) * (v3->x - v1->x) - (v2->x - v1->x) * (v3->z - v1->z)) + (v4->z - v1->z) * ((v2->x - v1->x) * (v3->y - v1->y) - (v2->y - v1->y) * (v3->x - v1->x))) / 6.0; return vol; } /*---------- volume_pyr ----------------------------------------------- * compute volume of a pyramid *---------------------------------------------------------------------*/ double volume_pyr (VERTEX *v1, VERTEX *v2, VERTEX *v3, VERTEX *v4, VERTEX *v5) { VERTEX p; double vol; p.x = 0.25 * (v1->x + v2->x + v3->x + v4->x); p.y = 0.25 * (v1->y + v2->y + v3->y + v4->y); p.z = 0.25 * (v1->z + v2->z + v3->z + v4->z); vol = (v5->x - p.x) * ((v3->y - v1->y) * (v4->z - v2->z) - (v3->z - v1->z) * (v4->y - v2->y)) + (v5->y - p.y) * ((v3->z - v1->z) * (v4->x - v2->x) - (v3->x - v1->x) * (v4->z - v2->z)) + (v5->z - p.z) * ((v3->x - v1->x) * (v4->y - v2->y) - (v3->y - v1->y) * (v4->x - v2->x)); return vol; } /*---------- volume_wdg ----------------------------------------------- * compute volume of a wedge (prism) *---------------------------------------------------------------------*/ double volume_wdg (VERTEX *v1, VERTEX *v2, VERTEX *v3, VERTEX *v4, VERTEX *v5, VERTEX *v6) { VERTEX p; double vol; p.x = (v1->x + v2->x + v3->x + v4->x + v5->x + v6->x) / 6.0; p.y = (v1->y + v2->y + v3->y + v4->y + v5->y + v6->y) / 6.0; p.z = (v1->z + v2->z + v3->z + v4->z + v5->z + v6->z) / 6.0; vol = volume_tet (v1, v2, v3, &p) + volume_tet (v4, v6, v5, &p) + volume_pyr (v1, v4, v5, v2, &p) + volume_pyr (v2, v5, v6, v3, &p) + volume_pyr (v1, v3, v6, v4, &p); return vol; } /*---------- volume_hex ----------------------------------------------- * compute volume of a hexahedron *---------------------------------------------------------------------*/ double volume_hex (VERTEX *v1, VERTEX *v2, VERTEX *v3, VERTEX *v4, VERTEX *v5, VERTEX *v6, VERTEX *v7, VERTEX *v8) { VERTEX p; double vol; p.x = 0.125 * (v1->x + v2->x + v3->x + v4->x + v5->x + v6->x + v7->x + v8->x); p.y = 0.125 * (v1->y + v2->y + v3->y + v4->y + v5->y + v6->y + v7->y + v8->y); p.z = 0.125 * (v1->z + v2->z + v3->z + v4->z + v5->z + v6->z + v7->z + v8->z); vol = volume_pyr (v1, v2, v3, v4, &p) + volume_pyr (v1, v5, v6, v2, &p) + volume_pyr (v2, v6, v7, v3, &p) + volume_pyr (v3, v7, v8, v4, &p) + volume_pyr (v4, v8, v5, v1, &p) + volume_pyr (v5, v8, v7, v6, &p); return vol; } /*---------- volume_element ------------------------------------------- * compute volume of an element *---------------------------------------------------------------------*/ double volume_element (int nn, VERTEX *v[]) { switch (nn) { case 4: return volume_tet (v[0], v[1], v[2], v[3]); case 5: return volume_pyr (v[0], v[1], v[2], v[3], v[4]); case 6: return volume_wdg (v[0], v[1], v[2], v[3], v[4], v[5]); case 8: return volume_hex (v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); } return 0.0; } /*---------- cell_volume ---------------------------------------------- * compute cell volume in a zone *---------------------------------------------------------------------*/ double cell_volume (ZONE *z, cgsize_t i, cgsize_t j, cgsize_t k) { cgsize_t ni, nj; VERTEX *v; double vol; ni = z->dim[0]; nj = ni * z->dim[1]; v = &z->verts[vertex_index (z, i, j, k)]; vol = volume_hex (v, v + 1, v + ni + 1, v + ni, v + nj, v + nj + 1, v + nj + ni + 1, v + nj + ni); return fabs (vol); } /*---------- vertex_volumes ------------------------------------------- * compute cell volumes at vertices *---------------------------------------------------------------------*/ void vertex_volumes (int nz) { int ns, nn, et, nv, ii; cgsize_t i, j, n, ne, ni; ZONE *z = &Zones[nz-1]; VERTEX *v[8]; double vol; if (z->verts == NULL) read_zone_grid (nz); if (z->esets == NULL) { if (z->type == CGNS_ENUMV(Structured)) structured_elements (nz); else read_zone_element (nz); } for (i = 0; i < z->nverts; i++) z->verts[i].w = 0.0; for (ns = 0; ns < z->nesets; ns++) { ne = z->esets[ns].end - z->esets[ns].start + 1; et = z->esets[ns].type; if (et < CGNS_ENUMV(TETRA_4) || et > CGNS_ENUMV(MIXED)) continue; for (n = 0, j = 0; j < ne; j++) { if (z->esets[ns].type == CGNS_ENUMV(MIXED)) et = (int)z->esets[ns].conn[n++]; switch (et) { case CGNS_ENUMV(TETRA_4): case CGNS_ENUMV(TETRA_10): nv = 4; break; case CGNS_ENUMV(PYRA_5): case CGNS_ENUMV(PYRA_14): nv = 5; break; case CGNS_ENUMV(PENTA_6): case CGNS_ENUMV(PENTA_15): case CGNS_ENUMV(PENTA_18): nv = 6; break; case CGNS_ENUMV(HEXA_8): case CGNS_ENUMV(HEXA_20): case CGNS_ENUMV(HEXA_27): nv = 8; break; default: nv = 0; break; } nn = element_node_counts[et]; if (nv) { for (ii = 0; ii < nv; ii++) v[ii] = &z->verts[z->esets[ns].conn[n+ii]-1]; vol = fabs (volume_element (nv, v)) / (double)nn; for (ii = 0; ii < nn; ii++) { ni = z->esets[ns].conn[n+ii] - 1; z->verts[ni].w += vol; } } n += nn; } } } /*---------- to_cell_vertex ------------------------------------------- * convert cell-centered field to cell-vertex *---------------------------------------------------------------------*/ static void to_cell_vertex (ZONE *z, SOLUTION *s, FIELD *f, double *w) { int nes, et, nv, ii; cgsize_t n, i, j, k, ni, nj, nk; cgsize_t np, nn, ns, nw; double *data; double *wsum; if (z->type == CGNS_ENUMV(Structured)) np = z->dim[0] * z->dim[1] * z->dim[2]; else np = z->dim[0]; data = (double *) malloc ((size_t)np * sizeof(double)); wsum = (double *) malloc ((size_t)np * sizeof(double)); if (NULL == data || NULL == wsum) FATAL ("to_cell_center", "malloc failed for field data"); for (n = 0; n < np; n++) { data[n] = 0.0; wsum[n] = 0.0; } if (z->type == CGNS_ENUMV(Structured)) { ni = z->dim[0]; nj = z->dim[1]; nk = z->dim[2]; for (k = 1; k < nk; k++) { for (j = 1; j < nj; j++) { for (i = 1; i < ni; i++) { ns = solution_index (z, s, i, j, k); nw = cell_index (z, i, j, k); nn = vertex_index (z, i, j, k); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, i+1, j, k); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, i, j+1, k); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, i+1, j+1, k); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, i, j, k+1); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, i+1, j, k+1); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, i, j+1, k+1); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, i+1, j+1, k+1); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; } } } if (s->rind[0][0]) { for (k = 1; k < nk; k++) { for (j = 1; j < nj; j++) { ns = solution_index (z, s, 0, j, k); nw = cell_index (z, 1, j, k); nn = vertex_index (z, 1, j, k); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, 1, j+1, k); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, 1, j, k+1); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, 1, j+1, k+1); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; } } } if (s->rind[0][1]) { for (k = 1; k < nk; k++) { for (j = 1; j < nj; j++) { ns = solution_index (z, s, ni, j, k); nw = cell_index (z, ni-1, j, k); nn = vertex_index (z, ni, j, k); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, ni, j+1, k); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, ni, j, k+1); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, ni, j+1, k+1); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; } } } if (s->rind[1][0]) { for (k = 1; k < nk; k++) { for (i = 1; i < ni; i++) { ns = solution_index (z, s, i, 0, k); nw = cell_index (z, i, 1, k); nn = vertex_index (z, i, 1, k); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, i+1, 1, k); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, i, 1, k+1); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, i+1, 1, k+1); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; } } } if (s->rind[1][1]) { for (k = 1; k < nk; k++) { for (i = 1; i < ni; i++) { ns = solution_index (z, s, i, nj, k); nw = cell_index (z, i, nj-1, k); nn = vertex_index (z, i, nj, k); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, i+1, nj, k); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, i, nj, k+1); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, i+1, nj, k+1); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; } } } if (s->rind[2][0]) { for (j = 1; j < nj; j++) { for (i = 1; i < ni; i++) { ns = solution_index (z, s, i, j, 0); nw = cell_index (z, i, j, 1); nn = vertex_index (z, i, j, 1); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, i+1, j, 1); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, i, j+1, 1); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, i+1, j+1, 1); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; } } } if (s->rind[2][1]) { for (j = 1; j < nj; j++) { for (i = 1; i < ni; i++) { ns = solution_index (z, s, i, j, nk); nw = cell_index (z, i, j, nk-1); nn = vertex_index (z, i, j, nk); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, i+1, j, nk); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, i, j+1, nk); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; nn = vertex_index (z, i+1, j+1, nk); data[nn] += (w[nw] * f->data[ns]); wsum[nn] += w[nw]; } } } } else { for (nes = 0; nes < z->nesets; nes++) { et = z->esets[nes].type; if (et < CGNS_ENUMV(TETRA_4) || et > CGNS_ENUMV(MIXED)) continue; for (n = 0, j = z->esets[nes].start-1; j < z->esets[nes].end; j++) { if (z->esets[nes].type == CGNS_ENUMV(MIXED)) et = (int)z->esets[nes].conn[n++]; nv = element_node_counts[et]; if (j < s->size && et >= CGNS_ENUMV(TETRA_4) && et <= CGNS_ENUMV(HEXA_27)) { for (ii = 0; ii < nv; ii++) { nn = z->esets[nes].conn[n+ii] - 1; data[nn] += (w[j] * f->data[j]); wsum[nn] += w[j]; } } n += nv; } } } for (n = 0; n < np; n++) { if (wsum[n] != 0.0) data[n] /= wsum[n]; } free (wsum); free (f->data); f->data = data; } /*---------- cell_vertex_solution ------------------------------------- * convert cell-center solution to cell-vertex *---------------------------------------------------------------------*/ void cell_vertex_solution (int nz, int ns, int weighting) { int nf, nes, et, nv, ii, jj; cgsize_t n, i, j, k, ni, nj, nk, nc; double *w; ZONE *z = &Zones[nz-1]; SOLUTION *s = &z->sols[ns-1]; if (s->location == CGNS_ENUMV(Vertex) || !s->size || !s->nflds) return; if (s->location != CGNS_ENUMV(CellCenter)) FATAL ("cell_vertex_solution", "solution not cell-centered"); if (z->type == CGNS_ENUMV(Structured)) { if (z->dim[0] < 2 || z->dim[1] < 2 || z->dim[2] < 2) FATAL ("cell_vertex_solution", "can only handle 3-dimensional structured zones"); ni = z->dim[0] - 1; nj = z->dim[1] - 1; nk = z->dim[2] - 1; nc = ni * nj * nk; } else { ni = nc = s->size; nj = nk = 1; if (z->esets == NULL && !read_zone_element (nz)) FATAL ("cell_vertex_solution", "no element sets defined"); } for (nf = 0; nf < s->nflds; nf++) { if (s->flds[nf].data != NULL) break; } if (nf == s->nflds) return; w = (double *) malloc ((size_t)nc * sizeof(double)); if (NULL == w) FATAL ("cell_vertex_solution", "malloc failed for weighting function"); if (weighting) { if (z->verts == NULL) read_zone_grid (nz); if (z->type == CGNS_ENUMV(Structured)) { n = 0; for (k = 1; k <= nk; k++) { for (j = 1; j <= nj; j++) { for (i = 1; i <= ni; i++) { w[n++] = fabs (cell_volume (z, i, j, k)); } } } } else { VERTEX *v[8]; for (n = 0; n < nc; n++) w[n] = 0.0; for (nes = 0; nes < z->nesets; nes++) { et = z->esets[nes].type; if (et < CGNS_ENUMV(TETRA_4) || et > CGNS_ENUMV(MIXED)) continue; for (n = 0, j = z->esets[nes].start-1; j < z->esets[nes].end; j++) { if (z->esets[nes].type == CGNS_ENUMV(MIXED)) et = (int)z->esets[nes].conn[n++]; switch (et) { case CGNS_ENUMV(TETRA_4): case CGNS_ENUMV(TETRA_10): nv = 4; break; case CGNS_ENUMV(PYRA_5): case CGNS_ENUMV(PYRA_14): nv = 5; break; case CGNS_ENUMV(PENTA_6): case CGNS_ENUMV(PENTA_15): case CGNS_ENUMV(PENTA_18): nv = 6; break; case CGNS_ENUMV(HEXA_8): case CGNS_ENUMV(HEXA_20): case CGNS_ENUMV(HEXA_27): nv = 8; break; default: nv = 0; break; } if (nv && j < nc) { for (ii = 0; ii < nv; ii++) v[ii] = &z->verts[z->esets[nes].conn[n+ii]-1]; w[j] = fabs (volume_element (nv, v)); } n += element_node_counts[et]; } } } } else { for (n = 0; n < nc; n++) w[n] = 1.0; } for (nf = 0; nf < s->nflds; nf++) { if (s->flds[nf].data != NULL) to_cell_vertex (z, s, &s->flds[nf], w); } free (w); s->location = CGNS_ENUMV(Vertex); for (jj = 0; jj < 3; jj++) for (ii = 0; ii < 2; ii++) s->rind[jj][ii] = 0; s->size = z->nverts; } /*---------- to_cell_center ------------------------------------------- * convert cell-vertex field to cell-centered *---------------------------------------------------------------------*/ static void to_cell_center (ZONE *z, SOLUTION *s, FIELD *f, double *w) { int nes, et, nv, ii; cgsize_t n, i, j, k, ni, nj, nk, np, nn, ns; double *data; double *wsum; if (z->type == CGNS_ENUMV(Structured)) { ni = z->dim[0]; nj = z->dim[1]; nk = z->dim[2]; np = (ni - 1 + s->rind[0][0] + s->rind[0][1]) * (nj - 1 + s->rind[1][0] + s->rind[1][1]) * (nk - 1 + s->rind[2][0] + s->rind[2][1]); } else np = z->dim[1]; data = (double *) malloc ((size_t)np * sizeof(double)); wsum = (double *) malloc ((size_t)np * sizeof(double)); if (NULL == data || NULL == wsum) FATAL ("to_cell_center", "malloc failed for field data"); for (n = 0; n < np; n++) { data[n] = 0.0; wsum[n] = 0.0; } if (z->type == CGNS_ENUMV(Structured)) { for (k = 1; k < nk; k++) { for (j = 1; j < nj; j++) { for (i = 1; i < ni; i++) { ns = solution_index (z, s, i, j, k); nn = vertex_index (z, i, j, k); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, i+1, j, k); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, i, j+1, k); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, i+1, j+1, k); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, i, j, k+1); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, i+1, j, k+1); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, i, j+1, k+1); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, i+1, j+1, k+1); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; } } } if (s->rind[0][0]) { for (k = 1; k < nk; k++) { for (j = 1; j < nj; j++) { ns = solution_index (z, s, 0, j, k); nn = vertex_index (z, 1, j, k); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, 1, j+1, k); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, 1, j, k+1); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, 1, j+1, k+1); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; } } } if (s->rind[0][1]) { for (k = 1; k < nk; k++) { for (j = 1; j < nj; j++) { ns = solution_index (z, s, ni, j, k); nn = vertex_index (z, ni, j, k); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, ni, j+1, k); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, ni, j, k+1); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, ni, j+1, k+1); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; } } } if (s->rind[1][0]) { for (k = 1; k < nk; k++) { for (i = 1; i < ni; i++) { ns = solution_index (z, s, i, 0, k); nn = vertex_index (z, i, 1, k); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, i+1, 1, k); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, i, 1, k+1); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, i+1, 1, k+1); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; } } } if (s->rind[1][1]) { for (k = 1; k < nk; k++) { for (i = 1; i < ni; i++) { ns = solution_index (z, s, i, nj, k); nn = vertex_index (z, i, nj, k); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, i+1, nj, k); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, i, nj, k+1); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, i+1, nj, k+1); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; } } } if (s->rind[2][0]) { for (j = 1; j < nj; j++) { for (i = 1; i < ni; i++) { ns = solution_index (z, s, i, j, 0); nn = vertex_index (z, i, j, 1); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, i+1, j, 1); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, i, j+1, 1); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, i+1, j+1, 1); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; } } } if (s->rind[2][1]) { for (j = 1; j < nj; j++) { for (i = 1; i < ni; i++) { ns = solution_index (z, s, i, j, nk); nn = vertex_index (z, i, j, nk); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, i+1, j, nk); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, i, j+1, nk); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; nn = vertex_index (z, i+1, j+1, nk); data[ns] += (w[nn] * f->data[nn]); wsum[ns] += w[nn]; } } } if (s->rind[0][0] && s->rind[1][0]) { for (k = 1; k < nk; k++) { ns = solution_index (z, s, 0, 0, k); nn = solution_index (z, s, 0, 1, k); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, 1, 0, k); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } } if (s->rind[0][0] && s->rind[1][1]) { for (k = 1; k < nk; k++) { ns = solution_index (z, s, 0, nj, k); nn = solution_index (z, s, 0, nj-1, k); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, 1, nj, k); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } } if (s->rind[0][1] && s->rind[1][0]) { for (k = 1; k < nk; k++) { ns = solution_index (z, s, ni, 0, k); nn = solution_index (z, s, ni, 1, k); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, ni-1, 0, k); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } } if (s->rind[0][1] && s->rind[1][1]) { for (k = 1; k < nk; k++) { ns = solution_index (z, s, ni, nj, k); nn = solution_index (z, s, ni, nj-1, k); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, ni-1, nj, k); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } } if (s->rind[0][0] && s->rind[2][0]) { for (j = 1; j < nj; j++) { ns = solution_index (z, s, 0, j, 0); nn = solution_index (z, s, 0, j, 1); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, 1, j, 0); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } } if (s->rind[0][0] && s->rind[2][1]) { for (j = 1; j < nj; j++) { ns = solution_index (z, s, 0, j, nk); nn = solution_index (z, s, 0, j, nk-1); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, 1, j, nk); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } } if (s->rind[0][1] && s->rind[2][0]) { for (j = 1; j < nj; j++) { ns = solution_index (z, s, ni, j, 0); nn = solution_index (z, s, ni, j, 1); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, ni-1, j, 0); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } } if (s->rind[0][1] && s->rind[2][1]) { for (j = 1; j < nj; j++) { ns = solution_index (z, s, ni, j, nk); nn = solution_index (z, s, ni, j, nk-1); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, ni-1, j, nk); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } } if (s->rind[1][0] && s->rind[2][0]) { for (i = 1; i < ni; i++) { ns = solution_index (z, s, i, 0, 0); nn = solution_index (z, s, i, 0, 1); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, i, 1, 0); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } } if (s->rind[1][0] && s->rind[2][1]) { for (i = 1; i < ni; i++) { ns = solution_index (z, s, i, 0, nk); nn = solution_index (z, s, i, 0, nk-1); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, i, 1, nk); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } } if (s->rind[1][1] && s->rind[2][0]) { for (i = 1; i < ni; i++) { ns = solution_index (z, s, i, nj, 0); nn = solution_index (z, s, i, nj, 1); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, i, nj-1, 0); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } } if (s->rind[1][1] && s->rind[2][1]) { for (i = 1; i < ni; i++) { ns = solution_index (z, s, i, nj, nk); nn = solution_index (z, s, i, nj, nk-1); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, i, nj-1, nk); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } } if (s->rind[0][0] && s->rind[1][0] && s->rind[2][0]) { ns = solution_index (z, s, 0, 0, 0); nn = solution_index (z, s, 1, 0, 0); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, 0, 1, 0); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, 0, 0, 1); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } if (s->rind[0][1] && s->rind[1][0] && s->rind[2][0]) { ns = solution_index (z, s, ni, 0, 0); nn = solution_index (z, s, ni-1, 0, 0); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, ni, 1, 0); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, ni, 0, 1); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } if (s->rind[0][0] && s->rind[1][1] && s->rind[2][0]) { ns = solution_index (z, s, 0, nj, 0); nn = solution_index (z, s, 1, nj, 0); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, 0, nj-1, 0); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, 0, nj, 1); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } if (s->rind[0][1] && s->rind[1][1] && s->rind[2][0]) { ns = solution_index (z, s, ni, nj, 0); nn = solution_index (z, s, ni-1, nj, 0); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, ni, nj-1, 0); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, ni, nj, 1); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } if (s->rind[0][0] && s->rind[1][0] && s->rind[2][1]) { ns = solution_index (z, s, 0, 0, nk); nn = solution_index (z, s, 1, 0, nk); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, 0, 1, nk); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, 0, 0, nk-1); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } if (s->rind[0][1] && s->rind[1][0] && s->rind[2][1]) { ns = solution_index (z, s, ni, 0, nk); nn = solution_index (z, s, ni-1, 0, nk); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, ni, 1, nk); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, ni, 0, nk-1); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } if (s->rind[0][0] && s->rind[1][1] && s->rind[2][1]) { ns = solution_index (z, s, 0, nj, nk); nn = solution_index (z, s, 1, nj, nk); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, 0, nj-1, nk); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, 0, nj, nk-1); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } if (s->rind[0][1] && s->rind[1][1] && s->rind[2][1]) { ns = solution_index (z, s, ni, nj, nk); nn = solution_index (z, s, ni-1, nj, nk); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, ni, nj-1, nk); data[ns] += data[nn]; wsum[ns] += wsum[nn]; nn = solution_index (z, s, ni, nj, nk-1); data[ns] += data[nn]; wsum[ns] += wsum[nn]; } } else { for (nes = 0; nes < z->nesets; nes++) { et = z->esets[nes].type; if (et < CGNS_ENUMV(TETRA_4) || et > CGNS_ENUMV(MIXED)) continue; for (n = 0, j = z->esets[nes].start-1; j < z->esets[nes].end; j++) { if (z->esets[nes].type == CGNS_ENUMV(MIXED)) et = (int)z->esets[nes].conn[n++]; nv = element_node_counts[et]; if (j < np && et >= CGNS_ENUMV(TETRA_4) && et <= CGNS_ENUMV(HEXA_27)) { for (ii = 0; ii < nv; ii++) { nn = z->esets[nes].conn[n+ii] - 1; data[j] += (w[nn] * f->data[nn]); wsum[j] += w[nn]; } } n += nv; } } } for (n = 0; n < np; n++) { if (wsum[n] != 0.0) data[n] /= wsum[n]; } free (wsum); free (f->data); f->data = data; } /*---------- cell_center_solution ------------------------------------- * convert cell-vertex solution to cell-center *---------------------------------------------------------------------*/ void cell_center_solution (int nz, int ns, int weighting) { int ii, jj, nf; cgsize_t n, i, j, k, ni, nj, nk, np, size; double *w, vol; ZONE *z = &Zones[nz-1]; SOLUTION *s = &z->sols[ns-1]; if (s->location == CGNS_ENUMV(CellCenter) || !s->size || !s->nflds) return; if (s->location != CGNS_ENUMV(Vertex)) FATAL ("cell_center_solution", "solution not at cell-vertex"); if (z->type == CGNS_ENUMV(Structured)) { if (z->dim[0] < 2 || z->dim[1] < 2 || z->dim[2] < 2) FATAL ("cell_vertex_solution", "can only handle 3-dimensional structured zones"); ni = z->dim[0]; nj = z->dim[1]; nk = z->dim[2]; np = ni * nj * nk; for (ii = 0; ii < 3; ii++) { for (jj = 0; jj < 2; jj++) { if (s->rind[ii][jj] < 0 || s->rind[ii][jj] > 1) FATAL ("cell_center_solution", "rind must be 0 or 1"); } } size = (ni - 1 + s->rind[0][0] + s->rind[0][1]) * (nj - 1 + s->rind[1][0] + s->rind[1][1]) * (nk - 1 + s->rind[2][0] + s->rind[2][1]); } else { ni = np = z->dim[0]; nj = nk = 1; if (z->esets == NULL && !read_zone_element (nz)) FATAL ("cell_vertex_solution", "no element sets defined"); size = z->dim[1]; } for (nf = 0; nf < s->nflds; nf++) { if (s->flds[nf].data != NULL) break; } if (nf == s->nflds) return; w = (double *) malloc ((size_t)np * sizeof(double)); if (NULL == w) FATAL ("cell_center_solution", "malloc failed for weighting function"); if (weighting) { if (z->verts == NULL) read_zone_grid (nz); if (z->type == CGNS_ENUMV(Structured)) { int *cnt = (int *) malloc ((size_t)np * sizeof(int)); if (NULL == cnt) FATAL ("cell_center_solution", "malloc failed for cnt array"); for (n = 0; n < np; n++) { w[n] = 0.0; cnt[n] = 0; } for (k = 1; k < nk; k++) { for (j = 1; j < nj; j++) { for (i = 1; i < ni; i++) { vol = cell_volume (z, i, j, k); n = vertex_index (z, i, j, k); w[n] += vol; cnt[n]++; n = vertex_index (z, i+1, j, k); w[n] += vol; cnt[n]++; n = vertex_index (z, i, j+1, k); w[n] += vol; cnt[n]++; n = vertex_index (z, i+1, j+1, k); w[n] += vol; cnt[n]++; n = vertex_index (z, i, j, k+1); w[n] += vol; cnt[n]++; n = vertex_index (z, i+1, j, k+1); w[n] += vol; cnt[n]++; n = vertex_index (z, i, j+1, k+1); w[n] += vol; cnt[n]++; n = vertex_index (z, i+1, j+1, k+1); w[n] += vol; cnt[n]++; } } } for (n = 0; n < np; n++) w[n] /= (double)cnt[n]; free (cnt); } else { for (n = 0; n < np; n++) w[n] = z->verts[n].w; vertex_volumes (nz); for (n = 0; n < np; n++) { vol = z->verts[n].w; z->verts[n].w = w[n]; w[n] = vol; } } } else { for (n = 0; n < np; n++) w[n] = 1.0; } for (nf = 0; nf < s->nflds; nf++) { if (s->flds[nf].data != NULL) to_cell_center (z, s, &s->flds[nf], w); } free (w); s->location = CGNS_ENUMV(CellCenter); s->size = size; } cgnslib_3.1.4/src/cgnstools/utilities/conserved.cnv0000664000076400007640000000103512160605674017500 00000000000000# convert primitive variables to conserved # Density -> Density # VelocityX -> MomentumX # VelocityY -> MomentumY # VelocityZ -> MomentumZ # Pressure -> EnergyStagnationDensity MomentumX = VelocityX * Density MomentumY = VelocityY * Density MomentumZ = VelocityZ * Density qq = VelocityX^2 + VelocityY^2 + VelocityZ^2 EnergyStagnationDensity = Pressure / (gamma-1) + 0.5*Density*qq # add conserved variables + MomentumX,MomentumY,MomentumZ,EnergyStagnationDensity # remove primitive variables - VelocityX,VelocityY,VelocityZ,Pressure cgnslib_3.1.4/src/cgnstools/utilities/dimensional.cnv0000664000076400007640000000045512160605674020017 00000000000000# sample conversion file for dimensional data CoordinateX = CoordinateX * ~LengthReference CoordinateY = CoordinateY * ~LengthReference CoordinateZ = CoordinateZ * ~LengthReference VelocityX = VelocityX * ~VelocitySound VelocityY = VelocityY * ~VelocitySound VelocityZ = VelocityZ * ~VelocitySound cgnslib_3.1.4/src/cgnstools/utilities/plot3d_to_cgns.c0000664000076400007640000004221612160605674020073 00000000000000/* * plot3d_to_cgns.c - convert a PLOT3D file to CGNS */ #include #include #include #include "getargs.h" #include "binaryio.h" #include "cgnslib.h" #include "cgnsutil.h" /* command line options */ static char options[] = "spinfuM:db:B:g:c"; static char *usgmsg[] = { "usage: plot3d_to_cgns [options] XYZfile [Qfile] CGNSfile", "options are :", " -s = single block file (default multi-block)", " -p = planar grid format (default whole format)", " -i = has iblank array", " -n = read iblank array, but ignore it", " -f = formatted (ASCII) Plot3d file format", " -u = Fortran unformatted Plot3d file format", " -M = machine type for binary or unformatted - one of:", " ieee bsieee iris alpha hp ibm", " sun dec cray convex nt linux", " case is not significant and only the first", " 2 characters are needed.", " -d = use double-precision (64-bit)", " -b = use CGNS base index ", " -B = set CGNS base name to ", " -c = convert solution to primitive variables", " -g= gamma for data conversions (default 1.4)", "Default is multi-block binary format with no iblank data.", NULL }; static int mblock = 1; static int whole = 1; static int has_iblank = 0; static int use_iblank = 0; static int is_double = 0; static double reference[4]; static double gamma = 1.4; static int convert = 0; /*---------- get_machine -------------------------------------------- * get machine type from command line option *-------------------------------------------------------------------*/ static int get_machine (char *name) { switch (*name++) { case 'i': case 'I': if ('r' == *name || 'R' == *name) return (MACH_IRIS); if ('b' == *name || 'B' == *name) return (MACH_IBM); return (MACH_IEEE); case 'b': case 'B': return (MACH_BSIEEE); case 's': case 'S': return (MACH_SUN); case 'h': case 'H': return (MACH_HP); case 'a': case 'A': return (MACH_ALPHA); case 'd': case 'D': return (MACH_DEC); case 'c': case 'C': if ('r' == *name || 'R' == *name) return (MACH_CRAY); return (MACH_CONVEX); case 'l': case 'L': return (MACH_LINUX); case 'n': return (MACH_WIN32); default: break; } print_usage (usgmsg, "unknown machine name - option (-M)"); return (0); /* quite compiler */ } /*---------- read_xyz ----------------------------------------------- * read PLOT3D XYZ file *-------------------------------------------------------------------*/ static void read_xyz (BINARYIO *bf) { int i, k, n, nk, nz, np, nmax; int *indices, *iblank; void *xyz; VERTEX *verts; /* get number of grid blocks */ if (mblock) { bf_getints (bf, 1, &nZones); if (nZones < 1 || nZones > 100000) { fprintf (stderr, "found %d blocks\n", nZones); fprintf (stderr, "file type and/or format is probably incorrect\n"); bf_close (bf); exit (1); } } else nZones = 1; printf ("reading %d grid blocks\n", nZones); /* read indices for grids */ indices = (int *) malloc (3 * nZones * sizeof(int)); if (NULL == indices) FATAL ("read_xyz", "malloc failed for grid indices"); bf_getints (bf, 3 * nZones, indices); /* create zone structures */ Zones = new_zone (nZones); for (nmax = 0, nz = 0; nz < nZones; nz++) { Zones[nz].type = CGNS_ENUMV(Structured); for (np = 1, n = 0; n < 3; n++) { nk = indices[3 * nz + n]; Zones[nz].dim[n] = nk; np *= nk; } Zones[nz].vertflags = 7; Zones[nz].datatype = is_double ? CGNS_ENUMV(RealDouble) : CGNS_ENUMV(RealSingle); Zones[nz].nverts = np; Zones[nz].verts = new_vertex (np); nk = whole ? (int)Zones[nz].nverts : (int)(Zones[nz].dim[0] * Zones[nz].dim[1]); if (nmax < nk) nmax = nk; } free (indices); if (is_double) xyz = (void *) malloc (3 * nmax * sizeof(double)); else xyz = (void *) malloc (3 * nmax * sizeof(float)); if (NULL == xyz) FATAL ("read_xyz", "malloc failed for coordinate working array"); if (has_iblank) { iblank = (int *) malloc (nmax * sizeof(int)); if (NULL == iblank) FATAL ("read_xyz", "malloc failed for iblank array"); } else use_iblank = 0; /* read the grid blocks */ for (nz = 0; nz < nZones; nz++) { printf ("reading block %d grid %dx%dx%d ...", nz+1, (int)Zones[nz].dim[0], (int)Zones[nz].dim[1], (int)Zones[nz].dim[2]); fflush (stdout); if (whole) { np = (int)Zones[nz].nverts; nk = 1; } else { np = (int)(Zones[nz].dim[0] * Zones[nz].dim[1]); nk = (int)Zones[nz].dim[2]; } verts = Zones[nz].verts; for (k = 0; k < nk; k++) { if (is_double) bf_getdoubles (bf, 3 * np, xyz); else bf_getfloats (bf, 3 * np, xyz); if (has_iblank) bf_getints (bf, np, iblank); if (is_double) { for (i = 0, n = 0; n < np; n++, i++) verts[n].x = ((double *)xyz)[i]; for (n = 0; n < np; n++, i++) verts[n].y = ((double *)xyz)[i]; for (n = 0; n < np; n++, i++) verts[n].z = ((double *)xyz)[i]; } else { for (i = 0, n = 0; n < np; n++, i++) verts[n].x = ((float *)xyz)[i]; for (n = 0; n < np; n++, i++) verts[n].y = ((float *)xyz)[i]; for (n = 0; n < np; n++, i++) verts[n].z = ((float *)xyz)[i]; } for (n = 0; n < np; n++, verts++) verts->id = use_iblank ? iblank[n] : 1; } puts (" done"); } free (xyz); if (has_iblank) free (iblank); } /*---------- read_q ------------------------------------------------- * read PLOT3D solution file *-------------------------------------------------------------------*/ static void read_q (BINARYIO *bf) { int i, k, n, nk, nz, np, nv, nmax; int *indices; void *data; SOLUTION *sol; FIELD *flds; double qq, rho; static char *fldnames[] = { "Density", "MomentumX", "MomentumY", "MomentumZ", "EnergyStagnationDensity", "VelocityX", "VelocityY", "VelocityZ", "Pressure" }; /* get number of grid blocks */ if (mblock) { bf_getints (bf, 1, &nz); if (nz != nZones) FATAL ("read_q", "number of blocks not the same as the XYZ file"); } /* read indices for grids */ indices = (int *) malloc (3 * nZones * sizeof(int)); if (NULL == indices) FATAL ("read_q", "malloc failed for grid indices"); bf_getints (bf, 3 * nZones, indices); for (nz = 0; nz < nZones; nz++) { for (n = 0; n < 3; n++) { if (indices[3*nz+n] != Zones[nz].dim[n]) FATAL ("read_q", "mismatch in block sizes"); } } free (indices); /* create solution data arrays */ for (nmax = 0, nz = 0; nz < nZones; nz++) { np = whole ? (int)Zones[nz].nverts : (int)(Zones[nz].dim[0] * Zones[nz].dim[1]); if (nmax < np) nmax = np; sol = new_solution (1); strcpy (sol->name, "FlowSolution"); sol->location = CGNS_ENUMV(Vertex); sol->size = Zones[nz].nverts; sol->nflds = 5; sol->flds = new_field (5, sol->size); for (nv = 0; nv < 5; nv++) { strcpy (sol->flds[nv].name, fldnames[nv]); sol->flds[nv].datatype = is_double ? CGNS_ENUMV(RealDouble) : CGNS_ENUMV(RealSingle); } Zones[nz].nsols = 1; Zones[nz].sols = sol; } if (nmax < 4) nmax = 4; if (is_double) data = (void *) malloc (nmax * sizeof(double)); else data = (void *) malloc (nmax * sizeof(float)); if (NULL == data) FATAL ("read_q", "malloc failed for solution working array"); /* read the solution data */ for (nz = 0; nz < nZones; nz++) { printf ("reading block %d solution ...", nz+1); fflush (stdout); if (is_double) { bf_getdoubles (bf, 4, data); if (0 == nz) { for (n = 0; n < 4; n++) reference[n] = ((double *)data)[n]; } } else { bf_getfloats (bf, 4, data); if (0 == nz) { for (n = 0; n < 4; n++) reference[n] = ((float *)data)[n]; } } if (whole) { np = (int)Zones[nz].nverts; nk = 1; } else { np = (int)(Zones[nz].dim[0] * Zones[nz].dim[1]); nk = (int)Zones[nz].dim[2]; } flds = Zones[nz].sols->flds; for (k = 0; k < nk; k++) { i = k * np; for (nv = 0; nv < 5; nv++) { if (is_double) { bf_getdoubles (bf, np, data); for (n = 0; n < np; n++) flds[nv].data[n+i] = ((double *)data)[n]; } else { bf_getfloats (bf, np, data); for (n = 0; n < np; n++) flds[nv].data[n+i] = ((float *)data)[n]; } } } if (convert) { for (nv = 1; nv < 5; nv++) strcpy (flds[nv].name, fldnames[4+nv]); for (n = 0; n < Zones[nz].nverts; n++) { rho = flds[0].data[n]; for (qq = 0.0, nv = 1; nv < 4; nv++) { flds[nv].data[n] /= rho; qq += flds[nv].data[n] * flds[nv].data[n]; } flds[4].data[n] = (gamma - 1.0) * (flds[4].data[n] - 0.5 * rho * qq); } } puts (" done"); } free (data); } /*---------- build_interfaces ----------------------------------------- * create interfaces from iblank data *---------------------------------------------------------------------*/ static void build_interfaces (void) { } /*---------- write_reference ------------------------------------------ * write reference conditions to CGNS file *---------------------------------------------------------------------*/ static void write_reference (void) { int n; cgsize_t cnt = 1; CGNS_ENUMT(DataType_t) datasize; float ref[4]; void *mach, *alpha, *rey, *time; printf ("writing reference state..."); fflush (stdout); if (cg_goto (cgnsfn, cgnsbase, "end") || cg_state_write ("PLOT3D reference state")) FATAL ("write_reference", NULL); if (is_double) { datasize = CGNS_ENUMV(RealDouble); mach = (void *)&reference[0]; alpha = (void *)&reference[1]; rey = (void *)&reference[2]; time = (void *)&reference[3]; } else { for (n = 0; n < 4; n++) ref[n] = (float)reference[n]; datasize = CGNS_ENUMV(RealSingle); mach = (void *)&ref[0]; alpha = (void *)&ref[1]; rey = (void *)&ref[2]; time = (void *)&ref[3]; } if (cg_goto (cgnsfn, cgnsbase, "ReferenceState_t", 1, "end") || cg_array_write ("Mach", datasize, 1, &cnt, mach) || cg_goto (cgnsfn, cgnsbase, "ReferenceState_t", 1, "DataArray_t", 1, "end") || cg_dataclass_write (CGNS_ENUMV(NondimensionalParameter))) FATAL ("write_reference", NULL); if (cg_goto (cgnsfn, cgnsbase, "ReferenceState_t", 1, "end") || cg_array_write ("AngleofAttack", datasize, 1, &cnt, alpha) || cg_goto (cgnsfn, cgnsbase, "ReferenceState_t", 1, "DataArray_t", 2, "end") || cg_dataclass_write (CGNS_ENUMV(Dimensional)) || cg_units_write (CGNS_ENUMV(MassUnitsNull), CGNS_ENUMV(LengthUnitsNull), CGNS_ENUMV(TimeUnitsNull), CGNS_ENUMV(TemperatureUnitsNull), CGNS_ENUMV(Degree))) FATAL ("write_reference", NULL); if (cg_goto (cgnsfn, cgnsbase, "ReferenceState_t", 1, "end") || cg_array_write ("Reynolds", datasize, 1, &cnt, rey) || cg_goto (cgnsfn, cgnsbase, "ReferenceState_t", 1, "DataArray_t", 3, "end") || cg_dataclass_write (CGNS_ENUMV(NondimensionalParameter))) FATAL ("write_reference", NULL); if (cg_goto (cgnsfn, cgnsbase, "ReferenceState_t", 1, "end") || cg_array_write ("TimeLatest", datasize, 1, &cnt, time) || cg_goto (cgnsfn, cgnsbase, "ReferenceState_t", 1, "DataArray_t", 4, "end") || cg_dataclass_write (CGNS_ENUMV(Dimensional)) || cg_units_write (CGNS_ENUMV(MassUnitsNull), CGNS_ENUMV(LengthUnitsNull), CGNS_ENUMV(Second), CGNS_ENUMV(TemperatureUnitsNull), CGNS_ENUMV(AngleUnitsNull))) FATAL ("write_reference", NULL); puts (" done"); } /*========== main ===================================================*/ int main (int argc, char *argv[]) { int n, ib = 0, nb, flags = 0, has_q = 0; BINARYIO *bf; static char basename[33] = "Base"; if (argc < 3) print_usage (usgmsg, NULL); /* get options */ while ((n = getargs (argc, argv, options)) > 0) { switch (n) { case 'f': flags &= ~OPEN_FORTRAN; flags |= OPEN_ASCII; break; case 'u': flags &= ~OPEN_ASCII; flags |= OPEN_FORTRAN; break; case 's': mblock = 0; break; case 'p': whole = 0; break; case 'i': use_iblank = 1; /* fall through */ case 'n': has_iblank = 1; break; case 'd': is_double = 1; break; case 'M': flags &= ~MACH_UNKNOWN; flags |= get_machine (argarg); break; case 'b': ib = atoi (argarg); break; case 'B': strncpy (basename, argarg, 32); basename[32] = 0; break; case 'g': gamma = atof (argarg); if (gamma <= 1.0) FATAL (NULL, "invalid value for gamma"); break; case 'c': convert = 1; break; } } if (argind > argc - 2) print_usage (usgmsg, "XYZfile and/or CGNSfile not given"); /* read Plot3d file */ printf ("reading PLOT3D grid file %s\n", argv[argind]); printf (" as %s-block %s", mblock ? "multi" : "single", flags == OPEN_ASCII ? "ASCII" : (flags == OPEN_FORTRAN ? "FORTRAN unformatted" : "binary")); if (has_iblank) printf (" with iblank array"); putchar ('\n'); if (!file_exists (argv[argind])) FATAL (NULL, "XYZ file does not exist or is not a file"); if (NULL == (bf = bf_open (argv[argind], flags | OPEN_READ))) { fprintf (stderr, "can't open <%s> for reading", argv[argind]); exit (1); } read_xyz (bf); bf_close (bf); if (use_iblank) build_interfaces (); /* read solution file if given */ if (++argind < argc-1) { printf ("\nreading PLOT3D solution file %s\n", argv[argind]); if (!file_exists (argv[argind])) FATAL (NULL, "Solution file does not exist or is not a file"); if (NULL == (bf = bf_open (argv[argind], flags | OPEN_READ))) { fprintf (stderr, "can't open <%s> for reading", argv[argind]); exit (1); } read_q (bf); bf_close (bf); argind++; has_q = 1; } /* open CGNS file */ printf ("\nwriting CGNS file to %s\n", argv[argind]); nb = open_cgns (argv[argind], 0); if (ib) { if (ib > nb) FATAL (NULL, "specified base index out of range"); if (cg_base_read (cgnsfn, ib, basename, &n, &n)) FATAL (NULL, NULL); } if (cg_base_write (cgnsfn, basename, 3, 3, &cgnsbase) || cg_goto (cgnsfn, cgnsbase, "end") || cg_dataclass_write (CGNS_ENUMV(NormalizedByUnknownDimensional))) FATAL (NULL, NULL); printf (" output to base %d - %s\n", cgnsbase, basename); write_zones (); for (n = 1; n <= nZones; n++) { printf ("writing zone %d ... grid", n); fflush (stdout); write_zone_grid (n); write_zone_interface (n); if (has_q) { printf (", solution"); fflush (stdout); write_zone_solution (n, 1); write_solution_field (n, 1, 0); } puts (" done"); } if (has_q) write_reference (); cg_close (cgnsfn); return 0; } cgnslib_3.1.4/src/cgnstools/utilities/convert_variables.c0000664000076400007640000003567312160605674020673 00000000000000/* * convert_variables.c - convert between primitive and conserved variables */ #include #include #include #include #ifdef _WIN32 # define unlink _unlink #else # include #endif #include "getargs.h" #include "cgnslib.h" #include "cgnsutil.h" #include "vec.h" #include "vecerr.h" #include "vecsym.h" #ifndef CG_MODE_MODIFY # define CG_MODE_MODIFY MODE_MODIFY #endif /* command line options */ static char options[] = "pcf:b:z:s:S:g:"; static char *usgmsg[] = { "usage : convert_variables [options] CGNSfile [newCGNSfile]", "options:", " -p = convert to primitive variables", " -c = convert to conserved variables", " -f = read conversion expressions from ", " -b = use CGNS base number (default 1)", " -z = read zone number (default all)", " -s = read solution number (default all)", " -S = write to solution (default same as read)", " -g= value of gamma for conversions (default 1.4)", NULL }; static double gamma = 1.4; typedef struct _VAR { char name[33]; int valid; VECDATA vd; } VAR; static int varlen = 0; static int maxvars = 0; static int numvars = 0; static VAR *vars; static int numrefs = 0; static VAR *refs; static char buff[1024]; /*-------------------------------------------------------------------*/ static void get_error (int errnum, char *errmsg, int pos, char *str) { if (pos >= 0 && NULL != str) { fprintf (stderr, "\n%s\n", str); while (pos-- > 0) putc ('-', stderr); putc ('^', stderr); } FATAL (NULL, errmsg); } /*-------------------------------------------------------------------*/ static void get_reference (void) { int n, narrays, na, dim; cgsize_t len, vec[12]; CGNS_ENUMT(DataType_t) datatype; char name[33]; numrefs = 0; if (cg_goto (cgnsfn, cgnsbase, "ReferenceState_t", 1, "end") || cg_narrays (&narrays) || narrays < 1) return; for (na = 1; na <= narrays; na++) { if (cg_array_info (na, name, &datatype, &dim, vec)) FATAL ("get_reference", NULL); if (dim >= 1 && vec[0] >= 1) numrefs++; } if (!numrefs) return; refs = (VAR *) malloc (numrefs * sizeof(VAR)); if (NULL == refs) FATAL ("get_reference", "malloc failed for reference variables"); for (n = 0, na = 1; na <= narrays; na++) { if (cg_array_info (na, name, &datatype, &dim, vec)) FATAL ("get_reference", NULL); if (dim < 1 || vec[0] < 1) continue; strcpy (refs[n].name, name); refs[n].valid = 1; len = dim * vec[0]; if (len == 1) { refs[n].vd.type = VEC_VALUE; refs[n].vd.len = 0; if (cg_array_read_as (na, CGNS_ENUMV(RealDouble), &refs[n].vd.f.val)) FATAL ("get_reference", NULL); } else { refs[n].vd.type = VEC_VECTOR; refs[n].vd.len = len; refs[n].vd.f.vec = (VECFLOAT *) malloc (len * sizeof(VECFLOAT)); if (NULL == refs[n].vd.f.vec) FATAL ("get_reference", "malloc failed for reference data"); if (cg_array_read_as (na, CGNS_ENUMV(RealDouble), refs[n].vd.f.vec)) FATAL ("get_reference", NULL); } n++; } } /*-------------------------------------------------------------------*/ static void init_conversions (ZONE *z, SOLUTION *s) { int n; sym_free (); sym_addval ("gamma", gamma, NULL); read_solution_field (z->id, s->id, 0); if (s->nflds > maxvars) { n = s->nflds + 10; if (maxvars) vars = (VAR *) realloc (vars, n * sizeof(VAR)); else vars = (VAR *) malloc (n * sizeof(VAR)); if (vars == NULL) FATAL ("init_conversions", "malloc failed for variables"); maxvars = n; } numvars = s->nflds; for (n = 0; n < s->nflds; n++) { strcpy (vars[n].name, s->flds[n].name); vars[n].valid = 1; vars[n].vd.type = VEC_VECTOR; vars[n].vd.len = s->size; vars[n].vd.f.vec = s->flds[n].data; } varlen = s->size; } /*-------------------------------------------------------------------*/ static void update_solution (ZONE *z, SOLUTION *s) { int n, i, nflds = 0; for (n = 0; n < numvars; n++) { if (vars[n].valid) nflds++; } s->nflds = nflds; if (nflds) s->flds = new_field (nflds, 0); for (i = 0, n = 0; n < numvars; n++) { if (vars[n].valid) { strcpy (s->flds[i].name, vars[n].name); s->flds[i].data = vars[n].vd.f.vec; i++; } else { if (vars[n].vd.f.vec != NULL) free (vars[n].vd.f.vec); } } } /*-------------------------------------------------------------------*/ static char *next_token (char *str, char token[33]) { int n; char *p = str; while (*p && (isspace(*p) || *p == ',')) p++; if (!*p) return NULL; if (*p == '"') { p++; for (n = 0; n < 32; n++) { if (!*p || *p == '"') break; token[n] = *p++; } if (*p++ != '"') FATAL ("missing quote", str); } else { for (n = 0; n < 32; n++) { if (!*p || (!isalnum(*p) && *p != '_')) break; token[n] = *p++; } } if (!n) return NULL; token[n] = 0; while (*p && isspace(*p)) p++; return p; } /*-------------------------------------------------------------------*/ static VECDATA *callback (int check, char **pp, char **err) { int n, nr = 0; char name[33], *p = *pp; if (*p == '~') { nr = 1; p++; } if ((p = next_token (p, name)) == NULL) return NULL; if (nr) { for (n = 0; n < numrefs; n++) { if (0 == strcmp (refs[n].name, name)) { *pp = p; return &refs[n].vd; } } *err = "reference variable not found"; } else { for (n = 0; n < numvars; n++) { if (0 == strcmp (vars[n].name, name)) { *pp = p; return &vars[n].vd; } } } return NULL; } /*-------------------------------------------------------------------*/ static int delete_var (char *name) { int n; for (n = 0; n < numvars; n++) { if (0 == strcmp (vars[n].name, name)) { vars[n].valid = 0; return 1; } } return 0; } /*-------------------------------------------------------------------*/ static int add_var (char *name) { int n; VECDATA *vd; for (n = 0; n < numvars; n++) { if (0 == strcmp (vars[n].name, name)) return 0; } vd = vec_parse (name, varlen, callback); if (vd == NULL || vd->type != VEC_VECTOR || vd->len != varlen) FATAL ("error computing", name); if (numvars == maxvars) { maxvars += 10; vars = (VAR *) realloc (vars, maxvars * sizeof(VAR)); if (vars == NULL) FATAL (NULL, "realloc failed for variables"); } strcpy (vars[numvars].name, name); vars[numvars].valid = 1; vars[numvars].vd.len = vd->len; vars[numvars].vd.len = vd->len; vars[numvars].vd.f.vec = vd->f.vec; numvars++; return 1; } /*-------------------------------------------------------------------*/ static int parse_command (char *cmd) { int n, nargs = 0; char *p, name[33]; for (p = cmd; *p && isspace(*p); p++) ; if (!*p) return 0; if (*p == '+') { strcpy (name, "add"); p++; } else if (*p == '-') { strcpy (name, "rem"); p++; } else { p = next_token (p, name); } if (p == NULL || !*p) return 0; if (*p == '(') { if (*++p && *p != ')') { nargs = atoi (p); if (nargs < 0 || nargs > 9) get_error (0, "invalid number of arguments", (int)(p - cmd), cmd); while (*p && *p != ')') p++; } if (*p != ')') get_error (0, "missing ')'", (int)(p - cmd), cmd); while (*++p && isspace(*p)); } if (*p == '=') { while (*++p && isspace(*p)); if (*p) sym_addequ (name, nargs, p, NULL); return 0; } if (0 == strncmp (name, "rem", 3) || 0 == strncmp (name, "del", 3)) { n = 0; while ((p = next_token (p, name)) != NULL) n += delete_var (name); return n; } if (0 == strncmp (name, "add", 3) || 0 == strncmp (name, "sav", 3)) { n = 0; while ((p = next_token (p, name)) != NULL) n += add_var (name); return n; } FATAL ("unknown cmd", name); return 0; /* quite compiler */ } /*-------------------------------------------------------------------*/ char *next_line (FILE *fp) { int n = 0, len; char *p, line[257]; while (fgets (line, sizeof(line), fp) != NULL) { line[sizeof(line)-1] = 0; p = line + strlen(line); while (--p >= line && isspace(*p)) ; *++p = 0; for (p = line; *p && isspace(*p); p++) ; if (!*p) continue; strcpy (buff, p); n = (int)strlen (buff); while (buff[n-1] == '\\') { for (n -= 2; n >= 0 && isspace(buff[n]); n--) ; buff[++n] = 0; if (fgets (line, sizeof(line), fp) == NULL) break; line[sizeof(line)-1] = 0; p = line + strlen(line); while (--p >= line && isspace(*p)) ; *++p = 0; for (p = line; *p && isspace(*p); p++) ; if (!*p) break; len = (int)strlen (p); if (n + len >= sizeof(buff)) FATAL ("next_line", "internal command buffer length exceeded"); strcpy (&buff[n], p); n += len; } if ((p = strchr (buff, '#')) != NULL) *p = 0; for (p = buff+strlen(buff)-1; p >= buff && isspace(*p); p--) ; *++p = 0; for (p = buff; *p && isspace(*p); p++) ; if (*p) return (p); } return (NULL); } /*-------------------------------------------------------------------*/ static int parse_file (char *cmdfile) { int changes = 0; char *cmd; FILE *fp = fopen (cmdfile, "r"); if (fp == NULL) { sprintf (buff, "couldn't open <%s> for reading", cmdfile); FATAL ("parse_file", buff); } while ((cmd = next_line (fp)) != NULL) changes += parse_command (cmd); fclose (fp); return changes; } /*-------------------------------------------------------------------*/ int main (int argc, char *argv[]) { int n, iz, is, nz, ns, dim; int izone = 0, isol = 0; char *p, *tmpfile, basename[33]; char *solname = NULL, *convfile = NULL; ZONE *z; SOLUTION *s; if (argc < 2) print_usage (usgmsg, NULL); while ((n = getargs (argc, argv, options)) > 0) { switch (n) { case 'p': convfile = "primitive.cnv"; break; case 'c': convfile = "conserved.cnv"; break; case 'f': convfile = argarg; break; case 'b': cgnsbase = atoi (argarg); break; case 'z': izone = atoi (argarg); break; case 's': isol = atoi (argarg); break; case 'S': solname = argarg; break; case 'g': gamma = atof (argarg); if (gamma <= 1.0) FATAL (NULL, "invalid value for gamma"); break; } } if (argind == argc) print_usage (usgmsg, "CGNSfile not given"); if (!file_exists (argv[argind])) FATAL (NULL, "CGNSfile does not exist or is not a file"); /* get the conversion expression file */ if (convfile == NULL) print_usage (usgmsg, "need to select one of -p, -c or -f options"); if ((p = find_file (convfile, argv[0])) == NULL) FATAL ("can't locate", convfile); convfile = p; printf ("converting variables using expressions from %s\n", convfile); /* create a working copy */ printf ("creating a working copy of %s\n", argv[argind]); tmpfile = temporary_file (argv[argind]); copy_file (argv[argind], tmpfile); /* read CGNS file */ printf ("reading CGNS file from %s\n", tmpfile); if (cg_open (tmpfile, CG_MODE_MODIFY, &cgnsfn) || cg_base_read (cgnsfn, cgnsbase, basename, &dim, &dim)) FATAL (NULL, NULL); printf ("reading zone information for base %d - %s\n", cgnsbase, basename); vec_errhandler = get_error; get_reference (); read_zones (); for (z = Zones, nz = 1; nz <= nZones; nz++, z++) { iz = 0; if (!izone || nz == izone) { read_zone_solution (nz); for (s = z->sols, ns = 1; ns <= z->nsols; ns++, s++) { is = 0; if ((!isol || ns == isol) && s->size && s->nflds >= 5) { printf ("checking zone %d, solution %d ... ", nz, ns); fflush (stdout); init_conversions (z, s); if (parse_file (convfile)) { update_solution (z, s); iz = z->id; is = s->id; puts ("updated"); } else puts ("ok"); } s->id = is; } } z->id = iz; } /* write CGNS file */ for (z = Zones, nz = 1; nz <= nZones; nz++, z++) { if (z->id) { for (s = z->sols, ns = 1; ns <= z->nsols; ns++, s++) { if (s->id) { printf ("writing zone %d, solution %d ... ", nz, ns); fflush (stdout); if (solname != NULL) { if (z->nsols == 1) strncpy (s->name, solname, 32); else if (strlen (solname) > 30) sprintf (s->name, "%30.30s%d", solname, s->id); else sprintf (s->name, "%s%d", solname, s->id); s->name[32] = 0; } write_zone_solution (nz, ns); write_solution_field (nz, ns, 0); puts ("done"); } } } } cg_close (cgnsfn); if (argind + 1 < argc) argind++; printf ("renaming %s to %s\n", tmpfile, argv[argind]); unlink (argv[argind]); if (rename (tmpfile, argv[argind])) { char msg[512]; sprintf (msg, "rename %s -> %s failed", tmpfile, argv[argind]); FATAL (NULL, msg); exit (1); } free (tmpfile); return 0; } cgnslib_3.1.4/src/cgnstools/utilities/cgnsImport.c0000664000076400007640000015712312160605674017303 00000000000000/* * import routines for CGNS */ #include #include #include #include #include #include "cgnsImport.h" #include "hash.h" #ifndef CG_MODE_READ # define CG_MODE_READ MODE_READ # define CG_MODE_WRITE MODE_WRITE # define CG_MODE_MODIFY MODE_MODIFY #endif #ifndef DOUBLE /* data type for coordinates */ #define DOUBLE double #endif #ifndef TOLERANCE /* tolerance for duplicate checking */ #define TOLERANCE 1.e-03 #endif #ifndef REGION_BASE /* base name for unnamed regions */ #define REGION_BASE "Region" #endif /*--- variables ---*/ static int num_vars = 0; static char **var_names = 0; /*--- node bit flags ---*/ #define USED_BIT 1 #define REGN_BIT 2 #define REFS_BIT 4 /*--- node structure ---*/ typedef struct { cgsize_t id; /* node ID */ int flags; /* references to node */ DOUBLE x, y, z; /* coordinates */ DOUBLE dist; /* distance from origin */ DOUBLE *vars; /* variables */ } cgnsNODE; /*--- node mapping data ---*/ #define NODEMAP_INC 50 /* realloc this many at a time */ typedef struct { cgsize_t nodeid; /* node id */ cgsize_t mapped; /* set when mapped */ cgnsNODE *node; /* pointer to node data */ } NODEMAP; static cgsize_t num_nodes = 0; /* number of nodes */ static cgsize_t max_nodes = 0; /* number of nodes malloced */ static NODEMAP *nodemap; /* list of nodes */ /*--- duplicate node checking ---*/ #define ENTRY_INC 50 static int no_check = 0; static double def_tol = TOLERANCE; static double tolerance = TOLERANCE; DOUBLE xmin, xmax, ymin, ymax, zmin, zmax; static cgsize_t num_entries = 0; static cgsize_t max_entries = 0; static cgnsNODE **node_list; /*--- element data ---*/ #define ELEMENT_INC 50 /* realloc this many at a time */ typedef struct { cgsize_t elemid; /* element ID */ int elemtype; /* element type (number of nodes) */ cgsize_t *nodeid; /* node ID's for element */ char facemap[6]; /* remapping of faces */ } cgnsELEM; static cgsize_t num_elements = 0;/* number of elements */ static cgsize_t max_elements = 0;/* number of elements malloced */ static cgnsELEM *elemlist; /* list of elements */ /*--- region data ---*/ #define REGION_INC 50 /* step increment for realloc */ static char region_name[33]; /* region name */ static int region_type; /* type of region */ static cgsize_t region_id = 0; /* region ID */ static cgsize_t region_max = 0; /* malloced size of region_list */ static cgsize_t region_nobjs = 0; /* number objects in region */ static cgsize_t *region_list; /* list of nodes in region */ typedef struct { char name[33]; /* region name */ int type; /* region type */ cgsize_t nobjs; /* number of objects */ cgsize_t *objid; /* object ID's */ } cgnsREGN; static int num_regions = 0; /* number of regions */ static cgnsREGN *reglist; /* list of regions */ /*--- external faces */ typedef struct { cgsize_t faceid; int nnodes; cgsize_t nodeid[4]; int flags; } cgnsFACE; static cgsize_t num_faces = 0; static cgnsFACE **facelist; /*--- CGNS data ---*/ int cgnsFile = 0; int cgnsBase = 0; int cgnsZone = 0; char cgnsZoneName[33] = ""; /*--- error handling callback ---*/ static void (*errcallback)( /* callback pointer to user routine */ char *errmsg /* error message */ ) = NULL; /*====================================================================== * Node routines *======================================================================*/ /*---------- NewNode --------------------------------------------------- * create a new node *----------------------------------------------------------------------*/ static cgnsNODE *NewNode (cgsize_t id, double x, double y, double z) { cgnsNODE *node = (cgnsNODE *) malloc (sizeof(cgnsNODE)); if (NULL != node) { node->id = id; node->flags = 0; node->x = x; node->y = y; node->z = z; node->dist = 0.0; node->vars = 0; if (num_vars) node->vars = (DOUBLE *) calloc (num_vars, sizeof(DOUBLE)); } return (node); } /*---------- GetNode --------------------------------------------------- * return the node for a given node id *----------------------------------------------------------------------*/ static cgnsNODE *GetNode (cgsize_t nodeid, cgsize_t *pos) { cgsize_t lo = 0, hi = num_nodes - 1; *pos = 0; if (!num_nodes || nodeid < nodemap[0].nodeid) return (NULL); if (nodeid == nodemap[0].nodeid) return (nodemap[0].node); if (!hi || nodeid > nodemap[hi].nodeid) { *pos = num_nodes; return (NULL); } if (nodeid == nodemap[hi].nodeid) { *pos = hi; return (nodemap[hi].node); } while (1) { *pos = (lo + hi) >> 1; if (nodeid == nodemap[*pos].nodeid) return (nodemap[*pos].node); if (hi - lo <= 1) break; if (nodeid < nodemap[*pos].nodeid) hi = *pos; else lo = *pos; } *pos = hi; return (NULL); } /*---------- CompareNodes ---------------------------------------------- * compare two nodes, returns 0 if nodes are the same within * the specifed tolerance, else 1 *----------------------------------------------------------------------*/ static int CompareNodes (cgnsNODE *node1, cgnsNODE *node2) { double dist = (node2->x - node1->x) * (node2->x - node1->x) + (node2->y - node1->y) * (node2->y - node1->y) + (node2->z - node1->z) * (node2->z - node1->z); return (dist < (tolerance * tolerance) ? 0 : 1); } /*====================================================================== duplicate node checking routines The nodes are stored in a sorted list based on radius from the origin. Once the position in the list is determined, then a scan backwards and forwards in the list is done for a matching node. ========================================================================*/ /*---------- FindPosition ---------------------------------------------- * bisection search to locate position for node *----------------------------------------------------------------------*/ static cgsize_t FindPosition (cgnsNODE *node) { cgsize_t mid, lo = 0, hi = num_entries - 1; if (!num_entries || node->dist <= node_list[0]->dist) return (0); if (!hi || node->dist > node_list[hi]->dist) return (num_entries); if (node->dist == node_list[hi]->dist) return (hi); while ((hi - lo) > 1) { mid = (lo + hi) >> 1; if (node->dist == node_list[mid]->dist) return (mid); if (node->dist < node_list[mid]->dist) hi = mid; else lo = mid; } return (hi); } /*---------- FindNode -------------------------------------------------- * search for matching node in Node List *----------------------------------------------------------------------*/ static cgnsNODE *FindNode (cgnsNODE *node, cgsize_t *pos) { cgsize_t n; *pos = FindPosition (node); for (n = *pos - 1; n >= 0; n--) { if (fabs (node->dist - node_list[n]->dist) >= tolerance) break; if (!CompareNodes (node, node_list[n])) return (node_list[n]); } for (n = *pos; n < num_entries; n++) { if (fabs (node->dist - node_list[n]->dist) >= tolerance) break; if (!CompareNodes (node, node_list[n])) return (node_list[n]); } return (NULL); } /*---------- AddNode --------------------------------------------------- * add a new node to the duplicate node checking list *----------------------------------------------------------------------*/ static void AddNode (cgnsNODE *node, cgsize_t pos) { cgsize_t n; if (num_entries == max_entries) { if (!max_entries) node_list = (cgnsNODE **) malloc (ENTRY_INC * sizeof(cgnsNODE *)); else node_list = (cgnsNODE **) realloc (node_list, (size_t)(max_entries + ENTRY_INC) * sizeof(cgnsNODE *)); if (NULL == node_list) cgnsImportFatal ( "AddNode:malloc failed for new node entry in duplicate node list"); max_entries += ENTRY_INC; } for (n = num_entries; n > pos; n--) node_list[n] = node_list[n-1]; node_list[pos] = node; num_entries++; } /*====================================================================== * Element routines *======================================================================*/ /*---------- GetElement ------------------------------------------------ * return the element for a given element id *----------------------------------------------------------------------*/ static cgnsELEM *GetElement (cgsize_t elemid, cgsize_t *pos) { cgsize_t lo = 0, hi = num_elements - 1; *pos = 0; if (!num_elements || elemid < elemlist[0].elemid) return (NULL); if (elemid == elemlist[0].elemid) return (&elemlist[0]); if (!hi || elemid > elemlist[hi].elemid) { *pos = num_elements; return (NULL); } if (elemid == elemlist[hi].elemid) { *pos = hi; return (&elemlist[hi]); } while (1) { *pos = (lo + hi) >> 1; if (elemid == elemlist[*pos].elemid) return (&elemlist[*pos]); if (hi - lo <= 1) break; if (elemid < elemlist[*pos].elemid) hi = *pos; else lo = *pos; } *pos = hi; return (NULL); } /*---------- NewElement ------------------------------------------------ * add new element to list of elements *----------------------------------------------------------------------*/ static cgnsELEM *NewElement (cgsize_t pos) { int i; cgsize_t n; /* malloc/realloc if needed */ if (num_elements == max_elements) { if (!max_elements) elemlist = (cgnsELEM *) malloc (ELEMENT_INC * sizeof(cgnsELEM)); else elemlist = (cgnsELEM *) realloc (elemlist, (size_t)(max_elements + ELEMENT_INC) * sizeof(cgnsELEM)); if (NULL == elemlist) cgnsImportFatal ("AddElement:malloc failed for element list"); max_elements += ELEMENT_INC; } /* insert new element */ for (n = num_elements; n > pos; n--) { elemlist[n].elemid = elemlist[n-1].elemid; elemlist[n].elemtype = elemlist[n-1].elemtype; elemlist[n].nodeid = elemlist[n-1].nodeid; for (i = 0; i < 6; i++) elemlist[n].facemap[i] = elemlist[n-1].facemap[i]; } num_elements++; return (&elemlist[pos]); } /*====================================================================== * Region routines *======================================================================*/ /*---------- GetRegion ------------------------------------------------- * return a region for a given region name *----------------------------------------------------------------------*/ static cgnsREGN *GetRegion (char *name, int *pos) { int cmp, lo = 0, hi = num_regions - 1; *pos = 0; if (!num_regions || (cmp = strcmp (name, reglist[0].name)) < 0) return (NULL); if (0 == cmp) return (®list[0]); if (!hi || (cmp = strcmp (name, reglist[hi].name)) > 0) { *pos = num_regions; return (NULL); } if (0 == cmp) { *pos = hi; return (®list[hi]); } while (1) { *pos = (lo + hi) >> 1; if (0 == (cmp = strcmp (name, reglist[*pos].name))) return (®list[*pos]); if (hi - lo <= 1) break; if (cmp < 0) hi = *pos; else lo = *pos; } *pos = hi; return (NULL); } /*---------- NewRegion ------------------------------------------------- * add a new region to region list *----------------------------------------------------------------------*/ static cgnsREGN *NewRegion (char *name, int pos) { int n; static char *errmsg = "NewRegion:malloc failed for region list"; if (!num_regions) reglist = (cgnsREGN *) malloc (sizeof(cgnsREGN)); else reglist = (cgnsREGN *) realloc (reglist, (num_regions + 1) * sizeof(cgnsREGN)); if (NULL == reglist) cgnsImportFatal (errmsg); for (n = num_regions; n > pos; n--) { strcpy (reglist[n].name, reglist[n-1].name); reglist[n].type = reglist[n-1].type; reglist[n].nobjs = reglist[n-1].nobjs; reglist[n].objid = reglist[n-1].objid; } strncpy (reglist[pos].name, name, 32); reglist[pos].name[32] = 0; reglist[pos].type = 0; reglist[pos].nobjs = 0; reglist[pos].objid = NULL; num_regions++; return (®list[pos]); } /*====================================================================== * external face regions *======================================================================*/ /*---------- get_face_nodes ----------------------------------------- * get nodes for an element face *-------------------------------------------------------------------*/ static int get_face_nodes (cgsize_t faceid, cgsize_t nodeid[4]) { cgnsELEM *elem; cgsize_t elemid = faceid >> 3; int facenum = (int)(faceid & 7); int n, nfaces = 0, noff = 0, nnodes; static int facenodes[20][5] = { /* tet */ {3, 0, 2, 1, 0}, {3, 0, 1, 3, 0}, {3, 1, 2, 3, 0}, {3, 2, 0, 3, 0}, /* pyramid */ {4, 0, 3, 2, 1}, {3, 0, 1, 4, 0}, {3, 1, 2, 4, 0}, {3, 2, 3, 4, 0}, {3, 3, 0, 4, 0}, /* wedge */ {4, 0, 1, 4, 3}, {4, 1, 2, 5, 4}, {4, 2, 0, 3, 5}, {3, 0, 2, 1, 0}, {3, 3, 4, 5, 0}, /* hex */ {4, 0, 3, 2, 1}, {4, 0, 1, 5, 4}, {4, 1, 2, 6, 5}, {4, 2, 3, 7, 6}, {4, 0, 4, 7, 3}, {4, 4, 5, 6, 7} }; if (elemid < 0 || elemid >= num_elements) cgnsImportFatal ("get_face_nodes:invalid element number"); elem = &elemlist[elemid]; switch (elem->elemtype) { case cgnsELEM_TET: noff = 0; nfaces = 4; break; case cgnsELEM_PYR: noff = 4; nfaces = 5; break; case cgnsELEM_WDG: noff = 9; nfaces = 5; break; case cgnsELEM_HEX: noff = 14; nfaces = 6; break; default: cgnsImportFatal ("get_face_nodes:invalid element type"); } if (facenum < 0 || facenum >= nfaces) return (0); noff += (int)elem->facemap[facenum]; nnodes = facenodes[noff][0]; for (n = 0; n < nnodes; n++) nodeid[n] = elem->nodeid[facenodes[noff][n+1]]; return (nnodes); } /*---------- compare_faces ------------------------------------------- * face comparison routine *--------------------------------------------------------------------*/ static int compare_faces (void *v1, void *v2) { cgnsFACE *f1 = (cgnsFACE *)v1; cgnsFACE *f2 = (cgnsFACE *)v2; int n; if (f1->nnodes != f2->nnodes) return (f1->nnodes - f2->nnodes); /* the following assumes nodes have been sorted */ for (n = 0; n < f1->nnodes; n++) { if (f1->nodeid[n] != f2->nodeid[n]) return (int)(f1->nodeid[n] - f2->nodeid[n]); } return (0); } /*---------- get_faces ---------------------------------------------- * get the exterior faces *-------------------------------------------------------------------*/ static void get_faces (void *v) { facelist[num_faces++] = (cgnsFACE *)v; } /*---------- hash_face ----------------------------------------------- * face hash function *--------------------------------------------------------------------*/ static size_t hash_face (void *v) { cgnsFACE *face = (cgnsFACE *)v; int n; size_t hash = 0; for (n = 0; n < face->nnodes; n++) hash += (size_t)face->nodeid[n]; return (hash); } /*---------- sortfaces ------------------------------------------------- * called by qsort to sort the list of faces *----------------------------------------------------------------------*/ static int sortfaces (const void *f1, const void *f2) { return (int)((*((cgnsFACE **)f1))->faceid - (*((cgnsFACE **)f2))->faceid); } /*---------- exterior_faces ----------------------------------------- * find exterior faces *-------------------------------------------------------------------*/ static void exterior_faces (void) { int i, j, k, nfaces; cgsize_t nodeid[4]; cgsize_t n, nn, id, faceid; HASH FaceList; cgnsFACE *pf, face; FaceList = HashCreate (2047, compare_faces, hash_face); if (NULL == FaceList) cgnsImportFatal ("exterior_faces:malloc failed for face hash table"); for (n = 0; n < num_elements; n++) { switch (elemlist[n].elemtype) { case cgnsELEM_WDG: nfaces = 5; break; case cgnsELEM_HEX: nfaces = 6; break; default: nfaces = elemlist[n].elemtype; break; } /* loop over element faces */ for (j = 0; j < nfaces; j++) { /* get face nodes and sort */ faceid = (n << 3) | j; face.nnodes = get_face_nodes (faceid, nodeid); for (i = 0; i < face.nnodes; i++) { id = nodeid[i]; for (k = 0; k < i; k++) { if (face.nodeid[k] > id) { nn = face.nodeid[k]; face.nodeid[k] = id; id = nn; } } face.nodeid[i] = id; } if (NULL == (pf = (cgnsFACE *) HashFind (FaceList, &face))) { /* create new face and add to list */ if (NULL == (pf = (cgnsFACE *) malloc (sizeof(cgnsFACE)))) cgnsImportFatal ("exterior_faces:malloc failed for new face"); pf->faceid = faceid; pf->flags = 0; pf->nnodes = face.nnodes; for (i = 0; i < face.nnodes; i++) pf->nodeid[i] = face.nodeid[i]; (void) HashAdd (FaceList, pf); } /* else already exists */ else { HashDelete (FaceList, pf); free (pf); } } } facelist = (cgnsFACE **) malloc (HashSize (FaceList) * sizeof(cgnsFACE *)); if (NULL == facelist) cgnsImportFatal ("exterior_faces:malloc failed for exterior face list"); num_faces = 0; HashDestroy (FaceList, get_faces); /* check if faces need sorting */ for (n = 1; n < num_faces; n++) { if (facelist[n]->faceid < facelist[n-1]->faceid) break; } if (n < num_faces) qsort (facelist, (size_t)num_faces, sizeof(cgnsFACE *), sortfaces); /* get face nodes in the correct order */ for (n = 0; n < num_faces; n++) { get_face_nodes (facelist[n]->faceid, nodeid); for (i = 0; i < 4; i++) facelist[n]->nodeid[i] = nodeid[i]; } } /*=================================================================== * write regions to cgns file *===================================================================*/ /*---------- sortnodes ------------------------------------------------- * called by qsort to sort list of node ID mappings *----------------------------------------------------------------------*/ static int sortnodes (const void *n1, const void *n2) { return (int)(*((cgsize_t *)n1) - *((cgsize_t *)n2)); } /*---------- write_node_region -------------------------------------- * write region from node list *-------------------------------------------------------------------*/ static cgsize_t write_node_region (cgnsREGN *reg, cgsize_t offset) { int nn, isect; cgsize_t i, j, mid, lo, hi, pos; cgsize_t nfaces, nc, *conns; CGNS_ENUMT(ElementType_t) elemtype = CGNS_ENUMV(ElementTypeNull); cgnsNODE *node; /* get exterior faces */ if (num_faces == 0) exterior_faces (); for (j = 0; j < num_faces; j++) facelist[j]->flags = 0; /* sort region nodes */ for (i = 1; i < reg->nobjs; i++) { if (reg->objid[i] < reg->objid[i-1]) break; } if (i < reg->nobjs) qsort (reg->objid, (size_t)reg->nobjs, sizeof(cgsize_t), sortnodes); /* scan list of exterior faces */ nfaces = nc = 0; for (j = 0; j < num_faces; j++) { if (facelist[j]->flags) continue; for (nn = 0; nn < facelist[j]->nnodes; nn++) { lo = 0; hi = reg->nobjs - 1; while (lo <= hi) { mid = (lo + hi) >> 1; if (facelist[j]->nodeid[nn] == reg->objid[mid]) break; if (facelist[j]->nodeid[nn] < reg->objid[mid]) hi = mid - 1; else lo = mid + 1; } if (lo > hi) break; } if (nn == facelist[j]->nnodes) { nfaces++; facelist[j]->flags = 1; if (nc != nn) { elemtype = nc ? CGNS_ENUMV(MIXED) : (nn == 3 ? CGNS_ENUMV(TRI_3) : CGNS_ENUMV(QUAD_4)); nc = nn; } } } if (!nfaces) return 0; conns = (cgsize_t *) malloc ((size_t)(5 * nfaces) * sizeof(cgsize_t)); if (NULL == conns) cgnsImportFatal ("write_node_region:malloc failed for connectivity"); /* write face connectivities */ for (nc = 0, j = 0; j < num_faces; j++) { if (facelist[j]->flags) { if (elemtype == CGNS_ENUMV(MIXED)) conns[nc++] = facelist[j]->nnodes == 3 ? CGNS_ENUMV(TRI_3) : CGNS_ENUMV(QUAD_4); for (nn = 0; nn < facelist[j]->nnodes; nn++) { if (NULL == (node = GetNode (facelist[j]->nodeid[nn], &pos))) cgnsImportFatal ("write_node_region:missing element node"); conns[nc++] = pos + 1; } } } if (cg_section_write (cgnsFile, cgnsBase, cgnsZone, reg->name, elemtype, offset, offset + nfaces - 1, 0, conns, &isect)) cgnsImportFatal ((char *)cg_get_error()); /* create parent cell mapping */ for (nc = 0, j = 0; j < num_faces; j++) { if (facelist[j]->flags) conns[nc++] = (facelist[j]->faceid >> 3) + 1; } for (j = 0; j < nfaces; j++) conns[nc++] = 0; for (j = 0; j < num_faces; j++) { if (facelist[j]->flags) conns[nc++] = (facelist[j]->faceid & 7) + 1; } for (j = 0; j < nfaces; j++) conns[nc++] = 0; if (cg_parent_data_write (cgnsFile, cgnsBase, cgnsZone, isect, conns)) cgnsImportFatal ((char *)cg_get_error()); free (conns); return nfaces; } /*---------- write_face_region -------------------------------------- * write region from face list *-------------------------------------------------------------------*/ static cgsize_t write_face_region (cgnsREGN *reg, cgsize_t offset) { int nn, facenum, i, isect; cgsize_t elemid, nodeid[4]; cgsize_t n, nc, pos, *conns; CGNS_ENUMT(ElementType_t) elemtype = CGNS_ENUMV(ElementTypeNull); cgnsELEM *elem; cgnsNODE *node; if (!reg->nobjs) return 0; conns = (cgsize_t *) malloc ((size_t)(5 * reg->nobjs) * sizeof(cgsize_t)); if (NULL == conns) cgnsImportFatal ("write_face_region:malloc failed for connectivity"); for (i = 0, n = 0; n < reg->nobjs; n++) { elemid = reg->objid[n] >> 3; facenum = (int)(reg->objid[n] & 7) - 1; if (NULL == (elem = GetElement (elemid, &pos))) cgnsImportFatal ("write_face_region:region element not found"); nn = get_face_nodes ((pos << 3) | facenum, nodeid); if (i != nn) { if (i) { elemtype = CGNS_ENUMV(MIXED); break; } i = nn; elemtype = nn == 3 ? CGNS_ENUMV(TRI_3) : CGNS_ENUMV(QUAD_4); } } for (nc = 0, n = 0; n < reg->nobjs; n++) { elemid = reg->objid[n] >> 3; facenum = (int)(reg->objid[n] & 7) - 1; elem = GetElement (elemid, &pos); nn = get_face_nodes ((pos << 3) | facenum, nodeid); if (elemtype == CGNS_ENUMV(MIXED)) conns[nc++] = nn == 3 ? CGNS_ENUMV(TRI_3) : CGNS_ENUMV(QUAD_4); for (i = 0; i < nn; i++) { if (NULL == (node = GetNode (nodeid[i], &pos))) cgnsImportFatal ("write_face_region:missing element node"); conns[nc++] = pos + i; } } if (cg_section_write (cgnsFile, cgnsBase, cgnsZone, reg->name, elemtype, offset, offset + reg->nobjs - 1, 0, conns, &isect)) cgnsImportFatal ((char *)cg_get_error()); free (conns); return reg->nobjs; } /*---------- write_elem_region -------------------------------------- * write elements as region *-------------------------------------------------------------------*/ static cgsize_t write_elem_region (cgnsREGN *reg, cgsize_t offset) { return 0; } /*====================================================================== * API routines *======================================================================*/ /*---------- cgnsImportError ------------------------------------------- * setup error handler call back *----------------------------------------------------------------------*/ void cgnsImportError (void (*callback)(char *msg)) { errcallback = callback; } /*---------- cgnsImportFatal ------------------------------------------- * write error message and exit *----------------------------------------------------------------------*/ void cgnsImportFatal (char *errmsg) { if (NULL != errcallback) (*errcallback) (errmsg); else if (NULL != errmsg && *errmsg) fprintf (stderr, "%s\n", errmsg); exit (-1); } /*---------- cgnsImportSetTol ------------------------------------------ * setup tolerance for duplicate node checking *----------------------------------------------------------------------*/ double cgnsImportSetTol (double tol) { tolerance = tol >= 0.0 ? tol : TOLERANCE; tol = def_tol; def_tol = tolerance; return (tol); } /*---------- cgnsImportGetTol ------------------------------------------ * return tolerance for duplicate node checking *----------------------------------------------------------------------*/ double cgnsImportGetTol (int rel) { double tol = def_tol; if (rel && num_nodes) { double avgvol = (xmax-xmin) * (ymax-ymin) * (zmax-zmin) / (DOUBLE)num_nodes; tol *= pow (avgvol, 0.33333); } return (tol); } /*---------- cgnsImportSetCheck ---------------------------------------- * set duplicate node checking on/off *----------------------------------------------------------------------*/ void cgnsImportSetCheck (int set) { no_check = set; } /*---------- cgnsImportRange -------------------------------------------- * gets bounding box of node coordinates *-----------------------------------------------------------------------*/ cgsize_t cgnsImportRange (double *x1, double *y1, double *z1, double *x2, double *y2, double *z2) { *x1 = xmin; *y1 = ymin; *z1 = zmin; *x2 = xmax; *y2 = ymax; *z2 = zmax; return num_nodes; } /*---------- cgnsImportCheck -------------------------------------------- * check for and remove duplicate nodes *-----------------------------------------------------------------------*/ cgsize_t cgnsImportCheck (int rel) { cgsize_t n, pos, dup_cnt = 0; cgnsNODE *node; if (num_nodes < 2) return (0); /* set tolerance */ tolerance = cgnsImportGetTol (rel); /* scan list of nodes, and remove duplicates */ for (n = 0; n < num_nodes; n++) { if (!nodemap[n].mapped) { nodemap[n].node->dist = sqrt ((double)( (nodemap[n].node->x - xmin) * (nodemap[n].node->x - xmin) + (nodemap[n].node->y - ymin) * (nodemap[n].node->y - ymin) + (nodemap[n].node->z - zmin) * (nodemap[n].node->z - zmin))); node = FindNode (nodemap[n].node, &pos); if (NULL == node) AddNode (nodemap[n].node, pos); else if (node != nodemap[n].node) { if (REFS_BIT == (nodemap[n].node->flags & REFS_BIT)) { for (pos = 0; pos < num_nodes; pos++) { if (nodemap[pos].mapped && nodemap[pos].node == nodemap[n].node) nodemap[pos].node = node; } } node->flags |= ((nodemap[n].node->flags & USED_BIT) | REFS_BIT); free (nodemap[n].node); nodemap[n].node = node; dup_cnt++; } nodemap[n].mapped = 1; } } /* free duplicate node checking list */ free (node_list); num_entries = max_entries = 0; return (dup_cnt); } /*---------- cgnsImportMap ---------------------------------------------- * map a node explictly to another *-----------------------------------------------------------------------*/ cgsize_t cgnsImportMap (cgsize_t nodeid, cgsize_t mapid) { cgsize_t p1, p2, ret; cgnsNODE *n1 = GetNode (nodeid, &p1); cgnsNODE *n2 = GetNode (mapid, &p2); if (NULL == n1 || NULL == n2) return (0); if (n1 == n2) return (n1->id); ret = CompareNodes (n1, n2) ? -1 : n1->id; if (REFS_BIT == (n2->flags & REFS_BIT)) { cgsize_t n; for (n = 0; n < num_nodes; n++) { if (nodemap[n].node == n2) { nodemap[n].node = n1; nodemap[n].mapped = 1; } } } else { nodemap[p2].node = n1; nodemap[p2].mapped = 1; } n1->flags |= ((n2->flags & USED_BIT) | REFS_BIT); free (n2); return (ret); } /*---------- cgnsImportNode --------------------------------------------- * import a node *-----------------------------------------------------------------------*/ cgsize_t cgnsImportNode (cgsize_t nodeid, double x, double y, double z) { cgsize_t n, pos; if (nodeid <= 0) return (0); /* find min/max bounds */ if (!num_nodes) { xmin = xmax = x; ymin = ymax = y; zmin = zmax = z; } else { if (xmin > x) xmin = x; if (xmax < x) xmax = x; if (ymin > y) ymin = y; if (ymax < y) ymax = y; if (zmin > z) zmin = z; if (zmax < z) zmax = z; } /* find position to place node id */ if (NULL != GetNode (nodeid, &pos)) { nodemap[pos].node->x = (DOUBLE)x; nodemap[pos].node->y = (DOUBLE)y; nodemap[pos].node->z = (DOUBLE)z; return (-1); } /* malloc/realloc if needed */ if (num_nodes == max_nodes) { if (!max_nodes) nodemap = (NODEMAP *) malloc (NODEMAP_INC * sizeof(NODEMAP)); else nodemap = (NODEMAP *) realloc (nodemap, (size_t)(max_nodes + NODEMAP_INC) * sizeof(NODEMAP)); if (NULL == nodemap) cgnsImportFatal ( "cgnsImportNode:malloc failed for node mapping data"); max_nodes += NODEMAP_INC; } /* insert new node */ for (n = num_nodes; n > pos; n--) { nodemap[n].nodeid = nodemap[n-1].nodeid; nodemap[n].mapped = nodemap[n-1].mapped; nodemap[n].node = nodemap[n-1].node; } nodemap[pos].nodeid = nodeid; nodemap[pos].mapped = no_check; nodemap[pos].node = NewNode (nodeid, x, y, z); if (NULL == nodemap[pos].node) cgnsImportFatal ("cgnsImportNode:malloc failed for a new node"); num_nodes++; return (nodeid); } /*---------- cgnsImportSetNode ------------------------------------------ * set node coordinates for node ID *-----------------------------------------------------------------------*/ cgsize_t cgnsImportSetNode (cgsize_t nodeid, double x, double y, double z) { cgsize_t n; cgnsNODE *node = GetNode (nodeid, &n); if (NULL != node) { node->x = (DOUBLE)x; node->y = (DOUBLE)y; node->z = (DOUBLE)z; return (node->id); } return (0); } /*---------- cgnsImportGetNode ------------------------------------------ * return node coordinates for node ID *-----------------------------------------------------------------------*/ cgsize_t cgnsImportGetNode (cgsize_t nodeid, double *x, double *y, double *z) { cgsize_t n; cgnsNODE *node = GetNode (nodeid, &n); if (NULL != node) { *x = node->x; *y = node->y; *z = node->z; return (node->id); } return (0); } /*---------- cgnsImportNodeList ----------------------------------------- * return list of all node ID's *-----------------------------------------------------------------------*/ cgsize_t *cgnsImportNodeList (void) { cgsize_t n, *nodeids; nodeids = (cgsize_t *) malloc ((size_t)(num_nodes + 1) * sizeof(cgsize_t)); if (NULL == nodeids) cgnsImportFatal ("cgnsImportNodeList:malloc failed for node ID list"); nodeids[0] = num_nodes; for (n = 0; n < num_nodes; n++) nodeids[n+1] = nodemap[n].nodeid; return (nodeids); } /*---------- cgnsImportAddVariable ------------------------------------- * create a node variable *----------------------------------------------------------------------*/ int cgnsImportAddVariable (char *varname) { int n; cgnsNODE *node; if (varname == NULL || !*varname) return -1; for (n = 0; n < num_vars; n++) { if (0 == strcmp(varname, var_names[n])) return n; } if (num_vars) var_names = (char **) realloc (var_names, (num_vars + 1) * sizeof(char *)); else var_names = (char **) malloc (sizeof(char *)); if (var_names == NULL) cgnsImportFatal ("AddVariable:malloc/realloc failed for variable name list"); var_names[num_vars] = (char *) malloc (strlen(varname) + 1); if (var_names[num_vars] == NULL) cgnsImportFatal ("AddVariable:malloc failed for variable name"); strcpy(var_names[num_vars++], varname); for (n = 0; n < num_entries; n++) { node = node_list[n]; if (num_vars == 1) node->vars = (DOUBLE *) malloc (sizeof(DOUBLE)); else node->vars = (DOUBLE *) realloc (node->vars, num_vars * sizeof(DOUBLE)); if (node->vars == NULL) cgnsImportFatal ("AddVariable:malloc failed for node variables"); node->vars[num_vars-1] = 0.0; } return num_vars-1; } /*---------- cgnsImportGetVariable ------------------------------------- * get the variable number for a node variable *----------------------------------------------------------------------*/ int cgnsImportGetVariable (char *varname) { int n; if (varname != NULL && *varname) { for (n = 0; n < num_vars; n++) { if (0 == strcmp(varname, var_names[n])) return n; } } return -1; } /*---------- cgnsImportVariable ---------------------------------------- * set the value of a variable at a node *----------------------------------------------------------------------*/ cgsize_t cgnsImportVariable (cgsize_t nodeid, int varnum, double val) { cgsize_t n; cgnsNODE *node = GetNode (nodeid, &n); if (NULL == node || varnum < 0 || varnum >= num_vars) return 0; node->vars[varnum] = (DOUBLE)val; return node->id; } /*---------- cgnsImportElement ------------------------------------------ * import an element *-----------------------------------------------------------------------*/ int cgnsImportElement (cgsize_t elemid, int elemtype, cgsize_t *nodelist) { int n, ret; cgsize_t pos; cgnsNODE *node; cgnsELEM *elem; if (elemid <= 0 || (elemtype != cgnsELEM_TET && elemtype != cgnsELEM_PYR && elemtype != cgnsELEM_WDG && elemtype != cgnsELEM_HEX)) return (0); /* element not found */ if (NULL == (elem = GetElement (elemid, &pos))) { ret = elemtype; elem = NewElement (pos); } /* element already exists */ else { ret = -1; free (elem->nodeid); } /* set element values */ elem->elemid = elemid; elem->elemtype = elemtype; elem->nodeid = (cgsize_t *) malloc (elemtype * sizeof(cgsize_t)); if (NULL == elem->nodeid) cgnsImportFatal ( "cgnsImportElement:malloc failed for a new element"); for (n = 0; n < elemtype; n++) { if (NULL == (node = GetNode (nodelist[n], &pos))) { char errmsg[50]; sprintf (errmsg, "cgnsImportElement:element node %ld not found", (long)nodelist[n]); cgnsImportFatal (errmsg); } elem->nodeid[n] = node->id; node->flags |= USED_BIT; } for (n = 0; n < 6; n++) elem->facemap[n] = n; return (ret); } /*---------- cgnsImportGetElement --------------------------------------- * return element for element ID *-----------------------------------------------------------------------*/ int cgnsImportGetElement (cgsize_t elemid, cgsize_t nodeid[]) { int n; cgsize_t pos; cgnsELEM *elem = GetElement (elemid, &pos); if (NULL != elem) { for (n = 0; n < elem->elemtype; n++) nodeid[n] = elem->nodeid[n]; return (elem->elemtype); } return (0); } /*---------- cgnsImportElementList -------------------------------------- * return list of all element ID's *-----------------------------------------------------------------------*/ cgsize_t *cgnsImportElementList (void) { cgsize_t n, *elemids; elemids = (cgsize_t *) malloc ((size_t)(num_elements + 1) * sizeof(int)); if (NULL == elemids) cgnsImportFatal ( "cgnsImportElementList:malloc failed for element ID list"); elemids[0] = num_elements; for (n = 0; n < num_elements; n++) elemids[n+1] = elemlist[n].elemid; return (elemids); } /*---------- cgnsImportGetFace ------------------------------------------ * return element face node ID's *-----------------------------------------------------------------------*/ int cgnsImportGetFace (cgsize_t elemid, int facenum, cgsize_t nodeid[]) { int nfaces; cgsize_t pos; cgnsELEM *elem = GetElement (elemid, &pos); if (NULL == elem) return (-1); switch (elem->elemtype) { case cgnsELEM_WDG: nfaces = 5; break; case cgnsELEM_HEX: nfaces = 6; break; default: nfaces = elem->elemtype; break; } if (--facenum < 0 || facenum >= nfaces) return (0); return get_face_nodes ((pos << 3) | facenum, nodeid); } /*---------- cgnsImportFindFace ----------------------------------------- * return element face number given face node ID's *-----------------------------------------------------------------------*/ int cgnsImportFindFace (cgsize_t elemid, int nnodes, cgsize_t nodeid[]) { int i, j, nfaces = 0, noff = 0, mask = 0; cgsize_t pos; cgnsELEM *elem = GetElement (elemid, &pos); static int facemask[4][6] = { /* tet */ { 7, 11, 14, 13, 0, 0}, /* pyramid */ {15, 19, 22, 28, 25, 0}, /* wedge */ {27, 54, 45, 7, 56, 0}, /* hex */ {15, 51, 102, 204, 153, 240} }; if (NULL == elem || NULL == nodeid) return (-1); switch (elem->elemtype) { case cgnsELEM_TET: if (nnodes != 3) return (-1); noff = 0; nfaces = 4; break; case cgnsELEM_PYR: if (nnodes < 3 || nnodes > 4) return (-1); noff = 1; nfaces = 5; break; case cgnsELEM_WDG: if (nnodes < 3 || nnodes > 4) return (-1); noff = 2; nfaces = 5; break; case cgnsELEM_HEX: if (nnodes != 4) return (-1); noff = 3; nfaces = 6; break; default: cgnsImportFatal ("cgnsImportFindFace:invalid element type"); } for (j = 0; j < nnodes; j++) { for (i = 0; i < elem->elemtype; i++) { if (nodeid[j] == elem->nodeid[i]) break; } if (i == elem->elemtype) return (0); mask |= (1 << i); } for (i = 0; i < nfaces; i++) { if (mask == facemask[noff][i]) { for (j = 0; j < 6; j++) { if (i == (int)elem->facemap[j]) return (j + 1); } } } return (0); } /*---------- cgnsImportBegReg -------------------------------------------- * begin a region specification *-----------------------------------------------------------------------*/ cgsize_t cgnsImportBegReg (char *regname, int regtype) { int n; cgnsREGN *reg; if (region_id) cgnsImportEndReg (); /* initialize region node list */ if (0 == region_max) { region_list = (cgsize_t *) malloc (REGION_INC * sizeof(cgsize_t)); if (NULL == region_list) cgnsImportFatal ( "cgnsImportBegReg:malloc failed for region node list"); region_max = REGION_INC; } /* initialize region data */ region_id = num_regions + 1; region_type = regtype; if (NULL == regname || !*regname) sprintf (region_name, "%s%ld", REGION_BASE, (long)region_id); else { strncpy (region_name, regname, sizeof(region_name)); region_name[sizeof(region_name)-1] = 0; } region_nobjs = 0; if (NULL == (reg = GetRegion (region_name, &n))) return (0); if (reg->type != regtype) cgnsImportFatal ("cgnsImportBegReg:only 1 type allowed for a region"); return (reg->nobjs); } /*---------- cgnsImportAddReg ------------------------------------------- * add nodes to the region *-----------------------------------------------------------------------*/ cgsize_t cgnsImportAddReg (cgsize_t numobjs, cgsize_t *objlist) { cgsize_t n, pos; char errmsg[50]; if (!region_id) cgnsImportFatal ("cgnsImportAddReg:region not defined"); /* realloc region list array if needed */ if (region_nobjs + numobjs > region_max) { n = region_nobjs + numobjs - region_max; if (n < REGION_INC) n = REGION_INC; region_list = (cgsize_t *) realloc (region_list, (size_t)(region_max + n) * sizeof(cgsize_t)); if (NULL == region_list) cgnsImportFatal ( "cgnsImportAddReg:malloc failed for region node list"); region_max += n; } /* node region */ if (region_type == cgnsREG_NODES) { cgnsNODE *node; for (n = 0; n < numobjs; n++) { if (NULL == (node = GetNode (objlist[n], &pos))) { sprintf (errmsg, "cgnsImportAddReg:region node %ld not found", (long)objlist[n]); cgnsImportFatal (errmsg); } region_list[region_nobjs++] = node->id; node->flags |= USED_BIT; } } /* face region */ else if (region_type == cgnsREG_FACES) { int facenum, nfaces; cgsize_t elemid; cgnsELEM *elem; for (n = 0; n < numobjs; n++) { elemid = objlist[n] >> 3; facenum = (int)(objlist[n] & 7); if (NULL == (elem = GetElement (elemid, &pos))) { sprintf (errmsg, "cgnsImportAddReg:region element %ld not found", (long)elemid); cgnsImportFatal (errmsg); } if (elem->elemtype == cgnsELEM_WDG) nfaces = 5; else if (elem->elemtype == cgnsELEM_HEX) nfaces = 6; else nfaces = elem->elemtype; if (facenum < 1 || facenum > nfaces) cgnsImportFatal ("cgnsImportAddReg:region face number out of range"); region_list[region_nobjs++] = objlist[n]; } } /* element region */ else if (region_type == cgnsREG_ELEMS) { for (n = 0; n < numobjs; n++) { if (NULL == GetElement (objlist[n], &pos)) { sprintf (errmsg, "cgnsImportAddReg:region element %ld not found", (long)objlist[n]); cgnsImportFatal (errmsg); } region_list[region_nobjs++] = objlist[n]; } } else cgnsImportFatal ("cgnsImportAddReg:undefined region type"); return (region_nobjs); } /*---------- cgnsImportEndReg ------------------------------------------- * end region definition and import region *-----------------------------------------------------------------------*/ cgsize_t cgnsImportEndReg (void) { int pos; cgsize_t n; cgnsREGN *reg; if (!region_id || !region_nobjs) return (region_id = 0); region_id = 0; /* create a new region */ if (NULL == (reg = GetRegion (region_name, &pos))) { reg = NewRegion (region_name, pos); reg->type = region_type; } if (0 == reg->nobjs) reg->objid = (cgsize_t *) malloc ((size_t)region_nobjs * sizeof(cgsize_t)); else reg->objid = (cgsize_t *) realloc (reg->objid, (size_t)(reg->nobjs + region_nobjs) * sizeof(cgsize_t)); if (NULL == reg->objid) cgnsImportFatal ( "cgnsImportRegion:malloc failed for the region object list"); for (n = 0; n < region_nobjs; n++) reg->objid[n+reg->nobjs] = region_list[n]; reg->nobjs += region_nobjs; return (reg->nobjs); } /*---------- cgnsImportRegion ------------------------------------------- * import a named region *-----------------------------------------------------------------------*/ cgsize_t cgnsImportRegion (char *regname, int regtype, cgsize_t numobjs, cgsize_t *objlist) { cgnsImportBegReg (regname, regtype); cgnsImportAddReg (numobjs, objlist); return (cgnsImportEndReg ()); } /*---------- cgnsImportRegionList --------------------------------------- * return a list of all region names *-----------------------------------------------------------------------*/ char **cgnsImportRegionList (void) { int n, len = 0; char **namelist, *names; for (n = 0; n < num_regions; n++) len += ((int)strlen (reglist[n].name) + 1); n = num_regions + 1; namelist = (char **) malloc (len + n * sizeof(char *)); if (NULL == namelist) cgnsImportFatal ( "cgnsImportRegionList:malloc failed for region name list"); names = (char *) (namelist + n); for (n = 0; n < num_regions; n++) { namelist[n] = names; strcpy (names, reglist[n].name); names += (strlen (reglist[n].name) + 1); } namelist[num_regions] = NULL; return (namelist); } /*---------- cgnsImportGetRegion ---------------------------------------- * get node ID's for a region *-----------------------------------------------------------------------*/ cgsize_t *cgnsImportGetRegion (char *regname) { int pos; cgsize_t n, *objlist; cgnsREGN *reg; if (NULL == regname || !*regname || NULL == (reg = GetRegion (regname, &pos))) return (NULL); objlist = (cgsize_t *) malloc ((size_t)(reg->nobjs + 2) * sizeof(cgsize_t)); if (NULL == objlist) cgnsImportFatal ( "cgnsImportGetRegion:malloc failed for region object ID list"); objlist[0] = reg->type; objlist[1] = reg->nobjs; for (n = 0; n < reg->nobjs; n++) objlist[n+2] = reg->objid[n]; return (objlist); } /*---------- cgnsImportOpen --------------------------------------------- * open CGNS file *-----------------------------------------------------------------------*/ int cgnsImportOpen (char *filename) { cgnsImportClose (); if (cg_open (filename, CG_MODE_MODIFY, &cgnsFile) && cg_open (filename, CG_MODE_WRITE, &cgnsFile)) cgnsImportFatal ((char *)cg_get_error()); return cgnsFile; } /*---------- cgnsImportBase --------------------------------------------- * set CGNS base *-----------------------------------------------------------------------*/ int cgnsImportBase (char *basename) { if (cg_base_write (cgnsFile, basename, 3, 3, &cgnsBase)) cgnsImportFatal ((char *)cg_get_error()); return cgnsBase; } /*---------- cgnsImportZone --------------------------------------------- * set CGNS zone *-----------------------------------------------------------------------*/ void cgnsImportZone (char *zonename) { int n; for (n = 0; n < num_nodes; n++) { if (nodemap[n].node != NULL) free (nodemap[n].node); } for (n = 0; n < num_elements; n++) { if (elemlist[n].nodeid != NULL) free (elemlist[n].nodeid); } if (num_regions) { for (n = 0; n < num_regions; n++) { if (reglist[n].objid != NULL) free (reglist[n].objid); } free (reglist); } if (num_faces) { for (n = 0; n < num_faces; n++) { if (facelist[n] != NULL) free (facelist[n]); } free (facelist); } num_nodes = num_elements = num_faces = 0; num_regions = 0; strncpy (cgnsZoneName, zonename, 32); cgnsZoneName[32] = 0; } /*---------- cgnsImportWrite -------------------------------------------- * write data to the CGNS file *-----------------------------------------------------------------------*/ int cgnsImportWrite (void) { int icoord, isect; cgsize_t n, nn, nnodes, sizes[3]; cgsize_t nc, nconn, *conns, pos; CGNS_ENUMT(ElementType_t) elemtype = CGNS_ENUMV(ElementTypeNull); #ifdef DOUBLE_PRECISION CGNS_ENUMT(DataType_t) datatype = CGNS_ENUMV(RealDouble); double *xyz; #else CGNS_ENUMT(DataType_t) datatype = CGNS_ENUMV(RealSingle); float *xyz; #endif cgnsNODE *node; cgnsELEM *elem; cgnsREGN *regn; if (!cgnsFile) cgnsImportFatal ("cgnsImportWrite:CGNS file not open"); if (region_id) cgnsImportEndReg (); /* count the nodes */ nnodes = 0; for (n = 0; n < num_nodes; n++) { if (nodemap[n].nodeid == nodemap[n].node->id && USED_BIT == (nodemap[n].node->flags & USED_BIT)) nnodes++; } if (!nnodes) return 0; if (!cgnsBase) cgnsImportBase ("Base"); if (!*cgnsZoneName) strcpy (cgnsZoneName, "Zone"); sizes[0] = nnodes; sizes[1] = num_elements; sizes[2] = 0; if (cg_zone_write (cgnsFile, cgnsBase, cgnsZoneName, sizes, CGNS_ENUMV(Unstructured), &cgnsZone)) cgnsImportFatal ((char *)cg_get_error()); /* write the node list */ #ifdef DOUBLE_PRECISION xyz = (double *) malloc ((size_t)nnodes * sizeof(double)); #else xyz = (float *) malloc ((size_t)nnodes * sizeof(float)); #endif if (NULL == xyz) cgnsImportFatal ("cgnsImportWrite:malloc failed for nodes"); for (nn = 0, n = 0; n < num_nodes; n++) { if (nodemap[n].nodeid == nodemap[n].node->id && USED_BIT == (nodemap[n].node->flags & USED_BIT)) #ifdef DOUBLE_PRECISION xyz[nn++] = (double)nodemap[n].node->x; #else xyz[nn++] = (float)nodemap[n].node->x; #endif } if (cg_coord_write (cgnsFile, cgnsBase, cgnsZone, datatype, "CoordinateX", (void *)xyz, &icoord)) cgnsImportFatal ((char *)cg_get_error()); for (nn = 0, n = 0; n < num_nodes; n++) { if (nodemap[n].nodeid == nodemap[n].node->id && USED_BIT == (nodemap[n].node->flags & USED_BIT)) #ifdef DOUBLE_PRECISION xyz[nn++] = (double)nodemap[n].node->y; #else xyz[nn++] = (float)nodemap[n].node->y; #endif } if (cg_coord_write (cgnsFile, cgnsBase, cgnsZone, datatype, "CoordinateY", (void *)xyz, &icoord)) cgnsImportFatal ((char *)cg_get_error()); for (nn = 0, n = 0; n < num_nodes; n++) { if (nodemap[n].nodeid == nodemap[n].node->id && USED_BIT == (nodemap[n].node->flags & USED_BIT)) #ifdef DOUBLE_PRECISION xyz[nn++] = (double)nodemap[n].node->z; #else xyz[nn++] = (float)nodemap[n].node->z; #endif } if (cg_coord_write (cgnsFile, cgnsBase, cgnsZone, datatype, "CoordinateZ", (void *)xyz, &icoord)) cgnsImportFatal ((char *)cg_get_error()); /* write variables */ if (num_vars) { int isol, ifld, nv; if (cg_sol_write(cgnsFile, cgnsBase, cgnsZone, "NodeVariables", CGNS_ENUMV(Vertex), &isol)) cgnsImportFatal ((char *)cg_get_error()); for (nv = 0; nv < num_vars; nv++) { for (nn = 0, n = 0; n < num_nodes; n++) { if (nodemap[n].nodeid == nodemap[n].node->id && USED_BIT == (nodemap[n].node->flags & USED_BIT)) #ifdef DOUBLE_PRECISION xyz[nn++] = (double)nodemap[n].node->vars[nv]; #else xyz[nn++] = (float)nodemap[n].node->vars[nv]; #endif } if (strlen(var_names[nv]) > 32) var_names[nv][32] = 0; if (cg_field_write(cgnsFile, cgnsBase, cgnsZone, isol, datatype, var_names[nv], xyz, &ifld)) cgnsImportFatal ((char *)cg_get_error()); } } free (xyz); /* write the element list */ switch (elemlist->elemtype) { case cgnsELEM_TET: elemtype = CGNS_ENUMV(TETRA_4); break; case cgnsELEM_PYR: elemtype = CGNS_ENUMV(PYRA_5); break; case cgnsELEM_WDG: elemtype = CGNS_ENUMV(PENTA_6); break; case cgnsELEM_HEX: elemtype = CGNS_ENUMV(HEXA_8); break; } for (n = 0, elem = elemlist; n < num_elements; n++, elem++) { if (elem->elemtype != elemlist->elemtype) { elemtype = CGNS_ENUMV(MIXED); break; } } if (elemtype == CGNS_ENUMV(MIXED)) { nconn = 0; for (n = 0, elem = elemlist; n < num_elements; n++, elem++) nconn += (1 + elem->elemtype); } else nconn = num_elements * elemlist->elemtype; conns = (cgsize_t *) malloc ((size_t)nconn * sizeof(cgsize_t)); if (NULL == conns) cgnsImportFatal ("cgnsImportWrite:malloc failed for element data"); nc = 0; for (n = 0, elem = elemlist; n < num_elements; n++, elem++) { if (elemtype == CGNS_ENUMV(MIXED)) { switch (elem->elemtype) { case cgnsELEM_TET : conns[nc] = CGNS_ENUMV(TETRA_4); break; case cgnsELEM_PYR: conns[nc] = CGNS_ENUMV(PYRA_5); break; case cgnsELEM_WDG: conns[nc] = CGNS_ENUMV(PENTA_6); break; case cgnsELEM_HEX: conns[nc] = CGNS_ENUMV(HEXA_8); break; } nc++; } for (nn = 0; nn < elem->elemtype; nn++) { if (NULL == (node = GetNode (elem->nodeid[nn], &pos))) cgnsImportFatal ("cgnsImportWrite:missing element node"); conns[nc++] = pos + 1; } } if (cg_section_write (cgnsFile, cgnsBase, cgnsZone, "GridElements", elemtype, 1, num_elements, 0, conns, &isect)) cgnsImportFatal ((char *)cg_get_error()); free (conns); /* write the regions */ nn = num_elements + 1; for (n = 0, regn = reglist; n < num_regions; n++, regn++) { if (regn->type == cgnsREG_NODES) nn += write_node_region (regn, nn); else if (regn->type == cgnsREG_FACES) nn += write_face_region (regn, nn); else if (regn->type == cgnsREG_ELEMS) nn += write_elem_region (regn, nn); } return cgnsZone; } /*---------- cgnsImportClose -------------------------------------------- * close the CGNS file *-----------------------------------------------------------------------*/ void cgnsImportClose (void) { if (cgnsFile) { cg_close (cgnsFile); cgnsFile = 0; } } cgnslib_3.1.4/src/cgnstools/utilities/tecplot.tcl0000664000076400007640000000756212160605674017171 00000000000000# tecplot.tcl - Tecplot import/export array set Import { tecfile "" fixbricks 0 singlezone 0 } set Export(tecfile) "" proc tecplot_import {w name exe} { global ProgData Font Import set cmd [get_executable $exe 1] if {$cmd == ""} return set Import(cgnsfile) $ProgData(file,name) toplevel $w wm title $w "Tecplot File Import" wm transient $w . wm protocol $w WM_DELETE_WINDOW {set Import(done) 0} import_input $w tecfile Tecplot {.dat .plt .tec} import_output $w 1 FrameCreate $w.opts -text "Options" -font $Font(bold) pack $w.opts -side top -padx 5 -pady 2 -fill x set opts [FrameGet $w.opts] set f [frame $opts.f] pack $f -side left checkbutton $f.fb -text "Fix Degenerate Bricks" \ -variable Import(fixbricks) -onvalue 1 -offvalue 0 checkbutton $f.sz -text "Import as Single Zone" \ -variable Import(singlezone) -onvalue 1 -offvalue 0 -state disabled pack $f.fb $f.sz -side top -anchor w frame $opts.dup pack $opts.dup -side right import_dup_check $opts.dup if {[import_buttons $w tecplot_import_check]} { if {$Import(fixbricks)} { lappend cmd -f } if {$Import(dupcheck,flag)} { lappend cmd -$Import(dupcheck) if {$Import(duptol) != ""} { lappend cmd -t$Import(duptol) } } if {$Import(basename) != ""} { lappend cmd -B$Import(basename) } lappend cmd $Import(tecfile) $Import(cgnsfile) import_run "Tecplot Import" $cmd $Import(cgnsfile) } } proc tecplot_import_check {w} { global Import if {[string trim $Import(tecfile)] == "" || [string trim $Import(cgnsfile)] == ""} { errormsg "must specify a Tecplot and a CGNS file" $w return } if {![file exists $Import(tecfile)]} { errormsg "Tecplot input file doesn't exist" $w return } set Import(done) 1 } proc tecplot_export {w name exe} { global ProgData Font Export set cmd [get_executable $exe 1] if {$cmd == ""} return toplevel $w wm title $w "Tecplot Export" wm transient $w . wm protocol $w WM_DELETE_WINDOW {set Export(done) 0} export_input $w 1 0 1 export_output $w tecfile Tecplot {.dat .plt .tec} FrameCreate $w.opts -text "Options" -font $Font(bold) pack $w.opts -side top -pady 2 -fill x set opts [FrameGet $w.opts] checkbutton $opts.fmt -text "ASCII Tecplot Output" \ -variable Export(ascii) -onvalue 1 -offvalue 0 \ -command tecplot_extension pack $opts.fmt -side top -anchor w checkbutton $opts.sol -text "Grid Ouput Only (no solution)" \ -variable Export(solution) -onvalue 0 -offvalue 1 pack $opts.sol -side top -anchor w checkbutton $opts.weight -text "Use Volume Weighting" \ -variable Export(weight) -onvalue 1 -offvalue 0 pack $opts.weight -side top -anchor w set Export(cgnsfile) $ProgData(file,name) set Export(tecfile) [file rootname $ProgData(file,name)] tecplot_extension if {[export_buttons $w tecplot_export_check]} { update idletasks if {$Export(basenum) != ""} { lappend cmd -b$Export(basenum) } if {$Export(solution)} { if {$Export(solnum) != ""} { lappend cmd -S$Export(solnum) } } else { lappend cmd -S0 } if {$Export(ascii)} { lappend cmd -a } if {$Export(weight)} { lappend cmd -w } lappend cmd $Export(cgnsfile) $Export(tecfile) update run_command "Tecplot Export" $cmd } } proc tecplot_extension {} { global Export if {$Export(tecfile) == ""} return if {$Export(ascii)} { set ext dat } else { set ext plt } set Export(tecfile) [file rootname $Export(tecfile)].$ext } proc tecplot_export_check {w} { global Export if {[string trim $Export(cgnsfile)] == "" || [string trim $Export(tecfile)] == ""} { errormsg "must specify a CGNS and a Tecplot file" $w return } if {![file exists $Export(cgnsfile)]} { errormsg "CGNS input file doesn't exist" $w return } set Export(done) 1 } cgnslib_3.1.4/src/cgnstools/utilities/extract_subset.c0000664000076400007640000006155212160605674020215 00000000000000/* * convert_location.c - convert between vertex and cell-center */ #include #include #include #ifdef _WIN32 # define unlink _unlink #else # include #endif #include "getargs.h" #include "cgnslib.h" #include "cgnsutil.h" #ifndef CG_MODE_MODIFY # define CG_MODE_MODIFY MODE_MODIFY #endif /* command line options */ static char options[] = "fb:z:ijkawB:"; static char *usgmsg[] = { "usage : extract_subset [options] CGNSfile [newCGNSfile]", "options:", " -b = use CGNS base number (default 1)", " -z = read zone number (default all)", " -i = subset in I-direction", " -j = subset in J-direction", " -k = subset in K-direction", " -a = subset in all directions (default)", " -w = use volume weighting for solution", " -B = write subset to base (default same as read)", NULL }; static int weighting = 0; /*-------------------------------------------------------------------*/ static void field_subset (ZONE *z, SOLUTION *s, int inc[3], double *f, double *w) { cgsize_t i, j, k, ip, jp, kp; cgsize_t nn, nf, nw, np; ZONE zn; double *fn, *wn; for (np = 1, nn = 0; nn < 3; nn++) { zn.dim[nn] = (z->dim[nn] - 1) / inc[nn] + 1; np *= (zn.dim[nn] - 1 + s->rind[nn][0] + s->rind[nn][1]); } fn = (double *) malloc ((size_t)(2 * np) * sizeof(double)); if (NULL == fn) FATAL (NULL, "malloc failed for solution field"); wn = fn + np; for (nn = 0; nn < np; nn++) { fn[nn] = 0.0; wn[nn] = 0.0; } /* interior */ for (k = 1; k < z->dim[2]; k += inc[2]) { kp = k + 1 < z->dim[2] ? k + 1 : k; for (j = 1; j < z->dim[1]; j += inc[1]) { jp = j + 1 < z->dim[1] ? j + 1 : j; for (i = 1; i < z->dim[0]; i += inc[0]) { ip = i + 1 < z->dim[0] ? i + 1 : i; nn = solution_index (&zn, s, (i - 1) / inc[0] + 1, (j - 1) / inc[1] + 1, (k - 1) / inc[2] + 1); nf = solution_index (z, s, i, j, k); nw = cell_index (z, i, j, k); fn[nn] += f[nf] * w[nw]; wn[nn] += w[nw]; nf = solution_index (z, s, ip, j, k); nw = cell_index (z, ip, j, k); fn[nn] += f[nf] * w[nw]; wn[nn] += w[nw]; nf = solution_index (z, s, i, jp, k); nw = cell_index (z, i, jp, k); fn[nn] += f[nf] * w[nw]; wn[nn] += w[nw]; nf = solution_index (z, s, ip, jp, k); nw = cell_index (z, ip, jp, k); fn[nn] += f[nf] * w[nw]; wn[nn] += w[nw]; nf = solution_index (z, s, i, j, kp); nw = cell_index (z, i, j, kp); fn[nn] += f[nf] * w[nw]; wn[nn] += w[nw]; nf = solution_index (z, s, ip, j, kp); nw = cell_index (z, ip, j, kp); fn[nn] += f[nf] * w[nw]; wn[nn] += w[nw]; nf = solution_index (z, s, i, jp, kp); nw = cell_index (z, i, jp, kp); fn[nn] += f[nf] * w[nw]; wn[nn] += w[nw]; nf = solution_index (z, s, ip, jp, kp); nw = cell_index (z, ip, jp, kp); fn[nn] += f[nf] * w[nw]; wn[nn] += w[nw]; } } } /* rind planes */ for (i = 1; i <= s->rind[0][0]; i++) { ip = 1 - i; for (k = 1; k < z->dim[2]; k += inc[2]) { kp = k + 1 < z->dim[2] ? k + 1 : k; for (j = 1; j < z->dim[1]; j += inc[1]) { jp = j + 1 < z->dim[1] ? j + 1 : j; nn = solution_index (&zn, s, ip, (j - 1) / inc[1] + 1, (k - 1) / inc[2] + 1); fn[nn] += f[solution_index (z, s, ip, j, k)] + f[solution_index (z, s, ip, jp, k)] + f[solution_index (z, s, ip, j, kp)] + f[solution_index (z, s, ip, jp, kp)]; wn[nn] += 4.0; } } } for (i = 1; i <= s->rind[0][1]; i++) { ip = z->dim[0] + i - 1; for (k = 1; k < z->dim[2]; k += inc[2]) { kp = k + 1 < z->dim[2] ? k + 1 : k; for (j = 1; j < z->dim[1]; j += inc[1]) { jp = j + 1 < z->dim[1] ? j + 1 : j; nn = solution_index (&zn, s, zn.dim[0] + i - 1, (j - 1) / inc[1] + 1, (k - 1) / inc[2] + 1); fn[nn] += f[solution_index (z, s, ip, j, k)] + f[solution_index (z, s, ip, jp, k)] + f[solution_index (z, s, ip, j, kp)] + f[solution_index (z, s, ip, jp, kp)]; wn[nn] += 4.0; } } } for (j = 1; j <= s->rind[1][0]; j++) { jp = 1 - j; for (k = 1; k < z->dim[2]; k += inc[2]) { kp = k + 1 < z->dim[2] ? k + 1 : k; for (i = 1; i < z->dim[0]; i += inc[0]) { ip = i + 1 < z->dim[0] ? i + 1 : i; nn = solution_index (&zn, s, (i - 1) / inc[0] + 1, jp, (k - 1) / inc[2] + 1); fn[nn] += f[solution_index (z, s, i, jp, k)] + f[solution_index (z, s, ip, jp, k)] + f[solution_index (z, s, i, jp, kp)] + f[solution_index (z, s, ip, jp, kp)]; wn[nn] += 4.0; } } } for (j = 1; j <= s->rind[1][1]; j++) { jp = z->dim[1] + j - 1; for (k = 1; k < z->dim[2]; k += inc[2]) { kp = k + 1 < z->dim[2] ? k + 1 : k; for (i = 1; i < z->dim[0]; i += inc[0]) { ip = i + 1 < z->dim[0] ? i + 1 : i; nn = solution_index (&zn, s, (i - 1) / inc[0] + 1, zn.dim[1] + j - 1, (k - 1) / inc[2] + 1); fn[nn] += f[solution_index (z, s, i, jp, k)] + f[solution_index (z, s, ip, jp, k)] + f[solution_index (z, s, i, jp, kp)] + f[solution_index (z, s, ip, jp, kp)]; wn[nn] += 4.0; } } } for (k = 1; k <= s->rind[2][0]; k++) { kp = 1 - k; for (j = 1; j < z->dim[1]; j += inc[1]) { jp = j + 1 < z->dim[1] ? j + 1 : j; for (i = 1; i < z->dim[0]; i += inc[0]) { ip = i + 1 < z->dim[0] ? i + 1 : i; nn = solution_index (&zn, s, (i - 1) / inc[0] + 1, (j - 1) / inc[1] + 1, kp); fn[nn] += f[solution_index (z, s, i, j, kp)] + f[solution_index (z, s, ip, j, kp)] + f[solution_index (z, s, i, jp, kp)] + f[solution_index (z, s, ip, jp, kp)]; wn[nn] += 4.0; } } } for (k = 1; k <= s->rind[2][1]; k++) { kp = z->dim[2] + k - 1; for (j = 1; j < z->dim[1]; j += inc[1]) { jp = j + 1 < z->dim[1] ? j + 1 : j; for (i = 1; i < z->dim[0]; i += inc[0]) { ip = i + 1 < z->dim[0] ? i + 1 : i; nn = solution_index (&zn, s, (i - 1) / inc[0] + 1, (j - 1) / inc[1] + 1, zn.dim[2] + k - 1); fn[nn] += f[solution_index (z, s, i, j, kp)] + f[solution_index (z, s, ip, j, kp)] + f[solution_index (z, s, i, jp, kp)] + f[solution_index (z, s, ip, jp, kp)]; wn[nn] += 4.0; } } } /* rind lines */ for (i = 1; i <= s->rind[0][0]; i++) { ip = 1 - i; for (j = 1; j <= s->rind[1][0]; j++) { jp = 1 - j; for (k = 1; k < zn.dim[2]; k++) { nn = solution_index (&zn, s, ip, jp, k); nf = solution_index (&zn, s, ip+1, jp, k); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp+1, k); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } } for (j = 1; j <= s->rind[1][1]; j++) { jp = zn.dim[1] + j - 1; for (k = 1; k < zn.dim[2]; k++) { nn = solution_index (&zn, s, ip, jp, k); nf = solution_index (&zn, s, ip+1, jp, k); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp-1, k); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } } for (k = 1; k <= s->rind[2][0]; k++) { kp = 1 - k; for (j = 1; j < zn.dim[1]; j++) { nn = solution_index (&zn, s, ip, j, kp); nf = solution_index (&zn, s, ip+1, j, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, j, kp+1); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } } for (k = 1; k <= s->rind[2][1]; k++) { kp = zn.dim[2] + k - 1; for (j = 1; j < zn.dim[1]; j++) { nn = solution_index (&zn, s, ip, j, kp); nf = solution_index (&zn, s, ip+1, j, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, j, kp-1); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } } } for (i = 1; i <= s->rind[0][1]; i++) { ip = zn.dim[0] + i - 1; for (j = 1; j <= s->rind[1][0]; j++) { jp = 1 - j; for (k = 1; k < zn.dim[2]; k++) { nn = solution_index (&zn, s, ip, jp, k); nf = solution_index (&zn, s, ip-1, jp, k); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp+1, k); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } } for (j = 1; j <= s->rind[1][1]; j++) { jp = zn.dim[1] + j - 1; for (k = 1; k < zn.dim[2]; k++) { nn = solution_index (&zn, s, ip, jp, k); nf = solution_index (&zn, s, ip-1, jp, k); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp-1, k); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } } for (k = 1; k <= s->rind[2][0]; k++) { kp = 1 - k; for (j = 1; j < zn.dim[1]; j++) { nn = solution_index (&zn, s, ip, j, kp); nf = solution_index (&zn, s, ip-1, j, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, j, kp+1); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } } for (k = 1; k <= s->rind[2][1]; k++) { kp = zn.dim[2] + k - 1; for (j = 1; j < zn.dim[1]; j++) { nn = solution_index (&zn, s, ip, j, kp); nf = solution_index (&zn, s, ip-1, j, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, j, kp-1); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } } } for (j = 1; j <= s->rind[1][0]; j++) { jp = 1 - j; for (k = 1; k <= s->rind[2][0]; k++) { kp = 1 - k; for (i = 1; i < zn.dim[0]; i++) { nn = solution_index (&zn, s, i, jp, kp); nf = solution_index (&zn, s, i, jp+1, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, i, jp, kp+1); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } } for (k = 1; k <= s->rind[2][1]; k++) { kp = zn.dim[2] + k - 1; for (i = 1; i < zn.dim[0]; i++) { nn = solution_index (&zn, s, i, jp, kp); nf = solution_index (&zn, s, i, jp+1, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, i, jp, kp-1); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } } } for (j = 1; j <= s->rind[1][1]; j++) { jp = zn.dim[1] + j - 1; for (k = 1; k <= s->rind[2][0]; k++) { kp = 1 - k; for (i = 1; i < zn.dim[0]; i++) { nn = solution_index (&zn, s, i, jp, kp); nf = solution_index (&zn, s, i, jp-1, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, i, jp, kp+1); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } } for (k = 1; k <= s->rind[2][1]; k++) { kp = zn.dim[2] + k - 1; for (i = 1; i < zn.dim[0]; i++) { nn = solution_index (&zn, s, i, jp, kp); nf = solution_index (&zn, s, i, jp-1, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, i, jp, kp-1); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } } } /* rind points */ for (i = 1; i <= s->rind[0][0]; i++) { ip = 1 - i; for (j = 1; j <= s->rind[1][0]; j++) { jp = 1 - j; for (k = 1; k <= s->rind[2][0]; k++) { kp = 1 - k; nn = solution_index (&zn, s, ip, jp, kp); nf = solution_index (&zn, s, ip+1, jp, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp+1, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp, kp+1); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } for (k = 1; k <= s->rind[2][1]; k++) { kp = zn.dim[2] + k - 1; nn = solution_index (&zn, s, ip, jp, kp); nf = solution_index (&zn, s, ip+1, jp, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp+1, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp, kp-1); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } } for (j = 1; j <= s->rind[1][1]; j++) { jp = zn.dim[1] + j - 1; for (k = 1; k <= s->rind[2][0]; k++) { kp = 1 - k; nn = solution_index (&zn, s, ip, jp, kp); nf = solution_index (&zn, s, ip+1, jp, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp-1, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp, kp+1); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } for (k = 1; k <= s->rind[2][1]; k++) { kp = zn.dim[2] + k - 1; nn = solution_index (&zn, s, ip, jp, kp); nf = solution_index (&zn, s, ip+1, jp, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp-1, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp, kp-1); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } } } for (i = 1; i <= s->rind[0][1]; i++) { ip = zn.dim[0] + i - 1; for (j = 1; j <= s->rind[1][0]; j++) { jp = 1 - j; for (k = 1; k <= s->rind[2][0]; k++) { kp = 1 - k; nn = solution_index (&zn, s, ip, jp, kp); nf = solution_index (&zn, s, ip-1, jp, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp+1, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp, kp+1); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } for (k = 1; k <= s->rind[2][1]; k++) { kp = zn.dim[2] + k - 1; nn = solution_index (&zn, s, ip, jp, kp); nf = solution_index (&zn, s, ip-1, jp, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp+1, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp, kp-1); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } } for (j = 1; j <= s->rind[1][1]; j++) { jp = zn.dim[1] + j - 1; for (k = 1; k <= s->rind[2][0]; k++) { kp = 1 - k; nn = solution_index (&zn, s, ip, jp, kp); nf = solution_index (&zn, s, ip-1, jp, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp-1, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp, kp+1); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } for (k = 1; k <= s->rind[2][1]; k++) { kp = zn.dim[2] + k - 1; nn = solution_index (&zn, s, ip, jp, kp); nf = solution_index (&zn, s, ip-1, jp, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp-1, kp); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; nf = solution_index (&zn, s, ip, jp, kp-1); fn[nn] += fn[nf] * wn[nf]; wn[nn] += wn[nf]; } } } for (nn = 0; nn < np; nn++) { if (wn[nn] == 0.0) wn[nn] = 1.0; f[nn] = fn[nn] / wn[nn]; } free (fn); } /*-------------------------------------------------------------------*/ static void extract_subset (int nz, int subset[3]) { int inc[3]; cgsize_t n, nn, np, i, j, k; ZONE *z = &Zones[nz-1]; INTERFACE *zi; BOCO *zb; SOLUTION *zs; double *w; /* grid coordinates */ for (n = 0; n < 3; n++) inc[n] = subset[n] < z->dim[n] ? subset[n] : 1; nn = 0; for (k = 1; k <= z->dim[2]; k += inc[2]) { for (j = 1; j <= z->dim[1]; j += inc[1]) { for (i = 1; i <= z->dim[0]; i += inc[0]) { np = vertex_index (z, i, j, k); z->verts[nn].x = z->verts[np].x; z->verts[nn].y = z->verts[np].y; z->verts[nn].z = z->verts[np].z; z->verts[nn].id = nn + 1; nn++; } } } /* interfaces */ for (zi = z->ints, n = 0; n < z->nints; n++, zi++) { for (i = 0; i < 3; i++) { nn = np = inc[i]; if (zi->d_zone) np = subset[i] < Zones[zi->d_zone-1].dim[i] ? subset[i] : 1; for (j = 0; j < 2; j++) { zi->range[i][j] = (zi->range[i][j] - 1) / nn + 1; zi->d_range[i][j] = (zi->d_range[i][j] - 1) / np + 1; } } } /* connectivities - remove these for now */ z->nconns = 0; /* boundary conditions */ for (zb = z->bocos, nn = 0; nn < z->nbocos; nn++, zb++) { if (zb->ptype == CGNS_ENUMV(PointRange)) { for (n = 0, j = 0; j < 2; j++) { for (i = 0; i < 3; i++, n++) zb->pnts[n] = (zb->pnts[n] - 1) / inc[i] + 1; } /* normals ? */ } else zb->id = 0; } /* solutions */ np = (z->dim[0] - 1) * (z->dim[1] - 1) * (z->dim[2] - 1); nn = 0; for (zs = z->sols, n = 0; n < z->nsols; n++, zs++) nn += zs->nflds; if (!np || !nn) { z->nsols = 0; return; } w = (double *) malloc ((size_t)np * sizeof(double)); if (NULL == w) FATAL (NULL, "malloc failed for weighting array"); if (weighting) { n = 0; for (k = 1; k < z->dim[2]; k++) for (j = 1; j < z->dim[1]; j++) for (i = 1; i < z->dim[0]; i++) w[n++] = cell_volume (z, i, j, k); } else { for (n = 0; n < np; n++) w[n] = 1.0; } for (zs = z->sols, n = 0; n < z->nsols; n++, zs++) { for (n = 0; n < zs->nflds; n++) field_subset (z, zs, inc, zs->flds[n].data, w); } free (w); } /*-------------------------------------------------------------------*/ int main (int argc, char *argv[]) { int n, nz, celldim, phydim; int subset[3], izone = 0; char basename[33], *newbase = NULL, *tmpfile; ZONE *z; if (argc < 2) print_usage (usgmsg, NULL); for (n = 0; n < 3; n++) subset[n] = 1; while ((n = getargs (argc, argv, options)) > 0) { switch (n) { case 'b': cgnsbase = atoi (argarg); break; case 'z': izone = atoi (argarg); break; case 'B': newbase = argarg; break; case 'a': for (n = 0; n < 3; n++) subset[n] = 2; break; case 'i': case 'j': case 'k': subset[n-'i'] = 2; break; case 'w': weighting = 1; break; } } if (argind == argc) print_usage (usgmsg, "CGNSfile not given"); if (!file_exists (argv[argind])) FATAL (NULL, "CGNSfile does not exist or is not a file"); if (subset[0] + subset[1] + subset[2] == 3) { for (n = 0; n < 3; n++) subset[n] = 2; } /* create a working copy */ printf ("creating a working copy of %s\n", argv[argind]); tmpfile = temporary_file (argv[argind]); copy_file (argv[argind], tmpfile); /* read CGNS file */ printf ("reading CGNS file from %s\n", tmpfile); if (cg_open (tmpfile, CG_MODE_MODIFY, &cgnsfn) || cg_base_read (cgnsfn, cgnsbase, basename, &celldim, &phydim)) FATAL (NULL, NULL); if (celldim != 3 || phydim != 3) FATAL (NULL, "cell and/or physical dimension must be 3"); printf ("reading zone information for base %d - %s\n", cgnsbase, basename); read_zones (); /* extract the subset */ for (z = Zones, nz = 1; nz <= nZones; nz++, z++) { if (izone && nz != izone) z->id = 0; else { if (z->type != CGNS_ENUMV(Structured)) { sprintf (basename, "zone %d is not Structured", nz); FATAL (NULL, basename); } printf ("extracting subset for zone %d - %ldx%ldx%ld ... ", nz, (long)z->dim[0], (long)z->dim[1], (long)z->dim[2]); fflush (stdout); read_zone_data (nz); extract_subset (nz, subset); puts ("done"); } } /* write CGNS file */ if (newbase != NULL) { strncpy (basename, newbase, 32); basename[32] = 0; if (cg_base_write (cgnsfn, basename, 3, 3, &cgnsbase)) FATAL (NULL, NULL); printf ("output to base %d - %s\n", cgnsbase, basename); } for (z = Zones, nz = 1; nz <= nZones; nz++, z++) { if (z->id) { z->nverts = 1; for (n = 0; n < 3; n++) { if (subset[n] < z->dim[n]) z->dim[n] = (z->dim[n] - 1) / subset[n] + 1; z->nverts *= z->dim[n]; } printf ("writing zone %d - %ldx%ldx%ld ... ", nz, (long)z->dim[0], (long)z->dim[1], (long)z->dim[2]); fflush (stdout); write_zone_data (nz); puts ("done"); } } cg_close (cgnsfn); if (argind + 1 < argc) argind++; printf ("renaming %s to %s\n", tmpfile, argv[argind]); unlink (argv[argind]); if (rename (tmpfile, argv[argind])) { char msg[512]; sprintf (msg, "rename %s -> %s failed", tmpfile, argv[argind]); FATAL (NULL, msg); exit (1); } free (tmpfile); return 0; } cgnslib_3.1.4/src/cgnstools/utilities/p3dfint.h0000664000076400007640000000267512160605674016533 00000000000000 #ifndef _P3DFINT_H_ #define _P3DFINT_H_ #ifdef _WIN32 void __stdcall OPENF (int *,char *,int); void __stdcall CLOSEF (void); void __stdcall READIF (int *,int *,int *); void __stdcall READFF (int *,float *,int *); void __stdcall READDF (int *,double *,int *); void __stdcall READGFF (int *,float *,int *,int *); void __stdcall READGDF (int *,double *,int *,int *); void __stdcall WRITEIF (int *,int *,int *); void __stdcall WRITEFF (int *,float *,int *); void __stdcall WRITEDF (int *,double *,int *); void __stdcall WRITEGFF(int *,float *,int *,int *); void __stdcall WRITEGDF(int *,double *,int *,int *); #else #if defined(__linux) || defined(__CYGWIN__) # ifndef UNDERSCORE # define UNDERSCORE # endif #endif #if !defined(CRAY) && !defined(VMS) # ifdef UNDERSCORE # define OPENF openf_ # define CLOSEF closef_ # define READIF readif_ # define READFF readff_ # define READDF readdf_ # define READGFF readgff_ # define READGDF readgdf_ # define WRITEIF writeif_ # define WRITEFF writeff_ # define WRITEDF writedf_ # define WRITEGFF writegff_ # define WRITEGDF writegdf_ # else # define OPENF openf # define CLOSEF closef # define READIF readif # define READFF readff # define READDF readdf # define READGFF readgff # define READGDF readgdf # define WRITEIF writeif # define WRITEFF writeff # define WRITEDF writedf # define WRITEGFF writegff # define WRITEGDF writegdf # endif #endif #endif #endif cgnslib_3.1.4/src/cgnstools/utilities/convert.tcl0000664000076400007640000002253512160605674017174 00000000000000# convert.tcl - CGNS conversion routines array set Tools { cnvfile "" location v variable p varcnv "" varcnv,flag 0 rmini "" rmaxi "" rminj "" rmaxj "" rmink "" rmaxk "" gamma 1.4 dataclass d datacnv "" datacnv,flag 0 datacnv,errs 0 } array set ConvFiles { p primitive.cnv c conserved.cnv d dimensional.cnv n nondimensional.cnv u undimensional.cnv } array set ConvLabels { p Primitive c Conserved d Dimensional n NormalizedByDimensional u NormalizedByUnknownDimensional } proc convert_location {w name exe} { global ProgData Tools Font if {$ProgData(file,name) == ""} return set cmd [get_executable $exe 1] if {$cmd == ""} return set Tools(cgnsinput) $ProgData(file,name) if {$Tools(cgnsoutput) == ""} { set Tools(cgnsoutput) $ProgData(file,name) } toplevel $w wm title $w "Solution Location" wm transient $w . wm protocol $w WM_DELETE_WINDOW {set Tools(done) 0} FrameCreate $w.loc -text Location -font $Font(bold) pack $w.loc -side top -pady 2 -fill x set f [FrameGet $w.loc] radiobutton $f.v -text "Vertex" \ -variable Tools(location) -value v \ -command "catch {pack forget $w.rind}" radiobutton $f.c -text "Cell Center" \ -variable Tools(location) -value c \ -command "catch {pack $w.rind -side top -pady 2 -fill x}" pack $f.v $f.c -side left -expand 1 tools_cgnsinput $w 2 tools_cgnsoutput $w solname tools_averaging $w FrameCreate $w.rind -text "Rind Cells" -font $Font(bold) if {$Tools(location) == "c"} { pack $w.rind -side top -pady 2 -fill x } set rind [FrameGet $w.rind] foreach i {i j k} { set f [frame $rind.$i] pack $f -side left -expand 1 checkbutton $f.min -text "min $i" \ -variable Tools(rmin$i) -onvalue $i -offvalue "" checkbutton $f.max -text "max $i" \ -variable Tools(rmax$i) -onvalue [string toupper $i] -offvalue "" pack $f.min $f.max -side top -anchor w } if {![tools_interact $w]} return set opts -$Tools(location)$Tools(weight) if {$Tools(location) == "c"} { foreach i {i j k} { foreach j {rmin rmax} { if {$Tools($j$i) != ""} { append opts $Tools($j$i) } } } } lappend cmd $opts foreach i {basenum zonenum solnum} { if {$Tools($i) != ""} { lappend cmd "-[string index $i 0]$Tools($i)" } } if {$Tools(solname) != ""} { lappend cmd "-S$Tools(solname)" } lappend cmd $Tools(cgnsinput) if {$Tools(cgnsoutput) != ""} { lappend cmd $Tools(cgnsoutput) } if {$Tools(location) == "c"} { tools_run "Vertex to CellCenter" $cmd $Tools(cgnsoutput) } else { tools_run "CellCenter to Vertex" $cmd $Tools(cgnsoutput) } } proc convert_variables {w name exe} { global ProgData Tools Font ConvLabels if {$ProgData(file,name) == ""} return set cmd [get_executable $exe 1] if {$cmd == ""} return set Tools(cgnsinput) $ProgData(file,name) if {$Tools(cgnsoutput) == ""} { set Tools(cgnsoutput) $ProgData(file,name) } toplevel $w wm title $w "Solution Variables" wm transient $w . wm protocol $w WM_DELETE_WINDOW {set Tools(done) 0} FrameCreate $w.var -text Variables -font $Font(bold) pack $w.var -side top -pady 2 -fill x set var [FrameGet $w.var] set f [frame $var.f1] pack $f -side top -fill x radiobutton $f.p -text $ConvLabels(p) -variable Tools(variable) \ -value p -command {convert_file p varcnv} radiobutton $f.c -text $ConvLabels(c) -variable Tools(variable) \ -value c -command {convert_file c varcnv} frame $f.g label $f.g.lab -text gamma entry $f.g.ent -textvariable Tools(gamma) -width 10 pack $f.g.lab $f.g.ent -side left pack $f.p $f.c $f.g -side left -expand 1 frame $var.sep -bd 1 -height 2 -relief sunken pack $var.sep -side top -fill x -pady 3 if {$Tools(varcnv) == ""} { convert_file $Tools(variable) varcnv } set f [frame $var.f2] pack $f -side top -fill x checkbutton $f.use -text "Use Conversion File" \ -variable Tools(varcnv,flag) -onvalue 1 -offvalue 0 button $f.edit -text "Edit Conversion File" \ -command "convert_edit varcnv $w" pack $f.use $f.edit -side left -expand 1 set f [frame $var.f3] pack $f -side top -fill x label $f.lab -text Filename -width 13 -anchor w pack $f.lab -side left entry $f.ent -textvariable Tools(varcnv) -width 20 pack $f.ent -side left -fill x -expand 1 button $f.but -text Browse -command "convert_browse varcnv $f.but" pack $f.but -side right tools_cgnsinput $w 2 tools_cgnsoutput $w solname if {![tools_interact $w check_variables]} return if {$Tools(varcnv,flag)} { lappend cmd -f$Tools(cnvfile) } else { lappend cmd -$Tools(variable) } foreach i {basenum zonenum solnum} { if {$Tools($i) != ""} { lappend cmd "-[string index $i 0]$Tools($i)" } } if {$Tools(solname) != ""} { lappend cmd "-S$Tools(solname)" } lappend cmd $Tools(cgnsinput) if {$Tools(cgnsoutput) != ""} { lappend cmd $Tools(cgnsoutput) } set n $Tools(variable) tools_run "$ConvLabels($n) Variables" $cmd $Tools(cgnsoutput) } proc convert_file {n ftype} { global Tools ConvFiles tcl_platform set name $ConvFiles($n) set cnvpath [get_file $name] if {$cnvpath == ""} { set Tools($ftype) $name } else { if {$tcl_platform(platform) == "windows"} { set Tools($ftype) [join [split $cnvpath /] \\] } else { set Tools($ftype) $cnvpath } } } proc convert_edit {name {parent .}} { global Tools _EditFile if {$Tools($name) == ""} return edit_file .editcnv $Tools($name) $parent tkwait window .editcnv set Tools($name) $_EditFile(.editcnv,name) } proc convert_browse {name w} { global Tools tcl_platform set fname [FileOpen "Conversion File" $Tools($name) $w \ {{{Conversion Scripts} {.cnv .clc .txt}} {{All Files} {*}}}] if {$fname != ""} { if {$tcl_platform(platform) == "windows"} { set Tools($name) [join [split $fname /] \\] } else { set Tools($name) $fname } } } proc check_variables {w} { global Tools tcl_platform if {$Tools(varcnv,flag)} { if {$Tools(varcnv) == ""} { errormsg "variable conversion file not specified" $w return 0 } set cnvpath [get_file $Tools(varcnv)] if {$cnvpath == ""} { errormsg "can't find conversion file $Tools(varcnv)" $w return 0 } if {$tcl_platform(platform) == "windows"} { set Tools(cnvfile) [join [split $cnvpath /] \\] } else { set Tools(cnvfile) $cnvpath } } if {$Tools(gamma) != ""} { if {[catch {expr $Tools(gamma) <= 1.0} nogood] || $nogood} { errormsg "invalid value for gamma" $w return 0 } } return [tools_check_input $w] } proc convert_dimensional {w name exe} { global ProgData Tools Font ConvLabels if {$ProgData(file,name) == ""} return set cmd [get_executable $exe 1] if {$cmd == ""} return set Tools(cgnsinput) $ProgData(file,name) if {$Tools(cgnsoutput) == ""} { set Tools(cgnsoutput) $ProgData(file,name) } toplevel $w wm title $w "Dimensionalization" wm transient $w . wm protocol $w WM_DELETE_WINDOW {set Tools(done) 0} FrameCreate $w.var -text "Data Class" -font $Font(bold) pack $w.var -side top -pady 2 -fill x set var [FrameGet $w.var] set f [frame $var.f1] pack $f -side top -fill x foreach i {d n u} { radiobutton $f.$i -text $ConvLabels($i) -variable Tools(dataclass) \ -value $i -command "convert_file $i datacnv" pack $f.$i -side left -expand 1 } frame $var.sep -bd 1 -height 2 -relief sunken pack $var.sep -side top -fill x -pady 3 if {$Tools(datacnv) == ""} { convert_file $Tools(dataclass) datacnv } set f [frame $var.f2] pack $f -side top -fill x checkbutton $f.use -text "Use Conversion File" \ -variable Tools(datacnv,flag) -onvalue 1 -offvalue 0 checkbutton $f.errs -text "Show Parsing Errors" \ -variable Tools(datacnv,errs) -onvalue 1 -offvalue 0 button $f.edit -text "Edit Conversion File" \ -command "convert_edit datacnv $w" pack $f.use $f.errs $f.edit -side left -expand 1 set f [frame $var.f3] pack $f -side top -fill x label $f.lab -text "Filename" -width 13 -anchor w pack $f.lab -side left entry $f.ent -textvariable Tools(datacnv) -width 20 pack $f.ent -side left -fill x -expand 1 button $f.but -text Browse -command "convert_browse datacnv $f.but" pack $f.but -side right tools_cgnsinput $w 2 tools_cgnsoutput $w if {![tools_interact $w check_dimensional]} return lappend cmd -$Tools(dataclass) if {$Tools(datacnv,errs)} { lappend cmd -v } if {$Tools(datacnv,flag)} { lappend cmd -f$Tools(cnvfile) } foreach i {basenum zonenum solnum} { if {$Tools($i) != ""} { lappend cmd "-[string index $i 0]$Tools($i)" } } lappend cmd $Tools(cgnsinput) if {$Tools(cgnsoutput) != ""} { lappend cmd $Tools(cgnsoutput) } set n $Tools(dataclass) tools_run $ConvLabels($n) $cmd $Tools(cgnsoutput) } proc check_dimensional {w} { global Tools tcl_platform if {$Tools(datacnv,flag)} { if {$Tools(datacnv) == ""} { errormsg "data class conversion file not specified" $w return 0 } set cnvpath [get_file $Tools(datacnv)] if {$cnvpath == ""} { errormsg "can't find conversion file $Tools(datacnv)" $w return 0 } if {$tcl_platform(platform) == "windows"} { set Tools(cnvfile) [join [split $cnvpath /] \\] } else { set Tools(cnvfile) $cnvpath } } return [tools_check_input $w] } cgnslib_3.1.4/src/cgnstools/utilities/CMakeLists.txt0000664000076400007640000001012312160605674017536 00000000000000############# # utilities # ############# include_directories(../..) include_directories(../calclib) include_directories(../common) # cgns_info link_directories(.) if (CGNS_USE_SHARED) link_libraries(cgns_shared) else (CGNS_USE_SHARED) link_libraries(cgns_static) endif (CGNS_USE_SHARED) link_libraries(calclib) if (NOT WIN32) link_libraries(m) endif (NOT WIN32) if (ENABLE_HDF5 AND HDF5_LIBRARY) link_libraries(${HDF5_LIBRARY}) if(HDF5_NEED_ZLIB AND ZLIB_LIBRARY) link_libraries(${ZLIB_LIBRARY}) endif(HDF5_NEED_ZLIB AND ZLIB_LIBRARY) if(HDF5_NEED_SZIP AND SZIP_LIBRARY) link_libraries(${SZIP_LIBRARY}) endif(HDF5_NEED_SZIP AND SZIP_LIBRARY) if(HDF5_NEED_MPI AND MPI_LIBS) link_libraries(${MPI_LIBS}) endif(HDF5_NEED_MPI AND MPI_LIBS) endif (ENABLE_HDF5 AND HDF5_LIBRARY) if (NOT WIN32) link_libraries(m) endif (NOT WIN32) set(cgns_info_FILES cgns_info.c cgnsutil.c ../common/getargs.c) add_executable(cgns_info ${cgns_info_FILES}) add_dependencies(cgns_info cgns_static calclib) # plot3d_to_cgns set(plot3d_to_cgns_FILES plot3d_to_cgns.c cgnsutil.c binaryio.c ../common/getargs.c) add_executable(plot3d_to_cgns ${plot3d_to_cgns_FILES}) add_dependencies(plot3d_to_cgns cgns_static calclib) # cgns_to_plot3d set(cgns_to_plot3d_FILES cgns_to_plot3d.c cgnsutil.c ../common/getargs.c p3dfout.c) add_executable(cgns_to_plot3d ${cgns_to_plot3d_FILES}) add_dependencies(cgns_to_plot3d cgns_static calclib) # patran_to_cgns set(patran_to_cgns_FILES patran_to_cgns.c cgnsImport.c ../common/getargs.c ../common/hash.c) add_executable(patran_to_cgns ${patran_to_cgns_FILES}) add_dependencies(patran_to_cgns cgns_static calclib) # tecplot_to_cgns set(tecplot_to_cgns_FILES tecplot_to_cgns.c cgnsImport.c ../common/getargs.c ../common/hash.c) add_executable(tecplot_to_cgns ${tecplot_to_cgns_FILES}) add_dependencies(tecplot_to_cgns cgns_static calclib) # cgns_to_tecplot set(cgns_to_tecplot_FILES cgns_to_tecplot.c cgnsutil.c ../common/getargs.c) add_executable(cgns_to_tecplot ${cgns_to_tecplot_FILES}) add_dependencies(cgns_to_tecplot cgns_static calclib) # cgns_to_vtk set(cgns_to_vtk_FILES cgns_to_vtk.c ../common/getargs.c) add_executable(cgns_to_vtk ${cgns_to_vtk_FILES}) add_dependencies(cgns_to_vtk cgns_static calclib) # convert_location set(convert_location_FILES convert_location.c cgnsutil.c ../common/getargs.c) add_executable(convert_location ${convert_location_FILES}) # convert_variables set(convert_variables_FILES convert_variables.c cgnsutil.c ../common/getargs.c) add_executable(convert_variables ${convert_variables_FILES}) add_dependencies(convert_variables cgns_static calclib) # convert_dataclass set(convert_dataclass_FILES convert_dataclass.c cgnsutil.c ../common/getargs.c) add_executable(convert_dataclass ${convert_dataclass_FILES}) add_dependencies(convert_dataclass cgns_static calclib) # extract_subset set(extract_subset_FILES extract_subset.c cgnsutil.c ../common/getargs.c) add_executable(extract_subset ${extract_subset_FILES}) add_dependencies(extract_subset cgns_static calclib) # interpolate_cgns set(interpolate_cgns_FILES interpolate_cgns.c cgnsutil.c ../common/getargs.c) add_executable(interpolate_cgns ${interpolate_cgns_FILES}) add_dependencies(interpolate_cgns cgns_static calclib) if (WIN32) install(TARGETS plot3d_to_cgns cgns_to_plot3d patran_to_cgns tecplot_to_cgns cgns_to_tecplot cgns_to_vtk convert_location convert_variables convert_dataclass extract_subset interpolate_cgns RUNTIME DESTINATION bin) install(FILES conserved.cnv convert.tcl dimensional.cnv patran.tcl plot3d.tcl primitive.cnv tecplot.tcl util.tcl utilities.mnu vtk.tcl DESTINATION share) else (WIN32) install(TARGETS plot3d_to_cgns cgns_to_plot3d patran_to_cgns tecplot_to_cgns cgns_to_tecplot cgns_to_vtk convert_location convert_variables convert_dataclass extract_subset interpolate_cgns RUNTIME DESTINATION bin/cgnstools) install(FILES conserved.cnv convert.tcl dimensional.cnv patran.tcl plot3d.tcl primitive.cnv tecplot.tcl util.tcl utilities.mnu vtk.tcl DESTINATION share/cgnstools) endif (WIN32) cgnslib_3.1.4/src/cgnstools/calclib/0000775000076400007640000000000012167722166014442 500000000000000cgnslib_3.1.4/src/cgnstools/calclib/vec.c0000664000076400007640000020304712160605672015304 00000000000000/* * vec.c - array processor for an equation */ #include #include #include #include #include #include #include #include #include "vec.h" #include "vecsym.h" #define INCLUDE_ERRDATA #include "vecerr.h" /*----- machine dependent defines -----*/ #ifndef SIGNAL #define SIGNAL void #endif /* #ifndef sgi #define USE_MATHERR #endif */ #ifndef SIG_ERR # ifdef BADSIG # define SIG_ERR BADSIG # else # define SIG_ERR ((SIGNAL (*)())-1) # endif #endif /*----- defined data values -----*/ #define STACK_INC 50 /* amount to increase size of op stack */ #define MAX_ARGS 9 /* maximum function arguments */ #define E 2.71828182845904523536 #ifndef PI # define PI 3.14159265358979323846 #endif #define TOLERANCE 0.0000000001 #define OPERATORS "^*/%+-<>=!&|?:),]" enum Tokens { /* operation tokens */ OP_NEGATE = 1, OP_POWER, OP_MULTIPLY, OP_DIVIDE, OP_MODULUS, OP_PLUS, OP_MINUS, OP_LESS, OP_LESS_EQ, OP_GREATER, OP_GREATER_EQ, OP_EQUALS, OP_NOT_EQUAL, OP_AND, OP_OR, OP_NOT, OP_IF, OP_ELSE, OP_ENDIF, OP_BEGIN_FUNC, OP_NOP, OP_VECTOR, OP_NUMBER, OP_INTEGER, OP_INDEX, OP_COUNTER, /* function tokens */ FUNC_ABS, FUNC_ACOS, FUNC_ACOSH, FUNC_ASIN, FUNC_ASINH, FUNC_ATAN, FUNC_ATAN2, FUNC_ATANH, FUNC_CEIL, FUNC_COS, FUNC_COSH, FUNC_DEG, FUNC_EXP, FUNC_FACT, FUNC_FLOOR, FUNC_LOG, FUNC_LOG10, FUNC_MOD, FUNC_POW, FUNC_POW10, FUNC_RAD, FUNC_RAND, FUNC_ROUND, FUNC_SIN, FUNC_SINH, FUNC_SQR, FUNC_SQRT, FUNC_TAN, FUNC_TANH, FUNC_AVG, FUNC_MAX, FUNC_MIN, FUNC_SUM, FUNC_SIZE, FUNC_LEN }; /*----- operation stack -----*/ struct op_stack_ { int op; size_t len; union { int ival; double num; VECFLOAT *vec; } op_val; }; static struct op_stack_ *op_start; /* operation stack */ static int op_size = 0; /* current size of operation stack */ static int op_pos; /* current position in stack */ static int op_index; /* counter for processing */ /*----- variable stack -----*/ static double *var_stack; /* processing stack */ static int var_size = 0; /* size of processing stack */ static int var_pos; /* current position in stack */ /*----- constant values -----*/ static double constants[] = { #define CONSTANT_E 0 E, #define CONSTANT_PI 1 PI, #define CONSTANT_TOL 2 TOLERANCE }; #define CONSTANT_DIM 3 /*----- intrinsic symbol table -----*/ #define VEC_ACROSS 0 #define VEC_ALONG 1 #define VEC_VARIABLE 2 static struct intrinsic_ { char *name; int type; int nargs; int op; } intrinsics[] = { {"abs", VEC_ACROSS, 1, FUNC_ABS }, {"acos", VEC_ACROSS, 1, FUNC_ACOS }, {"acosh", VEC_ACROSS, 1, FUNC_ACOSH }, {"asin", VEC_ACROSS, 1, FUNC_ASIN }, {"asinh", VEC_ACROSS, 1, FUNC_ASINH }, {"atan", VEC_ACROSS, 1, FUNC_ATAN }, {"atan2", VEC_ACROSS, 2, FUNC_ATAN2 }, {"atanh", VEC_ACROSS, 1, FUNC_ATANH }, {"avg", VEC_ALONG, 1, FUNC_AVG }, {"ceil", VEC_ACROSS, 1, FUNC_CEIL }, {"cos", VEC_ACROSS, 1, FUNC_COS }, {"cosh", VEC_ACROSS, 1, FUNC_COSH }, {"deg", VEC_ACROSS, 1, FUNC_DEG }, {"dim", CONSTANT_DIM, 0, OP_NUMBER }, {"e", CONSTANT_E, 0, OP_NUMBER }, {"exp", VEC_ACROSS, 1, FUNC_EXP }, {"fact", VEC_ACROSS, 1, FUNC_FACT }, {"floor", VEC_ACROSS, 1, FUNC_FLOOR }, {"index", VEC_VARIABLE, 0, OP_COUNTER }, {"len", VEC_ALONG, 1, FUNC_LEN }, {"log", VEC_ACROSS, 1, FUNC_LOG }, {"log10", VEC_ACROSS, 1, FUNC_LOG10 }, {"mag", VEC_ALONG, 1, FUNC_SIZE }, {"max", VEC_ALONG, 1, FUNC_MAX }, {"min", VEC_ALONG, 1, FUNC_MIN }, {"mod", VEC_ACROSS, 2, FUNC_MOD }, {"pi", CONSTANT_PI, 0, OP_NUMBER }, {"pow", VEC_ACROSS, 2, FUNC_POW }, {"pow10", VEC_ACROSS, 1, FUNC_POW10 }, {"rad", VEC_ACROSS, 1, FUNC_RAD }, {"rand", VEC_ACROSS, 0, FUNC_RAND }, {"round", VEC_ACROSS, 1, FUNC_ROUND }, {"sin", VEC_ACROSS, 1, FUNC_SIN }, {"sinh", VEC_ACROSS, 1, FUNC_SINH }, {"sqr", VEC_ACROSS, 1, FUNC_SQR }, {"sqrt", VEC_ACROSS, 1, FUNC_SQRT }, {"sum", VEC_ALONG, 1, FUNC_SUM }, {"tan", VEC_ACROSS, 1, FUNC_TAN }, {"tanh", VEC_ACROSS, 1, FUNC_TANH }, {"tol", CONSTANT_TOL, 0, OP_NUMBER } }; #define NUM_INTRINSICS sizeof(intrinsics)/sizeof(struct intrinsic_) /*----- list of intrinsics -----*/ static char *in_list[] = { "Intrinsic operators in order of precedence:", "Operator Type Operators", "-------------------------", "Expression () const func()", "Unary - !", "Exponential ^ **", "Multiplicative * / %", "Additive + -", "Relational < <= > >= == !=", "Logical &[&] |[|] ?:", "", "Defined constants:", "Name Value", "---------------------", "pi 3.14159265358979323846", "e 2.71828182845904523536", "tol 0.0000000001", "index current array index", "dim minimum array len", " any constant", "", "Defined functions:", "Name Operation", "-------------------------", "abs() absolute value", "acos() arc cosine (radians)", "acosh() arc hyperbolic cosine", "asin() arc sine (radians)", "asinh() arc hyperbolic sine", "atan() arc tangent (radians)", "atanh() arc hyperbolic tangent", "avg() average value in a vector", "ceil() next largest integer", "cos() cosine (radians)", "cosh() hyperbolic cosine", "deg() convert from radians to degrees", "exp() power of e", "fact() factorial of a number", "floor() next smallest integer", "len() length of a vector", "log() natural log", "log10() base 10 log", "size() magnitude of a vector", "max() maximum value in a vector", "min() minimum value in a vector", "pow10() power of 10", "rad() convert from degrees to radians", "rand() random number between 0 and 1", "round() round a number to integer", "sin() sine (radians)", "sinh() hyperbolic sine", "sqr() square a number", "sqrt() take square root of a number", "sum() sum of values in a vector", "tan() tangent (radians)", "tanh() hyperbolic tangent", NULL }; /*----- error handling -----*/ int vec_maxerr = VECERR_INVALID; int vec_errnum = 0; void (*vec_errhandler)(int,char *,int,char *) = NULL; typedef SIGNAL (*SIGHANDLER)(int); /*----- temporary vectors -----*/ typedef struct veclist_ { VECDATA *v; struct veclist_ *prev; } VECLIST; static VECLIST *veclist = NULL; /*----- defined macros -----*/ #define advance(amt) exp_ptr+=(amt) #define skip_space(p) while(*(p) && isspace(*(p)))(p)++ #define skip_int(p) while(*(p) && isdigit(*(p)))(p)++ /*----- parsing data -----*/ static int num_calls = 0; /* recursion counter */ static int max_calls = VEC_MAXCALLS;/* maximum recursive calls */ static size_t max_len = 0; /* maximum vector length */ static size_t counter_len = 0; /* min length of counter */ static VECCALL usr_func; /* pointer to user supplied function */ static char *exp_start = NULL; /* start of string being parsed */ static char *exp_ptr; /* location in string being parsed */ static SIGHANDLER old_fpe_sig; /* old SIGFPE handler */ static jmp_buf env_ptr; /* enviroment for return from longjmp() */ static int nest_level; /* nesting count for if-then-else */ static int vec_op; /* doing operations on array lengths */ static int num_args = 0; /* number arguments for equation */ static VECDATA *arglist[MAX_ARGS];/* equation argument list */ static int checking = 0; /* set if checking equation only */ /*----- function prototypes -----*/ static VECDATA *parse(); static void *handle_error(); static void clean_up(); static int do_intrinsic(); static int do_symbol(); static int get_args(); static void chk_index(); static void add_op(); static void logical(); static void relational(); static void additive(); static void multiplicative(); static void exponential(); static void unary(); static void expression(); static void push_var(); static void pop_var(); static double process_op(); static SIGNAL fpe_err (int signum); /*================================================================== * user callable routines *==================================================================*/ /*---------- vec_create -------------------------------------------- * creates a vector data structure *------------------------------------------------------------------*/ VECDATA *vec_create (int type, size_t len, int temp) { VECDATA *vdata; if (type == VEC_VECTOR) { if (len < 1 && temp >= 0) return (handle_error (VECERR_ZEROLEN)); } else if (type == VEC_VALUE) len = 0; else return (handle_error (VECERR_VECTYPE)); vdata = (VECDATA *) calloc (1, sizeof(VECDATA)); if (vdata == NULL) return (handle_error (VECERR_MALLOC)); if (len && temp >= 0) { vdata->f.vec = (VECFLOAT *) calloc (len, sizeof(VECFLOAT)); if (vdata->f.vec == NULL) { free (vdata); return (handle_error (VECERR_MALLOC)); } } else vdata->f.vec = NULL; vdata->type = type; vdata->len = len; /* add to temporary list */ if (temp) { VECLIST *vl = (VECLIST *) malloc (sizeof(VECLIST)); if (vl == NULL) { if (len) free (vdata->f.vec); free (vdata); return (handle_error (VECERR_MALLOC)); } vl->v = vdata; vl->prev = veclist; veclist = vl; } return (vdata); } /*---------- vec_destroy ------------------------------------------- * destroys a vector data structure *------------------------------------------------------------------*/ void vec_destroy (VECDATA *vdata) { if (vdata != NULL) { vec_remove (vdata); if (vdata->type == VEC_VECTOR && vdata->f.vec != NULL) free (vdata->f.vec); free (vdata); } } /*---------- vec_add ----------------------------------------------- * add vector to temporary vector list *------------------------------------------------------------------*/ int vec_add (VECDATA *vd) { VECLIST *vl = veclist; if (vd == NULL) return (0); /* check if already in list */ while (vl != NULL) { if (vl->v == vd) return (1); vl = vl->prev; } /* it's not, so add it */ if ((vl = (VECLIST *) malloc (sizeof(VECLIST))) == NULL) return (0); vl->v = vd; vl->prev = veclist; veclist = vl; return (1); } /*---------- vec_remove -------------------------------------------- * remove temporary vector from list *------------------------------------------------------------------*/ void vec_remove (VECDATA *vd) { VECLIST *prev, *vlist = veclist; if (vd == NULL || vlist == NULL) return; if (vlist->v == vd) { veclist = vlist->prev; free (vlist); return; } prev = vlist->prev; while (prev != NULL) { if (prev->v == vd) { vlist->prev = prev->prev; free (prev); return; } vlist = prev; prev = vlist->prev; } } /*---------- vec_free ---------------------------------------------- * releases internal resources *------------------------------------------------------------------*/ void vec_free (void) { /* free operation stack */ if (op_size) { op_size = 0; free (op_start); } /* free variable stack */ if (var_size) { var_size = 0; free (var_stack); } } /*---------- vec_maxcalls ------------------------------------------ * sets maximum recursive calls *------------------------------------------------------------------*/ void vec_maxcalls (int val) { max_calls = val > 0 ? val : VEC_MAXCALLS; } /*---------- vec_errmsg -------------------------------------------- * returns error message *------------------------------------------------------------------*/ char *vec_errmsg (void) { if (vec_errnum < 0 || vec_errnum >= VECERR_INVALID) vec_errnum = VECERR_INVALID; return (err_msg[vec_errnum]); } /*---------- vec_list ---------------------------------------------- * return list of intrinsics *------------------------------------------------------------------*/ char **vec_list (void) { return (in_list); } /*---------- vec_parse --------------------------------------------- * parse and process equation string *------------------------------------------------------------------*/ VECDATA *vec_parse (char *str, int min_len, VECCALL func) { VECDATA *vd; size_t old_len = counter_len; VECCALL old_func = usr_func; char *old_ptr = exp_ptr; char *old_start = exp_start; /* is there a string ? */ exp_start = NULL; if (str != NULL) skip_space (str); if (str == NULL || !*str) return (handle_error (VECERR_NOEXPR)); /* create operation stack if not done */ if (op_size == 0) { op_start = (struct op_stack_ *) malloc (STACK_INC * sizeof(struct op_stack_)); if (op_start == NULL) return (handle_error (VECERR_OP_STK)); op_size = STACK_INC; } /* create processing stack if not already done */ if (var_size == 0) { var_stack = (double *) malloc (STACK_INC * sizeof(double)); if (var_stack == NULL) return (handle_error (VECERR_VAR_STK)); var_size = STACK_INC; } /* install the SIGFPE handler */ if (num_calls == 0) { checking = op_pos = var_pos = op_index = 0; max_len = 0; old_fpe_sig = signal (SIGFPE, fpe_err); vec_randinit ((int) time (NULL)); /* jump here on parsing error */ vec_errnum = setjmp (env_ptr); if (vec_errnum != 0) { clean_up (); return (handle_error (vec_errnum)); } } usr_func = func; exp_ptr = str; exp_start = str; counter_len = min_len > 0 ? min_len : 1; vd = parse (); if (*exp_ptr) longjmp (env_ptr, VECERR_MISSING); vec_remove (vd); if (num_calls == 0) clean_up (); else { counter_len = old_len; usr_func = old_func; exp_ptr = old_ptr; exp_start = old_start; } return (vd); } /*---------- vec_check --------------------------------------------- * parse equation string and check for errors *------------------------------------------------------------------*/ size_t vec_check (char *str, int min_len, VECCALL func) { VECDATA *vd; size_t len; size_t old_len = counter_len; VECCALL old_func = usr_func; char *old_ptr = exp_ptr; char *old_start = exp_start; /* is there a string ? */ exp_start = NULL; if (str != NULL) skip_space (str); if (str == NULL || !*str) { handle_error (VECERR_NOEXPR); return (0); } /* create operation stack if not done */ if (op_size == 0) { op_start = (struct op_stack_ *) malloc (STACK_INC * sizeof(struct op_stack_)); if (op_start == NULL) { handle_error (VECERR_OP_STK); return (0); } op_size = STACK_INC; } /* create processing stack if not already done */ if (var_size == 0) { var_stack = (double *) malloc (STACK_INC * sizeof(double)); if (var_stack == NULL) { handle_error (VECERR_VAR_STK); return (0); } var_size = STACK_INC; } /* install the SIGFPE handler */ if (num_calls == 0) { checking = 1; max_len = op_pos = var_pos = op_index = 0; old_fpe_sig = signal (SIGFPE, fpe_err); vec_randinit ((int) time (NULL)); /* jump here on parsing error */ vec_errnum = setjmp (env_ptr); if (vec_errnum != 0) { clean_up (); handle_error (vec_errnum); return (0); } } usr_func = func; exp_ptr = str; exp_start = str; counter_len = min_len > 0 ? min_len : 1; vd = parse (); if (*exp_ptr) longjmp (env_ptr, VECERR_MISSING); len = vd->len ? vd->len : 1; if (num_calls == 0) clean_up (); else { counter_len = old_len; usr_func = old_func; exp_ptr = old_ptr; exp_start = old_start; } return (len); } /*=================================================================== * support routines callable by user *===================================================================*/ /*---------- vec_number -------------------------------------------- * gets a double and advances string pointer * This is similar to 'strtod, but I know what it's doing * Expects a number of the form : * [whitespace][{+|-}][digits][.digits][{d|D|e|E}[sign]digits] *------------------------------------------------------------------*/ int vec_number (double *dval, char **sp) { register char *p, c; char *start; int point = 0; p = start = *sp; *dval = 0.0; /* skip whitespace */ while (*p && isspace (*p)) p++; /* get to first required digit */ if (*p == '-' || *p == '+') p++; if (*p == '.') { point++; p++; } /* next character needs to be digit */ if (!*p || !isdigit (*p)) return (0); /* get past the number */ while (*p && (isdigit (*p) || *p == '.')) { if (*p == '.') { if (point) { *p = 0; *dval = (double) atof (*sp); *p = '.'; *sp = p; return (1); } point++; } p++; } *sp = p; /* check for an exponent */ if (*p == 'd' || *p == 'D' || *p == 'e' || *p == 'E') { if (*++p == '+' || *p == '-') p++; if (isdigit (*p)) { while (*++p && isdigit (*p)) ; *sp = p; } } c = **sp; **sp = 0; *dval = atof (start); **sp = c; return (1); } /*------------------------------------------------------------------- * system independent random number generator from Kluth *-------------------------------------------------------------------*/ #define MBIG 1000000000 #define MSEED 161803398 static int Rand_ext = 0; static int Rand_extp = 31; static long Rand_ma[56] = { 0,473269125,708359770,742015427, 65602533,275831218, 24831226, 897336983,199633574,555982024,514994949,279315436,156002375,334914356, 270182445,993586635,796323046,222779050,530019863,240216188,246247465, 251350083, 27923555, 17362715,286349234,561741882, 61883183, 25293241, 182316584,384320687, 97284929,343171996,939345275,385350967,340911449, 606343026,885561620,105803147,288011295,407490891,632823362,921005485, 393546951,638589878,430524660, 1651896,884594510,251198018,883223679, 254238950,266438063,664142955,409571047,306976444,378529592,649134132 }; /*---------- vec_randinit ------------------------------------------- * initialize the random number generator *-------------------------------------------------------------------*/ void vec_randinit (int seed) { int i, k; long mj, mk; mj = MSEED - (seed < 0 ? -seed : seed); mj %= MBIG; Rand_ma[55] = mj; mk = 1; for (i = 1; i <= 54; i++) { k = (21 * i) % 55; Rand_ma[k] = mk; mk = mj - mk; if (mk < 0) mk += MBIG; mj = Rand_ma[k]; } for (k = 1; k <= 4; k++) { for (i = 1; i <= 55; i++) { Rand_ma[i] -= Rand_ma[1+(i+30) % 55]; if (Rand_ma[i] < 0) Rand_ma[i] += MBIG; } } Rand_ext = 0; Rand_extp = 31; } /*---------- vec_rand ----------------------------------------------- * return random number between 0 and 1 *-------------------------------------------------------------------*/ double vec_rand (void) { long mj; if (++Rand_ext == 56) Rand_ext = 1; if (++Rand_extp == 56) Rand_extp = 1; mj = Rand_ma[Rand_ext] - Rand_ma[Rand_extp]; if (mj < 0) mj += MBIG; Rand_ma[Rand_ext] = mj; return ((double) mj / (double) MBIG); } /*================================================================== * parsing routines *==================================================================*/ /*---------- parse -------------------------------------------------- * does the parsing and evaluation of the string *-------------------------------------------------------------------*/ static VECDATA *parse () { size_t n; size_t cur_len = max_len; int cur_op = op_pos; int cur_index = op_index; int cur_var = var_pos; VECDATA *vd; if (++num_calls == max_calls) longjmp (env_ptr, VECERR_CALLS); max_len = 0; logical (); skip_space (exp_ptr); if (checking) { if (max_len == 1) vd = vec_create (VEC_VALUE, 0, -1); else vd = vec_create (VEC_VECTOR, max_len, -1); } else { vd = vec_create (VEC_VECTOR, max_len, 1); /* process the variables */ for (n = 0; n < max_len; n++) { var_pos = cur_var; op_index = cur_op; nest_level = vec_op = 0; vd->f.vec[n] = (VECFLOAT)process_op (n); } if (max_len == 1) { VECFLOAT f = vd->f.vec[0]; free (vd->f.vec); vd->type = VEC_VALUE; vd->len = 0; vd->f.val = f; } } max_len = cur_len; op_pos = cur_op; op_index = cur_index; var_pos = cur_var; num_calls--; return (vd); } /*---------- handle_error ------------------------------------------- * handle error message *-------------------------------------------------------------------*/ static void *handle_error (err) int err; { int pos = -1; char *str = exp_start; if (num_calls) longjmp (env_ptr, vec_errnum); if (err < 0 || err >= VECERR_INVALID) vec_errnum = VECERR_INVALID; else vec_errnum = err; exp_start = NULL; if (str != NULL) { pos = (int) (exp_ptr - str); if (pos < 0 || pos > (int)strlen (str)) { pos = -1; str = NULL; } } if (vec_errhandler != NULL) (*vec_errhandler) (vec_errnum, err_msg[vec_errnum], pos, str); else { if (str != NULL) { fprintf (stderr, "%s\n", str); while (pos-- > 0) putc ('-', stderr); putc ('^', stderr); } fprintf (stderr, "%s\n", err_msg[vec_errnum]); } return (NULL); } /*---------- reset_recurs ------------------------------------------ * reset recursion flags for equation symbols - called from sym_list *------------------------------------------------------------------*/ static int reset_recurs (VECSYM *sym, void *userdata) { if (vecsym_nargs(sym) < 0) vecsym_nargs(sym) = 0; return (0); } /*---------- clean_up ---------------------------------------------- * clean up on error or parsing completion *------------------------------------------------------------------*/ static void clean_up () { VECLIST *prev; if (old_fpe_sig != SIG_ERR) signal (SIGFPE, old_fpe_sig); (void) sym_list (VECSYM_EQUSTR, reset_recurs, NULL); while (veclist != NULL) { prev = veclist->prev; if (veclist->v->type == VEC_VECTOR && veclist->v->f.vec != NULL) free (veclist->v->f.vec); free (veclist->v); free (veclist); veclist = prev; } num_calls = num_args = 0; } /*---------- do_intrinsic ------------------------------------------ * process an intrinsic variable *------------------------------------------------------------------*/ static int do_intrinsic () { char c, *p = exp_ptr; int lo, hi, n, m; struct intrinsic_ *ins; if (!isalpha (*p)) return (0); while (*++p && (isalnum (*p) || *p == '_')) ; c = *p; *p = 0; lo = 0; hi = NUM_INTRINSICS - 1; n = hi / 2; ins = &intrinsics[n]; while (1) { if ((m = strcmp (exp_ptr, ins->name)) == 0) break; if (lo >= hi) break; if (m < 0) hi = n - 1; else lo = n + 1; n = (lo + hi) / 2; ins = &intrinsics[n]; } *p = c; if (m) return (0); exp_ptr = p; if (ins->op == OP_NUMBER) { if (ins->type == CONSTANT_DIM) { double dval = counter_len; add_op (OP_NUMBER, &dval); } else add_op (OP_NUMBER, &constants[ins->type]); } else if (ins->type == VEC_VARIABLE) add_op (ins->op, NULL); else if (ins->type == VEC_ALONG) { size_t msave = max_len; add_op (OP_BEGIN_FUNC, NULL); (void) get_args (ins->nargs); add_op (ins->op, NULL); max_len = msave ? msave : 1; } else { (void) get_args (ins->nargs); add_op (ins->op, NULL); } return (1); } /*---------- get_args ---------------------------------------------- * extracts arguments for intrinsic function *------------------------------------------------------------------*/ static int get_args (nargs) int nargs; { int n = 0; skip_space (exp_ptr); if (*exp_ptr != '(') longjmp (env_ptr, VECERR_FUNC); advance (1); skip_space (exp_ptr); if (*exp_ptr == ')') { if (nargs > 0) longjmp (env_ptr, VECERR_ARGS); advance (1); return (0); } while (1) { skip_space (exp_ptr); logical (); n++; skip_space (exp_ptr); if (*exp_ptr == ')') break; if (*exp_ptr == ',') { if (n == nargs) longjmp (env_ptr, VECERR_ARGS); if (n == FUNC_MAXARGS) longjmp (env_ptr, VECERR_MAXARGS); advance (1); } else longjmp (env_ptr, VECERR_ARGS); } if (nargs > 0 && n != nargs) longjmp (env_ptr, VECERR_ARGS); advance (1); return (n); } /*---------- do_symbol --------------------------------------------- * processes a user symbol *------------------------------------------------------------------*/ static int do_symbol () { int c, is_func; char symname[SYMNAME_MAXLEN+2], *p = exp_ptr; VECSYM *sym; /* check for replaceable argument */ if (*p == '$') { if (*++p && isdigit (*p)) { c = *p - '1'; if (c < 0 || c >= num_args) longjmp (env_ptr, VECERR_EQUARG); exp_ptr = p; advance (1); if (arglist[c]->type == VEC_VALUE) { double dval = arglist[c]->f.val; add_op (OP_NUMBER, &dval); } else if (arglist[c]->type == VEC_VECTOR) add_op (OP_VECTOR, arglist[c]); else longjmp (env_ptr, VECERR_VECTYPE); return (1); } return (0); } /* get symbol name */ if (*p == '\\') p++; if (!*p || (!isalpha (*p) && *p != '_' && *p != '"')) return (0); symname[0] = '.'; if (*p == '"') { for (++p, c = 1; c <= SYMNAME_MAXLEN; c++) { if (!*p || *p == '"') break; symname[c] = *p++; } if (*p++ != '"') return 0; } else { for (c = 1; c <= SYMNAME_MAXLEN; c++) { symname[c] = *p++; if (!*p || (!isalnum (*p) && *p != '_')) break; } } if (c > SYMNAME_MAXLEN) return (0); symname[++c] = 0; /* check if function */ while (*p && isspace (*p)) p++; is_func = *p == '('; /* find symbol */ if (*exp_ptr == '\\' || (sym = find_symbol (symname, is_func)) == NULL) sym = find_symbol (&symname[1], is_func); /*--- symbol not found ---*/ if (sym == NULL) return (0); /*--- value ---*/ if (vecsym_type(sym) == VECSYM_VALUE) { double val = vecsym_value(sym); add_op (OP_NUMBER, &val); exp_ptr = p; return (1); } /*--- vector ---*/ if (vecsym_type(sym) == VECSYM_VECTOR) { VECDATA vdat; exp_ptr = p; vdat.len = vecsym_veclen(sym); vdat.f.vec = vecsym_vector(sym); chk_index (&vdat); return (1); } /*--- equation ---*/ if (vecsym_type(sym) == VECSYM_EQUSTR) { char *s; int nargs = 0; VECDATA *vd[9], *vtmp; if (vecsym_nargs(sym) < 0) longjmp (env_ptr, VECERR_RECURSE); if (vecsym_nargs(sym) == 0) { vecsym_nargs(sym) = -1; if (is_func) { p++; skip_space (p); if (*p != ')') longjmp (env_ptr, VECERR_PAREN); p++; } } else { exp_ptr = p; if (*exp_ptr++ != '(') longjmp (env_ptr, VECERR_FUNC); skip_space (exp_ptr); while (*exp_ptr && *exp_ptr != ')') { if (nargs == vecsym_nargs(sym)) longjmp (env_ptr, VECERR_MAXARGS); vd[nargs++] = parse (); if (*exp_ptr == ',') advance (1); skip_space (exp_ptr); } if (*exp_ptr != ')' || nargs != vecsym_nargs(sym)) longjmp (env_ptr, VECERR_ARGS); advance (1); p = exp_ptr; } for (c = 0; c < 9; c++) { vtmp = arglist[c]; arglist[c] = vd[c]; vd[c] = vtmp; } c = nargs; nargs = num_args; num_args = c; s = exp_start; exp_start = exp_ptr = vecsym_equstr(sym); logical (); if (*exp_ptr) longjmp (env_ptr, VECERR_MISSING); if (vecsym_nargs(sym) < 0) vecsym_nargs(sym) = 0; exp_start = s; exp_ptr = p; num_args = nargs; for (c = 0; c < num_args; c++) arglist[c] = vd[c]; return (1); } /*--- function ---*/ if (vecsym_type(sym) == VECSYM_FUNC) { int nargs = 0; VECDATA *vd[FUNC_MAXARGS+1]; exp_ptr = p; if (*exp_ptr++ != '(') longjmp (env_ptr, VECERR_FUNC); skip_space (exp_ptr); if (*exp_ptr != ')') { while (1) { vd[nargs] = parse (); if (++nargs > FUNC_MAXARGS) longjmp (env_ptr, VECERR_MAXARGS); if (*exp_ptr == ',') advance (1); else if (*exp_ptr != ')') longjmp (env_ptr, VECERR_ARGS); else break; } } advance (1); if (vecsym_nargs(sym) >= 0 && vecsym_nargs(sym) != nargs) longjmp (env_ptr, VECERR_ARGS); p = NULL; vd[nargs] = (*vecsym_func(sym)) (checking, nargs, vd, &p); if (vd[nargs] == NULL) { if (p == NULL || !*p) longjmp (env_ptr, VECERR_SYMBOL); else { err_msg[VECERR_USER] = p; longjmp (env_ptr, VECERR_USER); } } if (vd[nargs]->type == VEC_VALUE) { double dval = vd[nargs]->f.val; add_op (OP_NUMBER, &dval); } else if (vd[nargs]->type == VEC_VECTOR) add_op (OP_VECTOR, vd[nargs]); else longjmp (env_ptr, VECERR_VECTYPE); for (c = 0; c < nargs; c++) vec_destroy (vd[c]); return (1); } /*--- unknown ---*/ return (0); } /*---------- chk_index --------------------------------------------- * check for a vector index *------------------------------------------------------------------*/ static void chk_index (vdata) VECDATA *vdata; { if (*exp_ptr == '[') { advance (1); logical (); skip_space (exp_ptr); if (*exp_ptr != ']') longjmp (env_ptr, VECERR_BRACKET); advance (1); add_op (OP_INDEX, NULL); if (max_len <= 1) { add_op (OP_VECTOR, vdata); max_len = 1; return; } } add_op (OP_VECTOR, vdata); } /*---------- do_userfunc ------------------------------------------- * call user routine *------------------------------------------------------------------*/ static int do_userfunc () { char *p, *s; double dval; VECDATA *vd; if (usr_func == NULL) return (0); p = exp_ptr; s = NULL; if ((vd = (*usr_func) (checking, &p, &s)) == NULL) { if (s == NULL || !*s) return (0); err_msg[VECERR_USER] = s; longjmp (env_ptr, VECERR_USER); } if (p <= exp_ptr) longjmp (env_ptr, VECERR_POINTER); exp_ptr = p; if (vd->type == VEC_VALUE) { dval = vd->f.val; add_op (OP_NUMBER, (void *)&dval); } else if (vd->type == VEC_VECTOR) { skip_space (exp_ptr); chk_index (vd); } else longjmp (env_ptr, VECERR_VECTYPE); return (1); } /*---------- add_op ------------------------------------------------ * adds operation to the stack *------------------------------------------------------------------*/ static void add_op (op, op_val) int op; void *op_val; { if (op_pos >= op_size) { op_size += STACK_INC; op_start = (struct op_stack_ *) realloc (op_start, op_size * sizeof(struct op_stack_)); if (op_start == NULL) longjmp (env_ptr, VECERR_OP_STK); } switch (op) { case OP_INTEGER: op_start[op_pos].len = 1; op_start[op_pos].op_val.ival = *((int *)op_val); break; case OP_NUMBER: op_start[op_pos].len = 1; op_start[op_pos].op_val.num = *((double *)op_val); break; case OP_VECTOR: { VECDATA *vdat = (VECDATA *)op_val; op_start[op_pos].len = vdat->len; op_start[op_pos].op_val.vec = vdat->f.vec; /* if (counter_len < vdat->len)*/ counter_len = vdat->len; break; } case OP_INDEX: case FUNC_RAND: op_start[op_pos].len = 1; break; case OP_COUNTER: op_start[op_pos].len = counter_len; break; default: op_start[op_pos].len = 0; break; } op_start[op_pos].op = op; if (max_len < op_start[op_pos].len) max_len = op_start[op_pos].len; op_pos++; } /*---------- logical ----------------------------------------------- * evaluates logical operations *------------------------------------------------------------------*/ static void logical () { relational (); while (1) { skip_space (exp_ptr); if (*exp_ptr == '?') { advance (1); add_op (OP_IF, NULL); logical (); skip_space (exp_ptr); if (*exp_ptr != ':') longjmp (env_ptr, VECERR_IFELSE); advance (1); add_op (OP_ELSE, NULL); logical (); add_op (OP_ENDIF, NULL); } else if (*exp_ptr == '&') { advance (1); if (*exp_ptr == '&') advance (1); relational (); add_op (OP_AND, NULL); } else if (*exp_ptr == '|') { advance (1); if (*exp_ptr == '|') advance (1); relational (); add_op (OP_OR, NULL); } else break; } } /*---------- relational -------------------------------------------- * evaluates relational operators *------------------------------------------------------------------*/ static void relational () { additive (); while (1) { skip_space (exp_ptr); if (*exp_ptr == '<') { advance (1); if (*exp_ptr == '=') { advance (1); additive (); add_op (OP_LESS_EQ, NULL); } else { additive (); add_op (OP_LESS, NULL); } } else if (*exp_ptr == '>') { advance (1); if (*exp_ptr == '=') { advance (1); additive (); add_op (OP_GREATER_EQ, NULL); } else { additive (); add_op (OP_GREATER, NULL); } } else if (*exp_ptr == '=') { advance (1); if (*exp_ptr != '=') longjmp (env_ptr, VECERR_EQUALS); advance (1); additive (); add_op (OP_EQUALS, NULL); } else if (*exp_ptr == '!') { advance (1); if (*exp_ptr != '=') longjmp (env_ptr, VECERR_NOTEQS); advance (1); additive (); add_op (OP_NOT_EQUAL, NULL); } else break; } } /*---------- additive ---------------------------------------------- * evaluates additive operators *------------------------------------------------------------------*/ static void additive () { multiplicative (); while (1) { skip_space (exp_ptr); if (*exp_ptr == '+') { advance (1); multiplicative (); add_op (OP_PLUS, NULL); } else if (*exp_ptr == '-') { advance (1); multiplicative (); add_op (OP_MINUS, NULL); } else break; } } /*---------- multiplicative ---------------------------------------- * evaluates multiplicative operators *------------------------------------------------------------------*/ static void multiplicative () { exponential (); while (1) { skip_space (exp_ptr); if (*exp_ptr == '*') { advance (1); exponential (); add_op (OP_MULTIPLY, NULL); } else if (*exp_ptr == '/') { advance (1); exponential (); add_op (OP_DIVIDE, NULL); } else if (*exp_ptr == '%') { advance (1); exponential (); add_op (OP_MODULUS, NULL); } else if (strchr (OPERATORS, *exp_ptr) == NULL) { exponential (); add_op (OP_MULTIPLY, NULL); } else break; } } /*---------- exponential ------------------------------------------- * evaluates exponential operators *------------------------------------------------------------------*/ static void exponential () { unary (); while (1) { skip_space (exp_ptr); if (*exp_ptr == '^') { advance (1); unary (); add_op (OP_POWER, NULL); } else if (*exp_ptr == '*' && *(exp_ptr+1) == '*') { advance (2); unary (); add_op (OP_POWER, NULL); } else break; } } /*---------- unary ------------------------------------------------- * evaluates unary operations *------------------------------------------------------------------*/ static void unary () { skip_space (exp_ptr); if (*exp_ptr == '-') { advance (1); expression (); add_op (OP_NEGATE, NULL); } else if (*exp_ptr == '!') { advance (1); expression (); add_op (OP_NOT, NULL); } else expression (); } /*---------- expression -------------------------------------------- * evaluates an expression *------------------------------------------------------------------*/ static void expression () { char *p; int i; size_t ii; double dval; VECDATA *vd; skip_space (exp_ptr); if (*exp_ptr == '(') { advance (1); logical (); skip_space (exp_ptr); if (*exp_ptr != ')') longjmp (env_ptr, VECERR_PAREN); advance (1); } else if (*exp_ptr == '[') { advance (1); p = exp_ptr; i = 0; while (*exp_ptr && *exp_ptr != ']' && vec_number (&dval, &exp_ptr)) { i++; skip_space (exp_ptr); if (*exp_ptr == ',') advance(1); } if (!i || *exp_ptr != ']') longjmp (env_ptr, VECERR_BADVEC); advance (1); vd = vec_create (VEC_VECTOR, i, 1); for (ii = 0; ii < vd->len; ii++) { vec_number (&dval, &p); vd->f.vec[ii] = (VECFLOAT)dval; skip_space (p); if (*p == ',') p++; } add_op (OP_VECTOR, (void *)vd); } else if (isdigit (*exp_ptr) || *exp_ptr == '.') { if (!vec_number (&dval, &exp_ptr)) longjmp (env_ptr, VECERR_BADNUM); add_op (OP_NUMBER, (void *)&dval); } else if (*exp_ptr == '\\') { advance (1); if (!do_userfunc() && !do_symbol() && !do_intrinsic()) longjmp (env_ptr, VECERR_SYMBOL); } else if (!do_intrinsic() && !do_symbol() && !do_userfunc()) longjmp (env_ptr, VECERR_SYMBOL); } /*================================================================== * processing routines *==================================================================*/ /*---------- push_var ---------------------------------------------- * push a variable on the stack *------------------------------------------------------------------*/ static void push_var (v) double v; { if (var_pos >= var_size) { var_size += STACK_INC; var_stack = (double *) realloc (var_stack, var_size * sizeof(double)); if (var_stack == NULL) longjmp (env_ptr, VECERR_PUSH); } var_stack[var_pos++] = v; } /*---------- pop_var ------------------------------------------------ * pop a variable from the stack *------------------------------------------------------------------*/ static void pop_var (v) double *v; { if (--var_pos < 0) longjmp (env_ptr, VECERR_POP); *v = var_stack[var_pos]; } /*---------- process_op -------------------------------------------- * processes the operation stack for given variables *------------------------------------------------------------------*/ static double process_op (n) int n; { int m, done = 0, level, index = 0; long j; struct op_stack_ *op; double f1, f2; while (op_index < op_pos && !done) { op = &op_start[op_index++]; switch (op->op) { case OP_NOP: case OP_BEGIN_FUNC: break; case OP_INTEGER: push_var ((double)op->op_val.ival); break; case OP_COUNTER: push_var ((double)(n + 1)); break; case OP_INDEX: pop_var (&f1); index = (int)(f1 + TOLERANCE); if (index < 1) longjmp (env_ptr, VECERR_BADINDX); if (op_index == op_pos) longjmp (env_ptr, VECERR_POP); op = &op_start[op_index++]; if (op->op != OP_VECTOR) longjmp (env_ptr, VECERR_INDEX); case OP_VECTOR: { VECFLOAT *vec = op->op_val.vec; if (!index) index = n + 1; if (--index < 0 || index >= (int)op->len) longjmp (env_ptr, VECERR_BADINDX); push_var ((double)(vec[index])); index = 0; break; } case OP_NUMBER: push_var (op->op_val.num); break; /* unary operations */ case OP_NEGATE: pop_var (&f1); push_var (-f1); break; case OP_NOT: pop_var (&f1); push_var ((double)(f1 == 0.0 ? 1 : 0)); break; /* arithmetic operations */ case OP_POWER: pop_var (&f2); pop_var (&f1); push_var (pow (f1, f2)); break; case OP_MULTIPLY: pop_var (&f2); pop_var (&f1); push_var (f1 * f2); break; case OP_DIVIDE: pop_var (&f2); pop_var (&f1); if (f2 == 0.0) longjmp (env_ptr, VECERR_DIVIDE); push_var (f1 / f2); break; case OP_MODULUS: pop_var (&f2); pop_var (&f1); push_var (fmod (f1, f2)); break; case OP_PLUS: pop_var (&f2); pop_var (&f1); push_var (f1 + f2); break; case OP_MINUS: pop_var (&f2); pop_var (&f1); push_var (f1 - f2); break; /* comparisons */ case OP_LESS: pop_var (&f2); pop_var (&f1); push_var ((double)(f1 < f2 ? 1 : 0)); break; case OP_LESS_EQ: pop_var (&f2); pop_var (&f1); push_var ((double)(f1 <= f2 ? 1 : 0)); break; case OP_GREATER: pop_var (&f2); pop_var (&f1); push_var ((double)(f1 > f2 ? 1 : 0)); break; case OP_GREATER_EQ: pop_var (&f2); pop_var (&f1); push_var ((double)(f1 >= f2 ? 1 : 0)); break; case OP_EQUALS: pop_var (&f2); pop_var (&f1); push_var ((double)(f1 == f2 ? 1 : 0)); break; case OP_NOT_EQUAL: pop_var (&f2); pop_var (&f1); push_var ((double)(f1 != f2 ? 1 : 0)); break; case OP_AND: pop_var (&f2); pop_var (&f1); push_var ((double)(f1 && f2 ? 1 : 0)); break; case OP_OR: pop_var (&f2); pop_var (&f1); push_var ((double)(f1 || f2 ? 1 : 0)); break; /* if-then operation */ case OP_IF: level = ++nest_level; pop_var (&f1); if (f1 == 0.0) { /* skip if(TRUE) operations */ while (1) { op = &op_start[op_index++]; if (op->op == OP_ELSE) { if (level == nest_level) break; level--; } else if (op->op == OP_IF) level++; } } push_var (process_op (n)); nest_level--; break; case OP_ELSE: level = nest_level; while (1) { op = &op_start[op_index++]; if (op->op == OP_ENDIF) { if (level == nest_level) break; level--; } else if (op->op == OP_IF) level++; } case OP_ENDIF: if (nest_level) done = 1; break; /* functions which operate on the vectors */ case FUNC_MAX: case FUNC_MIN: case FUNC_SUM: case FUNC_AVG: case FUNC_SIZE: case FUNC_LEN: /* if currently processing vector, return */ if (vec_op) { done = 1; break; } /* else, first time here - find start of operations */ /* also check that all vectors are the same length */ index = op_index - 1; level = m = 0; while (op_start[--op_index].op != OP_BEGIN_FUNC) { if (op_start[op_index].op == OP_VECTOR) { if (!level) level = op_start[op_index].len; else if (level != op_start[op_index].len) longjmp (env_ptr, VECERR_VECLEN); } else if (op_start[op_index].op == OP_COUNTER) m = op_start[op_index].len; } if (!level && m) level = m; /* set BEGIN_FUNC op to NOP and set start of processing */ op_start[op_index].op = OP_NOP; vec_op = ++op_index; /* evaluate intrinsic function */ pop_var (&f1); if (op->op == FUNC_LEN) f1 = level ? level : 1; else { for (m = 1; m < level; m++) { op_index = vec_op; f2 = process_op (m); switch (op->op) { case FUNC_MAX: if (f1 < f2) f1 = f2; break; case FUNC_MIN: if (f1 > f2) f1 = f2; break; case FUNC_AVG: case FUNC_SUM: f1 += f2; break; case FUNC_SIZE: f1 += (f2 * f2); break; } } if (op->op == FUNC_AVG) f1 /= (double)(level ? level : 1); else if (op->op == FUNC_SIZE) f1 = sqrt (f1); } /* set stack ops to NOP */ for (m = vec_op; m < index; m++) op_start[m].op = OP_NOP; op = &op_start[index]; op_index = index + 1; vec_op = index = 0; /* put final result on stack */ op->op = OP_NUMBER; op->op_val.num = f1; push_var (f1); break; /* function operations */ case FUNC_ABS: pop_var (&f1); push_var (fabs (f1)); break; case FUNC_ACOS: pop_var (&f1); push_var (acos (f1)); break; case FUNC_ACOSH: pop_var (&f1); if (f1 < 1.0) longjmp (env_ptr, VECERR_ACOSH); push_var (log (f1 + sqrt (f1 * f1 - 1.0))); break; case FUNC_ASIN: pop_var (&f1); push_var (asin (f1)); break; case FUNC_ASINH: pop_var (&f1); push_var (log (f1 + sqrt (f1 * f1 + 1.0))); break; case FUNC_ATAN: pop_var (&f1); push_var (atan (f1)); break; case FUNC_ATAN2: pop_var (&f2); pop_var (&f1); push_var (atan2 (f1, f2)); break; case FUNC_ATANH: pop_var (&f1); if (f1 <= -1.0 || f1 >= 1.0) longjmp (env_ptr, VECERR_ATANH); push_var (0.5 * log ((1.0 + f1) / (1.0 - f1))); break; case FUNC_CEIL: pop_var (&f1); push_var (ceil (f1)); break; case FUNC_COSH: pop_var (&f1); push_var (cosh (f1)); break; case FUNC_COS: pop_var (&f1); push_var (cos (f1)); break; case FUNC_DEG: pop_var (&f1); push_var (f1 * 180.0 / PI); break; case FUNC_EXP: pop_var (&f1); push_var (exp (f1)); break; case FUNC_FACT: pop_var (&f1); j = (int)f1; f2 = j; if (j == 0) f2 = 1; else if (j > 0) { while (--j) f2 *= (double)j; } else { while (++j) f2 *= (double)j; } push_var (f2); break; case FUNC_FLOOR: pop_var (&f1); push_var (floor (f1)); break; case FUNC_LOG10: pop_var (&f1); push_var (log10 (f1)); break; case FUNC_LOG: pop_var (&f1); push_var (log (f1)); break; case FUNC_MOD: pop_var (&f2); pop_var (&f1); push_var (fmod (f1, f2)); break; case FUNC_POW: pop_var (&f2); pop_var (&f1); push_var (pow (f1, f2)); break; case FUNC_POW10: pop_var (&f1); push_var (pow (10.0, f1)); break; case FUNC_RAD: pop_var (&f1); push_var (f1 * PI / 180.0); break; case FUNC_RAND: push_var (vec_rand ()); break; case FUNC_ROUND: pop_var (&f1); if (fmod (f1, 1.0) >= 0.5) push_var (ceil (f1)); else push_var (floor (f1)); break; case FUNC_SINH: pop_var (&f1); push_var (sinh (f1)); break; case FUNC_SIN: pop_var (&f1); push_var (sin (f1)); break; case FUNC_SQRT: pop_var (&f1); push_var (sqrt (f1)); break; case FUNC_SQR: pop_var (&f1); push_var (f1 * f1); break; case FUNC_TANH: pop_var (&f1); push_var (tanh (f1)); break; case FUNC_TAN: pop_var (&f1); push_var (tan (f1)); break; default: longjmp (env_ptr, VECERR_OPERR); } } pop_var (&f1); return (f1); } /*=================================================================== * math exception handling *===================================================================*/ #ifdef _WIN32 #include #endif /*---------- fpe_err ----------------------------------------------- * signal handler for arithmetic exceptions *------------------------------------------------------------------*/ static SIGNAL fpe_err (int signum) { strcpy (err_msg[VECERR_MATH], "arithmetic exception (SIGFPE)"); #if defined(__MSDOS__) || defined(MSDOS) || defined(_WIN32) _fpreset (); #endif longjmp (env_ptr, VECERR_MATH); } #ifdef USE_MATHERR #ifdef _WIN32 #define matherr _matherr #define exception _exception #endif /*---------- matherr ----------------------------------------------- * use this math error handler, instead of library * This handles errors generated by math function calls *------------------------------------------------------------------*/ int matherr (e) struct exception *e; { switch (e->type) { case DOMAIN: sprintf (err_msg[VECERR_MATH], "%s : argument domain error", e->name); break; case SING: sprintf (err_msg[VECERR_MATH], "%s : argument singularity", e->name); break; case OVERFLOW: sprintf (err_msg[VECERR_MATH], "%s : overflow range error", e->name); break; case UNDERFLOW: sprintf (err_msg[VECERR_MATH], "%s : underflow range error", e->name); break; case PLOSS: sprintf (err_msg[VECERR_MATH], "%s : partial loss of significance", e->name); break; case TLOSS: sprintf (err_msg[VECERR_MATH], "%s : total loss of significance", e->name); break; default: sprintf (err_msg[VECERR_MATH], "%s : unknown error", e->name); break; } longjmp (env_ptr, VECERR_MATH); return (0); /* quite compiler */ } #endif /* USE_MATHERR */ /*========== print_op ============================================== * debug print out of operation stack *==================================================================*/ #ifdef VEC_DEBUG static char HEADER1[] = "op code pop push stack\n"; static char HEADER2[] = "------- --- ---- -----\n"; static char FORMAT[] = "%-20s%7d%7d%10d\n"; static char NUMFORM[] = "%-20.3g%7d%7d%10d\n"; void print_op (fp) FILE *fp; { int m, push, pop, stack_size = 0; char *opname; struct op_stack_ *op; if (op_size == 0) fprintf (fp, "OP STACK not created\n"); else if (op_pos == 0) fprintf (fp, "OP STACK is empty\n"); else { fprintf (fp, HEADER1); fprintf (fp, HEADER2); op_index = 0; while (op_index < op_pos) { op = &op_start[op_index++]; push = pop = 1; switch (op->op) { case OP_NOP: push = pop = 0; opname = "nop"; break; case OP_BEGIN_FUNC: push = pop = 0; opname = "beginfunc"; break; case OP_INTEGER: pop = 0; opname = "integer"; break; case OP_COUNTER: pop = 0; opname = "counter"; break; case OP_INDEX: push = 0; opname = "index"; break; case OP_VECTOR: pop = 0; opname = "vector"; break; case OP_NUMBER: pop = 0; opname = "number"; break; /* unary operations */ case OP_NEGATE: opname = "negate"; break; case OP_NOT: opname = "not"; break; /* arithmetic operations */ case OP_POWER: pop = 2; opname = "power"; break; case OP_MULTIPLY: pop = 2; opname = "multiply"; break; case OP_DIVIDE: pop = 2; opname = "divide"; break; case OP_MODULUS: pop = 2; opname = "modulus"; break; case OP_PLUS: pop = 2; opname = "plus"; break; case OP_MINUS: pop = 2; opname = "minus"; break; /* comparisons */ case OP_LESS: pop = 2; opname = "<"; break; case OP_LESS_EQ: pop = 2; opname = "<="; break; case OP_GREATER: pop = 2; opname = ">"; break; case OP_GREATER_EQ: pop = 2; opname = ">="; break; case OP_EQUALS: pop = 2; opname = "=="; break; case OP_NOT_EQUAL: pop = 2; opname = "!="; break; case OP_AND: pop = 2; opname = "and"; break; case OP_OR: pop = 2; opname = "or"; break; /* if-then operation */ case OP_IF: opname = "if"; break; case OP_ELSE: push = pop = 0; opname = "else"; break; case OP_ENDIF: push = pop = 0; opname = "endif"; break; /* functions which operate on the vectors */ case FUNC_MAX: opname = "max()"; break; case FUNC_MIN: opname = "min()"; break; case FUNC_SUM: opname = "sum()"; break; case FUNC_AVG: opname = "avg()"; break; case FUNC_SIZE: opname = "size()"; break; case FUNC_LEN: opname = "len()"; break; /* function operations */ case FUNC_ABS: opname = "abs()"; break; case FUNC_ACOS: opname = "acos()"; break; case FUNC_ACOSH: opname = "acosh()"; break; case FUNC_ASIN: opname = "asin()"; break; case FUNC_ASINH: opname = "asinh()"; break; case FUNC_ATAN: opname = "atan()"; break; case FUNC_ATANH: opname = "atanh()"; break; case FUNC_CEIL: opname = "ceil()"; break; case FUNC_COSH: opname = "cosh()"; break; case FUNC_COS: opname = "cos()"; break; case FUNC_DEG: opname = "deg()"; break; case FUNC_EXP: opname = "exp()"; break; case FUNC_FACT: opname = "fact()"; break; case FUNC_FLOOR: opname = "floor()"; break; case FUNC_LOG10: opname = "log10()"; break; case FUNC_LOG: opname = "log()"; break; case FUNC_POW10: opname = "pow10()"; break; case FUNC_RAD: opname = "rad()"; break; case FUNC_RAND: pop = 0; opname = "rand()"; break; case FUNC_ROUND: opname = "round()"; break; case FUNC_SINH: opname = "sinh()"; break; case FUNC_SIN: opname = "sin()"; break; case FUNC_SQRT: opname = "sqrt()"; break; case FUNC_SQR: opname = "sqr()"; break; case FUNC_TANH: opname = "tanh()"; break; case FUNC_TAN: opname = "tan()"; break; default: fprintf (fp, "UNREGOGNIZED op code\n"); return; } stack_size += (push - pop); fprintf (fp, FORMAT, opname, pop, push, stack_size); } fprintf (fp, FORMAT, "RESULT", 1, 0, --stack_size); } if (veclist == NULL) fprintf (fp, "Vector list is clear\n"); else { VECLIST *vl = veclist; m = 0; while (vl != NULL) { m++; vl = vl->prev; } fprintf (fp, "%d Vectors in vector list\n"); } } #endif /* VEC_DEBUG */ cgnslib_3.1.4/src/cgnstools/calclib/vecsym.c0000664000076400007640000003610212160605672016031 00000000000000/* * vecsym.c - symbol table for vector processor */ #include #include #include #include #include "vecsym.h" #define HASH_SIZE 127 /* size of hash table */ static VECSYM *hash_table[HASH_SIZE];/* user symbol hash table */ static int num_symbols = 0; /* number symbols in hash table */ static int max_namelen = 0; /* max length of user symbol name */ /*----- error mesages -----*/ static char *errmsg[] = { "no error", "NULL or blank symbol name", "NULL or blank equation string", "failed to add new symbol to symbol table", "malloc failed - out of space", "NULL funtion pointer", "user function has too many arguments", "0 length or NULL vector", "symbol name too long", "invalid error code" }; /*----- callback for deleting symbol -----*/ void (*sym_delfunc) (struct symbol_ *) = NULL; /*----- local functions -----*/ static void init_hash(void); static int hash_name(char *name); static VECSYM *add_symbol(char *name); /*================================================================== * these routines are needed by vec.c *==================================================================*/ /*---------- find_symbol ------------------------------------------- * find a symbol in the hash table *------------------------------------------------------------------*/ VECSYM *find_symbol (char *name, int is_func) { VECSYM *sym; if (!num_symbols) return (NULL); sym = hash_table[hash_name (name)]; while (sym != NULL) { if (strcmp (name, vecsym_name(sym)) == 0) { if (vecsym_type(sym) == VECSYM_FUNC) return (is_func ? sym : NULL); if (vecsym_type(sym) == VECSYM_EQUSTR || vecsym_type(sym) == VECSYM_MACRO) { if (vecsym_nargs(sym) > 0) return (is_func ? sym : NULL); return (sym); } return (is_func ? NULL : sym); } sym = sym->next; } return (NULL); } /*================================================================== * hashing routines for user symbols *==================================================================*/ /*---------- init_hash --------------------------------------------- * initialize hash table *------------------------------------------------------------------*/ static void init_hash (void) { int n; for (n = 0; n < HASH_SIZE; n++) hash_table[n] = NULL; } /*---------- hash_name --------------------------------------------- * hashing routine *------------------------------------------------------------------*/ static int hash_name (char *name) { unsigned long hash = 0; while (*name) hash += *name++; return ((int)(hash % HASH_SIZE)); } /*---------- add_symbol -------------------------------------------- * add a symbol to the hash table *------------------------------------------------------------------*/ static VECSYM *add_symbol (char *name) { int hash = hash_name (name); VECSYM *sym = hash_table[hash]; while (sym != NULL) { if (strcmp (name, vecsym_name(sym)) == 0) { if (vecsym_type(sym) == VECSYM_EQUSTR) free (vecsym_equstr(sym)); else if (vecsym_type(sym) == VECSYM_MACRO) free (vecsym_macro(sym)); else if (vecsym_type(sym) == VECSYM_VECTOR) free (vecsym_vector(sym)); return (sym); } sym = sym->next; } sym = (VECSYM *) malloc (sizeof(VECSYM)); if (sym != NULL) { int len = (int)strlen (name); strcpy (vecsym_name(sym), name); sym->next = hash_table[hash]; hash_table[hash] = sym; num_symbols++; if (max_namelen < len) max_namelen = len; } return (sym); } /*---------- sym_free ---------------------------------------------- * free symbol table resources *------------------------------------------------------------------*/ void sym_free (void) { int n; VECSYM *sym, *next; if (!num_symbols) return; for (n = 0; n < HASH_SIZE; n++) { sym = hash_table[n]; while (sym != NULL) { next = sym->next; if (sym_delfunc != NULL) (*sym_delfunc) (sym); if (vecsym_type(sym) == VECSYM_EQUSTR) free (vecsym_equstr(sym)); else if (vecsym_type(sym) == VECSYM_MACRO) free (vecsym_macro(sym)); else if (vecsym_type(sym) == VECSYM_VECTOR) free (vecsym_vector(sym)); free (sym); sym = next; } hash_table[n] = NULL; } num_symbols = 0; max_namelen = 0; } /*---------- sym_errmsg --------------------------------------------- * returns error message *-------------------------------------------------------------------*/ char *sym_errmsg (int errnum) { if (errnum >= 0 && errnum < SYMERR_INVALID) return (errmsg[errnum]); return (errmsg[SYMERR_INVALID]); } /*---------- sym_addval -------------------------------------------- * adds a value to user symbol table *------------------------------------------------------------------*/ int sym_addval (char *name, VECFLOAT val, void *user) { VECSYM *sym; if (name == NULL || !*name) return (SYMERR_NONAME); if (strlen (name) > SYMNAME_MAXLEN) return (SYMERR_TOOLONG); if (!num_symbols) init_hash (); if ((sym = add_symbol (name)) == NULL) return (SYMERR_SYMTABLE); vecsym_type(sym) = VECSYM_VALUE; vecsym_nargs(sym) = 0; vecsym_veclen(sym) = 0; vecsym_value(sym) = val; vecsym_user(sym) = user; return (0); } /*---------- sym_addvec -------------------------------------------- * adds a vector to user symbol table *------------------------------------------------------------------*/ int sym_addvec (char *name, size_t len, VECFLOAT *vec, void *user) { VECSYM *sym; if (name == NULL || !*name) return (SYMERR_NONAME); if (strlen (name) > SYMNAME_MAXLEN) return (SYMERR_TOOLONG); if (len < 1 || vec == NULL) return (SYMERR_NOVEC); if (!num_symbols) init_hash (); if ((sym = add_symbol (name)) == NULL) return (SYMERR_SYMTABLE); vecsym_vector(sym) = (VECFLOAT *) malloc (len * sizeof(VECFLOAT)); if (vecsym_vector(sym) == NULL) { vecsym_type(sym) = VECSYM_VALUE; sym_delsym (name); return (SYMERR_MALLOC); } vecsym_type(sym) = VECSYM_VECTOR; vecsym_nargs(sym) = 0; vecsym_veclen(sym) = len; vecsym_user(sym) = user; memcpy (vecsym_vector(sym), vec, len * sizeof(VECFLOAT)); return (0); } /*---------- sym_addequ -------------------------------------------- * adds an equation to user symbol table *------------------------------------------------------------------*/ int sym_addequ (char *name, int nargs, char *equ, void *user) { VECSYM *sym; if (name == NULL || !*name) return (SYMERR_NONAME); if (strlen (name) > SYMNAME_MAXLEN) return (SYMERR_TOOLONG); if (equ == NULL) return (SYMERR_NOEXPR); while (*equ && isspace (*equ)) equ++; if (!*equ) return (SYMERR_NOEXPR); if (!num_symbols) init_hash (); if ((sym = add_symbol (name)) == NULL) return (SYMERR_SYMTABLE); vecsym_equstr(sym) = (char *) malloc (strlen (equ) + 1); if (vecsym_equstr(sym) == NULL) { vecsym_type(sym) = VECSYM_VALUE; sym_delsym (name); return (SYMERR_MALLOC); } vecsym_type(sym) = VECSYM_EQUSTR; vecsym_nargs(sym) = nargs; vecsym_user(sym) = user; strcpy (vecsym_equstr(sym), equ); return (0); } /*---------- sym_addfunc ------------------------------------------- * adds a function to user symbol table *------------------------------------------------------------------*/ int sym_addfunc (char *name, int nargs, VECFUNC func, void *user) { VECSYM *sym; if (name == NULL || !*name) return (SYMERR_NONAME); if (strlen (name) > SYMNAME_MAXLEN) return (SYMERR_TOOLONG); if (func == NULL) return (SYMERR_NOFUNC); if (nargs > FUNC_MAXARGS) return (SYMERR_MAXARGS); if (!num_symbols) init_hash (); if ((sym = add_symbol (name)) == NULL) return (SYMERR_SYMTABLE); vecsym_type(sym) = VECSYM_FUNC; vecsym_nargs(sym) = nargs; vecsym_func(sym) = func; vecsym_user(sym) = user; return (0); } /*---------- sym_addmacro ------------------------------------------ * adds a macro to user symbol table *------------------------------------------------------------------*/ int sym_addmacro (char *name, int nargs, char *macro, void *user) { VECSYM *sym; if (name == NULL || !*name) return (SYMERR_NONAME); if (strlen (name) > SYMNAME_MAXLEN) return (SYMERR_TOOLONG); if (macro == NULL) return (SYMERR_NOEXPR); while (*macro && isspace (*macro)) macro++; if (!*macro) return (SYMERR_NOEXPR); if (!num_symbols) init_hash (); if ((sym = add_symbol (name)) == NULL) return (SYMERR_SYMTABLE); vecsym_macro(sym) = (char *) malloc (strlen (macro) + 1); if (vecsym_macro(sym) == NULL) { vecsym_type(sym) = VECSYM_VALUE; sym_delsym (name); return (SYMERR_MALLOC); } vecsym_type(sym) = VECSYM_MACRO; vecsym_nargs(sym) = nargs; vecsym_user(sym) = user; strcpy (vecsym_macro(sym), macro); return (0); } /*---------- sym_adddata ------------------------------------------- * adds user data to user symbol table *------------------------------------------------------------------*/ int sym_adddata (char *name, void *data, void *user) { VECSYM *sym; if (name == NULL || !*name) return (SYMERR_NONAME); if (strlen (name) > SYMNAME_MAXLEN) return (SYMERR_TOOLONG); if (!num_symbols) init_hash (); if ((sym = add_symbol (name)) == NULL) return (SYMERR_SYMTABLE); vecsym_type(sym) = VECSYM_DATA; vecsym_nargs(sym) = 0; vecsym_data(sym) = data; vecsym_user(sym) = user; return (0); } /*---------- sym_delsym ---------------------------------------------- * delete a symbol from the symbol table *--------------------------------------------------------------------*/ void sym_delsym (char *name) { VECSYM *sym, *prev; int hash; if (!num_symbols || name == NULL || !*name) return; hash = hash_name (name); if ((prev = hash_table[hash]) == NULL) return; if (strcmp (name, vecsym_name(prev)) == 0) { hash_table[hash] = prev->next; if (sym_delfunc != NULL) (*sym_delfunc) (prev); if (vecsym_type(prev) == VECSYM_EQUSTR) free (vecsym_equstr(prev)); else if (vecsym_type(prev) == VECSYM_MACRO) free (vecsym_macro(prev)); else if (vecsym_type(prev) == VECSYM_VECTOR) free (vecsym_vector(prev)); free (prev); return; } sym = prev->next; while (sym != NULL) { if (strcmp (name, vecsym_name(sym)) == 0) { prev->next = sym->next; if (sym_delfunc != NULL) (*sym_delfunc) (sym); if (vecsym_type(sym) == VECSYM_EQUSTR) free (vecsym_equstr(sym)); else if (vecsym_type(sym) == VECSYM_MACRO) free (vecsym_macro(sym)); else if (vecsym_type(sym) == VECSYM_VECTOR) free (vecsym_vector(sym)); free (sym); return; } prev = sym; sym = prev->next; } } /*---------- sym_count --------------------------------------------- * return number of symbols of given type *------------------------------------------------------------------*/ int sym_count (int type) { int n, cnt = 0; VECSYM *sym; if (num_symbols) { for (n = 0; n < HASH_SIZE; n++) { sym = hash_table[n]; while (sym != NULL) { if (!type || vecsym_type(sym) == type) cnt++; sym = sym->next; } } } return (cnt); } /*---------- sym_names --------------------------------------------- * return list of symbol names *------------------------------------------------------------------*/ char **sym_names (int type) { int n, cnt = sym_count (type); VECSYM *sym; char **names = NULL; if (cnt) { names = (char **) malloc ((cnt+1) * sizeof(char *)); if (NULL == names) return (NULL); for (n = 0, cnt = 0; n < HASH_SIZE; n++) { sym = hash_table[n]; while (sym != NULL) { if (!type || vecsym_type(sym) == type) names[cnt++] = vecsym_name(sym); sym = sym->next; } } names[cnt] = NULL; } return (names); } /*---------- sym_list ---------------------------------------------- * lists symbols *------------------------------------------------------------------*/ int sym_list (int type, int (*func)(struct symbol_ *, void *), void *userdata) { int n, cnt = 0; VECSYM *sym; if (num_symbols && NULL != func) { for (n = 0; n < HASH_SIZE; n++) { sym = hash_table[n]; while (sym != NULL) { if (!type || vecsym_type(sym) == type) cnt += (*func) (sym, userdata); sym = sym->next; } } } return (cnt); } /*---------- sym_print --------------------------------------------- * print symbol list *------------------------------------------------------------------*/ void sym_print (FILE *fp) { int i, fld; VECSYM *sym; if (!num_symbols) { fprintf (fp, "\nNo Symbols defined\n"); return; } fld = max_namelen > 5 ? max_namelen : 5; fprintf (fp, "Defined Symbols:\n"); fprintf (fp, "%-*s Type Nargs/Expression/Value/Length\n", fld, "Name"); i = fld + 43; while (i--) putc ('-', fp); putc ('\n', fp); for (i = 0; i < HASH_SIZE; i++) { sym = hash_table[i]; while (sym != NULL) { fprintf (fp, "%-*.*s ", fld, fld, vecsym_name(sym)); if (vecsym_type(sym) == VECSYM_VALUE) fprintf (fp, "value %g\n", vecsym_value(sym)); else if (vecsym_type(sym) == VECSYM_VECTOR) fprintf (fp, "vector %ld\n", (long)vecsym_veclen(sym)); else if (vecsym_type(sym) == VECSYM_EQUSTR) fprintf (fp, "equation %s\n", vecsym_equstr(sym)); else if (vecsym_type(sym) == VECSYM_MACRO) fprintf (fp, "macro %s\n", vecsym_macro(sym)); else if (vecsym_type(sym) == VECSYM_FUNC) { fprintf (fp, "function "); if (vecsym_nargs(sym) < 0) fprintf (fp, "variable\n"); else fprintf (fp, "%d\n", vecsym_nargs(sym)); } else if (vecsym_type(sym) == VECSYM_DATA) fprintf (fp, "user data\n"); else fprintf (fp, "unknown type\n"); sym = sym->next; } } } cgnslib_3.1.4/src/cgnstools/calclib/calctest.c0000664000076400007640000002514012160605672016325 00000000000000#include #include #include #include #include #include "calc.h" static int verbose = 0; static int recurs = 0; static char buff[1025]; static char errmsg[513]; /*===================================================================== * main *=====================================================================*/ #define PROMPT "\n$ " static char *commands[] = { "cmd = execute command 'cmd'", "> cmd = execute command 'cmd' with output", "< cmdfile = read command file 'cmdfile'", "& cgnsfile = load CGNS file 'cgnsfile'", "%> = turn on output", "%< = turn off output", "%% = reset calculator", "%b base = set base number 'base'", "%z zone = set zone number 'zone'", "%s soln = set solution number 'soln'", "?n = list number of bases,zones and solutions", "?[rcvsi] = list Reference,Coordinates,Variables,Symbols,Intrinsics", "?% = show base,zone,solution and output state", "** = exit", NULL }; /*---------- next_line ---------------------------------------------- * return next input line, handling blanks, comments and continuations *-------------------------------------------------------------------*/ static char *next_line (FILE *fp) { int n = 0, len; char *p, line[257]; while (fgets (line, sizeof(line), fp) != NULL) { line[sizeof(line)-1] = 0; p = line + strlen(line); while (--p >= line && isspace(*p)) ; *++p = 0; for (p = line; *p && isspace(*p); p++) ; if (!*p) continue; strcpy (buff, p); n = strlen (buff); while (buff[n-1] == '\\') { for (n -= 2; n >= 0 && isspace(buff[n]); n--) ; buff[++n] = 0; if (fgets (line, sizeof(line), fp) == NULL) break; line[sizeof(line)-1] = 0; p = line + strlen(line); while (--p >= line && isspace(*p)) ; *++p = 0; for (p = line; *p && isspace(*p); p++) ; if (!*p) break; len = strlen (p); if (n + len >= sizeof(buff)) cgnsCalcFatal ("internal command buffer length exceeded"); strcpy (&buff[n], p); n += len; } if ((p = strchr (buff, '#')) != NULL) *p = 0; for (p = buff+strlen(buff)-1; p >= buff && isspace(*p); p--) ; *++p = 0; for (p = buff; *p && isspace(*p); p++) ; if (*p) return (p); } return (NULL); } /*---------- process_command --------------------------------------- * extract prefix/suffix and process command *------------------------------------------------------------------*/ static void process_command (char *expression) { int echo = verbose; char *p, *cmd = expression; VECSYM *sym; /* skip leading and trailing space */ for (p = cmd + strlen(cmd) - 1; p >= cmd && isspace(*p); p--) ; *++p = 0; while (*cmd && isspace(*cmd)) cmd++; if (!*cmd) return; /* check for echo */ if (*cmd == '>') { echo = 1; while (*++cmd && isspace (*cmd)) ; } /* empty string */ if (!*cmd) { if (echo) putchar ('\n'); return; } /* evaluate the expression */ if (NULL == (sym = cgnsCalcCommand (cmd)) || !echo) return; /* value */ if (vecsym_type(sym) == VECSYM_VALUE) { printf ("%s = %g\n", vecsym_name(sym), vecsym_value(sym)); return; } /* vector */ if (vecsym_type(sym) == VECSYM_VECTOR) { int n, len = vecsym_veclen(sym); VECFLOAT vmin, vmax, *vec = vecsym_vector(sym); vmin = vmax = *vec; for (n = 1; n < len; n++) { if (vmin > vec[n]) vmin = vec[n]; if (vmax < vec[n]) vmax = vec[n]; } printf ("%s = %d:%g->%g\n", vecsym_name(sym), len, vmin, vmax); return; } /* equation or macro */ if (vecsym_type(sym) == VECSYM_EQUSTR || vecsym_type(sym) == VECSYM_MACRO) { printf ("%s(%d) %s %s\n", vecsym_name(sym), vecsym_nargs(sym), vecsym_type(sym) == VECSYM_MACRO ? ":=" : "=", vecsym_equstr(sym)); } } /*---------- parse_commands --------------------------------------------- * process command lines *-----------------------------------------------------------------------*/ static void parse_commands (FILE *fp, char *pmt) { int n, len; char *p; if (++recurs == 10) cgnsCalcFatal ("too many recursions"); while (1) { if (NULL != pmt && *pmt) printf (pmt); if ((p = next_line (fp)) == NULL) break; /* quit */ if (*p == '*') { if (*++p == '*') { cgnsCalcDone (); exit (0); } continue; } /* set output */ else if (*p == '%') { switch (*++p) { case '>': verbose = 1; break; case '<': verbose = 0; break; case '%': cgnsCalcReset (); break; case 'b': n = atoi (++p); if (n < 1 || n > NumBases) { sprintf (errmsg, "base %d invalid\n", n); cgnsCalcError (errmsg); } else cgnsCalcBase (n); break; case 'z': n = atoi (++p); if (n < 1 || n > NumZones) { sprintf (errmsg, "zone %d invalid\n", n); cgnsCalcError (errmsg); } else cgnsCalcZone (n); break; case 's': n = atoi (++p); if (n < 1 || n > NumSolns) { sprintf (errmsg, "solution %d invalid\n", n); cgnsCalcError (errmsg); } else cgnsCalcSoln (n); break; } continue; } /* help */ if (*p == '?') { if (!*++p) { for (n = 0; commands[n] != NULL; n++) printf ("%s\n", commands[n]); continue; } while (*p) { switch (*p) { case 'n': printf ("number of bases = %d\n", NumBases); printf (" zones = %d\n", NumZones); printf (" solns = %d\n", NumSolns); break; case 'r': printf ("=== Reference ===\n"); for (n = 0; n < NumReference; n++) { if (reference[n].len > 1) printf ("%s[%d]\n", reference[n].name, reference[n].len); else printf ("%s\n", reference[n].name); } break; case 'c': printf ("=== Coordinates ===\n"); for (n = 0; n < NumCoordinates; n++) printf ("%s[%d]\n", coordinates[n].name, coordinates[n].len); break; case 'v': printf ("=== Solution ===\n"); for (n = 0; n < NumVariables; n++) printf ("%s[%d]\n", variables[n].name, variables[n].len); break; case 'i': { char **in = vec_list (); printf ("=== Intrinsics ===\n"); for (n = 0; in[n] != NULL; n++) printf ("%s\n", in[n]); break; } case 's': cgnsCalcSymList (stdout); break; case '%': printf ("current base = %d\n", cgnsBase); printf (" zone = %d\n", cgnsZone); printf (" soln = %d\n", cgnsSoln); printf ("output is %s\n", verbose ? "on" : "off"); break; default: break; } p++; } continue; } /* load CGNS file */ if (*p == '&') { while (*++p && isspace(*p)) ; if (!*p) continue; if (access (p, 0)) { sprintf (errmsg, "results file <%s> does not exist", p); cgnsCalcError (errmsg); } else cgnsCalcInit (p, 0, NULL); continue; } /* load command file */ if (*p == '<') { FILE *file; while (*++p && isspace (*p)) ; if (!*p) continue; if (access (p, 0)) { sprintf (errmsg, "command file <%s> does not exist", p); cgnsCalcError (errmsg); } else if ((file = fopen (p, "r")) == NULL) { sprintf (errmsg, "couldn't open command file <%s>", p); cgnsCalcError (errmsg); } else { parse_commands (file, NULL); fclose (file); } continue; } /* process command */ process_command (p); } recurs--; } /*================================================================*/ int main (int argc, char *argv[]) { int n = 1; if (n < argc) { cgnsCalcInit (argv[n++], 0, NULL); if (n < argc) { FILE *fp = fopen (argv[n], "r"); if (NULL == fp) { sprintf (errmsg, "couldn't open command file <%s>", argv[n]); cgnsCalcFatal (errmsg); } parse_commands (fp, NULL); } } if (isatty(fileno(stdin)) && isatty(fileno(stdout))) { putchar ('\n'); for (n = 0; commands[n] != NULL; n++) printf ("%s\n", commands[n]); parse_commands (stdin, PROMPT); } else parse_commands (stdin, NULL); cgnsCalcDone (); return 0; } cgnslib_3.1.4/src/cgnstools/calclib/vecerr.h0000664000076400007640000000745512160605672016027 00000000000000#ifndef _VECERR_H_ #define _VECERR_H_ extern int vec_maxerr; /* max error code */ extern int vec_errnum; /* error number */ /*----- user error handler -----*/ extern void (*vec_errhandler) ( /* user error handler */ int errnum, /* error number */ char *errmsg, /* error message */ int offset, /* offset in parse string */ char *exp /* expression being parsed */ ); /*----- error codes -----*/ enum VecErrors { VECERR_NOERR=0, /* sucessfull evaluation */ VECERR_SYMBOL, /* unrecognized or invalid symbol */ VECERR_BADEXPR, /* bad expression */ VECERR_NOEXPR, /* NULL or blank expression string argument */ VECERR_FUNC, /* function name not followed by '(' */ VECERR_DIVIDE, /* math error: divide by 0 */ VECERR_PAREN, /* '(' without ')' */ VECERR_IFELSE, /* if (?) without else (:) */ VECERR_EQUALS, /* '=' instead of '==' */ VECERR_NOTEQS, /* '!' instead of '!=' */ VECERR_MATH, /* general math error */ VECERR_MISSING, /* missing operator */ VECERR_POINTER, /* user function did not update pointer */ VECERR_CALLS, /* too many recursive calls */ VECERR_BADNUM, /* single '.' not preceeded/followed by digit */ VECERR_RECURSE, /* recursion in expression detected */ VECERR_ARGS, /* function argument list error */ VECERR_MAXARGS, /* user function has too many arguments */ VECERR_MALLOC, /* malloc failed */ VECERR_OPERR, /* internal error - op code */ VECERR_PUSH, /* out of space for variable stack */ VECERR_POP, /* tried to pop empty variable stack */ VECERR_OP_STK, /* couldn't malloc/realloc operation stack */ VECERR_VAR_STK, /* couldn't malloc variable stack */ VECERR_BRACKET, /* '[' without ']' */ VECERR_NOVECT, /* couldn't malloc vector data */ VECERR_VECLEN, /* vector lengths not the same */ VECERR_INDEX, /* index not associated with a variable */ VECERR_BADINDX, /* index out of range of vector data */ VECERR_VECTYPE, /* bad vector data type */ VECERR_ZEROLEN, /* vector len < 1 */ VECERR_EQUARG, /* equation argument out of range */ VECERR_ACOSH, /* argument to acosh < 1 */ VECERR_ATANH, /* argument to atanh <= -1 or >= 1 */ VECERR_BADVEC, /* bad vector specification */ VECERR_USER, /* user call-back function error */ VECERR_INVALID /* invalid error message number */ }; #ifdef INCLUDE_ERRDATA /*----- error messages -----*/ static char *err_msg[] = { "sucessfull evaluation", "unrecognized or invalid symbol", "bad expression", "NULL or blank expression string argument", "function name not followed by '('", "math error: divide by 0", "'(' without ')'", "if (?) without else (:)", "'=' instead of '=='", "'!' instead of '!='", " ", "missing operator", "user function did not update pointer", "too many recursive calls", "single '.' not preceeded or followed by digit", "recursion in expression detected", "function argument list error", "user function has too many arguments", "malloc failed", "internal error - op code", "out of space for variable stack", "tried to pop empty variable stack", "couldn't malloc/realloc operation stack", "couldn't malloc variable stack", "'[' without ']'", "couldn't malloc vector data", "vector lengths not the same", "index not associated with a variable", "index out of range of vector data", "bad vector data type", "vector len < 1", "equation argument out of range", "argument to acosh() < 1", "argument to atanh() <= -1 or >= 1", "bad vector specification", NULL, "invalid error message number" }; #endif /* INCLUDE_ERRDATA */ #endif /* _VECERR_H_ */ cgnslib_3.1.4/src/cgnstools/calclib/Makefile.win0000664000076400007640000000174312160605672016616 00000000000000include ..\make.win CALCLIB = cgnscalc.lib COPTS = $(CFLAGS) -I$(CGNSDIR) READ_NODE = -DREAD_NODE lib : $(CALCLIB) all : $(CALCLIB) calctest.exe install : $(CALCLIB) #-------------------------------------------------- $(CALCLIB) : calc.obj vec.obj vecsym.obj $(LINK) /lib /out:$@ calc.obj vec.obj vecsym.obj #-------------------------------------------------- calctest.exe : calctest.obj $(CALCLIB) $(LINK) $(LFLAGS) /out:$@ calctest.obj $(CALCLIB) \ $(CGNSLIB) $(BUILDLIBS) $(CLIBS) calctest.obj : calctest.c #-------------------------------------------------- vec.obj : vec.c vec.h vecsym.h vecerr.h $(CC) $(COPTS) $(MATHERR) -c vec.c vecsym.obj : vecsym.c vec.h vecsym.h calc.obj : calc.c calc.h vecerr.h $(CC) $(COPTS) $(READ_NODE) -c calc.c calc.h : vecsym.h vecsym.h : vec.h #-------------------------------------------------- .c.obj : $(CC) $(COPTS) -Fo$@ -c $< clean: -$(RM) *.obj -$(RM) *.lib -$(RM) *.pdb -$(RM) *.ilk -$(RM) *.bak -$(RM) *.exe cgnslib_3.1.4/src/cgnstools/calclib/Makefile.unix0000664000076400007640000000165012160605672017001 00000000000000# Makefile for Unix/Linux include ../make.defs CALCLIB = libcgnscalc.$(A) COPTS = $(CFLAGS) $(CALCOPTS) -I$(CGNSDIR) lib : $(CALCLIB) all : $(CALCLIB) calctest$(EXE) install : $(CALCLIB) #---------------------------------------------------- $(CALCLIB) : calc.$(O) vec.$(O) vecsym.$(O) $(AR) $@ calc.$(O) vec.$(O) vecsym.$(O) $(RANLIB) $@ #---------------------------------------------------- calctest$(EXE) : calctest.$(O) $(CALCLIB) $(CC) $(LDFLAGS) -o $@ calctest.$(O) $(CALCLIB) \ $(CGNSLIB) $(BUILDLIBS) -lm $(STRIP) $@ calctest.$(O) : calctest.c #--------------------------------------------------- calc.$(O) : calc.c calc.h vecerr.h vec.$(O) : vec.c vec.h vecsym.h vecerr.h vecsym.$(O) : vecsym.c vec.h vecsym.h calc.h : vecsym.h vecsym.h : vec.h #--------------------------------------------------------------- .c.$(O) : $(CC) $(COPTS) -c $< clean: -$(RM) $(CALCLIB) *.$(O) *~ *.bak calctest$(EXE) cgnslib_3.1.4/src/cgnstools/calclib/vecsym.h0000664000076400007640000001136512160605672016042 00000000000000/* * vecsym.h - symbol table interface for vec.c */ #ifndef _VECSYM_H_ #define _VECSYM_H_ /*=================================================================== * none of this is used directly by vec.c * The symbol structure is used indirectly, however, through * the macros defined below *===================================================================*/ #include #ifndef _VEC_H_ #include "vec.h" /* for definition of VECDATA */ #endif /*----- error return codes -----*/ enum SymErrors { SYMERR_NOERR=0, /* no error */ SYMERR_NONAME, /* NULL or blank symbol name */ SYMERR_NOEXPR, /* NULL or blank equation string */ SYMERR_SYMTABLE,/* failed to add new symbol to symbol table */ SYMERR_MALLOC, /* malloc failed - out of space */ SYMERR_NOFUNC, /* NULL function pointer */ SYMERR_MAXARGS, /* user function has too many arguments */ SYMERR_NOVEC, /* 0 length or NULL vector */ SYMERR_TOOLONG, /* symbol name too long */ SYMERR_INVALID /* invalid error code */ }; /*----- symbol table structure -----*/ #define SYMNAME_MAXLEN 32 struct symbol_ { char name[SYMNAME_MAXLEN+1]; int type; int nargs; size_t len; union { VECFLOAT val; VECFLOAT *vec; char *equ; VECFUNC func; void *data; } op; void *user; struct symbol_ *next; }; /*----- callback for deleting a symbol -----*/ extern void (*sym_delfunc) (struct symbol_ *); /*----- function prototypes -----*/ void sym_free (void); /* free symbol table */ char *sym_errmsg ( /* get error message */ int errnum /* error number */ ); int sym_addval ( /* add value symbol */ char *name, /* symbol name */ VECFLOAT val, /* symbol value */ void *user /* user data */ ); int sym_addvec ( /* add vector symbol */ char *name, /* symbol name */ size_t len, /* vector length */ VECFLOAT *vec, /* vector */ void *user /* user data */ ); int sym_addequ ( /* add equation symbol */ char *name, /* symbol name */ int nargs, /* number of arguments */ char *equ, /* equation string */ void *user /* user data */ ); int sym_addfunc ( /* add function symbol */ char *name, /* symbol name */ int nargs, /* number of arguments */ VECFUNC func, /* function pointer */ void *user /* user data */ ); int sym_addmacro ( /* add macro symbol */ char *name, /* symbol name */ int nargs, /* number of arguments */ char *equ, /* macro string */ void *user /* user data */ ); int sym_adddata ( /* add user data symbol */ char *name, /* symbol name */ void *data, /* symbol data */ void *user /* user data */ ); void sym_delsym ( /* remove symbol */ char *name /* symbol name */ ); int sym_count ( /* count number of symbols */ int type /* symbol type (0 for all) */ ); char **sym_names ( /* return NULL terminated list of symbol names */ int type /* symbol type (0 for all) */ ); int sym_list ( /* list symbols */ int type, /* symbol type (0 for all) */ int (*func) ( /* callback function for list */ struct symbol_ *, /* symbol */ void * /* user data */ ), void *userdata /* user data */ ); void sym_print ( /* print list of symbols */ FILE *fp /* where output goes */ ); /*=================================================================== * the following need to be defined for use by vec.c *===================================================================*/ /*----- symbol definition -----*/ typedef struct symbol_ VECSYM; /*----- maximum arguments to a function -----*/ #define FUNC_MAXARGS 5 /*----- symbol types -----*/ #define VECSYM_VALUE 1 /* constant value */ #define VECSYM_VECTOR 2 /* vector */ #define VECSYM_EQUSTR 3 /* equation string */ #define VECSYM_FUNC 4 /* user function */ #define VECSYM_MACRO 5 /* macro string */ #define VECSYM_DATA 6 /* user data */ /*----- macros for accessing symbols -----*/ #define vecsym_name(SYM) ((SYM)->name) #define vecsym_type(SYM) ((SYM)->type) #define vecsym_user(SYM) ((SYM)->user) #define vecsym_value(SYM) ((SYM)->op.val) #define vecsym_veclen(SYM) ((SYM)->len) #define vecsym_vector(SYM) ((SYM)->op.vec) #define vecsym_nargs(SYM) ((SYM)->nargs) #define vecsym_equstr(SYM) ((SYM)->op.equ) #define vecsym_macro(SYM) ((SYM)->op.equ) #define vecsym_func(SYM) ((SYM)->op.func) #define vecsym_data(SYM) ((SYM)->op.data) /*----- function prototypes -----*/ VECSYM *find_symbol ( /* find a symbol */ char *name, /* symbol name */ int is_func /* non-zero if symbol is a function */ ); #endif /* _VECSYM_H_ */ cgnslib_3.1.4/src/cgnstools/calclib/vec.h0000664000076400007640000000531112160605672015303 00000000000000/* * vec.h */ #ifndef _VEC_H_ #define _VEC_H_ #define VEC_MAXCALLS 10 /* max recursive calls */ /*----- vector data structure -----*/ #define VEC_VALUE 0 #define VEC_VECTOR 1 #define VEC_COMPLEX 2 typedef double VECFLOAT; typedef struct { int type; /* type of data */ size_t len; /* length of vector */ union { VECFLOAT val; /* single data value */ VECFLOAT *vec; /* vector data */ } f; } VECDATA; /*--- function prototypes ---*/ #ifdef __cplusplus extern "C" { #endif typedef VECDATA *(*VECFUNC)( int checking, /* set if checking string instead of parsing */ int nv, /* number of arguments */ VECDATA **v, /* arguments */ char **errmsg /* returned error message */ ); typedef VECDATA *(*VECCALL)( int checking, /* set if checking string instead of parsing */ char **pos, /* pointer to position in equation string */ char **errmsg /* returned error message */ ); VECDATA *vec_create ( /* create a vector data structure */ int type, /* type of data */ size_t len, /* length of vector */ int temp /* set if temporary */ ); void vec_destroy ( /* destroy a vector data structure */ VECDATA *vdata /* structure to destroy */ ); int vec_add ( /* add vector to temporary list */ VECDATA *vdata /* data to add */ ); void vec_remove ( /* remove vector from temporary list */ VECDATA *vdata /* data to remove */ ); void vec_free ( /* free internal memory */ void ); void vec_maxcalls ( /* sets maximum number recursive calls */ int maxcalls /* max recursive calls */ ); char *vec_errmsg ( /* returns error messages */ void ); char **vec_list ( /* return list of intrinsics */ void ); VECDATA *vec_parse ( /* parse and process equation */ char *str, /* equation string */ int min_len, /* minimum length of vector for counter */ VECCALL func /* user call-back for unknown symbols */ ); size_t vec_check ( /* parse equation and check for errors */ char *str, /* equation string */ int min_len, /* minimum length of vector for counter */ VECCALL func /* user call-back for unknown symbols */ ); int vec_number ( /* get floating point number from string */ double *dval, /* returned number */ char **sp /* updated string pointer */ ); void vec_randinit ( /* initialize random number generator */ int seed /* initialization seed */ ); double vec_rand ( /* return random floating point number */ void ); #ifdef __cplusplus } #endif #endif /* _VEC_H_ */ cgnslib_3.1.4/src/cgnstools/calclib/calc.c0000664000076400007640000011441312160605672015427 00000000000000#include #include #include #include #include #include "cgnslib.h" #include "calc.h" #include "vecerr.h" #if CGNS_VERSION < 3000 # define Celsius Celcius #endif #ifndef CG_MODE_READ # define CG_MODE_READ MODE_READ # define CG_MODE_MODIFY MODE_MODIFY #endif #ifdef READ_NODE #include "cgns_header.h" #include "cgns_io.h" #endif #ifndef CGNSTYPES_H # define cgsize_t int # define cglong_t long # define cgulong_t unsigned long #endif #ifndef CGNS_ENUMT # define CGNS_ENUMT(e) e # define CGNS_ENUMV(e) e #endif #ifndef CG_MAX_INT32 # define CG_MAX_INT32 0x7FFFFFFF #endif int cgnsFile = 0; /*--- base data ---*/ int NumBases = 0; int cgnsBase; char BaseName[33]; int CellDim, PhyDim; int BaseClass, BaseUnits[5]; /*--- zone data ---*/ int NumZones = 0; int cgnsZone; char ZoneName[33]; int ZoneType; int ZoneDims[6]; int ZoneClass, ZoneUnits[5]; int GridClass, GridUnits[5]; /*--- solution data ---*/ int NumSolns = 0; int cgnsSoln; char SolnName[33]; int SolnLocation; int SolnDims[3], SolnRind[6]; int SolnClass, SolnUnits[5]; /*--- field data ---*/ int NumReference = 0; Variable *reference; int NumCoordinates = 0; Variable *coordinates; int NumVariables = 0; Variable *variables; /*--- local variables ---*/ static int cmdstrlen = 0; static char *cmdstr; static int VectorLen = 100; /* unit specifications */ typedef struct { char *name; int type; int value; } UnitSpec; static UnitSpec unitspec[] = { {"cel", 3, CGNS_ENUMV(Celsius}), {"cen", 1, CGNS_ENUMV(Centimeter}), {"cm", 1, CGNS_ENUMV(Centimeter}), {"c", 3, CGNS_ENUMV(Celsius}), {"d", 4, CGNS_ENUMV(Degree}), {"fa", 3, CGNS_ENUMV(Fahrenheit}), {"fo", 1, CGNS_ENUMV(Foot}), {"ft", 1, CGNS_ENUMV(Foot}), {"f", 3, CGNS_ENUMV(Fahrenheit}), {"g", 0, CGNS_ENUMV(Gram}), {"in", 1, CGNS_ENUMV(Inch}), {"ke", 3, CGNS_ENUMV(Kelvin}), {"ki", 0, CGNS_ENUMV(Kilogram}), {"kg", 0, CGNS_ENUMV(Kilogram}), {"k", 3, CGNS_ENUMV(Kelvin}), {"lb", 0, CGNS_ENUMV(PoundMass}), {"me", 1, CGNS_ENUMV(Meter}), {"mi", 1, CGNS_ENUMV(Millimeter}), {"mm", 1, CGNS_ENUMV(Millimeter}), {"m", 1, CGNS_ENUMV(Meter}), {"p", 0, CGNS_ENUMV(PoundMass}), {"rad", 4, CGNS_ENUMV(Radian}), {"ran", 3, CGNS_ENUMV(Rankine}), {"r", 3, CGNS_ENUMV(Rankine}), {"se", 2, CGNS_ENUMV(Second}), {"sl", 0, CGNS_ENUMV(Slug}), {"s", 2, CGNS_ENUMV(Second}) }; #define NUM_UNITSPEC (sizeof(unitspec)/sizeof(UnitSpec)) /*---------- read_node --------------------------------------------- * read a node from the CGNS file *------------------------------------------------------------------*/ #ifdef READ_NODE static VECDATA *read_node (char *nodename) { cgns_file *cgfile; int n, bytes, dt, cgio; int ndim; cgsize_t np, dims[CGIO_MAX_DIMENSIONS]; char *values; char type[CGIO_MAX_DATATYPE_LENGTH+1]; char errmsg[CGIO_MAX_ERROR_LENGTH+1]; double rootid, nodeid; VECDATA *vd; static struct dataTypes { char *name; int bytes; } data_types[6] = { {"I4", 4}, {"I8", 8}, {"U4", 4}, {"U8", 8}, {"R4", 4}, {"R8", 8} }; /* get node ID for node */ cgfile = cgi_get_file (cgnsFile); cgio = cgfile->cgio; rootid = cgfile->rootid; if (cgio_get_node_id (cgio, rootid, nodename, &nodeid)) { cgio_error_message (errmsg); cgnsCalcFatal (errmsg); } /* get the type of data */ if (cgio_get_data_type (cgio, nodeid, type)) { cgio_error_message (errmsg); cgnsCalcFatal (errmsg); } for (n = 0; n < CGIO_MAX_DATATYPE_LENGTH && type[n]; n++) { if (islower (type[n])) type[n] = toupper (type[n]); } for (bytes = 0, dt = 0; dt < 6; dt++) { if (0 == strncmp (type, data_types[dt].name, 2)) { bytes = data_types[dt].bytes; break; } } if (bytes == 0) { sprintf (errmsg, "can't handle data type %s", type); cgnsCalcFatal (errmsg); } /* get data dimensions */ if (cgio_get_dimensions (cgio, nodeid, &ndim, dims)) { cgio_error_message (errmsg); cgnsCalcFatal (errmsg); } np = 0; if (ndim > 0) { for (np = 1, n = 0; n < ndim; n++) np *= dims[n]; } if (np == 0) cgnsCalcFatal ("no data for node"); if (np > CG_MAX_INT32) cgnsCalcFatal ("exceeded 32-bit integer"); /* read the data */ values = (char *) malloc ((size_t)(np * bytes)); if (NULL == values) cgnsCalcFatal ("malloc failed for node data"); if (cgio_read_all_data (cgio, nodeid, values)) { cgio_error_message (errmsg); cgnsCalcFatal (errmsg); } if (np == 1) { vd = vec_create (VEC_VALUE, 0, 1); if (dt == 0) { int *data = (int *)values; vd->f.val = (VECFLOAT)*data; } else if (dt == 1) { cglong_t *data = (cglong_t *)values; vd->f.val = (VECFLOAT)*data; } else if (dt == 2) { unsigned int *data = (unsigned int *)values; vd->f.val = (VECFLOAT)*data; } else if (dt == 3) { cgulong_t *data = (cgulong_t *)values; vd->f.val = (VECFLOAT)*data; } else if (dt == 4) { float *data = (float *)values; vd->f.val = (VECFLOAT)*data; } else { double *data = (double *)values; vd->f.val = (VECFLOAT)*data; } } else { vd = vec_create (VEC_VECTOR, (int)np, 1); if (dt == 0) { int *data = (int *)values; for (n = 0; n < np; n++) vd->f.vec[n] = (VECFLOAT)data[n]; } else if (dt == 1) { cglong_t *data = (cglong_t *)values; for (n = 0; n < np; n++) vd->f.vec[n] = (VECFLOAT)data[n]; } else if (dt == 2) { unsigned int *data = (unsigned int *)values; for (n = 0; n < np; n++) vd->f.vec[n] = (VECFLOAT)data[n]; } else if (dt == 3) { cgulong_t *data = (cgulong_t *)values; for (n = 0; n < np; n++) vd->f.vec[n] = (VECFLOAT)data[n]; } else if (dt == 4) { float *data = (float *)values; for (n = 0; n < np; n++) vd->f.vec[n] = (VECFLOAT)data[n]; } else { double *data = (double *)values; for (n = 0; n < np; n++) vd->f.vec[n] = (VECFLOAT)data[n]; } } free (values); return vd; } #endif /*---------- read_units ----------------------------------------------- * read unit specifications *---------------------------------------------------------------------*/ static int read_units (int units[5]) { int n; CGNS_ENUMT(MassUnits_t) mass; CGNS_ENUMT(LengthUnits_t) length; CGNS_ENUMT(TimeUnits_t) time; CGNS_ENUMT(TemperatureUnits_t) temp; CGNS_ENUMT(AngleUnits_t) angle; if (cg_units_read (&mass, &length, &time, &temp, &angle)) { for (n = 0; n < 5; n++) units[n] = 0; return 0; } units[0] = mass; units[1] = length; units[2] = time; units[3] = temp; units[4] = angle; return 1; } /*---------- read_class ----------------------------------------------- * get data class, units and conversion factors *---------------------------------------------------------------------*/ static void read_class (Variable *var, int dataclass, int units[5]) { int i; CGNS_ENUMT(DataType_t) datatype; if (cg_dataclass_read ((CGNS_ENUMT(DataClass_t) *)&var->dataclass)) var->dataclass = dataclass; var->hasunits = read_units (var->units); if (!var->hasunits) { for (i = 0; i < 5; i++) var->units[i] = units[i]; } if (cg_conversion_info (&datatype) || (datatype != CGNS_ENUMV(RealSingle) && datatype != CGNS_ENUMV(RealDouble))) { var->hasconv = 0; var->dataconv[0] = 1.0; var->dataconv[1] = 0.0; } else { var->hasconv = datatype; if (datatype == CGNS_ENUMV(RealSingle)) { float conv[2]; if (cg_conversion_read (conv)) cgnsCalcFatal ((char *)cg_get_error()); for (i = 0; i < 2; i++) var->dataconv[i] = conv[i]; } else { if (cg_conversion_read (var->dataconv)) cgnsCalcFatal ((char *)cg_get_error()); } } if (cg_exponents_info (&datatype) || (datatype != CGNS_ENUMV(RealSingle) && datatype != CGNS_ENUMV(RealDouble))) { var->hasexp = 0; for (i = 0; i < 5; i++) var->exponent[i] = 0.0; } else { var->hasexp = datatype; if (datatype == CGNS_ENUMV(RealSingle)) { float exp[5]; if (cg_exponents_read (exp)) cgnsCalcFatal ((char *)cg_get_error()); for (i = 0; i < 5; i++) var->exponent[i] = exp[i]; } else { if (cg_exponents_read (var->exponent)) cgnsCalcFatal ((char *)cg_get_error()); } } } /*---------- read_reference -------------------------------------------- * read reference conditions *----------------------------------------------------------------------*/ static void read_reference (void) { int n, narrays, na, dim; cgsize_t vec[12]; CGNS_ENUMT(DataType_t) datatype; char name[33]; NumReference = 0; if (cg_goto (cgnsFile, cgnsBase, "ReferenceState_t", 1, "end") || cg_narrays (&narrays) || narrays < 1) return; for (na = 1; na <= narrays; na++) { if (cg_array_info (na, name, &datatype, &dim, vec)) cgnsCalcFatal ((char *)cg_get_error()); if (datatype != CGNS_ENUMV(Character) && dim >= 1 && vec[0] >= 1) NumReference++; } if (!NumReference) return; reference = (Variable *) malloc (NumReference * sizeof(Variable)); if (NULL == reference) cgnsCalcFatal ("malloc failed for reference variables"); for (n = 0, na = 1; na <= narrays; na++) { if (cg_array_info (na, name, &datatype, &dim, vec)) cgnsCalcFatal ((char *)cg_get_error()); if (datatype != CGNS_ENUMV(Character) && dim >= 1 && vec[0] >= 1) { dim *= vec[0]; strcpy (reference[n].name, name); reference[n].type = 0; reference[n].id = na; reference[n].len = dim; reference[n].valid = 1; reference[n].datatype = datatype; if (dim == 1) { reference[n].vd = vec_create (VEC_VALUE, 0, 0); if (cg_array_read_as (na, CGNS_ENUMV(RealDouble), &reference[n].vd->f.val)) cgnsCalcFatal ((char *)cg_get_error()); } else { reference[n].vd = vec_create (VEC_VECTOR, dim, 0); if (cg_array_read_as (na, CGNS_ENUMV(RealDouble), reference[n].vd->f.vec)) cgnsCalcFatal ((char *)cg_get_error()); } if (cg_goto (cgnsFile, cgnsBase, "ReferenceState_t", 1, "DataArray_t", na, "end")) cgnsCalcFatal ((char *)cg_get_error()); read_class (&reference[n], BaseClass, BaseUnits); cg_goto (cgnsFile, cgnsBase, "ReferenceState_t", 1, "end"); n++; } } } /*---------- get_variable ---------------------------------------------- * return variable data - read if neccessary *----------------------------------------------------------------------*/ static VECDATA *get_variable (Variable *var) { if (var->vd == NULL) { int n; cgsize_t min[3], max[3]; for (n = 0; n < 3; n++) { min[n] = 1; max[n] = SolnDims[n]; } var->vd = vec_create (VEC_VECTOR, var->len, 0); if (cg_field_read (cgnsFile, cgnsBase, cgnsZone, cgnsSoln, var->name, CGNS_ENUMV(RealDouble), min, max, var->vd->f.vec)) cgnsCalcFatal ((char *)cg_get_error()); } return var->vd; } /*---------- get_coordinate -------------------------------------------- * return coordinate data - read if neccessary *----------------------------------------------------------------------*/ static VECDATA *get_coordinate (Variable *var) { if (var->vd == NULL) { int n; cgsize_t min[3], max[3]; for (n = 0; n < 3; n++) { min[n] = 1; max[n] = ZoneDims[n]; } var->vd = vec_create (VEC_VECTOR, var->len, 0); if (cg_coord_read (cgnsFile, cgnsBase, cgnsZone, var->name, CGNS_ENUMV(RealDouble), min, max, var->vd->f.vec)) cgnsCalcFatal ((char *)cg_get_error()); } return var->vd; } /*---------- print_error --------------------------------------------- * print error message on parsing error *--------------------------------------------------------------------*/ static void print_error (int errnum, char *errmsg, int pos, char *str) { printf (errnum < 0 ? "FATAL:" : "ERROR:"); if (NULL != str) { printf ("%s\n ", str); while (pos-- > 0) putchar ('-'); putchar ('^'); } printf ("%s\n", errmsg); } /*---------- get_name ----------------------------------------------- * get symbol name from string *-------------------------------------------------------------------*/ static char *get_name (char **str) { int n; char *p = *str; static char name[SYMNAME_MAXLEN+1]; if (*p == '"') { for (++p, n = 0; n < SYMNAME_MAXLEN && *p; n++) { if (*p == '"') break; name[n] = *p++; } if (*p++ != '"') return NULL; } else if (!isalpha (*p) && *p != '_') return (NULL); else { for (n = 0; n < SYMNAME_MAXLEN && *p; n++) { if (!isalnum(*p) && *p != '_') break; name[n] = *p++; } } name[n] = 0; *str = p; return name; } /*---------- print_symbols ------------------------------------------ * print symbol names *-------------------------------------------------------------------*/ static int print_symbols (VECSYM *sym, void *data) { FILE *fp = (FILE *)data; if (VECSYM_EQUSTR == vecsym_type(sym)) fprintf (fp, "%s{%d}\n", vecsym_name(sym), vecsym_nargs(sym)); else if (VECSYM_MACRO == vecsym_type(sym)) fprintf (fp, "%s<%d>\n", vecsym_name(sym), vecsym_nargs(sym)); else if (VECSYM_FUNC == vecsym_type(sym)) { if (vecsym_nargs(sym) < 0) fprintf (fp, "%s(...)\n", vecsym_name(sym)); else fprintf (fp, "%s(%d)\n", vecsym_name(sym), vecsym_nargs(sym)); } else if (VECSYM_VECTOR == vecsym_type(sym)) fprintf (fp, "%s[%ld]\n", vecsym_name(sym), (long)vecsym_veclen(sym)); else fprintf (fp, "%s\n", vecsym_name(sym)); return 0; } /*---------- delete_units ------------------------------------------- * called when symbol deleted *-------------------------------------------------------------------*/ static void delete_units (VECSYM *sym) { if (vecsym_user(sym) != NULL) free (vecsym_user(sym)); } /*---------- callback ----------------------------------------------- * callback function for vector parser *-------------------------------------------------------------------*/ static VECDATA *callback (int check, char **pp, char **err) { int n, type = 0; char *p = *pp, *name; /* check for reading node data */ #ifdef READ_NODE if (*p == '{') { char nodename[257]; for (n = 0; n < 256; n++) { if (!*++p || *p == '}') break; nodename[n] = *p; } if (n == 256) { *err = "internal node name length exceeded"; return NULL; } if (!n || *p != '}') { *err = "incomplete node name specification"; return NULL; } *pp = ++p; return read_node (nodename); } #endif /* check for reference or coordinate data */ if (*p == '~' || *p == '\'') type = *p++; /* get name */ if ((name = get_name (&p)) != NULL) { /* check for variable */ if (!type) { for (n = 0; n < NumVariables; n++) { if (0 == strcmp (variables[n].name, name)) { *pp = p; return get_variable (&variables[n]); } } } /* check for grid coordinates */ if (type != '~') { for (n = 0; n < NumCoordinates; n++) { if (0 == strcmp (coordinates[n].name, name)) { *pp = p; return get_coordinate (&coordinates[n]); } } } /* check for reference quantity */ if (type != '\'') { for (n = 0; n < NumReference; n++) { if (0 == strcmp (reference[n].name, name)) { *pp = p; return reference[n].vd; } } } } return (NULL); } /*---------- parse_units ------------------------------------------- * get unit specification *------------------------------------------------------------------*/ static Units *parse_units (char **pp) { int n, par, div; char *p = *pp, name[33]; float exp; Units units, *u; UnitSpec *us; for (n = 0; n < 5; n++) { units.units[n] = 0; units.exps[n] = 0.0; } par = div = 0; while (1) { while (*p && isspace (*p)) p++; if (*p == '*' || *p == '-') { p++; continue; } if (*p == '/') { div++; p++; continue; } if (*p == '(') { par++; p++; continue; } if (*p == ')') { if (!par--) return NULL; if (div) div--; p++; continue; } n = 0; while (*p && isalpha (*p)) { if (n < 32) name[n++] = tolower (*p); p++; } if (!n) break; name[n] = 0; for (n = 0; n < NUM_UNITSPEC; n++) { if (name[0] == unitspec[n].name[0]) break; } us = NULL; while (n < NUM_UNITSPEC) { if (name[0] != unitspec[n].name[0]) break; if (!strncmp (name, unitspec[n].name, strlen(unitspec[n].name))) { us = &unitspec[n]; break; } n++; } if (us == NULL) return NULL; while (*p && isspace (*p)) p++; if (*p == '^') { if (1 != sscanf (++p, "%f%n", &exp, &n)) return NULL; for (p += n; *p && isspace(*p); p++) ; } else exp = 1.0; units.units[us->type] = us->value; if (div) { units.exps[us->type] -= exp; if (*p != '-' && div > par) div--; } else units.exps[us->type] += exp; } u = (Units *) malloc (sizeof(Units)); if (u == NULL) cgnsCalcFatal ("malloc failed for unit specification"); for (n = 0; n < 5; n++) { u->units[n] = units.units[n]; u->exps[n] = units.exps[n]; } *pp = p; return u; } /*---------- free_all ---------------------------------------------- * free all data *------------------------------------------------------------------*/ static void free_all (void) { int n; if (NumReference) { for (n = 0; n < NumReference; n++) vec_destroy (reference[n].vd); free (reference); NumReference = 0; } if (NumCoordinates) { for (n = 0; n < NumCoordinates; n++) vec_destroy (coordinates[n].vd); free (coordinates); NumCoordinates = 0; } if (NumVariables) { for (n = 0; n < NumVariables; n++) vec_destroy (variables[n].vd); free (variables); NumVariables = 0; } } /*---------- cgnsCalcFatal ----------------------------------------- * terminate with error message *------------------------------------------------------------------*/ void cgnsCalcFatal (char *errmsg) { cgnsCalcDone (); if (NULL != errmsg && *errmsg) { if (NULL == vec_errhandler) print_error (-1, errmsg, 0, NULL); else (*vec_errhandler) (-1, errmsg, 0, NULL); } exit (-1); } /*---------- cgnsCalcError ----------------------------------------- * print error message *------------------------------------------------------------------*/ void cgnsCalcError (char *errmsg) { if (NULL != errmsg && *errmsg) { if (NULL == vec_errhandler) print_error (0, errmsg, 0, NULL); else (*vec_errhandler) (0, errmsg, 0, NULL); } } /*---------- cgnsCalcReset ----------------------------------------- * reset calculator (symbol table) *------------------------------------------------------------------*/ void cgnsCalcReset (void) { sym_free (); #ifdef EXTERN_FUNCS add_funcs (); #endif VectorLen = 100; } /*---------- cgnsCalcInit ------------------------------------------ * load CGNS file and initialize *------------------------------------------------------------------*/ int cgnsCalcInit (char *cgnsfile, int modify, void (*errhandler)(int,char *,int,char *)) { cgnsCalcDone (); /* set up error handler */ if (NULL == errhandler) vec_errhandler = print_error; else vec_errhandler = errhandler; /* callback to delete unit data */ sym_delfunc = delete_units; /* open CGNS file */ if (modify) { if (cg_open (cgnsfile, CG_MODE_MODIFY, &cgnsFile)) cgnsCalcFatal ("couldn't open file in modify mode"); } else { if (cg_open (cgnsfile, CG_MODE_READ, &cgnsFile)) cgnsCalcFatal ("couldn't open file in read mode"); } if (cg_nbases (cgnsFile, &NumBases)) cgnsCalcFatal ((char *)cg_get_error()); if (NumBases < 1) cgnsCalcFatal ("no bases found in CGNS file"); cgnsCalcBase (1); /* return number of bases */ return NumBases; } /*---------- cgnsCalcDone ------------------------------------------ * close CGNS file *------------------------------------------------------------------*/ void cgnsCalcDone (void) { if (cgnsFile) { cg_close (cgnsFile); cgnsFile = 0; } free_all (); cgnsBase = NumBases = 0; cgnsZone = NumZones = 0; cgnsSoln = NumSolns = 0; } /*---------- cgnsCalcBase ------------------------------------------ * set base for calculations *------------------------------------------------------------------*/ int cgnsCalcBase (int base) { if (base < 1 || base > NumBases) cgnsCalcFatal ("invalid base specified"); if (cg_base_read (cgnsFile, base, BaseName, &CellDim, &PhyDim)) cgnsCalcFatal ((char *)cg_get_error()); free_all (); cgnsBase = base; cgnsZone = NumZones = 0; cgnsSoln = NumSolns = 0; /* read base class and units */ if (cg_goto (cgnsFile, cgnsBase, "end")) cgnsCalcFatal ((char *)cg_get_error()); if (cg_dataclass_read ((CGNS_ENUMT(DataClass_t) *)&BaseClass)) BaseClass = 0; read_units (BaseUnits); /* read reference conditions */ read_reference (); /* get number of zones and initilize */ if (cg_nzones (cgnsFile, cgnsBase, &NumZones)) cgnsCalcFatal ((char *)cg_get_error()); if (NumZones) cgnsCalcZone (1); return NumZones; } /*---------- cgnsCalcZone ------------------------------------------ * set zone for calculations *------------------------------------------------------------------*/ int cgnsCalcZone (int zone) { int n, nc, size = 1; cgsize_t dims[9]; CGNS_ENUMT(DataType_t) datatype; char name[33]; if (zone < 1 || zone > NumZones) cgnsCalcFatal ("invalid zone specified"); if (cg_zone_read (cgnsFile, cgnsBase, zone, ZoneName, dims) || cg_zone_type (cgnsFile, cgnsBase, zone, (CGNS_ENUMT(ZoneType_t) *)&ZoneType)) cgnsCalcFatal ((char *)cg_get_error()); cgnsZone = zone; cgnsSoln = NumSolns = 0; for (n = 0; n < 6; n++) ZoneDims[n] = 1; if (ZoneType == CGNS_ENUMV(Structured)) { for (n = 0; n < CellDim; n++) { ZoneDims[n] = dims[n]; ZoneDims[n+3] = dims[n+CellDim]; size *= dims[n]; } } else if (ZoneType == CGNS_ENUMV(Unstructured)) { ZoneDims[0] = dims[0]; ZoneDims[3] = dims[1]; size = dims[0]; } else cgnsCalcFatal ("invalid zone type"); VectorLen = size; /* free-up previous data */ if (NumCoordinates) { for (n = 0; n < NumCoordinates; n++) vec_destroy (coordinates[n].vd); free (coordinates); NumCoordinates = 0; } if (NumVariables) { for (n = 0; n < NumVariables; n++) vec_destroy (variables[n].vd); free (variables); NumVariables = 0; } /* read zone class and units */ if (cg_goto (cgnsFile, cgnsBase, "Zone_t", cgnsZone, "end")) cgnsCalcFatal ((char *)cg_get_error()); if (cg_dataclass_read ((CGNS_ENUMT(DataClass_t) *)&ZoneClass)) ZoneClass = BaseClass; if (!read_units (ZoneUnits)) { for (n = 0; n < 5; n++) ZoneUnits[n] = BaseUnits[n]; } GridClass = ZoneClass; for (n = 0; n < 5; n++) GridUnits[n] = ZoneUnits[n]; /* get coordinate info */ if (cg_ncoords (cgnsFile, cgnsBase, cgnsZone, &nc)) cgnsCalcFatal ((char *)cg_get_error()); if (nc > 0) { /* read grid class and units */ if (cg_goto (cgnsFile, cgnsBase, "Zone_t", cgnsZone, "GridCoordinates_t", 1, "end")) cgnsCalcFatal ((char *)cg_get_error()); if (cg_dataclass_read ((CGNS_ENUMT(DataClass_t) *)&GridClass)) GridClass = ZoneClass; if (!read_units (GridUnits)) { for (n = 0; n < 5; n++) GridUnits[n] = ZoneUnits[n]; } /* read coordinates */ NumCoordinates = nc; coordinates = (Variable *) malloc (NumCoordinates * sizeof(Variable)); if (NULL == coordinates) cgnsCalcFatal ("malloc failed for coordinate info"); for (n = 0; n < NumCoordinates; n++) { if (cg_coord_info (cgnsFile, cgnsBase, cgnsZone, n+1, &datatype, name)) cgnsCalcFatal ((char *)cg_get_error()); strcpy (coordinates[n].name, name); coordinates[n].type = 1; coordinates[n].id = n + 1; coordinates[n].len = size; coordinates[n].valid = 1; coordinates[n].datatype = datatype; if (cg_goto (cgnsFile, cgnsBase, "Zone_t", cgnsZone, "GridCoordinates_t", 1, "DataArray_t", n+1, "end")) cgnsCalcFatal ((char *)cg_get_error()); read_class (&coordinates[n], GridClass, GridUnits); coordinates[n].vd = NULL; } } /* get number of solutions and initilize */ if (cg_nsols (cgnsFile, cgnsBase, cgnsZone, &NumSolns)) cgnsCalcFatal ((char *)cg_get_error()); if (NumSolns) cgnsCalcSoln (1); return NumSolns; } /*---------- cgnsCalcSoln ------------------------------------------ * set solution for calculations *------------------------------------------------------------------*/ int cgnsCalcSoln (int soln) { int i, n, size, nflds; CGNS_ENUMT(DataType_t) datatype; char name[33]; if (soln < 1 || soln > NumSolns) cgnsCalcFatal ("invalid solution specified"); if (cg_sol_info (cgnsFile, cgnsBase, cgnsZone, soln, SolnName, (CGNS_ENUMT(GridLocation_t) *)&SolnLocation)) cgnsCalcFatal ((char *)cg_get_error()); cgnsSoln = soln; for (n = 0; n < 3; n++) SolnDims[n] = 1; if (ZoneType == CGNS_ENUMV(Structured)) { size = 1; if (SolnLocation == CGNS_ENUMV(CellCenter)) { if (cg_goto (cgnsFile, cgnsBase, "Zone_t", cgnsZone, "FlowSolution_t", cgnsSoln, "end")) cgnsCalcFatal ((char *)cg_get_error()); if (cg_rind_read (SolnRind)) { for (n = 0; n < 6; n++) SolnRind[n] = 0; } for (i = 0, n = 0; n < CellDim; n++, i += 2) { SolnDims[n] = ZoneDims[n] - 1 + SolnRind[i] + SolnRind[i+1]; size *= SolnDims[n]; } } else { for (n = 0; n < 6; n++) SolnRind[n] = 0; for (n = 0; n < CellDim; n++) { SolnDims[n] = ZoneDims[n]; size *= SolnDims[n]; } } } else { for (n = 0; n < 6; n++) SolnRind[n] = 0; size = SolnLocation == CGNS_ENUMV(CellCenter) ? ZoneDims[3] : ZoneDims[0]; SolnDims[0] = size; } VectorLen = size; /* free-up previous data */ if (NumVariables) { for (n = 0; n < NumVariables; n++) vec_destroy (variables[n].vd); free (variables); NumVariables = 0; } /* read solution class and units */ if (cg_goto (cgnsFile, cgnsBase, "Zone_t", cgnsZone, "FlowSolution_t", cgnsSoln, "end")) cgnsCalcFatal ((char *)cg_get_error()); if (cg_dataclass_read ((CGNS_ENUMT(DataClass_t) *)&SolnClass)) SolnClass = ZoneClass; if (!read_units (SolnUnits)) { for (n = 0; n < 5; n++) SolnUnits[n] = ZoneUnits[n]; } /* get field info */ if (cg_nfields (cgnsFile, cgnsBase, cgnsZone, cgnsSoln, &nflds)) cgnsCalcFatal ((char *)cg_get_error()); if (nflds > 0) { NumVariables = nflds; variables = (Variable *) malloc (NumVariables * sizeof(Variable)); if (NULL == variables) cgnsCalcFatal ("malloc failed for field info"); for (n = 0; n < NumVariables; n++) { if (cg_field_info (cgnsFile, cgnsBase, cgnsZone, cgnsSoln, n+1, &datatype, name)) cgnsCalcFatal ((char *)cg_get_error()); strcpy (variables[n].name, name); variables[n].type = 2; variables[n].id = n + 1; variables[n].len = size; variables[n].valid = 1; variables[n].datatype = datatype; if (cg_goto (cgnsFile, cgnsBase, "Zone_t", cgnsZone, "FlowSolution_t", cgnsSoln, "DataArray_t", n+1, "end")) cgnsCalcFatal ((char *)cg_get_error()); read_class (&variables[n], SolnClass, SolnUnits); variables[n].vd = NULL; } } return NumVariables; } /*---------- cgnsCalcCheck ----------------------------------------- * check expression *------------------------------------------------------------------*/ int cgnsCalcCheck (char *expression) { int length = (int)strlen (expression); char *p, *cmd, *name; Units *units; if (length > cmdstrlen) { if (cmdstrlen == 0) { cmdstrlen = length > 256 ? length : 256; cmdstr = (char *) malloc (cmdstrlen + 1); } else { cmdstrlen = length + 32; cmdstr = (char *) realloc (cmdstr, cmdstrlen + 1); } if (cmdstr == NULL) cgnsCalcFatal ("malloc failed for cmdstr"); } cmd = strcpy (cmdstr, expression); for (p = cmd + strlen(cmd) - 1; p >= cmd && isspace(*p); p--) ; *++p = 0; while (*cmd && isspace(*cmd)) cmd++; if (!*cmd) return (0); p = cmd; if ((name = get_name (&p)) != NULL) { int nargs = -1; char *equ; for (equ = p; *equ && isspace(*equ); equ++) ; /* check for units */ if ('[' == *equ) { equ++; units = parse_units (&equ); if (units == NULL || *equ != ']') { cgnsCalcError ("bad units specification"); if (units != NULL) free (units); return 0; } free (units); while (*++equ && isspace (*equ)) ; if (!*equ) { if (find_symbol (name, 0) != NULL) return 1; } } /* check for equation */ if ('(' == *equ) { char *arg = equ; while (*++arg && (isspace (*arg) || isdigit(*arg))) ; if (')' == *arg) { nargs = atoi (equ + 1); for (equ = arg+1; *equ && isspace (*equ); equ++) ; } } if ('=' == *equ && '=' != *++equ) { for (cmd = equ; *cmd && isspace(*cmd); cmd++) ; if (nargs > 9) { cgnsCalcError ("invalid number of equation arguments"); return 0; } } } return vec_check (cmd, VectorLen, callback); } /*---------- cgnsCalcCommand --------------------------------------- * parse expression and return results *------------------------------------------------------------------*/ VECSYM *cgnsCalcCommand (char *expression) { int n, length = (int)strlen (expression); char *p, *cmd, *name, sym[SYMNAME_MAXLEN+1]; VECDATA *vd; Units *units = NULL; if (length > cmdstrlen) { if (cmdstrlen == 0) { cmdstrlen = length > 256 ? length : 256; cmdstr = (char *) malloc (cmdstrlen + 1); } else { cmdstrlen = length + 32; cmdstr = (char *) realloc (cmdstr, cmdstrlen + 1); } if (cmdstr == NULL) cgnsCalcFatal ("malloc failed for cmdstr"); } cmd = strcpy (cmdstr, expression); /* skip leading and trailing space */ for (p = cmd + strlen(cmd) - 1; p >= cmd && isspace(*p); p--) ; *++p = 0; while (*cmd && isspace(*cmd)) cmd++; /* empty string */ if (!*cmd) return (NULL); /* check for defining a new symbol */ p = cmd; strcpy (sym, "_temp_"); if ((name = get_name (&p)) != NULL) { int nargs = -1; char *equ; for (equ = p; *equ && isspace(*equ); equ++) ; /* check for units */ if ('[' == *equ) { equ++; units = parse_units (&equ); if (units == NULL || *equ != ']') { cgnsCalcError ("bad units specification"); if (units != NULL) free (units); return (NULL); } while (*++equ && isspace (*equ)) ; if (!*equ) { VECSYM *symbol = find_symbol (name, 0); if (symbol != NULL) { if (vecsym_user(symbol) != NULL) free (vecsym_user(symbol)); vecsym_user(symbol) = units; return (symbol); } } } /* check for equation */ if ('(' == *equ) { char *arg = equ; while (*++arg && (isspace (*arg) || isdigit(*arg))) ; if (')' == *arg) { nargs = atoi (equ + 1); for (equ = arg+1; *equ && isspace (*equ); equ++) ; } } if ('=' == *equ && '=' != *++equ) { strcpy (sym, name); for (cmd = equ; *cmd && isspace(*cmd); cmd++) ; /* add equation as string */ if (nargs >= 0) { if (nargs > 9) { cgnsCalcError ("invalid number of equation arguments"); return (NULL); } n = sym_addequ (sym, nargs, cmd, units); if (n) { cgnsCalcError (sym_errmsg (n)); return (NULL); } return (find_symbol (sym, 1)); } } } vd = vec_parse (cmd, VectorLen, callback); if (NULL == vd) { if (NULL != units) free (units); return (NULL); } /* add to symbol table */ if (VEC_VALUE == vd->type) n = sym_addval (sym, vd->f.val, units); else n = sym_addvec (sym, vd->len, vd->f.vec, units); vec_destroy (vd); if (!n) return (find_symbol (sym, 0)); cgnsCalcError (sym_errmsg (n)); return (NULL); } /*---------- cgnsCalcVarGet ---------------------------------------- * return a variable *------------------------------------------------------------------*/ Variable *cgnsCalcVarGet (char *varname) { int n, type = 0; char *name = varname; if (name == NULL || !*name) return NULL; if (*name == '~' || *name == '\'') type = *name++; /* check for variable */ if (!type) { for (n = 0; n < NumVariables; n++) { if (0 == strcmp (variables[n].name, name)) return &variables[n]; } } /* check for grid coordinates */ if (type != '~') { for (n = 0; n < NumCoordinates; n++) { if (0 == strcmp (coordinates[n].name, name)) return &coordinates[n]; } } /* check for reference quantity */ if (type != '\'') { for (n = 0; n < NumReference; n++) { if (0 == strcmp (reference[n].name, name)) return &reference[n]; } } return NULL; } /*---------- cgnsCalcVarList --------------------------------------- * print variables *------------------------------------------------------------------*/ void cgnsCalcVarList (FILE *fp) { int n; if (NULL == fp) fp = stdout; if (NumReference) { fprintf (fp, "=== Reference ===\n"); for (n = 0; n < NumReference; n++) { if (reference[n].len > 1) fprintf (fp, "~%s[%d]\n", reference[n].name, reference[n].len); else fprintf (fp, "~%s\n", reference[n].name); } } if (NumCoordinates) { fprintf (fp, "=== Coordinates ===\n"); for (n = 0; n < NumCoordinates; n++) fprintf (fp, "'%s[%d]\n", coordinates[n].name, coordinates[n].len); } if (NumVariables) { fprintf (fp, "=== Solution ===\n"); for (n = 0; n < NumVariables; n++) fprintf (fp, "%s[%d]\n", variables[n].name, variables[n].len); } } /*---------- cgnsCalcSymList --------------------------------------- * print list of symbols *------------------------------------------------------------------*/ void cgnsCalcSymList (FILE *fp) { if (NULL == fp) fp = stdout; fprintf (fp, "=== Symbols ===\n"); sym_list (0, print_symbols, fp); } cgnslib_3.1.4/src/cgnstools/calclib/calc.h0000664000076400007640000000571712160605672015442 00000000000000#ifndef _CALC_H_ #define _CALC_H_ #include #include "vecsym.h" extern int cgnsFile; /*--- base data ---*/ extern int NumBases, cgnsBase; extern char BaseName[33]; extern int CellDim, PhyDim; extern int BaseClass, BaseUnits[5]; /*--- zone data ---*/ extern int NumZones, cgnsZone; extern char ZoneName[33]; extern int ZoneType, ZoneDims[6]; extern int ZoneClass, ZoneUnits[5]; extern int GridClass, GridUnits[5]; /*--- solution data ---*/ extern int NumSolns, cgnsSoln; extern char SolnName[33]; extern int SolnLocation; extern int SolnDims[3], SolnRind[6]; extern int SolnClass, SolnUnits[5]; /*--- solution field data ---*/ typedef struct { int units[5]; float exps[5]; } Units; typedef struct { char name[33]; int type; int id; int valid; int len; int datatype; int dataclass; int hasunits; int units[5]; int hasconv; double dataconv[2]; int hasexp; double exponent[5]; VECDATA *vd; } Variable; /*----- variables -----*/ extern Variable *variables; extern int NumVariables; /*----- reference conditions -----*/ extern Variable *reference; extern int NumReference; /*----- mesh -----*/ extern Variable *coordinates; extern int NumCoordinates; /*----- external functions -----*/ #ifdef EXTERN_FUNCS extern void add_funcs ( void ); #endif /*----- functions -----*/ void cgnsCalcFatal ( /* terminate with error message */ char *errmsg /* error message */ ); void cgnsCalcError ( /* print error message */ char *errmsg /* error message */ ); void cgnsCalcReset ( /* reset calculator (symbol table) */ void ); int cgnsCalcInit ( /* load CGNS file and initialize */ char *cgnsfile, /* CGNS file */ int modify, /* set for modify mode */ void (*errhandler)( /* calculator error callback */ int errnum, /* error number */ char *errmsg, /* error message */ int pos, /* location in string */ char *str /* string being parsed */ ) ); void cgnsCalcDone ( /* close CGNS file */ void ); int cgnsCalcBase ( /* set base for calculations */ int base /* base number */ ); int cgnsCalcZone ( /* set zone for calculations */ int zone /* zone number */ ); int cgnsCalcSoln ( /* set solution for calculations */ int soln /* solution number */ ); int cgnsCalcCheck ( /* parse command and check for errors */ char *expression /* expression to be parsed */ ); VECSYM *cgnsCalcCommand (/* parse command string and return results */ char *expression /* expression to be parsed */ ); Variable *cgnsCalcVarGet (/* return a variable */ char *varname ); void cgnsCalcVarList ( /* print variables */ FILE *fp /* output file (NULL gives stdout) */ ); void cgnsCalcSymList ( /* print list of symbols */ FILE *fp /* output file (NULL gives stdout) */ ); #endif /* _CALC_H_ */ cgnslib_3.1.4/src/cgnstools/calclib/CMakeLists.txt0000664000076400007640000000021412160605672017112 00000000000000########### # calclib # ########### set(calclib_FILES calc.c vec.c vecsym.c) add_library(calclib STATIC ${calclib_FILES}) # Add test cgnslib_3.1.4/src/cgnstools/common/0000775000076400007640000000000012160611175014327 500000000000000cgnslib_3.1.4/src/cgnstools/common/getargs.h0000664000076400007640000000115012160605672016056 00000000000000/* * getargs.h - include file for getargs.c */ #ifndef _GETARGS_H_ #define _GETARGS_H_ #ifdef __cplusplus extern "C" { #endif extern int argind; /* index into argv array */ extern int argerr; /* flag for printing errors */ extern char *argarg; /* pointer to argument string */ void print_usage ( char **usgmsg, /* usage message */ char *errmsg /* error message */ ); int getargs ( int argc, /* number of arguments */ char **argv, /* argument list */ char *ostr /* option list */ ); #ifdef __cplusplus } #endif #endif /* _GETARGS_H_ */ cgnslib_3.1.4/src/cgnstools/common/tree.tcl0000664000076400007640000004725312160605672015732 00000000000000 set _Tree(font) {Helvetica 10} set _Tree(maskdata) { #define mask_width 9 #define mask_height 9 static unsigned char mask_bits[] = { 0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, 0x01};} set _Tree(openbm) { #define open_width 9 #define open_height 9 static unsigned char open_bits[] = { 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff, 0x01};} set _Tree(closedbm) { #define closed_width 9 #define closed_height 9 static unsigned char closed_bits[] = { 0xff, 0x01, 0x01, 0x01, 0x11, 0x01, 0x11, 0x01, 0x7d, 0x01, 0x11, 0x01, 0x11, 0x01, 0x01, 0x01, 0xff, 0x01};} #----- create a new tree widget proc TreeCreate {w args} { global _Tree canvas $w bind $w "TreeDestroy $w" foreach i {sort icon tags selection selidx build list} { set _Tree($w:$i) {} } set _Tree($w:root) 0 set _Tree($w:open) 0 set _Tree($w:padx) 0 set _Tree($w:pady) 0 set _Tree($w:indent) 12 set _Tree($w:space) 17 set _Tree($w:lines) 1 set _Tree($w:fill) [$w cget -insertbackground] set _Tree($w:font) $_Tree(font) set _Tree($w:iconbg) "" image create bitmap _Tree($w:openbm) \ -maskdata $_Tree(maskdata) -data $_Tree(openbm) image create bitmap _Tree($w:closedbm) \ -maskdata $_Tree(maskdata) -data $_Tree(closedbm) eval TreeConfig $w $args } #----- configure tree widget proc TreeConfig {w args} { global _Tree set opts {} foreach {op val} $args { switch -glob -- $op { -padx {set _Tree($w:padx) $val} -pady {set _Tree($w:pady) $val} -fore* - -fg - -fill {set _Tree($w:fill) $val} -font {set _Tree($w:font) $val} -ind* {set _Tree($w:indent) $val} -spac* {set _Tree($w:space) $val} -sort {set _Tree($w:sort) $val} -icon - -imag* {set _Tree($w:icon) $val} -tag* {set _Tree($w:tags) $val} -open {set _Tree($w:open) $val} -lin* {set _Tree($w:lines) $val} -iconbg {set _Tree($w:iconbg) $val} default {lappend opts $op $val} } } eval $w config $opts set bg [$w cget -background] _Tree($w:openbm) configure -foreground $_Tree($w:fill) -background $bg _Tree($w:closedbm) configure -foreground $_Tree($w:fill) -background $bg Tree:buildwhenidle $w } #----- destroy the tree widget proc TreeDestroy {w} { global _Tree catch {destroy $w} image delete _Tree($w:openbm) _Tree($w:closedbm) foreach t [array names _Tree $w:*] { unset _Tree($t) } } #----- insert a new item in the tree proc TreeInsert {w v args} { global _Tree if {$v == "/"} { set _Tree($w:root) 1 } else { set dir [file dirname $v] set n [file tail $v] foreach {op arg} $args { switch -exact -- $op { -dir { set dir $arg set n $v if {$dir == "/"} { set v "/$n" } else { set v "$dir/$n" } } } } if {![info exists _Tree($w:$dir:open)]} { return -code error "parent item \"$dir\" is missing" } lappend _Tree($w:$dir:children) $n if {$_Tree($w:sort) != ""} { set _Tree($w:$dir:children) [eval lsort $_Tree($w:sort) \ {$_Tree($w:$dir:children)}] } } Tree:dfltconfig $w $v foreach {op val} $args { switch -glob -- $op { -fore* - -fg - -fill {set _Tree($w:$v:fill) $val} -font {set _Tree($w:$v:font) $val} -icon - -imag* {set _Tree($w:$v:icon) $val} -tag* {set _Tree($w:$v:tags) $val} -text {set _Tree($w:$v:text) $val} -open {set _Tree($w:$v:open) $val} -iconbg {set _Tree($w:$v:iconbg) $val} } } Tree:buildwhenidle $w } #----- delete item from the tree proc TreeDelete {w v} { global _Tree if {![info exists _Tree($w:$v:open)]} return if {$v == "/"} { foreach t [array names _Tree $w:*:*] { unset _Tree($t) } set _Tree($w:root) 0 set _Tree($w:selection) {} set _Tree($w:selidx) {} set _Tree($w:list) {} Tree:buildwhenidle $w return } foreach c $_Tree($w:$v:children) { catch {TreeDelete $w $v/$c} } foreach t [array names _Tree $w:$v:*] { unset _Tree($t) } set dir [file dirname $v] set n [file tail $v] set i [lsearch -exact $_Tree($w:$dir:children) $n] if {$i >= 0} { set _Tree($w:$dir:children) [lreplace $_Tree($w:$dir:children) $i $i] } if {$_Tree($w:selection) != "" && ![TreeExists $w $_Tree($w:selection)]} { set _Tree($w:selection) "" } Tree:buildwhenidle $w } #----- move/rename an item proc TreeMove {w vold vnew} { global _Tree if {![TreeExists $w $vold]} return set pold [file dirname $vold] set pnew [file dirname $vnew] if {$pnew == "."} { if {$vnew == [file tail $vold]} return } else { if {![TreeExists $w $pnew]} return } set n [lsearch -exact $_Tree($w:$pold:children) [file tail $vold]] if {$pnew == "."} { set _Tree($w:$pold:children) \ [lreplace $_Tree($w:$pold:children) $n $n $vnew] if {$pold == "/"} { set vnew "/$vnew" } else { set vnew "$pold/$vnew" } set pnew $pold } else { set _Tree($w:$pold:children) \ [lreplace $_Tree($w:$pold:children) $n $n] lappend _Tree($w:$pnew:children) [file tail $vnew] } if {$_Tree($w:sort) != ""} { set _Tree($w:$pnew:children) [eval lsort $_Tree($w:sort) \ {$_Tree($w:$pnew:children)}] } set n [string length "$w:$vold"] foreach told [array names _Tree "$w:$vold\[/:\]*"] { set _Tree($w:$vnew[string range $told $n end]) $_Tree($told) unset _Tree($told) } set _Tree($w:$vnew:text) [file tail $vnew] Tree:buildwhenidle $w } #----- check if item exists in tree proc TreeExists {w v} { global _Tree return [info exists _Tree($w:$v:open)] } #----- check if item is visible in tree proc TreeVisible {w v} { global _Tree if {$_Tree($w:build) != ""} { Tree:build $w } return [info exists _Tree($w:$v:tag)] } #----- set/get item proc TreeSet {w v args} { global _Tree if {![TreeExists $w $v]} return set redraw 0 foreach {op val} $args { switch -glob -- $op { -fore* - -fg - -fill {set tag fill} -font {set tag font} -icon - -imag* {set tag icon} -tag* {set tag tags} -open {set tag open} -iconbg {set tag iconbg} default {set tag ""} } if {$tag != ""} { if {$val == ""} {set val $_Tree($w:$tag)} if {$val != $_Tree($w:$v:$tag)} { incr redraw set _Tree($w:$v:$tag) $val } } } if {$redraw} { Tree:buildwhenidle $w } } proc TreeGet {w v op} { global _Tree if {[TreeExists $w $v]} { switch -glob -- $op { -fore* - -fg - -fill {return $_Tree($w:$v:fill)} -font {return $_Tree($w:$v:font)} -icon - -imag* {return $_Tree($w:$v:icon)} -tag* {return $_Tree($w:$v:tags)} -open {return $_Tree($w:$v:open)} -child* {return $_Tree($w:$v:children)} -iconbg {return $_Tree($w:$v:iconbg)} } } return "" } #----- open/close a branch of a tree proc TreeOpen {w v} { global _Tree if {[info exists _Tree($w:$v:open)] && !$_Tree($w:$v:open) && [llength $_Tree($w:$v:children)] > 0} { set _Tree($w:$v:open) 1 Tree:build $w } } proc TreeClose {w v} { global _Tree if {[info exists _Tree($w:$v:open)] && $_Tree($w:$v:open)} { set _Tree($w:$v:open) 0 Tree:build $w } } proc TreeToggle {w v} { global _Tree if {[info exists _Tree($w:$v:open)]} { if {$_Tree($w:$v:open)} { TreeClose $w $v } else { TreeOpen $w $v } } } #----- open/close one level below a branch proc TreeOpenLevel {w v} { global _Tree if {$v == "/"} { set cnt 0 foreach c $_Tree($w:$v:children) { incr cnt [Tree:openlevel $w "/$c"] } } else { set cnt [Tree:openlevel $w $v] } if $cnt { Tree:build $w } } proc TreeCloseLevel {w v} { global _Tree if {$v == "/"} { set cnt 0 foreach c $_Tree($w:$v:children) { incr cnt [Tree:closelevel $w "/$c"] } } else { set cnt [Tree:closelevel $w $v] } if $cnt { Tree:build $w } } #----- expand/collapse a branch of the tree proc TreeExpand {w v} { global _Tree if {$_Tree($w:root)} { Tree:setopen $w $v 1 Tree:build $w } } proc TreeCollapse {w v} { global _Tree if {$_Tree($w:root)} { Tree:setopen $w $v 0 Tree:build $w } } #----- set/get selection proc TreeSelectionSet {w v} { global _Tree if {[TreeExists $w $v]} { set _Tree($w:selection) $v } else { set _Tree($w:selection) "" } if {$_Tree($w:build) == ""} { Tree:drawselection $w } } proc TreeSelectionGet {w} { global _Tree return $_Tree($w:selection) } #----- get item at specified coordinates proc TreeAt {w x y} { global _Tree set x [$w canvasx $x] set y [$w canvasy $y] foreach m [$w find overlapping $x $y $x $y] { if {[info exists _Tree($w:tag:$m)]} { return $_Tree($w:tag:$m) } } return "" } proc TreeTypeAt {w x y} { global _Tree set x [$w canvasx $x] set y [$w canvasy $y] foreach m [$w find overlapping $x $y $x $y] { if {[info exists _Tree($w:tag:$m)]} { return [list [$w type $m] $_Tree($w:tag:$m)] } } return "" } #----- search for an item proc TreeFind {w v pat {case 0}} { global _Tree if {![TreeExists $w $v]} {return ""} if {$case} { set opts "" } else { set opts -nocase } if {$v == "/"} { return [Tree:match $w / 0 $pat $opts] } if {$_Tree($w:$v:children) != {}} { set node [Tree:match $w $v 0 $pat $opts] if {$node != ""} {return $node} } while {$v != "/"} { set parent [file dirname $v] set node [file tail $v] set n [lsearch -exact $_Tree($w:$parent:children) $node] if {$n >= 0} { incr n set node [Tree:match $w $parent $n $pat $opts] if {$node != ""} {return $node} } set v $parent } return "" } #----- force item to be visible proc TreeSee {w v} { global _Tree if {![info exists _Tree($w:$v:open)]} return set redraw 0 set node {} foreach p [split [file dirname $v] /] { if {$p != {}} { append node "/$p" if {!$_Tree($w:$node:open)} { set _Tree($w:$node:open) 1 incr redraw } } } if {$redraw || $_Tree($w:build) != ""} { Tree:build $w } set bb [$w cget -scrollregion] set wd [expr [lindex $bb 2] - [lindex $bb 0]] set ht [expr [lindex $bb 3] - [lindex $bb 1]] set bb [$w bbox $_Tree($w:$v:tag)] set yt [$w canvasy 0] set yb [$w canvasy [winfo height $w]] if {[expr [lindex $bb 1] <= $yt || [lindex $bb 3] >= $yb]} { set sr [$w yview] set ds [expr [lindex $sr 1] - [lindex $sr 0]] set yp [expr 0.5 * (double([lindex $bb 1] + [lindex $bb 3]) / \ double($ht) - $ds)] if {$yp < 0.0} {set yp 0.0} $w yview moveto $yp } set xl [$w canvasx 0] set xr [$w canvasx [winfo width $w]] if {[expr [lindex $bb 0] <= $xl || [lindex $bb 2] >= $xr]} { set sr [$w xview] set ds [expr [lindex $sr 1] - [lindex $sr 0]] set xp [expr 0.5 * (double([lindex $bb 0] + [lindex $bb 2]) / \ double($wd) - $ds)] if {$xp < 0.0} {set xp 0.0} $w xview moveto $xp } } #----- edit item proc TreeEdit {w v} { global _Tree if {![info exists _Tree($w:$v:open)]} return TreeSee $w $v set tag $_Tree($w:$v:tag) set coords [$w coords $tag] set x [lindex $coords 0] set y [lindex $coords 1] set fg $_Tree($w:$v:fill) set bg [$w cget -bg] set wd [expr {[winfo width $w] - [$w cget -bd] - \ [$w cget -highlightthickness]}] set wmax [expr {[$w canvasx $wd] - $x}] set _Tree($w:edit) [file tail $v] set selection [TreeSelectionGet $w] TreeSelectionSet $w "" $w itemconfigure $tag -fill $bg set frame [frame $w.edit -relief flat -bd 0 \ -highlightthickness 0 -bg $bg] set ent [entry $frame.ent -relief solid -bd 0 \ -highlightthickness 1 -fg $fg -bg $bg -width 0 \ -font [$w itemcget $tag -font] -textvariable _Tree($w:edit)] pack $ent -side left -anchor w -ipadx 5 bind $ent "set _Tree($w:done) 0" bind $ent "set _Tree($w:done) 1" set id [$w create window $x $y -window $frame -anchor w] trace variable _Tree($w:edit) w "Tree:edit_size $w $ent $id $wmax" set oldFocus [focus] set oldGrab [grab current $w] if {$oldGrab != ""} { set grabStatus [grab status $oldGrab] } catch {grab $frame} tkwait visibility $ent focus $ent $ent selection range 0 end $ent icursor end $ent xview end tkwait variable _Tree($w:done) trace vdelete _Tree($w:edit) w "Tree:edit_size $w $ent $id $wmax" catch {focus $oldFocus} if {$oldGrab != ""} { if {$grabStatus == "global"} { grab -global $oldGrab } else { grab $oldGrab } } destroy $frame $w delete $id $w itemconfigure $tag -fill $fg TreeSelectionSet $w $selection if {$_Tree($w:done)} { return $_Tree($w:edit) } return "" } #----- get next/previous visible item proc TreeNext {w v} { global _Tree if {![TreeVisible $w $v]} {return ""} set n [lsearch -exact $_Tree($w:list) $_Tree($w:$v:tag)] if {$n < 0} {return ""} incr n if {$n == [llength $_Tree($w:list)]} {set n 0} return $_Tree($w:tag:[lindex $_Tree($w:list) $n]) } proc TreePrev {w v} { global _Tree if {![TreeVisible $w $v]} {return ""} set n [lsearch -exact $_Tree($w:list) $_Tree($w:$v:tag)] if {$n < 0} {return ""} incr n -1 if {$n < 0} { set n [expr [llength $_Tree($w:list)] - 1] } return $_Tree($w:tag:[lindex $_Tree($w:list) $n]) } #---------------------------------------------------------------- # these are for internal use only #---------------------------------------------------------------- proc Tree:dfltconfig {w v} { global _Tree set _Tree($w:$v:children) {} if {![info exists _Tree($w:$v:open)]} { set _Tree($w:$v:open) $_Tree($w:open) } foreach i {fill font icon tags iconbg} { set _Tree($w:$v:$i) $_Tree($w:$i) } if {$v == "/"} { set _Tree($w:$v:text) $v } else { set _Tree($w:$v:text) [file tail $v] } } proc Tree:buildwhenidle {w} { global _Tree if {$_Tree($w:build) == ""} { set _Tree($w:build) [after idle "Tree:build $w"] } } proc Tree:build {w} { global _Tree if {$_Tree($w:build) != ""} { catch {after cancel $_Tree($w:build)} set _Tree($w:build) "" } $w delete all foreach t [array names _Tree $w:*:tag] { unset _Tree($t) } set _Tree($w:list) {} if {!$_Tree($w:root)} return set icon $_Tree($w:/:icon) set taglist x foreach tag $_Tree($w:/:tags) { lappend taglist $tag } set x 5 set y 5 if {$icon != ""} { set k [$w create image $x $y -image $icon -anchor w -tags $taglist] incr x 20 set _Tree($w:tag:$k) / } set j [$w create text $x $y -text $_Tree($w:/:text) \ -font $_Tree($w:/:font) -fill $_Tree($w:/:fill) \ -anchor w -tags $taglist] lappend _Tree($w:list) $j set _Tree($w:tag:$j) / set _Tree($w:/:tag) $j set _Tree($w:y) [expr $y + 17] Tree:buildlayer $w / $_Tree($w:indent) set bb [$w bbox all] $w config -scrollregion [list [expr [lindex $bb 0] - 5] \ [expr [lindex $bb 1] - 5] [expr [lindex $bb 2] + 5] \ [expr [lindex $bb 3] + 5]] Tree:drawselection $w } proc Tree:buildlayer {w v in} { global _Tree if {$v=="/"} { set vx {} } else { set vx $v } set start [expr $_Tree($w:y)-10] set y $start foreach c $_Tree($w:$v:children) { set y $_Tree($w:y) incr _Tree($w:y) 17 if {$_Tree($w:lines)} { $w create line $in $y [expr $in+10] $y -fill $_Tree($w:fill) } set icon $_Tree($w:$vx/$c:icon) set taglist x foreach tag $_Tree($w:$vx/$c:tags) { lappend taglist $tag } set x [expr $in+12] if {$icon != ""} { set k [$w create image $x $y -image $icon -anchor w -tags $taglist] incr x [image width $icon] if {$_Tree($w:$vx/$c:iconbg) != ""} { set bb [$w bbox $k] set r [$w create rectangle $bb -fill $_Tree($w:$vx/$c:iconbg) -outline ""] $w lower $r } set _Tree($w:tag:$k) $vx/$c } incr x $_Tree($w:padx) set j [$w create text $x $y -text $_Tree($w:$vx/$c:text) \ -font $_Tree($w:$vx/$c:font) -fill $_Tree($w:$vx/$c:fill) \ -anchor w -tags $taglist] lappend _Tree($w:list) $j set _Tree($w:tag:$j) $vx/$c set _Tree($w:$vx/$c:tag) $j if {[string length $_Tree($w:$vx/$c:children)]} { if {$_Tree($w:$vx/$c:open)} { set j [$w create image $in $y -image _Tree($w:openbm)] Tree:buildlayer $w $vx/$c [expr $in+$_Tree($w:indent)] } else { set j [$w create image $in $y -image _Tree($w:closedbm)] } $w bind $j <1> "TreeToggle $w {$vx/$c}" } else { set _Tree($w:$vx/$c:open) 0 } } if {$_Tree($w:lines)} { set j [$w create line $in $start $in [expr $y+1] -fill $_Tree($w:fill)] $w lower $j } } proc Tree:setopen {w v open} { global _Tree if {[info exists _Tree($w:$v:children)] && [string length $_Tree($w:$v:children)]>0} { set _Tree($w:$v:open) $open if {$v=="/"} { set vx {} } else { set vx $v } foreach c $_Tree($w:$v:children) { Tree:setopen $w $vx/$c $open } } } proc Tree:openlevel {w v} { global _Tree set cnt 0 if {[info exists _Tree($w:$v:children)] && [llength $_Tree($w:$v:children)] > 0} { if {!$_Tree($w:$v:open)} { set _Tree($w:$v:open) 1 incr cnt } else { foreach c $_Tree($w:$v:children) { incr cnt [Tree:openlevel $w "$v/$c"] } } } return $cnt } proc Tree:closelevel {w v} { global _Tree set cnt 0 if {[info exists _Tree($w:$v:children)] && [llength $_Tree($w:$v:children)] > 0 && $_Tree($w:$v:open)} { foreach c $_Tree($w:$v:children) { if {$_Tree($w:$v/$c:open)} { incr cnt [Tree:closelevel $w "$v/$c"] } } if !$cnt { set _Tree($w:$v:open) 0 incr cnt } } return $cnt } proc Tree:drawselection {w} { global _Tree set selfg [$w cget -selectforeground] set selbg [$w cget -selectbackground] if {[string length $_Tree($w:selidx)]} { set id [$w find withtag sel] if {$id != ""} { set tag [lindex [$w gettags $id] 1] if {[info exists _Tree($w:tag:$tag)]} { set v $_Tree($w:tag:$tag) $w itemconfigure $tag -fill $_Tree($w:$v:fill) } } $w delete $_Tree($w:selidx) } set v $_Tree($w:selection) if {![string length $v] ||![info exists _Tree($w:$v:tag)]} return set bbox [$w bbox $_Tree($w:$v:tag)] if {[llength $bbox]==4} { set tag $_Tree($w:$v:tag) $w itemconfigure $tag -fill $selfg set i [eval $w create rectangle $bbox -fill $selbg \ -outline $selbg -tags [list "sel $tag"]] set _Tree($w:selidx) $i $w lower $i } else { set _Tree($w:selidx) {} } } proc Tree:match {w v n pat args} { global _Tree if {$v == "/"} { set vx "" } else { set vx $v } set len [llength $_Tree($w:$v:children)] while {$n < $len} { set c [lindex $_Tree($w:$v:children) $n] if {[eval string match $args {$pat} {$c}] || [eval string match $args {$pat} {$vx/$c}]} {return "$vx/$c"} set node [Tree:match $w "$vx/$c" 0 $pat $args] if {$node != ""} {return $node} incr n } return "" } proc Tree:edit_size {path entry id wmax args} { set entw [winfo reqwidth $entry] if {$entw + 5 >= $wmax} { $path itemconfigure $id -width $wmax } else { $path itemconfigure $id -width 0 } } cgnslib_3.1.4/src/cgnstools/common/cgns-mask.xbm0000664000076400007640000000157012160605672016652 00000000000000#define cgnsmask_width 32 #define cgnsmask_height 32 static char cgnsmask_bits[] = { 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, 0x7d, 0x00, 0x00, 0xff, 0xe7, 0x01, 0x00, 0xff, 0x9f, 0x07, 0x00, 0x3e, 0x7f, 0x0e, 0x00, 0x3e, 0xf3, 0x18, 0x00, 0x3c, 0xce, 0x33, 0x00, 0x38, 0xb6, 0x67, 0x00, 0x38, 0xc6, 0xce, 0x00, 0x70, 0x8a, 0x9d, 0x01, 0xe0, 0x04, 0x3f, 0x03, 0xc0, 0x09, 0xfe, 0x06, 0x82, 0x03, 0xfc, 0x0f, 0x04, 0x07, 0x78, 0x1f, 0x08, 0x1e, 0xf8, 0x1e, 0x30, 0xf8, 0xf8, 0x3e, 0x64, 0xe0, 0xff, 0x3c, 0xd8, 0x81, 0x7f, 0x3c, 0xb0, 0x07, 0x3e, 0x7c, 0xe0, 0x1f, 0x00, 0x7e, 0xc0, 0x3f, 0x00, 0x7f, 0x80, 0xff, 0xff, 0x7f, 0x00, 0xfe, 0xff, 0x7f, 0x00, 0xfc, 0xff, 0x7f, 0x00, 0xf0, 0xff, 0x7f, 0x00, 0xc0, 0xff, 0x7f, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00}; cgnslib_3.1.4/src/cgnstools/common/cgns-icon.xbm0000664000076400007640000000157012160605672016647 00000000000000#define cgnsicon_width 32 #define cgnsicon_height 32 static char cgnsicon_bits[] = { 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0xff, 0x7c, 0x00, 0x00, 0x3f, 0xe0, 0x01, 0x00, 0x1f, 0x86, 0x07, 0x00, 0x1e, 0x1f, 0x0e, 0x00, 0x1e, 0x73, 0x18, 0x00, 0x1c, 0xc2, 0x31, 0x00, 0x38, 0x86, 0x63, 0x00, 0x38, 0x04, 0xc6, 0x00, 0x70, 0x08, 0x8c, 0x01, 0xe0, 0x00, 0x1c, 0x03, 0xc0, 0x01, 0x38, 0x06, 0x82, 0x03, 0x70, 0x0e, 0x04, 0x07, 0x70, 0x1c, 0x08, 0x1e, 0xf0, 0x1c, 0x30, 0xf8, 0xf8, 0x3c, 0x60, 0xe0, 0xff, 0x3c, 0xc0, 0x81, 0x7f, 0x3c, 0x80, 0x07, 0x3e, 0x7c, 0x00, 0x1f, 0x00, 0x7e, 0x00, 0x3c, 0x00, 0x7f, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0xe0, 0xff, 0x7f, 0x00, 0xc0, 0xff, 0x3f, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; cgnslib_3.1.4/src/cgnstools/common/config.tcl0000664000076400007640000002057612160605672016237 00000000000000#--- configure for default fonts foreach type {normal italic bold fixed large} { set Font($type) "" } #----- init fonts and colors proc do_config {args} { global argc argv bgColor tkPalette tk_strictMotif UseNativeDialogs set config "" set proc "" set fg "" set bg "" set native 0 set fonts 0 set motif 0 set focus 0 if {$argc} { eval lappend args $argv } set len [llength $args] if {$len} { for {set n 0} {$n < $len} {incr n} { set arg [string tolower [lindex $args $n]] if [string match "-con*" $arg] { incr n if {$n < $len} { set config [lindex $args $n] } } elseif [string match "-win*" $arg] { set proc setup_windows set config "" } elseif [string match "-def*" $arg] { set proc config_init set config "" } elseif [string match "-fon*" $arg] { set fonts 1 } elseif [string match "-nat*" $arg] { set native 1 } elseif [string match "-fgc*" $arg] { incr n if {$n < $len} { set fg [lindex $args $n] } } elseif [string match "-bgc*" $arg] { incr n if {$n < $len} { set bg [lindex $args $n] } } elseif [string match "-mot*" $arg] { set motif 1 } elseif [string match "-foc*" $arg] { set focus 1 } } } if {$config != "" && ![catch {option readfile $config}]} { set UseNativeDialogs 0 config_init if {$fonts} setup_fonts . configure -background $bgColor(normal) if {[option get . keyboardFocusPolicy TakeFocus] == "pointer"} { set focus 1 } } elseif {$proc != ""} { $proc } else { if {$bg != ""} { if {$fg == ""} { catch {tk_setPalette $bg} } else { catch {tk_setPalette background $bg foreground $fg} } option add *background $tkPalette(background) option add *foreground $tkPalette(foreground) . configure -background $tkPalette(background) } if {$fonts} setup_fonts config_init } if {$native} {set UseNativeDialogs 1} if {$motif} { set tk_strictMotif 1 set focus 0 } if {$focus} { if {[info commands tk_focusFollowsMouse] != ""} { tk_focusFollowsMouse } else { bind all {+focus %W} } } } proc setup_fonts {} { global Font tcl_platform if {$tcl_platform(platform) == "windows"} { set Font(normal) "Helvetica 8" set Font(italic) "Helvetica 8 italic" set Font(bold) "Helvetica 8 bold" set Font(fixed) "Courier 8" set Font(large) "Helvetica 10" } else { set Font(normal) "Helvetica -12" set Font(italic) "Helvetica -12 italic" set Font(bold) "Helvetica -12 bold" set Font(fixed) "Courier -12" set Font(large) "Helvetica -16" } option add *font $Font(normal) # option add *Entry.font $Font(fixed) # option add *Listbox.font $Font(fixed) # option add *Text.font $Font(fixed) } #--- setup colors for windows proc setup_windows {} { global UseNativeDialogs tcl_platform if {$tcl_platform(platform) == "windows"} { set UseNativeDialogs 1 option add *Listbox.background SystemWindow option add *Listbox.foreground SystemWindowText # option add *Canvas.background SystemWindow option add *Button.padY 0 } else { set UseNativeDialogs 0 tk_setPalette #C0C0C0 option add *selectBackground #00007F option add *selectForeground white option add *Text.background white option add *Entry.background white option add *Listbox.background white # option add *Canvas.background white } setup_fonts config_init } #--- get colors and fonts into globals proc config_init {} { global Font bgColor fgColor tcl_platform UseNativeDialogs checkbutton .configbutton text .configtext label .configlabel #--- background colors set bgColor(normal) [.configlabel cget -background] set bgColor(button) [.configbutton cget -background] set bgColor(text) [.configtext cget -background] set bgColor(active) [.configbutton cget -activebackground] set bgColor(highlight) [.configtext cget -highlightbackground] set bgColor(disabled) $bgColor(normal) set bgColor(select) [.configtext cget -selectbackground] set bgColor(indicator) [.configbutton cget -selectcolor] if {![info exists bgColor(canvas)]} { canvas .configcanvas set bgColor(canvas) [.configcanvas cget -background] destroy .configcanvas } #--- foreground colors set fgColor(normal) [.configlabel cget -foreground] set fgColor(button) [.configbutton cget -foreground] set fgColor(text) [.configtext cget -foreground] set fgColor(active) [.configbutton cget -activeforeground] set fgColor(highlight) [.configtext cget -highlightcolor] set fgColor(disabled) [.configbutton cget -disabledforeground] set fgColor(select) [.configtext cget -selectforeground] set fgColor(indicator) $bgColor(indicator) if {![info exists fgColor(canvas)]} { set mx [lindex [winfo rgb . white] 0] set bg [winfo rgb . $bgColor(canvas)] if [expr (0.3 * [lindex $bg 0] + 0.59 * [lindex $bg 1] + \ 0.11 * [lindex $bg 2]) >= (0.5 * $mx)] { set fgColor(canvas) black } else { set fgColor(canvas) white } } #--- fonts foreach type {normal fixed italic bold large} { if {$Font($type) == ""} { set font [option get . $type\Font Font] if {$font != ""} { if ![catch {button .fntbutton -font $font}] { set Font($type) $font } catch {destroy .fntbutton} } } } set font [.configlabel cget -font] set family [lindex $font 0] set size [lindex $font 1] if {$Font(normal) == ""} { set Font(normal) [list $family $size] } if {$Font(fixed) == ""} { set Font(fixed) [list Courier $size] } if {$Font(bold) == ""} { set Font(bold) [list $family $size bold] } if {$Font(italic) == ""} { set Font(italic) [list $family $size italic] } if {$Font(large) == ""} { if {$size < 0} { incr size -2 } else { incr size 2 } set Font(large) [list $family $size] } destroy .configbutton destroy .configtext destroy .configlabel if {![info exists UseNativeDialogs] || $UseNativeDialogs == ""} { if {$tcl_platform(platform) == "windows"} { set UseNativeDialogs 1 } else { set UseNativeDialogs 0 } } # needed for tcl 8.5 to prevent tristate behavior # when using "" as on/off value for chaeck/radio buttons catch { option add *Checkbutton.tristateValue "-----" option add *Radiobutton.tristateValue "-----" } } proc config_defaults {{native ""}} { global UseNativeDialogs tcl_platform bgColor fgColor set UseNativeDialogs $native setup_fonts config_init if {$tcl_platform(platform) == "windows"} { option add *Listbox.background $bgColor(text) option add *Listbox.foreground $fgColor(text) option add *Button.padX 0 option add *Button.padY 0 } else { set fgColor(text) $fgColor(highlight) set bgColor(text) $bgColor(highlight) option add *Text.background $bgColor(text) option add *Text.foreground $fgColor(text) option add *Text.insertBackground $fgColor(text) option add *Entry.background $bgColor(text) option add *Entry.foreground $fgColor(text) option add *Entry.insertBackground $fgColor(text) option add *Listbox.background $bgColor(text) option add *Listbox.foreground $fgColor(text) option add *Button.padX 3 option add *Button.padY 3 } option add *Canvas.background $bgColor(text) option add *Canvas.insertBackground $fgColor(text) option add *Canvas.selectBackground $bgColor(select) option add *Canvas.selectForeground $fgColor(select) # option add *Button.highlightThickness 0 } proc config_icon {w iconlist {pathlist .}} { global tcl_platform if {$tcl_platform(platform) == "windows" && [info commands LoadIcon] != ""} { foreach i $iconlist { foreach p $pathlist { if [file exists $p/$i.ico] { update idletasks LoadIcon @$p/$i.ico return } } } } foreach i $iconlist { foreach p $pathlist { if [file exists $p/$i-icon.xbm] { wm iconbitmap $w @$p/$i-icon.xbm if [file exists $p/$i-mask.xbm] { wm iconmask $w @$p/$i-mask.xbm } return } if [file exists $p/$i.xbm] { wm iconbitmap $w @$p/$i.xbm wm iconmask $w @$p/$i.xbm return } } } } cgnslib_3.1.4/src/cgnstools/common/cgns.ico0000664000076400007640000000206612160605672015706 00000000000000 è&(( @€€€€€€€€€€ÀÀÀ€€€ÿÿ!Îÿÿÿÿÿÿÿÿÿ33330333333333;»»»»³033»»»»»»»³33»»»»»»»»»3;»»»»»»»»»3;»»»»»»»»»»33»»33»»»»3»»°33330 »»°3 »°33;»»3»»°0»°3 »»»³»»0 °3 »»»»»»»»3;»»»»»»»° 0»°»»»3»°tD@D@D´KDD D´@DCD´C;´@3D·DDCDDK´D;D@DsDDKD3»´D@DKD´KD@;»3»» °;»°3;»°»3»° 333»° °;»³ 33 »»;»³;»»0»°»»³3»»³ °»»»333 »»»»»3»»°»»»»»»° »»»»°»»»ÿÿÿÿÿÿàÿÿÿüÿðÿÀÿ€þüƒøòÁäbÃÙˆƒó‡îGÀÜ@¸ð0à“?À‡Âü ÿ‚pÿgÿÏÿÁÿÿÿÿÿÿÿÿ€ÿÿÀÿÿÿÿÿÿÿ( À€€€€€€€€€ÀÀÀ€€€ÿÿ!Îÿÿÿÿÿÿÿÿÿ33303»»»3»»»»»;°»»°30 » ;»³»;»»»» Ì¼Ì ¼ Ì ; ̼ ; ¼< Ì Ì<¼<̰ 3»°;° »;;³3°»»33» »»»ÿüøñðæèð€ˆŠˆ‹ƒˆ˜'Ï?€ÿcgnslib_3.1.4/src/cgnstools/common/getargs.c0000664000076400007640000000501612160605672016056 00000000000000#include #include #include #include #include "getargs.h" /*---------- usage -------------------------------------------------- * display usage message and exit *-------------------------------------------------------------------*/ void print_usage (char **usgmsg, char *errmsg) { int n; if (NULL != errmsg) fprintf (stderr, "ERROR: %s\n", errmsg); for (n = 0; NULL != usgmsg[n]; n++) fprintf (stderr, "%s\n", usgmsg[n]); exit (NULL != errmsg); } /*---------- getargs --------------------------------------------------- * get option letter from argument vector or terminates on error * this is similar to getopt() *----------------------------------------------------------------------*/ int argind = 0; /* index into argv array */ int argerr = 1; /* error output flag */ char *argarg; /* pointer to argument string */ int getargs (int argc, char **argv, char *ostr) { int argopt; char *oli; static char *place; static int nextarg; /* initialization */ if (!argind) nextarg = 1; if (nextarg) { /* update scanning pointer */ if (argind >= argc || ++argind == argc) { argarg = NULL; return (-1); } if ('-' != argv[argind][0]) { argarg = argv[argind]; return (0); } place = argarg = &argv[argind][1]; if (!*place) { if (++argind == argc) { argarg = NULL; return (-1); } argarg = argv[argind]; return (0); } nextarg = 0; } /* check for valid option */ if ((argopt = *place++) == ':' || argopt == ';' || (oli = strchr (ostr, argopt)) == NULL) { if (argerr) { fprintf (stderr, "invalid option - `%c'\n", argopt); exit (-1); } return (argopt); } /* don't need argument */ if (*++oli != ':') { if (*place && *oli == ';') { /* optional argument */ argarg = place; nextarg = 1; } else { argarg = NULL; if (!*place) nextarg = 1; } return (argopt); } /* get argument */ if (!*place) { if (++argind >= argc) { if (!argerr) return (':'); fprintf (stderr, "missing argument for option `%c'\n", argopt); exit (1); } place = argv[argind]; } argarg = place; nextarg = 1; return (argopt); } cgnslib_3.1.4/src/cgnstools/common/menubar.tcl0000664000076400007640000000655412160605672016423 00000000000000set _MenuData(next) 0 proc menubar_create {menulist {top .}} { global _MenuData tcl_platform bgColor if {$top == "." || $top == ""} { set mw .menubar set ms .menusep } else { set mw $top.menubar set ms $top.menusep } set _MenuData(menu) $mw set _MenuData(list) "" if {$tcl_platform(platform) == "windows"} { menu $mw -tearoff 0 -relief flat -type menubar foreach j $menulist { set i [string tolower $j] lappend _MenuData(list) $i set m m$_MenuData(next) incr _MenuData(next) $mw add cascade -label $j -menu $mw.$m -underline 0 menu $mw.$m -tearoff 0 set _MenuData($i,menu) $mw.$m } . configure -menu $mw } else { frame $mw -relief flat -bg $bgColor(button) pack $mw -side top -fill x foreach j $menulist { set i [string tolower $j] lappend _MenuData(list) $i set m m$_MenuData(next) incr _MenuData(next) menubutton $mw.$m -text $j -menu $mw.$m.menu -pady 0 \ -highlightthickness 0 -underline 0 pack $mw.$m -side left -padx 5 menu $mw.$m.menu -tearoff 0 set _MenuData($i,menu) $mw.$m.menu } } frame $ms -bd 1 -height 2 -relief sunken pack $ms -side top -fill x } proc menubar_add {menu {before ""}} { global tcl_platform _MenuData bgColor set i [string tolower $menu] if {[info exists _MenuData($i,menu)]} { return $_MenuData($i,menu) } set where "" if {$before != ""} { set before [string tolower $before] set n [lsearch $_MenuData(list) $before] if {$n >= 0} {set where $n} } set mw $_MenuData(menu) set m m$_MenuData(next) incr _MenuData(next) if {$tcl_platform(platform) == "windows"} { if {$where == ""} { $mw add cascade -label $menu -menu $mw.$m -underline 0 } else { $mw insert $where cascade -label $menu -menu $mw.$m -underline 0 } set _MenuData($i,menu) $mw.$m } else { menubutton $mw.$m -text $menu -menu $mw.$m.menu -pady 0 \ -highlightthickness 0 -underline 0 if {$where == ""} { pack $mw.$m -side left -padx 5 } else { pack $mw.$m -side left -padx 5 \ -before [winfo parent $_MenuData($before,menu)] } set _MenuData($i,menu) $mw.$m.menu } menu $_MenuData($i,menu) -tearoff 0 if {$where == ""} { lappend _MenuData(list) $i } else { set _MenuData(list) [linsert $_MenuData(list) $where $i] } return $_MenuData($i,menu) } proc menubar_delete {menu} { global _MenuData tcl_platform set i [string tolower $menu] set n [lsearch $_MenuData(list) $i] if {$n < 0} return if {$tcl_platform(platform) == "windows"} { $_MenuData(menu) delete $n $n } else { set m [winfo parent $_Menudata($i,menu)] pack forget $m destroy $m } set _MenuData(list) [lreplace $_MenuData(list) $n $n] } proc menubar_get {menu} { global _MenuData set i [string tolower $menu] if {[lsearch $_MenuData(list) $i] >= 0} { return $_MenuData($i,menu) } return "" } proc menubar_state {menu state {entry ""}} { global _MenuData tcl_platform set i [string tolower $menu] set n [lsearch $_MenuData(list) $i] if {$n < 0} return if {$entry != ""} { $_MenuData($i,menu) entryconfigure $entry -state $state } elseif {$tcl_platform(platform) == "windows"} { $_MenuData(menu) entryconfigure $n -state $state } else { [winfo parent $_MenuData($i,menu)] configure -state $state } } cgnslib_3.1.4/src/cgnstools/common/balloon.tcl0000664000076400007640000000557412160605672016421 00000000000000 array set Balloon { set 0 first 0 id "" } proc set_balloon {target message} { global Balloon set tags [bindtags $target] set n [lsearch $tags Balloon] if {$message == ""} { if {$n >= 0} { bindtags $target [lreplace $tags $n $n] } } else { if {$n < 0} { bindtags $target "Balloon $tags" } } set Balloon($target) $message } proc end_balloon {target} { set_balloon $target "" } bind Balloon { set Balloon(set) 0 set Balloon(first) 1 set Balloon(id) [after 500 {Balloon:show %W $Balloon(%W) %X %Y}] } bind Balloon