├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── README.md └── src ├── animat.c ├── bbfile.c ├── camera.c ├── cenrad.c ├── chrono.c ├── chrono.h ├── clip.c ├── clipvol.c ├── compil.date ├── critip.c ├── cube.c ├── dlists.c ├── eigenv.c ├── eigenv.h ├── ellipse.c ├── extern.h ├── geometry.c ├── gisfil.c ├── grafic.h ├── hash.c ├── ilists.c ├── image.c ├── image.h ├── inmesh.c.old ├── inmsh2.c ├── inout.c ├── insol.c.tmp ├── items.c ├── keyboard.c ├── libmesh5.c ├── libmesh5.h ├── listnum.c ├── material.c ├── medit.c ├── medit.h ├── memory.c ├── memory.h ├── menus.c ├── mesh.c ├── mesh.h ├── mlists.c ├── morphing.c ├── mouse.c ├── normal.c ├── outmsh.c.old ├── param.c ├── parsar.c ├── parsop.c ├── particle.c ├── path.c ├── persp.c ├── picking.c ├── picking.c.sav ├── psfile.c ├── scene.c ├── scissor.c ├── sftcpy.c ├── sproto.h ├── status.c ├── stream.c ├── tiles.c ├── transform.c ├── util.c ├── vector.c ├── view.c ├── zaldy1.c └── zaldy2.c /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *# 3 | .DS_Store 4 | #* 5 | build 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | language: c++ 3 | 4 | compiler: 5 | - gcc 6 | - clang 7 | 8 | os: 9 | - linux 10 | - osx 11 | 12 | addons: 13 | apt: 14 | packages: 15 | - freeglut3-dev 16 | - libxmu-dev 17 | - libxi-dev 18 | 19 | script: 20 | - mkdir build 21 | - cd build 22 | - cmake .. 23 | - make 24 | - sudo make install 25 | 26 | notifications: 27 | email: false 28 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 2.8) 3 | set(CMAKE_BUILD_TYPE "Release") 4 | set(CMAKE_CXX_FLAGS "-w -O3") 5 | set(CMAKE_C_FLAGS "-w -O3") 6 | add_definitions("-w") 7 | set(CMAKE_MACOSX_RPATH 1) 8 | set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) 9 | set(CMAKE_INSTALL_RPATH "$ENV{HOME}/lib") 10 | set(CMAKE_INSTALL_NAME_DIR "$ENV{HOME}/lib") 11 | #INCLUDE_DIRECTORIES( "$ENV{HOME}/include") 12 | #LINK_DIRECTORIES( "$ENV{HOME}/lib") 13 | #SET(CMAKE_SKIP_BUILD_RPATH TRUE) 14 | 15 | 16 | 17 | macro(DATE RESULT) 18 | if(WIN32) 19 | execute_process(COMMAND "cmd" " /C date /T" OUTPUT_VARIABLE ${RESULT} OUTPUT_STRIP_TRAILING_WHITESPACE) 20 | string(REGEX REPLACE "(..)/(..)/(....).*" "\\3-\\2-\\1" ${RESULT} ${${RESULT}}) 21 | elseif(UNIX) 22 | execute_process(COMMAND "date" "+%Y-%m-%d" OUTPUT_VARIABLE ${RESULT} OUTPUT_STRIP_TRAILING_WHITESPACE) 23 | else() 24 | message(SEND_ERROR "Unable to detect date") 25 | set(${RESULT} UNKNOWN) 26 | endif() 27 | endmacro() 28 | macro(TIME RESULT) 29 | if(WIN32) 30 | execute_process(COMMAND "cmd" " /C echo %TIME%" OUTPUT_VARIABLE ${RESULT} OUTPUT_STRIP_TRAILING_WHITESPACE) 31 | string(REGEX REPLACE "(..:..:..),(..)" "\\1" ${RESULT} ${${RESULT}}) 32 | elseif(UNIX) 33 | execute_process(COMMAND "date" "+%H:%M:%S" OUTPUT_VARIABLE ${RESULT} OUTPUT_STRIP_TRAILING_WHITESPACE) 34 | else() 35 | message(SEND_ERROR "Unable to detect time") 36 | set(${RESULT} UNKNOWN) 37 | endif() 38 | endmacro() 39 | 40 | 41 | 42 | project(libMedit) 43 | #string(TIMESTAMP time "%Y-%m-%d %H:%M:%S") 44 | DATE(day) 45 | TIME(hour) 46 | file(WRITE src/compil.date "#define COMPIL \"${day} ${hour}\"") 47 | file( GLOB_RECURSE sources src/*.c) 48 | file( GLOB_RECURSE hea src/*.h) 49 | 50 | 51 | IF(APPLE) 52 | add_library( Medit3D STATIC ${sources}) 53 | INCLUDE_DIRECTORIES ( /System/Library/Frameworks ) 54 | FIND_LIBRARY(COCOA_LIBRARY Cocoa) 55 | FIND_LIBRARY(GLUT_LIBRARY GLUT ) 56 | FIND_LIBRARY(OpenGL_LIBRARY OpenGL ) 57 | MARK_AS_ADVANCED (COCOA_LIBRARY 58 | GLUT_LIBRARY 59 | OpenGL_LIBRARY) 60 | SET(GL_LIBS ${COCOA_LIBRARY} ${GLUT_LIBRARY} ${OpenGL_LIBRARY}) 61 | 62 | target_link_libraries( Medit3D ${GL_LIBS}) 63 | 64 | elseif(UNIX) 65 | add_library( Medit3D SHARED ${sources}) 66 | find_package(GLUT REQUIRED) 67 | include_directories(${GLUT_INCLUDE_DIRS}) 68 | link_directories(${GLUT_LIBRARY_DIRS}) 69 | add_definitions(${GLUT_DEFINITIONS}) 70 | if(NOT GLUT_FOUND) 71 | message(ERROR " GLUT not found!") 72 | endif(NOT GLUT_FOUND) 73 | find_package(OpenGL REQUIRED) 74 | include_directories(${OpenGL_INCLUDE_DIRS}) 75 | link_directories(${OpenGL_LIBRARY_DIRS}) 76 | add_definitions(${OpenGL_DEFINITIONS}) 77 | if(NOT OPENGL_FOUND) 78 | message(ERROR " OPENGL not found!") 79 | endif(NOT OPENGL_FOUND) 80 | set(GL_LIBS ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ) 81 | 82 | target_link_libraries( Medit3D ${GL_LIBS}) 83 | INSTALL( TARGETS Medit3D LIBRARY DESTINATION "$ENV{HOME}/lib") 84 | INSTALL( FILES ${hea} DESTINATION "$ENV{HOME}/include") 85 | 86 | ENDIF() 87 | 88 | target_link_libraries( Medit3D ${GL_LIBS}) 89 | 90 | 91 | project(medit) 92 | add_executable( medit src/medit.c) 93 | target_link_libraries( medit Medit3D)# ${GL_LIBS}) 94 | INSTALL( TARGETS medit RUNTIME DESTINATION "$ENV{HOME}/bin") 95 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Medit [![Build Status](https://travis-ci.org/ISCDtoolbox/Medit.svg?branch=master)](https://travis-ci.org/ISCDtoolbox/Medit) 2 | OpenGL-based scientific visualization software 3 | 4 | Medit was developped to visualize numerical simulation results on unstructured meshes in two and three dimensions. Scalar, vector and tensor fields can be easily associated and displayed with meshes. 5 | 6 | #### Installation 7 | 8 | In a terminal, clone this repository: 9 | 10 | ` git clone https://github.com/ISCDtoolbox/Medit.git ` 11 | 12 | navigate to the downloaded directory: 13 | 14 | ` cd Medit ` 15 | 16 | then create build directory and compile the project using cmake 17 | ``` 18 | mkdir build 19 | cd build 20 | cmake .. 21 | make 22 | make install 23 | ``` 24 | 25 | #### Usage 26 | 27 | * Simply run : 28 | `medit yourFile.mesh` 29 | 30 | * Thanks to C. Dobrzynski, there is an [inline HTML documentation](https://www.ljll.math.upmc.fr/frey/logiciels/Docmedit.dir/index.html) available in french. 31 | 32 | * There is also a [technical report](https://www.ljll.math.upmc.fr/frey/publications/RT-0253.pdf) describing its main features. 33 | 34 | #### Remark : 35 | 36 | * The experimental branch `feature/multi-sols` allows the visualisation of a solution field stored in a .sol file that contains multiple solution fields. 37 | -------------------------------------------------------------------------------- /src/animat.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "extern.h" 3 | #include "sproto.h" 4 | 5 | extern void resetLists(pScene ,pMesh ); 6 | 7 | 8 | static int getmesh(pMesh mesh,int range) { 9 | int k,ret; 10 | char *ptr,data[256]; 11 | static char base[256]; 12 | 13 | /* allocate mesh structure */ 14 | if ( ddebug ) fprintf(stdout,"getmesh: create mesh %d\n",range); 15 | if ( mesh->tria ) M_free(mesh->tria); 16 | if ( mesh->quad ) M_free(mesh->quad); 17 | if ( mesh->edge ) M_free(mesh->edge); 18 | if ( mesh->tetra ) M_free(mesh->tetra); 19 | if ( mesh->hexa ) M_free(mesh->hexa); 20 | if ( mesh->adja ) M_free(mesh->adja); 21 | if ( mesh->voy ) M_free(mesh->voy); 22 | if ( mesh->point ) M_free(mesh->point); 23 | if ( mesh->extra ) { 24 | if ( mesh->extra->nv ) M_free(mesh->extra->nv); 25 | if ( mesh->extra->nt ) M_free(mesh->extra->nt); 26 | if ( mesh->extra->nq ) M_free(mesh->extra->nq); 27 | if ( mesh->extra->n ) M_free(mesh->extra->n); 28 | if ( mesh->extra->t ) M_free(mesh->extra->t); 29 | if ( mesh->extra->tv ) M_free(mesh->extra->tv); 30 | if ( mesh->extra->te ) M_free(mesh->extra->te); 31 | M_free(mesh->extra); 32 | mesh->extra = (void*)0; 33 | } 34 | if ( mesh->sol && mesh->nbb ) { 35 | if ( (mesh->dim==2 && mesh->nfield==3) || (mesh->dim==3 && mesh->nfield==6) ) 36 | for (k=1; k<=mesh->nbb; k++) 37 | free(mesh->sol[k].m); 38 | M_free(mesh->sol); 39 | mesh->sol = (void*)0; 40 | } 41 | mesh->point = (void*)0; 42 | mesh->tria = (void*)0; 43 | mesh->quad = (void*)0; 44 | mesh->edge = (void*)0; 45 | mesh->tetra = (void*)0; 46 | mesh->hexa = (void*)0; 47 | mesh->adja = (void*)0; 48 | mesh->voy = (void*)0; 49 | mesh->np = mesh->nt = mesh->nq = mesh->ne = 0; 50 | mesh->ntet = mesh->nhex = mesh->nbb = 0; 51 | 52 | if ( animdep == range ) { 53 | sprintf(data,".%d",range); 54 | ptr = (char *)strstr(mesh->name,data); 55 | if ( ptr ) *ptr = '\0'; 56 | strcpy(base,mesh->name); 57 | } 58 | 59 | /* adjust file name */ 60 | sprintf(mesh->name,"%s.%d",base,range); 61 | if ( ddebug ) fprintf(stdout,"load %s\n",mesh->name); 62 | 63 | /* read mesh */ 64 | if ( quiet ) { 65 | fprintf(stdout," Loading %s \r",mesh->name); 66 | fflush(stdout); 67 | } 68 | mesh->typ = 0; 69 | ret = loadMesh(mesh); 70 | if ( ret < 1 ) { 71 | mesh->typ = 1; 72 | ret = inmsh2(mesh); 73 | if ( !ret ) { 74 | mesh->typ = 2; 75 | ret = loadGIS(mesh); 76 | if ( !ret ) return(0); 77 | } 78 | } 79 | if ( (mesh->ntet && !mesh->nt) || (mesh->nhex && !mesh->nq) ) 80 | meshSurf(mesh); 81 | 82 | meshBox(mesh,animdep==range); 83 | if ( !quiet ) meshInfo(mesh); 84 | 85 | return(1); 86 | } 87 | 88 | static int getsol(pMesh mesh,int range) { 89 | char *ptr,data[256]; 90 | static char base[256]; 91 | 92 | if ( animdep == range ) { 93 | sprintf(data,".%d",range); 94 | ptr = (char *)strstr(mesh->name,data); 95 | if ( ptr ) *ptr = '\0'; 96 | strcpy(base,mesh->name); 97 | } 98 | 99 | /* read metric */ 100 | sprintf(mesh->name,"%s.%d",base,range); 101 | if ( !loadSol(mesh,mesh->name,1) ) 102 | bbfile(mesh); 103 | if ( !quiet && mesh->nbb ) 104 | fprintf(stdout," Solutions %8d\n",mesh->nbb); 105 | 106 | return(1); 107 | } 108 | 109 | int loadNextMesh(pMesh mesh,int km,int ks,int parse) { 110 | pScene sc; 111 | int is; 112 | 113 | if ( !getmesh(mesh,km) ) return(0); 114 | if ( !getsol(mesh,ks) ) return(0); 115 | if ( ddebug ) printf("loadNextMesh: create %d window(s)\n",cv.nbs); 116 | 117 | /* compute mesh box */ 118 | is = currentScene(); 119 | if ( !cv.scene[is] ) { 120 | cv.scene[is] = (pScene)M_calloc(1,sizeof(Scene),"loadNextMesh.scene"); 121 | if ( !cv.scene[is] ) return(0); 122 | } 123 | sc = cv.scene[is]; 124 | sc->iso.palette = 0; 125 | if ( parse ) { 126 | parsop(sc,mesh); 127 | } 128 | 129 | if ( sc->mode & S_DISPL ) { 130 | meshCoord(mesh,1); 131 | } 132 | /*setupPalette(sc,mesh);*/ 133 | meshRef(sc,mesh); 134 | matSort(sc); 135 | 136 | return(1); 137 | } 138 | 139 | 140 | int playAnim(pScene sc,pMesh mesh,int deb,int fin) { 141 | int k; 142 | char *ptr,data[256],base[256]; 143 | 144 | /* get basename */ 145 | sprintf(data,".%d",deb); 146 | ptr = (char *)strstr(mesh->name,data); 147 | if ( ptr ) *ptr = '\0'; 148 | strcpy(base,mesh->name); 149 | 150 | if ( saveimg ) { 151 | glDrawBuffer(GL_BACK_LEFT); 152 | } 153 | 154 | /* start animation */ 155 | sc->par.cumtim = sc->par.timdep; 156 | for (k=deb; k<=fin; k++) { 157 | strcpy(mesh->name,base); 158 | 159 | resetLists(sc,mesh); 160 | if ( !loadNextMesh(mesh,k,k,0) ) { /* modif le 3/08/09 */ 161 | strcpy(mesh->name,base); 162 | if ( !loadNextMesh(mesh,deb,k,0) ) { 163 | fprintf(stderr," ** %s NOT FOUND.\n",data); 164 | return(0); 165 | } 166 | } 167 | doLists(sc,mesh); 168 | sc->glist = geomList(sc,mesh); 169 | if ( sc->mode & S_MAP ) doMapLists(sc,mesh,1); 170 | if ( sc->isotyp ) doIsoLists(sc,mesh,1); 171 | 172 | if ( !saveimg ) { 173 | sprintf(data,"Medit - [%s] #%d",mesh->name,sc->idwin); 174 | glutSetWindowTitle(data); 175 | } 176 | 177 | glClearColor(sc->par.back[0],sc->par.back[1],sc->par.back[2],sc->par.back[3]); 178 | if ( sc->type & S_SCISSOR ) 179 | scissorScene(); 180 | else 181 | redrawScene(); 182 | sc->par.cumtim += sc->par.dt; 183 | } 184 | fprintf(stdout,"\n Done.\n"); 185 | strcpy(mesh->name,base); 186 | sc->par.cumtim -= sc->par.dt; 187 | 188 | if ( saveimg ) { 189 | //glDrawBuffer(GL_FRONT | GL_BACK); 190 | glDrawBuffer(GL_BACK); 191 | sprintf(data,"Medit - [%s] #%d",mesh->name,sc->idwin); 192 | glutSetWindowTitle(data); 193 | glutPostRedisplay(); 194 | saveimg = 0; 195 | } 196 | 197 | return(1); 198 | } 199 | 200 | 201 | int animParticle(pScene sc,pMesh mesh) { 202 | int cur; 203 | char *ptr,data[256],base[256]; 204 | 205 | /* get basename */ 206 | strcpy(base,mesh->name); 207 | ptr = (char *)strstr(base,"."); 208 | sscanf(ptr,".%d",&cur); 209 | cur++; 210 | if ( cur > animfin ) return(0); 211 | if ( ptr ) ptr[0] = '\0'; 212 | sprintf(data,"%s.%.3d",base,cur); 213 | strcpy(mesh->name,base); 214 | 215 | resetLists(sc,mesh); 216 | if ( !loadNextMesh(mesh,cur,cur,1) ) return(0); 217 | 218 | doLists(sc,mesh); 219 | sc->glist = geomList(sc,mesh); 220 | if ( sc->mode & S_MAP ) doMapLists(sc,mesh,1); 221 | if ( sc->isotyp ) doIsoLists(sc,mesh,2); 222 | 223 | if ( !advectParticle(sc,mesh) ) return(0); 224 | 225 | return(1); 226 | } 227 | 228 | 229 | int animat() { 230 | pMesh mesh; 231 | pScene sc; 232 | char data[128],*name; 233 | 234 | /* default */ 235 | if ( ddebug ) printf("animat: read file(s)\n"); 236 | 237 | /* enter basename */ 238 | if ( !cv.nbm ) { 239 | fprintf(stdout," File name(s) missing. Please enter : "); 240 | fflush(stdout); fflush(stdin); 241 | fgets(data,120,stdin); 242 | if ( !strlen(data) ) { 243 | fprintf(stdout," ## Error\n"); 244 | return(0); 245 | } 246 | fprintf(stdout," Enter range [start,end] :"); 247 | fflush(stdout); fflush(stdin); 248 | fscanf(stdin,"%d %d",&animdep,&animfin); 249 | 250 | /* parse file name(s) */ 251 | name = strtok(data," \n"); 252 | while( name ) { 253 | if ( !cv.mesh[cv.nbm] ) { 254 | cv.mesh[cv.nbm] = (pMesh)M_calloc(1,sizeof(Mesh),"animat.mesh"); 255 | if ( !cv.mesh[cv.nbm] ) return(0); 256 | } 257 | /*(cv.mesh[cv.nbm])->name = calloc(strlen(name)+15,sizeof(char));*/ 258 | strcpy(cv.mesh[cv.nbm]->name,name); 259 | break; 260 | } 261 | if ( !cv.nbm ) return(0); 262 | } 263 | cv.nbs = cv.nbm; 264 | 265 | /* read initial mesh */ 266 | mesh = cv.mesh[0]; 267 | if ( !loadNextMesh(mesh,animdep,animdep,1) ) return(0); 268 | 269 | /* create grafix */ 270 | sc = cv.scene[0]; 271 | if ( !createScene(sc,0) ) { 272 | fprintf(stderr," ## Unable to create scene\n"); 273 | return(0); 274 | } 275 | 276 | quiet = 1; 277 | return(1); 278 | } 279 | -------------------------------------------------------------------------------- /src/bbfile.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "extern.h" 3 | #include "sproto.h" 4 | #include "eigenv.h" 5 | 6 | 7 | int EatLine(FILE *in) { 8 | int k,c; 9 | 10 | k = 0; 11 | while ( (c=fgetc(in)) != EOF ) { 12 | k++; 13 | if ( c==10 || c== 13) return(1); 14 | } 15 | return(0); 16 | } 17 | 18 | 19 | int EatSpace(FILE *in) { 20 | int k,c,ret=0; 21 | 22 | k=0; 23 | while (isspace(c=fgetc(in)) ) { 24 | k++; 25 | if ( c==10 || c== 13 ) ret=1; 26 | } 27 | if ( c==EOF) return -1; 28 | 29 | /* fprintf(stdout,"EatSpace %d %d last char=%d\n",ret,k,c); */ 30 | ungetc(c,in); 31 | 32 | return ret; 33 | } 34 | 35 | 36 | int bbfile(pMesh mesh) { 37 | FILE *in; 38 | pSolution ps; 39 | double a,b,c,lambda[3],eigv[3][3],m[6],vp[2][2]; 40 | float dummy; 41 | int j,k,l,dim,np,nfield,nf,i1,i2,i3,i4,err,iord; 42 | char *ptr,data[128],tmp[128]; 43 | ubyte bigbb; 44 | 45 | /* default */ 46 | strcpy(tmp,mesh->name); 47 | ptr = (char *)strstr(tmp,".mesh"); 48 | if ( ptr ) *ptr = '\0'; 49 | 50 | sprintf(data,"%s.bb",tmp); 51 | in = fopen(data,"r"); 52 | bigbb = 0; 53 | if ( !in ) { 54 | sprintf(data,"%s.pbb",tmp); 55 | in = fopen(data,"r"); 56 | } 57 | if ( !in ) { 58 | bigbb = 1; 59 | sprintf(data,"%s.BB",tmp); 60 | in = fopen(data,"r"); 61 | if ( !in ) { /* hack FH pour le mac */ 62 | sprintf(data,"%s.gbb",tmp); 63 | in = fopen(data,"r"); 64 | } 65 | 66 | } 67 | if ( !in ) 68 | return(0); 69 | 70 | /* if ( !quiet ) fprintf(stdout," Reading %s\n",data); */ 71 | i1=i2=i3=i4=-1; 72 | /* read file format */ 73 | err=0; 74 | fscanf(in,"%d",&dim); 75 | if(EatSpace(in)) err++; 76 | fscanf(in,"%d",&i1); 77 | if(EatSpace(in)) err++; 78 | fscanf(in,"%d",&i2); 79 | if(EatSpace(in)) err++; 80 | fscanf(in,"%d",&i3); 81 | bigbb= (EatSpace(in)==0); /* not nl after the 4 integer => BB */ 82 | 83 | if ( !quiet ) { 84 | if ( bigbb ) fprintf(stdout," Reading BB file %s\n",data); 85 | else fprintf(stdout," Reading bb file %s\n",data); 86 | } 87 | if ( dim < 2 || dim > 3 || err ) { 88 | fprintf(stderr," %%%% Wrong file (dim=%d) (err=%d). Ignored\n",dim,err); 89 | return(0); 90 | } 91 | /* read number of field(s) */ 92 | nf = 0; 93 | 94 | if ( bigbb ) { 95 | /* get only 1st field */ 96 | /* fscanf(in,"%d",&nfield);*/ 97 | nfield=i1; 98 | /*fscanf(in,"%d",&mesh->nfield);*/ 99 | mesh->nfield = i2; 100 | if (nfield>1) 101 | { 102 | nf += i3; 103 | for (k=1; ktypage); 113 | printf(" np= %d, type= %d\n",np,mesh->typage); 114 | } 115 | else { 116 | /* fscanf(in,"%d",&mesh->nfield); 117 | fscanf(in,"%d",&np);*/ 118 | /* read file type */ 119 | /* fscanf(in,"%d",&mesh->typage);*/ 120 | mesh->nfield=i1; 121 | np=i2; 122 | mesh->typage=i3; 123 | } 124 | 125 | 126 | if ( mesh->typage == 2 ) { 127 | if ( np < mesh->np ) { 128 | fprintf(stderr," %%%% Wrong solution number (%d , %d). Ignored\n",np,mesh->np); 129 | fclose(in); 130 | return(0); 131 | } 132 | mesh->nbb = mesh->np; 133 | } 134 | else if ( mesh->typage == 1 ) { 135 | if ( np < mesh->ne ) { 136 | fprintf(stderr," %%%% Wrong solution number (%d , %d). Ignored\n",np,mesh->ne); 137 | fclose(in); 138 | return(0); 139 | } 140 | mesh->nbb = mesh->ne; 141 | } 142 | else { 143 | fprintf(stderr," %%%% Wrong typage (%d). Ignored\n",mesh->typage); 144 | fclose(in); 145 | return(0); 146 | } 147 | 148 | /* read solutions */ 149 | mesh->bbmin = 1.e10; 150 | mesh->bbmax = -1.e10; 151 | 152 | /* allocate memory */ 153 | if ( !zaldy2(mesh) ) { 154 | mesh->nbb = 0; 155 | fclose(in); 156 | return(0); 157 | } 158 | 159 | /* scalar field */ 160 | if ( mesh->nfield == 1 ) { 161 | if ( ddebug ) printf(" scalar (isotropic) field\n"); 162 | for (k=1; k<=mesh->nbb; k++) { 163 | ps = &mesh->sol[k]; 164 | ps->bb = 0.0; 165 | if ( fscanf(in,"%s",data) != 1 ) continue; 166 | ptr = strpbrk(data,"dD"); 167 | if ( ptr ) *ptr = 'E'; 168 | sscanf(data,"%f",&ps->bb); 169 | if ( ps->bb < mesh->bbmin ) mesh->bbmin = ps->bb; 170 | if ( ps->bb > mesh->bbmax ) mesh->bbmax = ps->bb; 171 | for (j=1; j<=nf; j++) fscanf(in,"%f",&dummy); 172 | } 173 | } 174 | 175 | /* vector field */ 176 | else if ( mesh->nfield == mesh->dim ) { 177 | if ( ddebug ) fprintf(stdout," vector field \n"); 178 | for (k=1; k<=mesh->nbb; k++) { 179 | ps = &mesh->sol[k]; 180 | ps->bb = 0.0; 181 | for (l=0; ldim; l++) { 182 | if ( fscanf(in,"%s",data) != 1 ) continue; 183 | ptr = strpbrk(data,"dD"); 184 | if ( ptr ) *ptr = 'E'; 185 | sscanf(data,"%f",&ps->m[l]); 186 | ps->bb += ps->m[l]*ps->m[l]; 187 | } 188 | ps->bb = sqrt(ps->bb); 189 | 190 | if ( ps->bb < mesh->bbmin ) mesh->bbmin = ps->bb; 191 | if ( ps->bb > mesh->bbmax ) 192 | mesh->bbmax = ps->bb; 193 | for (j=1; jnfield == 3 ) { 199 | if ( ddebug ) fprintf(stdout," 2D metric field\n"); 200 | for (k=1; k<=mesh->np; k++) { 201 | ps = &mesh->sol[k]; 202 | fscanf(in,"%lf %lf %lf",&a,&b,&c); 203 | ps->m[0] = a; 204 | ps->m[1] = b; 205 | ps->m[2] = c; 206 | m[0] = a; 207 | m[1] = b; 208 | m[2] = c; 209 | eigen2(m,lambda,vp); 210 | ps->bb = min(lambda[0],lambda[1]); 211 | if ( ps->bb < mesh->bbmin ) mesh->bbmin = ps->bb; 212 | if ( ps->bb > mesh->bbmax ) mesh->bbmax = ps->bb; 213 | for (j=1; jnfield == 6 ) { 217 | if ( ddebug ) fprintf(stdout," 3D metric field\n"); 218 | for (k=1; k<=mesh->np; k++) { 219 | ps = &mesh->sol[k]; 220 | ps->bb = 0.0f; 221 | for (l=0; l<6; l++) { 222 | if ( fscanf(in,"%s",data) != 1 ) continue; 223 | ptr = strpbrk(data,"dD"); 224 | if ( ptr ) *ptr = 'E'; 225 | sscanf(data,"%f",&dummy); 226 | m[l] = dummy; 227 | } 228 | ps->m[0] = m[0]; 229 | ps->m[1] = m[1]; 230 | ps->m[2] = m[3]; 231 | ps->m[3] = m[2]; 232 | ps->m[4] = m[4]; 233 | ps->m[5] = m[5]; 234 | 235 | m[2] = ps->m[2]; 236 | m[3] = ps->m[3]; 237 | iord = eigenv(1,m,lambda,eigv); 238 | if ( iord ) { 239 | ps->bb = lambda[0]; 240 | ps->bb = max(ps->bb,lambda[1]); 241 | ps->bb = max(ps->bb,lambda[2]); 242 | if ( ps->bb < mesh->bbmin ) mesh->bbmin = ps->bb; 243 | if ( ps->bb > mesh->bbmax ) mesh->bbmax = ps->bb; 244 | } 245 | else { 246 | fprintf(stdout," ## Eigenvalue problem.\n"); 247 | } 248 | 249 | for (j=1; jnbb = 0; 255 | } 256 | 257 | fclose(in); 258 | return(np); 259 | } 260 | -------------------------------------------------------------------------------- /src/camera.c: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | 5 | #include "medit.h" 6 | #include "extern.h" 7 | #include "sproto.h" 8 | 9 | 10 | double Azimuth(pCamera c) { 11 | double dd,azim,cosazim,sinazim; 12 | 13 | dd = sqrt((double)c->speed[0]*c->speed[0]+(double)c->speed[2]*c->speed[2]); 14 | cosazim = c->speed[2] / dd; 15 | sinazim = c->speed[0] / dd; 16 | azim = atan2(sinazim,cosazim) * RTOD; 17 | return(azim); 18 | } 19 | 20 | double Elevation(pCamera c) { 21 | double elev; 22 | 23 | elev = sqrt((double)c->speed[0]*c->speed[0]+(double)c->speed[2]*c->speed[2]); 24 | elev = atan2(c->speed[1],elev) * RTOD; 25 | return(elev); 26 | } 27 | 28 | /* compute new sun position */ 29 | void updateSun(pScene sc,pCamera c) { 30 | double dd; 31 | GLfloat axe[3],sunf[4]; 32 | GLdouble speed[3],sunp[4],matrix[16]; 33 | 34 | axe[0] = c->speed[2]; 35 | axe[1] = 0.0f; 36 | axe[2] = -c->speed[0]; 37 | dd = sqrt(axe[0]*axe[0] + axe[2]*axe[2]); 38 | if ( dd != 0.0f ) { 39 | axe[0] /= dd; 40 | axe[2] /= dd; 41 | } 42 | 43 | speed[0] = c->speed[0]; 44 | speed[1] = c->speed[1]; 45 | speed[2] = c->speed[2]; 46 | 47 | glPushMatrix(); 48 | glLoadIdentity(); 49 | glRotatef(-30.0f,axe[0],axe[1],axe[2]); 50 | glGetDoublev(GL_MODELVIEW_MATRIX,matrix); 51 | glPopMatrix(); 52 | transformPointd(sunp,speed,matrix); 53 | sunf[0] = -sc->dmax*sunp[0]; 54 | sunf[1] = -sc->dmax*sunp[1]; 55 | sunf[2] = -sc->dmax*sunp[2]; 56 | sunf[3] = 0.0; 57 | 58 | glLightfv(GL_LIGHT0,GL_POSITION,sunf); 59 | 60 | if ( ddebug ) { 61 | printf(" speed %g %g %g\n",c->speed[0],c->speed[1],c->speed[2]); 62 | printf(" axe %g %g %g\n",axe[0],axe[1],axe[2]); 63 | printf(" sunpos %g %g %g\n",sunp[0],sunp[1],sunp[2]); 64 | } 65 | } 66 | 67 | 68 | void updateCamera(pScene sc,pCamera c,double azim,double elev) { 69 | double d,lazim,lelev; 70 | 71 | /* compute speed vector */ 72 | if ( elev > 89.0f ) elev = 89.0; 73 | else if ( elev < -89.0f ) elev = -89.0; 74 | lazim = azim * DTOR; 75 | lelev = elev * DTOR; 76 | c->speed[0] = sin(lazim)*cos(lelev); 77 | c->speed[1] = sin(lelev); 78 | c->speed[2] = cos(lazim)*cos(lelev); 79 | 80 | d = (double)c->speed[0]*sc->par.sunpos[0] + c->speed[1]*sc->par.sunpos[1] + 81 | c->speed[2]*sc->par.sunpos[2]; 82 | d = d / sqrt((double)sc->par.sunpos[0]*sc->par.sunpos[0]+ 83 | sc->par.sunpos[1]*sc->par.sunpos[1]+ 84 | sc->par.sunpos[2]*sc->par.sunpos[2]); 85 | d = acos(d); 86 | if ( fabs(d) > 0.10*sc->persp->fovy*DTOR ) 87 | updateSun(sc,c); 88 | } 89 | 90 | 91 | pCamera initCamera(pScene sc,int up) { 92 | pCamera c; 93 | pMesh mesh; 94 | double dd; 95 | double look[3]; 96 | 97 | if ( ddebug ) printf(" initCamera dmax %g\n",sc->dmax); 98 | if ( sc->camera ) c = sc->camera; 99 | else { 100 | c = (pCamera)M_calloc(1,sizeof(struct camera),"camera"); 101 | if ( !c ) { 102 | printf(" ## unable to allocate memory / camera\n"); 103 | exit(1); 104 | } 105 | } 106 | 107 | /* adjust coeffs */ 108 | mesh = cv.mesh[sc->idmesh]; 109 | c->eye[0] = c->eye[1] = 0.0; 110 | c->eye[2] = sc->dmax; 111 | 112 | c->vecup = up; 113 | 114 | c->speed[0] = 0.0; 115 | c->speed[1] = 0.0; 116 | c->speed[2] = c->eye[2]; 117 | dd = -1.0 / sqrt(c->speed[2]*c->speed[2]); 118 | c->speed[2] *= dd; 119 | c->spmod = 0.01*sc->dmax; 120 | c->altinc = 0.01*(mesh->ymax-mesh->ymin); 121 | 122 | /* set sun position */ 123 | updateSun(sc,c); 124 | 125 | if ( ddebug ) { 126 | look[0] = c->eye[0] + sc->dmax*c->speed[0]; 127 | look[1] = c->eye[1] + sc->dmax*c->speed[1]; 128 | look[2] = c->eye[2] + sc->dmax*c->speed[2]; 129 | printf(" eye %g %g %g\n",c->eye[0],c->eye[1],c->eye[2]); 130 | printf(" speed %g %g %g\n",c->speed[0],c->speed[1],c->speed[2]); 131 | printf(" look %g %g %g\n",look[0],look[1],look[2]); 132 | } 133 | 134 | return(c); 135 | } 136 | 137 | #ifdef __cplusplus 138 | } 139 | #endif 140 | -------------------------------------------------------------------------------- /src/cenrad.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "medit.h" 6 | #include "extern.h" 7 | #include "sproto.h" 8 | 9 | 10 | /* compute circumradius and center */ 11 | int cenrad(pMesh mesh,int iel,double *c,double *rad) { 12 | pTetra pt; 13 | pPoint p1,p2,p3,p4; 14 | double dd,ux,uy,uz,n1[3],n2[3],n3[3],c1,c2,c3,pl1,pl2,pl3; 15 | 16 | pt = &mesh->tetra[iel]; 17 | if ( !pt->v[0] ) return(0); 18 | 19 | p1 = &mesh->point[pt->v[0]]; 20 | p2 = &mesh->point[pt->v[1]]; 21 | p3 = &mesh->point[pt->v[2]]; 22 | p4 = &mesh->point[pt->v[3]]; 23 | 24 | ux = p4->c[0] - p1->c[0]; 25 | uy = p4->c[1] - p1->c[1]; 26 | uz = p4->c[2] - p1->c[2]; 27 | dd = 1.0 / sqrt(ux*ux + uy*uy + uz*uz); 28 | n1[0] = ux*dd; 29 | n1[1] = uy*dd; 30 | n1[2] = uz*dd; 31 | /* plan: vecteur directeur passant par milieu(1,4) */ 32 | pl1 = n1[0]*(p4->c[0]+p1->c[0]) \ 33 | + n1[1]*(p4->c[1]+p1->c[1]) + n1[2]*(p4->c[2]+p1->c[2]); 34 | 35 | ux = p4->c[0] - p2->c[0]; 36 | uy = p4->c[1] - p2->c[1]; 37 | uz = p4->c[2] - p2->c[2]; 38 | dd = 1.0 / sqrt(ux*ux + uy*uy + uz*uz); 39 | n2[0] = ux*dd; 40 | n2[1] = uy*dd; 41 | n2[2] = uz*dd; 42 | pl2 = n2[0]*(p4->c[0]+p2->c[0]) \ 43 | + n2[1]*(p4->c[1]+p2->c[1]) + n2[2]*(p4->c[2]+p2->c[2]); 44 | 45 | ux = p4->c[0] - p3->c[0]; 46 | uy = p4->c[1] - p3->c[1]; 47 | uz = p4->c[2] - p3->c[2]; 48 | dd = 1.0 / sqrt(ux*ux + uy*uy + uz*uz); 49 | n3[0] = ux*dd; 50 | n3[1] = uy*dd; 51 | n3[2] = uz*dd; 52 | pl3 = n3[0]*(p4->c[0]+p3->c[0]) \ 53 | + n3[1]*(p4->c[1]+p3->c[1]) + n3[2]*(p4->c[2]+p3->c[2]); 54 | 55 | /* center = intersection of 3 planes */ 56 | ux = n2[1]*n3[2] - n2[2]*n3[1]; 57 | uy = n1[2]*n3[1] - n1[1]*n3[2]; 58 | uz = n1[1]*n2[2] - n1[2]*n2[1]; 59 | 60 | dd = n1[0]*ux + n2[0]*uy + n3[0]*uz; 61 | dd = 0.5 / dd; 62 | 63 | c1 = ux*pl1 + uy*pl2 + uz*pl3; 64 | c2 = pl1 * (n2[2]*n3[0] - n2[0]*n3[2]) \ 65 | + pl2 * (n1[0]*n3[2] - n3[0]*n1[2]) \ 66 | + pl3 * (n2[0]*n1[2] - n2[2]*n1[0]); 67 | c3 = pl1 * (n2[0]*n3[1] - n2[1]*n3[0]) \ 68 | + pl2 * (n3[0]*n1[1] - n3[1]*n1[0]) \ 69 | + pl3 * (n1[0]*n2[1] - n2[0]*n1[1]); 70 | 71 | c[0] = dd * c1; 72 | c[1] = dd * c2; 73 | c[2] = dd * c3; 74 | 75 | /* radius (squared) */ 76 | *rad = (c[0] - p4->c[0]) * (c[0] - p4->c[0]) \ 77 | + (c[1] - p4->c[1]) * (c[1] - p4->c[1]) \ 78 | + (c[2] - p4->c[2]) * (c[2] - p4->c[2]); 79 | 80 | return(1); 81 | } 82 | -------------------------------------------------------------------------------- /src/chrono.c: -------------------------------------------------------------------------------- 1 | /* 2 | * simulation of a chronograph 3 | * in : tim 4 | * out: tim.dtim = elapsed time in micro-secs 5 | * tim.ptim = elapsed time in secs 6 | * tim.call = number of calls 7 | * 8 | * Written by Pascal J. Frey 9 | * email: Pascal.Frey@inria.fr, 1999 10 | */ 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | 16 | #include 17 | #include 18 | #include 19 | #include "chrono.h" 20 | 21 | 22 | /* return elapsed time in secs. */ 23 | static double diftim(time_t t2,time_t t1) { 24 | struct tm *ptm; 25 | double tim; 26 | int hh1,mm1,ss1,hh2,mm2,ss2; 27 | 28 | ptm = localtime(&t1); 29 | hh1 = ptm->tm_hour; 30 | mm1 = ptm->tm_min; 31 | ss1 = ptm->tm_sec; 32 | 33 | ptm = localtime(&t2); 34 | hh2 = ptm->tm_hour; 35 | mm2 = ptm->tm_min; 36 | ss2 = ptm->tm_sec; 37 | if ( hh2 < hh1 ) hh2 += 24; 38 | 39 | tim = 3600.0*(hh2-hh1); 40 | tim += 60.0*(mm2-mm1); 41 | tim += ss2-ss1; 42 | 43 | return(tim); 44 | } 45 | 46 | 47 | /* get system and user times in micro-seconds */ 48 | void chrono(int cmode,mytime *ptt) { 49 | time_t tt; 50 | 51 | if ( cmode == RESET ) { 52 | ptt->dtim = clock(); 53 | ptt->ctim = 0.0f; 54 | ptt->ptim = 0; 55 | ptt->call = 0; 56 | } 57 | else { 58 | ptt->dtim = difftime(clock(),ptt->dtim); /* in secs */ 59 | if ( cmode == ON ) { 60 | ptt->ptim = time(NULL); 61 | ptt->call++; 62 | } 63 | else if ( cmode == OFF ) { 64 | tt = time(NULL); 65 | ptt->ctim += diftim(tt,ptt->ptim); 66 | ptt->ptim = 0; 67 | } 68 | } 69 | } 70 | 71 | 72 | /* return time (converted in secs */ 73 | double gttime(mytime t) { 74 | 75 | if ( t.ctim < MAXCLK ) 76 | return(t.dtim / (double)CLOCKS_PER_SEC); 77 | else 78 | return(t.ctim); 79 | } 80 | 81 | 82 | /* initialize time table */ 83 | void tminit(mytime *t,int maxtim) { 84 | int k; 85 | 86 | for (k=0; k 6 | 7 | #ifndef ON 8 | #define RESET 0 9 | #define ON 1 10 | #define OFF 2 11 | #endif 12 | 13 | #define TIMEMAX 16 14 | #define MAXCLK ( 1073741823. / (double)CLOCKS_PER_SEC ) 15 | 16 | 17 | typedef struct mytime { 18 | double ctim,dtim; 19 | time_t ptim; 20 | short call; 21 | } mytime; 22 | 23 | 24 | /* prototypes */ 25 | void chrono(int cmode,mytime *ptt); 26 | double gttime(mytime t); 27 | void tminit(mytime *t,int maxtim); 28 | 29 | 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | -------------------------------------------------------------------------------- /src/clip.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "extern.h" 3 | #include "sproto.h" 4 | 5 | static pClip cclip = 0; 6 | static ubyte curclip = 0; 7 | static GLfloat plane[4] = {-1.0, 0.0, 0.0, 0.0}; 8 | 9 | 10 | static void drawCap(pScene sc,pClip clip,GLboolean docap) { 11 | 12 | if ( !docap ) { 13 | if ( clip->active & C_EDIT ) glColor3f(1.0,0.0,1.0); 14 | else if ( clip->active & C_FREEZE ) glColor3f(0.0,0.6,0.9); 15 | else glColor3f(0.0,1.0,0.0); 16 | 17 | glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); 18 | glLineWidth(3.); 19 | glBegin(GL_QUADS); 20 | glVertex3f(0.,-1.,-1.); 21 | glVertex3f(0., 1.,-1.); 22 | glVertex3f(0., 1.,1.); 23 | glVertex3f(0.,-1.,1.); 24 | glEnd(); 25 | 26 | glLineWidth(1.); 27 | glColor3f(1.,0.7,0.); 28 | glBegin(GL_LINES); 29 | glVertex3f(0.,0.,-1.); 30 | glVertex3f(0.,0.,1.); 31 | glColor3f(1.,0.7,0.); 32 | glVertex3f(0.,-1.,0.); 33 | glVertex3f(0.,1.,0.); 34 | glEnd(); 35 | 36 | glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 37 | } 38 | else { 39 | glDisable(GL_LIGHTING); 40 | glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 41 | glColor4fv(sc->material[DEFAULT_MAT].dif); 42 | glRecti(-100,-100,100,100); 43 | } 44 | } 45 | 46 | 47 | /* display clipping plane */ 48 | void updateClip(pClip clip,pMesh mesh) { 49 | pScene sc; 50 | pTransform cliptr,view; 51 | GLfloat dd,dmax,inv[16],axis[4],trans[4],matrix[16]; 52 | int idw; 53 | 54 | /* default */ 55 | if ( ddebug ) printf("updateClip\n"); 56 | 57 | /* retrieve context */ 58 | idw = currentScene(); 59 | sc = cv.scene[idw]; 60 | view = sc->view; 61 | cliptr = clip->cliptr; 62 | 63 | /* compute clip transform */ 64 | if ( clip->active & C_EDIT ) { 65 | invertMatrix(view->matrix,inv); 66 | inv[3] = inv[7] = inv[11] = 0.0; inv[15] = 1.0; 67 | 68 | /* rotation cumulative */ 69 | if ( cliptr->angle != 0.0 ) { 70 | transformVector(trans,cliptr->axis,inv); 71 | glPushMatrix(); 72 | glLoadIdentity(); 73 | glRotatef(cliptr->angle,trans[0],trans[1],trans[2]); 74 | glMultMatrixf(cliptr->rot); 75 | glGetFloatv(GL_MODELVIEW_MATRIX,cliptr->rot); 76 | glPopMatrix(); 77 | } 78 | 79 | /* translation cumulative */ 80 | axis[0] = cliptr->panx; 81 | axis[1] = cliptr->pany; 82 | axis[2] = 0.0; 83 | axis[3] = 1.0; 84 | if ( cliptr->manim == GL_FALSE ) 85 | cliptr->panx = cliptr->pany = 0.0; 86 | transformVector(trans,axis,inv); 87 | 88 | dd = trans[0]*clip->eqn[0]+trans[1]*clip->eqn[1]+trans[2]*clip->eqn[2]; 89 | trans[0] = dd*clip->eqn[0]; 90 | trans[1] = dd*clip->eqn[1]; 91 | trans[2] = dd*clip->eqn[2]; 92 | 93 | cliptr->tra[12] += trans[0]; 94 | cliptr->tra[13] += trans[1]; 95 | cliptr->tra[14] += trans[2]; 96 | 97 | /* truncation */ 98 | dmax = mesh->xmax - mesh->xmin; 99 | dmax = max(dmax,mesh->ymax - mesh->ymin); 100 | dmax = max(dmax,mesh->zmax - mesh->zmin) / 1.8; 101 | if ( fabs(cliptr->tra[12]) > dmax || fabs(cliptr->tra[13]) > dmax || 102 | fabs(cliptr->tra[14]) > dmax ) { 103 | if ( cliptr->manim == GL_TRUE ) { 104 | cliptr->panx = -cliptr->panx; 105 | cliptr->pany = -cliptr->pany; 106 | } 107 | else { 108 | cliptr->tra[12] = max(-dmax,min(dmax,cliptr->tra[12])); 109 | cliptr->tra[13] = max(-dmax,min(dmax,cliptr->tra[13])); 110 | cliptr->tra[14] = max(-dmax,min(dmax,cliptr->tra[14])); 111 | } 112 | } 113 | 114 | /* final transformation */ 115 | glPushMatrix(); 116 | glLoadIdentity(); 117 | glMultMatrixf(cliptr->tra); 118 | glMultMatrixf(cliptr->rot); 119 | glGetFloatv(GL_MODELVIEW_MATRIX,cliptr->matrix); 120 | glPopMatrix(); 121 | 122 | /* compute plane equation */ 123 | invertMatrix(cliptr->matrix,inv); 124 | transformPoint(clip->eqn,plane,inv); 125 | 126 | if ( clip->active & C_REDO ) 127 | clipVertices(mesh,sc,clip); 128 | /* clip->active |= C_REDO;*/ 129 | } 130 | 131 | else if ( clip->active & C_FREEZE ) { 132 | glPushMatrix(); 133 | glLoadMatrixf(view->matrix); 134 | glTranslatef(sc->cx,sc->cy,sc->cz); 135 | glGetFloatv(GL_MODELVIEW_MATRIX,matrix); 136 | glPopMatrix(); 137 | invertMatrix(matrix,inv); 138 | inv[3] = inv[7] = inv[11] = 0.0; inv[15] = 1.0; 139 | 140 | glPushMatrix(); 141 | glLoadMatrixf(inv); 142 | glMultMatrixf(view->oldmat); 143 | glTranslatef(sc->cx,sc->cy,sc->cz); 144 | glMultMatrixf(cliptr->matrix); 145 | glGetFloatv(GL_MODELVIEW_MATRIX,cliptr->matrix); 146 | glPopMatrix(); 147 | 148 | /* compute plane equation */ 149 | invertMatrix(cliptr->matrix,inv); 150 | transformPoint(clip->eqn,plane,inv); 151 | clip->active |= C_REDO; 152 | } 153 | if ( !cliptr->manim ) { 154 | cliptr->angle = 0.0; 155 | clip->active ^= C_UPDATE; 156 | } 157 | } 158 | 159 | 160 | void clipVertices(pMesh mesh,pScene sc,pClip clip) { 161 | pTetra pt; 162 | pHexa ph; 163 | pPoint p0; 164 | double dd1,zero; 165 | int k,l,nbpos,nbneg,nbnul; 166 | 167 | /* check points in plane */ 168 | zero = sc->dmax*1.e-13; 169 | for (k=1; k<=mesh->np; k++) { 170 | p0 = &mesh->point[k]; 171 | if ( p0->tag & M_UNUSED ) continue; 172 | dd1 = p0->c[0]*clip->eqn[0] + p0->c[1]*clip->eqn[1] \ 173 | + p0->c[2]*clip->eqn[2] + clip->eqn[3]; 174 | if ( dd1 > zero ) p0->clip = 2; 175 | else if ( dd1 < zero ) p0->clip = 1; 176 | else p0->clip = 0; 177 | } 178 | 179 | /* update tetrahedra */ 180 | for (k=1; k<=mesh->ntet; k++) { 181 | pt = &mesh->tetra[k]; 182 | pt->clip = 0; 183 | nbpos = nbneg = nbnul = 0; 184 | for (l=0; l<4; l++) { 185 | p0 = &mesh->point[pt->v[l]]; 186 | if ( p0->clip == 2 ) nbpos++; 187 | else if ( p0->clip == 1 ) nbneg++; 188 | else nbnul++; 189 | } 190 | if ( nbpos && nbpos+nbnul < 4 ) pt->clip = 1; 191 | } 192 | 193 | /* update hexahedra */ 194 | for (k=1; k<=mesh->nhex; k++) { 195 | ph = &mesh->hexa[k]; 196 | ph->clip = 0; 197 | nbpos = nbneg = nbnul = 0; 198 | for (l=0; l<8; l++) { 199 | p0 = &mesh->point[ph->v[l]]; 200 | if ( p0->clip == 2 ) nbpos++; 201 | else if ( p0->clip == 1 ) nbneg++; 202 | else nbnul++; 203 | } 204 | if ( nbpos && nbpos+nbnul < 8 ) ph->clip = 1; 205 | } 206 | } 207 | 208 | 209 | void drawClip(pScene sc,pClip clip,pMesh mesh,GLboolean docap) { 210 | pTransform cliptr,view; 211 | GLfloat scale; 212 | 213 | /* default */ 214 | if ( ddebug ) printf("drawClip\n"); 215 | view = sc->view; 216 | cliptr = clip->cliptr; 217 | 218 | if ( clip->active & C_UPDATE ) updateClip(clip,mesh); 219 | 220 | /* update clip plane */ 221 | if ( clip->active & C_REDO ) { 222 | if ( !animate ) glutSetCursor(GLUT_CURSOR_WAIT); 223 | clipVertices(mesh,sc,clip); 224 | 225 | /* build display lists */ 226 | if ( clip->active & C_VOL ) { 227 | if ( sc->clist[LTets] ) glDeleteLists(sc->clist[LTets],1); 228 | if ( sc->clist[LHexa] ) glDeleteLists(sc->clist[LHexa],1); 229 | if ( sc->cmlist[LTets] ) glDeleteLists(sc->cmlist[LTets],1); 230 | if ( sc->cmlist[LHexa] ) glDeleteLists(sc->cmlist[LHexa],1); 231 | sc->clist[LTets] = sc->cmlist[LTets] = (GLuint)0; 232 | sc->clist[LHexa] = sc->cmlist[LHexa] = (GLuint)0; 233 | 234 | if ( clip->active & C_CAP ) { 235 | sc->clist[LTets] = capTetra(mesh); 236 | if ( sc->mode & S_MAP ) 237 | sc->cmlist[LTets] = capTetraMap(mesh); 238 | else if ( sc->isotyp & S_ISOLINE ) 239 | sc->ilist[LTets] = capTetraIso(mesh); 240 | } 241 | else { 242 | sc->clist[LTets] = listTetra(sc,mesh,1); 243 | sc->clist[LHexa] = listHexa(sc,mesh,1); 244 | if ( sc->mode & S_MAP ) { 245 | sc->cmlist[LTets] = listTetraMap(sc,mesh,1); 246 | sc->cmlist[LHexa] = listHexaMap(sc,mesh,1); 247 | } 248 | } 249 | if ( !animate ) clip->active ^= C_REDO; 250 | } 251 | else clip->active ^= C_REDO; 252 | 253 | if ( sc->isotyp & S_VECTOR ) { 254 | if ( sc->vlist[LTets] ) glDeleteLists(sc->vlist[LTets],1); 255 | sc->vlist[LTets] = listClipTetraVector(mesh); 256 | if ( sc->vlist[LHexa] ) glDeleteLists(sc->vlist[LHexa],1); 257 | sc->vlist[LHexa] = listClipHexaVector(mesh); 258 | } 259 | if ( !animate ) glutSetCursor(GLUT_CURSOR_INHERIT); 260 | } 261 | 262 | /* display plane frame */ 263 | if ( clip->active & C_HIDE ) return; 264 | 265 | glPushMatrix(); 266 | glMultMatrixf(cliptr->matrix); 267 | scale = 0.3*(sc->dmax+sc->dmin); 268 | glScalef(scale,scale,scale); 269 | drawCap(sc,clip,docap); 270 | glPopMatrix(); 271 | } 272 | 273 | 274 | void copyClip(pClip clip) { 275 | if ( !cclip ) { 276 | cclip = (pClip)M_calloc(1,sizeof(struct clip),"clip"); 277 | if ( !clip ) exit(2); 278 | } 279 | cclip = (pClip)memcpy(cclip,clip,sizeof(struct clip)); 280 | if ( !cclip ) exit(2); 281 | curclip = 1; 282 | } 283 | 284 | int pasteClip(pClip clip) { 285 | if ( !curclip ) return(0); 286 | clip = (pClip)memcpy(clip,cclip,sizeof(struct clip)); 287 | if ( !clip ) exit(2); 288 | clip->active = 0; 289 | curclip = 0; 290 | return(1); 291 | } 292 | 293 | void tiltClip(pScene sc,pClip clip) { 294 | float axis[4]; 295 | 296 | axis[0] = clip->cliptr->axis[0]; 297 | axis[1] = clip->cliptr->axis[1]; 298 | axis[2] = clip->cliptr->axis[2]; 299 | 300 | transformVector(clip->cliptr->axis,axis,sc->view->matrix); 301 | /*clip->cliptr->angle = 90.0;*/ 302 | 303 | clip->active |= C_REDO; 304 | } 305 | 306 | /* change clip orientation */ 307 | void invertClip(pScene sc,pClip clip) { 308 | clip->eqn[0] = -clip->eqn[0]; 309 | clip->eqn[1] = -clip->eqn[1]; 310 | clip->eqn[2] = -clip->eqn[2]; 311 | clip->eqn[3] = -clip->eqn[3]; 312 | plane[0] = -plane[0]; 313 | } 314 | 315 | void resetClip(pScene sc,pClip clip,pMesh mesh) { 316 | double dd; 317 | 318 | resetTransform(clip->cliptr); 319 | dd = sc->par.clip[0]*sc->par.clip[3] + sc->par.clip[1]*sc->par.clip[4] \ 320 | + sc->par.clip[2]*sc->par.clip[5]; 321 | 322 | clip->active |= C_REDO; 323 | clip->eqn[0] = sc->par.clip[3]; 324 | clip->eqn[1] = sc->par.clip[4]; 325 | clip->eqn[2] = sc->par.clip[5]; 326 | clip->eqn[3] = -dd; 327 | /*clip->active = C_ON + C_VOL;*/ 328 | } 329 | 330 | 331 | /* create a clipping plane */ 332 | pClip createClip(pScene sc,pMesh mesh) { 333 | pClip clip; 334 | 335 | /* default */ 336 | clip = (pClip)M_calloc(1,sizeof(struct clip),"clip"); 337 | assert(clip); 338 | clip->cliptr = (pTransform)M_calloc(1,sizeof(struct transform),"clip"); 339 | assert(clip->cliptr); 340 | 341 | resetClip(sc,clip,mesh); 342 | return(clip); 343 | } 344 | 345 | 346 | -------------------------------------------------------------------------------- /src/compil.date: -------------------------------------------------------------------------------- 1 | #define COMPIL "2021-05-20 07:58:25" -------------------------------------------------------------------------------- /src/critip.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "extern.h" 3 | #include "sproto.h" 4 | 5 | typedef struct saddle { 6 | double r1,r2; 7 | float pt[3]; 8 | float vp1[2],vp2[2]; 9 | int k; 10 | } Saddle; 11 | 12 | 13 | #define EPSD 1.e-14 14 | #define EPS3 1.e-03 15 | #define MAXPS 100 16 | 17 | static int idir[5] = {0,1,2,0,1}; 18 | 19 | 20 | int closedBall(pMesh mesh,int depart,ubyte i) { 21 | pTriangle pt; 22 | int adj,iadr; 23 | ubyte voy; 24 | 25 | pt = &mesh->tria[depart]; 26 | voy = idir[i+1]; 27 | iadr = 3*(depart-1)+1; 28 | adj = mesh->adja[iadr+voy]; 29 | 30 | /* search triangles in ball */ 31 | while ( adj && adj != depart ) { 32 | voy = mesh->voy[iadr+voy]; 33 | iadr = 3*(adj-1)+1; 34 | voy = idir[voy+2]; 35 | adj = mesh->adja[iadr+voy]; 36 | } 37 | 38 | return( adj == depart ); 39 | } 40 | 41 | 42 | GLuint listCritPoint(pScene sc,pMesh mesh) { 43 | pTriangle pt; 44 | pPoint p0,p1,p2; 45 | pSolution s0,s1,s2; 46 | pMaterial pm; 47 | Saddle sad[MAXPS]; 48 | GLuint dlist; 49 | double aire,ux,uy,vx,vy,dd,cb0[3],cb1[3],cb2[3],vv[3][2],bc[3]; 50 | double rgb[3],a0,a1,delta,rr1,rr2,aa,dmin; 51 | double p[3]; 52 | int *adj,iadr,i,i1,i2,k,m,ncp,ps,ifilt; 53 | ubyte typ,tag; 54 | static double hsv[3] = {0.0f, 1.0f, 0.80f}; 55 | 56 | if ( !mesh->nbb || mesh->nfield != mesh->dim ) return(0); 57 | if ( mesh->nt && !hashTria(mesh) ) return(0); 58 | if ( egal(sc->iso.val[0],sc->iso.val[MAXISO-1]) ) return(0); 59 | fprintf(stdout," Identification of critical points\n"); 60 | 61 | /* build list */ 62 | typ = 0; 63 | ncp = 0; 64 | ps = 0; 65 | dlist = glGenLists(1); 66 | glNewList(dlist,GL_COMPILE); 67 | if ( glGetError() ) return(0); 68 | glPointSize(4.0); 69 | 70 | dmin = sc->dmax * EPS; 71 | dmin *= dmin; 72 | ifilt = 0; 73 | hsv[0] = sc->iso.col[0]; 74 | hsvrgb(hsv,rgb); 75 | 76 | for (m=0; mpar.nbmat; m++) { 77 | pm = &sc->material[m]; 78 | k = pm->depmat[LTria]; 79 | if ( !k || pm->flag ) continue; 80 | 81 | while ( k != 0 ) { 82 | pt = &mesh->tria[k]; 83 | if ( !pt->v[0] ) { 84 | k = pt->nxt; 85 | continue; 86 | } 87 | p0 = &mesh->point[pt->v[0]]; 88 | p1 = &mesh->point[pt->v[1]]; 89 | p2 = &mesh->point[pt->v[2]]; 90 | s0 = &mesh->sol[pt->v[0]]; 91 | s1 = &mesh->sol[pt->v[1]]; 92 | s2 = &mesh->sol[pt->v[2]]; 93 | 94 | ux = p1->c[0] - p0->c[0]; 95 | uy = p1->c[1] - p0->c[1]; 96 | vx = p2->c[0] - p0->c[0]; 97 | vy = p2->c[1] - p0->c[1]; 98 | aire = ux*vy - uy*vx; 99 | if ( fabs(aire) < 1.e-200 ) { 100 | k = pt->nxt; 101 | continue; 102 | } 103 | else if ( aire < 0.0 ) { 104 | p1 = &mesh->point[pt->v[2]]; 105 | p2 = &mesh->point[pt->v[1]]; 106 | s1 = &mesh->sol[pt->v[2]]; 107 | s2 = &mesh->sol[pt->v[1]]; 108 | aire = -aire; 109 | } 110 | 111 | /* coef des barycentriques */ 112 | aire = 1.0 / aire; 113 | cb0[0] = p1->c[1] - p2->c[1]; 114 | cb0[1] = -(p1->c[0] - p2->c[0]); 115 | cb0[2] = p1->c[0]*p2->c[1] - p1->c[1]*p2->c[0]; 116 | 117 | cb1[0] = p2->c[1] - p0->c[1]; 118 | cb1[1] = -(p2->c[0] - p0->c[0]); 119 | cb1[2] = p2->c[0]*p0->c[1] - p2->c[1]*p0->c[0]; 120 | 121 | cb2[0] = p0->c[1] - p1->c[1]; 122 | cb2[1] = -(p0->c[0] - p1->c[0]); 123 | cb2[2] = p0->c[0]*p1->c[1] - p0->c[1]*p1->c[0]; 124 | for (i=0; i<3; i++) { 125 | vv[i][0] = aire * (cb0[i]*s0->m[0] + cb1[i]*s1->m[0] + cb2[i]*s2->m[0]); 126 | vv[i][1] = aire * (cb0[i]*s0->m[1] + cb1[i]*s1->m[1] + cb2[i]*s2->m[1]); 127 | } 128 | 129 | dd = vv[0][0]*vv[1][1] - vv[0][1]*vv[1][0]; 130 | if ( fabs(dd) < EPSD ) { 131 | k = pt->nxt; 132 | continue; 133 | } 134 | 135 | dd = 1.0 / dd; 136 | p[0] = dd * (vv[1][0]*vv[2][1] - vv[2][0]*vv[1][1]); 137 | p[1] = dd * (vv[0][1]*vv[2][0] - vv[0][0]*vv[2][1]); 138 | p[2] = 0.0; 139 | 140 | if ( p[0] < mesh->xmin-mesh->xtra || p[0] > mesh->xmax-mesh->xtra 141 | || p[1] < mesh->ymin-mesh->ytra || p[1] > mesh->ymax-mesh->ytra ) { 142 | k = pt->nxt; 143 | continue; 144 | } 145 | else if ( !inTria(mesh,k,p,bc) ) { 146 | k = pt->nxt; 147 | continue; 148 | } 149 | 150 | /* filtering boundary points */ 151 | tag = 0; 152 | for (i=0; i<3; i++) tag |= (bc[i] < EPS3) << i; 153 | if ( tag ) { 154 | iadr = 3*(k-1)+1; 155 | adj = &mesh->adja[iadr]; 156 | ifilt ++; 157 | switch (tag) { 158 | case 1: 159 | if ( !adj[0] ) { 160 | k = pt->nxt; 161 | continue; 162 | } 163 | break; 164 | case 2: 165 | if ( !adj[1] ) { 166 | k = pt->nxt; 167 | continue; 168 | } 169 | break; 170 | case 4: 171 | if ( !adj[2] ) { 172 | k = pt->nxt; 173 | continue; 174 | } 175 | break; 176 | case 3: 177 | if ( !closedBall(mesh,k,2) ) { 178 | k = pt->nxt; 179 | continue; 180 | } 181 | break; 182 | case 5: 183 | if ( !closedBall(mesh,k,1) ) { 184 | k = pt->nxt; 185 | continue; 186 | } 187 | break; 188 | case 6: 189 | if ( !closedBall(mesh,k,0) ) { 190 | k = pt->nxt; 191 | continue; 192 | } 193 | break; 194 | } 195 | } 196 | 197 | /* eigenvalues of jacobian */ 198 | a1 = -(vv[0][0] + vv[1][1]); 199 | a0 = vv[0][0] *vv[1][1] - vv[0][1]*vv[1][0]; 200 | delta = a1*a1 - 4*a0; 201 | i1 = i2 = 0; 202 | if ( delta >= 0.0 ) { 203 | delta = sqrt(delta); 204 | rr1 = 0.5 * (-a1+delta); 205 | rr2 = 0.5 * (-a1-delta); 206 | } 207 | else { 208 | delta = sqrt(fabs(delta)); 209 | rr1 = rr2 = -0.5 * a1; 210 | i1 = i2 = 0.5 * delta; 211 | } 212 | 213 | /* classification */ 214 | if ( i1 && i2 ) { 215 | glColor3f(0.0,1.0,0.5); 216 | if ( rr1 == 0.0f && rr2 == 0.0f ) 217 | output2(p[0],p[1],"Cp"); /* center */ 218 | else if ( rr1 > 0.0f && rr2 > 0.0f ) 219 | output2(p[0],p[1],"Rf"); /* repelling focus */ 220 | else if ( rr1 < 0.0f && rr2 < 0.0f ) 221 | output2(p[0],p[1],"Af"); /* attracting focus */ 222 | } 223 | else if ( !i1 && !i2 ) { 224 | glColor3f(1.0,0.5,0.0); 225 | if ( rr1 > 0.0f && rr2 > 0.0f ) 226 | output2(p[0],p[1],"Rn"); /* repelling node */ 227 | else if ( rr1 < 0.0f && rr2 < 0.0f ) 228 | output2(p[0],p[1],"An"); /* attracting node */ 229 | else if ( rr1*rr2 < 0.0f ) { 230 | output2(p[0],p[1],"Sp"); /* Saddle point */ 231 | if ( ddebug ) 232 | printf(" saddle point %f %f\n",p[0]+mesh->xtra,p[1]+mesh->ytra); 233 | if ( ps < MAXPS-5 ) { 234 | ++ps; 235 | sad[ps].pt[0] = p[0]; 236 | sad[ps].pt[1] = p[1]; 237 | sad[ps].pt[2] = 0.0f; 238 | 239 | /* eigenvalues */ 240 | sad[ps].r1 = rr1; 241 | sad[ps].r2 = rr2; 242 | 243 | /* eigenvectors */ 244 | aa = vv[0][0]*vv[0][0]; 245 | dd = vv[1][1]*vv[1][1]; 246 | delta = sqrt(aa-2.0*vv[0][0]*vv[1][1]+dd+4.0*vv[0][1]*vv[1][0]); 247 | sad[ps].vp1[0] = -0.5*(-vv[0][0]+vv[1][1]-delta); 248 | sad[ps].vp1[1] = vv[0][1]; 249 | 250 | sad[ps].vp2[0] = -0.5*(-vv[0][0]+vv[1][1]+delta); 251 | sad[ps].vp2[1] = vv[0][1]; 252 | 253 | sad[ps].k = k; 254 | } 255 | } 256 | } 257 | /* point color */ 258 | glBegin(GL_POINTS); 259 | glColor3dv(rgb); 260 | glVertex2f(p[0],p[1]); 261 | glEnd(); 262 | pt->cpt--; 263 | ++ncp; 264 | fprintf(stdout," %3d: %f %f \n",p[0]+mesh->xtra,p[1]+mesh->ytra,ncp); 265 | k = pt->nxt; 266 | } 267 | } 268 | glPointSize(1.0); 269 | glEndList(); 270 | 271 | if ( ncp ) 272 | fprintf(stdout," %d critical points identified (%d filtered)\n",ncp,ifilt); 273 | 274 | return(dlist); 275 | 276 | if ( ps ) { 277 | fprintf(stdout," Building streamline(s)"); 278 | fflush(stdout); 279 | 280 | if ( !sc->slist ) { 281 | sc->stream = createStream(sc,mesh); 282 | if ( !sc->stream ) return(dlist); 283 | } 284 | for (k=1; k<=ps; k++) { 285 | if ( ddebug ) printf(" eigenv1 %f %f\n",sad[k].vp1[0],sad[k].vp1[1]); 286 | 287 | listSaddleStream(sc,mesh,sad[k].k,sad[k].pt,sad[k].vp1,sad[k].r1); 288 | sad[k].vp1[0] = -sad[k].vp1[0]; 289 | sad[k].vp1[1] = -sad[k].vp1[1]; 290 | listSaddleStream(sc,mesh,sad[k].k,sad[k].pt,sad[k].vp1,sad[k].r1); 291 | 292 | if ( ddebug ) printf(" eigenv2 %f %f\n",sad[k].vp2[0],sad[k].vp2[1]); 293 | listSaddleStream(sc,mesh,sad[k].k,sad[k].pt,sad[k].vp2,sad[k].r2); 294 | sad[k].vp2[0] = -sad[k].vp2[0]; 295 | sad[k].vp2[1] = -sad[k].vp2[1]; 296 | listSaddleStream(sc,mesh,sad[k].k,sad[k].pt,sad[k].vp2,sad[k].r2); 297 | } 298 | sc->isotyp |= S_STREAML; 299 | fprintf(stdout,": %d lines",ps); 300 | } 301 | 302 | return(dlist); 303 | } 304 | -------------------------------------------------------------------------------- /src/cube.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "extern.h" 3 | #include "sproto.h" 4 | 5 | 6 | /* display cube */ 7 | void updateCube(pCube cube,pMesh mesh) { 8 | pScene sc; 9 | pTransform cubetr,view; 10 | GLfloat inv[16],axis[4],trans[4]; 11 | int idw; 12 | 13 | /* default */ 14 | if ( ddebug ) printf("updateCube\n"); 15 | 16 | /* retrieve context */ 17 | idw = currentScene(); 18 | sc = cv.scene[idw]; 19 | view = sc->view; 20 | cubetr = cube->cubetr; 21 | 22 | /* compute cube transform */ 23 | if ( cube->active & C_EDIT ) { 24 | invertMatrix(view->matrix,inv); 25 | inv[3] = inv[7] = inv[11] = 0.0f; inv[15] = 1.0; 26 | 27 | /* rotation cumulative */ 28 | if ( cubetr->angle != 0.0 ) { 29 | transformVector(trans,cubetr->axis,inv); 30 | glPushMatrix(); 31 | glLoadIdentity(); 32 | glRotatef(cubetr->angle,trans[0],trans[1],trans[2]); 33 | glMultMatrixf(cubetr->rot); 34 | glGetFloatv(GL_MODELVIEW_MATRIX,cubetr->rot); 35 | glPopMatrix(); 36 | } 37 | 38 | /* translation cumulative */ 39 | axis[0] = cubetr->panx; 40 | axis[1] = cubetr->pany; 41 | axis[2] = 0.0; 42 | axis[3] = 1.0; 43 | transformVector(trans,axis,inv); 44 | 45 | cubetr->tra[12] = trans[0]; 46 | cubetr->tra[13] = trans[1]; 47 | cubetr->tra[14] = trans[2]; 48 | 49 | /* final transformation */ 50 | glPushMatrix(); 51 | glLoadIdentity(); 52 | glMultMatrixf(cubetr->tra); 53 | glMultMatrixf(cubetr->rot); 54 | glGetFloatv(GL_MODELVIEW_MATRIX,cubetr->matrix); 55 | glPopMatrix(); 56 | } 57 | if ( !cubetr->manim ) { 58 | cubetr->angle = 0.0; 59 | cube->active ^= C_UPDATE; 60 | } 61 | } 62 | 63 | 64 | void dumpCube(pScene sc,pMesh mesh,pCube cube) { 65 | float *tr,u[4]; 66 | double v[4]; 67 | int i; 68 | FILE *out; 69 | 70 | tr = cube->cubetr->matrix; 71 | 72 | out = fopen("tr.data","w"); 73 | for (i=0; i<4; i++) 74 | fprintf(out,"%f %f %f %f\n",tr[i],tr[4+i],tr[8+i],tr[12+i]); 75 | 76 | u[0] = cube->cmi[0] - mesh->xtra; 77 | u[1] = cube->cmi[1] - mesh->ytra; 78 | u[2] = cube->cmi[2] - mesh->ztra; 79 | u[3] = 1.0; 80 | /*printf("avant %f %f %f %f\n",u[0],u[1],u[2],u[3]);*/ 81 | transformPoint2(v,u,tr); 82 | fprintf(out,"\n%f %f %f %f\n", 83 | v[0]+mesh->xtra,v[1]+mesh->ytra,v[2]+mesh->ztra,v[3]); 84 | 85 | u[0] = cube->cma[0] - mesh->xtra; 86 | u[1] = cube->cma[1] - mesh->ytra; 87 | u[2] = cube->cma[2] - mesh->ztra; 88 | /*printf("avant %f %f %f %f\n",u[0],u[1],u[2],u[3]);*/ 89 | transformPoint2(v,u,tr); 90 | fprintf(out,"%f %f %f %f\n", 91 | v[0]+mesh->xtra,v[1]+mesh->ytra,v[2]+mesh->ztra,v[3]); 92 | 93 | fprintf(out,"\n%f %f %f\n", 94 | cube->cubetr->tra[12],cube->cubetr->tra[13],cube->cubetr->tra[14]); 95 | 96 | fprintf(out,"%f %f %f %f\n", 97 | cube->cubetr->angle,cube->cubetr->axis[0],cube->cubetr->axis[1], 98 | cube->cubetr->axis[2]); 99 | fclose(out); 100 | } 101 | 102 | 103 | void resetCube(pScene sc,pCube cube,pMesh mesh) { 104 | 105 | resetTransform(cube->cubetr); 106 | 107 | cube->active |= C_REDO; 108 | cube->cmi[0] = mesh->xmin; 109 | cube->cmi[1] = mesh->ymin; 110 | cube->cmi[2] = mesh->zmin; 111 | cube->cma[0] = mesh->xmax; 112 | cube->cma[1] = mesh->ymax; 113 | cube->cma[2] = mesh->zmax; 114 | } 115 | 116 | 117 | pCube createCube(pScene sc,pMesh mesh) { 118 | pCube cube; 119 | 120 | cube = (pCube)M_calloc(1,sizeof(struct cube),"cube"); 121 | assert(cube); 122 | 123 | cube->cubetr = (pTransform)M_calloc(1,sizeof(struct transform),"cube"); 124 | if ( !cube->cubetr ) return(0); 125 | 126 | resetCube(sc,cube,mesh); 127 | return(cube); 128 | } 129 | -------------------------------------------------------------------------------- /src/eigenv.h: -------------------------------------------------------------------------------- 1 | int eigenv(int symmat,double *mat,double lambda[3],double v[3][3]); 2 | int eigen2(double *mm,double *lambda,double vp[2][2]); 3 | -------------------------------------------------------------------------------- /src/ellipse.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "extern.h" 3 | #include "sproto.h" 4 | #include "eigenv.h" 5 | 6 | #ifndef M_PI2 7 | #define M_PI2 (2.0*M_PI) 8 | #endif 9 | 10 | extern int refmat; 11 | extern int eigen2(double m[3],double lambda[2],double vp[2][2]); 12 | 13 | static GLfloat IdMatrix[16] = { 14 | 1.0, 0.0, 0.0, 0.0, 15 | 0.0, 1.0, 0.0, 0.0, 16 | 0.0, 0.0, 1.0, 0.0, 17 | 0.0, 0.0, 0.0, 1.0 18 | }; 19 | 20 | void drawEllipsoid(pScene sc,pMesh mesh,int typel,int k) { 21 | pMaterial pm; 22 | pSolution ps; 23 | pTriangle pt; 24 | pTetra pt1; 25 | pPoint p0; 26 | GLfloat mat[16],cx,cy,cz; 27 | double m[6],lambda[3],v[3][3]; 28 | int i,j,l,iord; 29 | 30 | /* compute average size */ 31 | if ( mesh->nfield != 6 || !mesh->nbb ) return; 32 | 33 | /* draw average ellipse at element */ 34 | if ( typel == LPoint ) { 35 | p0 = &mesh->point[k]; 36 | /*pm = &sc->material[refmat];*/ 37 | pm = &sc->material[p0->ref]; 38 | ps = &mesh->sol[k]; 39 | for (j=0; j<6; j++) m[j] = ps->m[j]; 40 | 41 | iord = eigenv(1,m,lambda,v); 42 | if ( !iord ) return; 43 | lambda[0] = fabs(lambda[0]); 44 | lambda[1] = fabs(lambda[1]); 45 | lambda[2] = fabs(lambda[2]); 46 | 47 | if ( mesh->ne ) { 48 | fprintf(stdout," Eigenvectors :\n vp1 : %f %f %f\n", 49 | v[0][0],v[0][1],v[0][2]); 50 | fprintf(stdout," vp2 : %f %f %f\n",v[1][0],v[1][1],v[1][2]); 51 | fprintf(stdout," vp3 : %f %f %f\n",v[2][0],v[2][1],v[2][2]); 52 | fprintf(stdout," Eigenvalues : %f %f %f %d\n", 53 | lambda[0],lambda[1],lambda[2],iord); 54 | fprintf(stdout," Sizes : %f %f %f\n", 55 | 1.0/sqrt(lambda[0]),1.0/sqrt(lambda[1]),1.0/sqrt(lambda[2])); 56 | } 57 | lambda[0] = max(EPS,0.5/sqrt(lambda[0])); 58 | lambda[1] = max(EPS,0.5/sqrt(lambda[1])); 59 | lambda[2] = max(EPS,0.5/sqrt(lambda[2])); 60 | memcpy(mat,IdMatrix,16*sizeof(GLfloat)); 61 | for (j=0; j<3; j++) 62 | for (l=0; l<3; l++) 63 | mat[j*4+l] = v[j][l]; 64 | 65 | glDisable(GL_LIGHTING); 66 | glPushMatrix(); 67 | glColor4fv(pm->dif); 68 | glTranslatef(p0->c[0],p0->c[1],p0->c[2]); 69 | glMultMatrixf(mat); 70 | glScalef(lambda[0],lambda[1],lambda[2]); 71 | glutWireSphere(1.,30,30); 72 | glPopMatrix(); 73 | glEnable(GL_LIGHTING); 74 | } 75 | 76 | else if ( typel == LTria ) { 77 | pt = &mesh->tria[k]; 78 | if ( mesh->nbb == mesh->np ) 79 | pm = &sc->material[refmat]; 80 | else if ( mesh->nbb == mesh->nt ) 81 | pm = &sc->material[k]; 82 | else 83 | return; 84 | glColor4fv(pm->dif); 85 | for (j=0; j<6; j++) m[j] = 0.; 86 | cx = cy = cz = 0.0; 87 | for (i=0; i<3; i++) { 88 | ps = &mesh->sol[pt->v[i]]; 89 | p0 = &mesh->point[pt->v[i]]; 90 | cx += p0->c[0]; 91 | cy += p0->c[1]; 92 | cz += p0->c[2]; 93 | for (j=0; j<6; j++) 94 | m[j] += ps->m[j]; 95 | } 96 | cx /= 3.; cy /= 3.; cz /= 3.; 97 | for (j=0; j<6; j++) m[j] /= 6.; 98 | 99 | if ( !eigenv(1,m,lambda,v) ) return; 100 | lambda[0] = max(EPS,0.5/sqrt(lambda[0])); 101 | lambda[1] = max(EPS,0.5/sqrt(lambda[1])); 102 | lambda[2] = max(EPS,0.5/sqrt(lambda[2])); 103 | 104 | memcpy(mat,IdMatrix,16*sizeof(GLfloat)); 105 | for (j=0; j<3; j++) 106 | for (l=0; l<3; l++) 107 | mat[j*4+l] = v[j][l]; 108 | 109 | glDisable(GL_LIGHTING); 110 | glPushMatrix(); 111 | glColor4fv(pm->dif); 112 | glTranslatef(cx,cy,cz); 113 | glMultMatrixf(mat); 114 | glScalef(lambda[0],lambda[1],lambda[2]); 115 | glutWireSphere(1.,30,30); 116 | glPopMatrix(); 117 | glEnable(GL_LIGHTING); 118 | } 119 | 120 | else if ( typel == LTets ) { 121 | pt1 = &mesh->tetra[k]; 122 | pm = &sc->material[refmat]; 123 | glColor4fv(pm->dif); 124 | for (j=0; j<6; j++) m[j] = 0.; 125 | cx = cy = cz = 0.0; 126 | for (i=0; i<4; i++) { 127 | if ( mesh->nbb == mesh->np ) 128 | ps = &mesh->sol[pt1->v[i]]; 129 | else if ( mesh->nbb == mesh->ntet ) 130 | ps = &mesh->sol[k]; 131 | else 132 | return; 133 | p0 = &mesh->point[pt1->v[i]]; 134 | cx += p0->c[0]; 135 | cy += p0->c[1]; 136 | cz += p0->c[2]; 137 | for (j=0; j<6; j++) 138 | m[j] += ps->m[j]; 139 | } 140 | cx /= 4.; cy /= 4.; cz /= 4.; 141 | for (j=0; j<6; j++) m[j] /= 6.; 142 | 143 | if ( !eigenv(1,m,lambda,v) ) return; 144 | lambda[0] = max(EPS,0.5/sqrt(lambda[0])); 145 | lambda[1] = max(EPS,0.5/sqrt(lambda[1])); 146 | lambda[2] = max(EPS,0.5/sqrt(lambda[2])); 147 | 148 | memcpy(mat,IdMatrix,16*sizeof(GLfloat)); 149 | for (j=0; j<3; j++) 150 | for (l=0; l<3; l++) 151 | mat[j*4+l] = v[j][l]; 152 | glDisable(GL_LIGHTING); 153 | glPushMatrix(); 154 | glColor4fv(pm->dif); 155 | glTranslatef(cx,cy,cz); 156 | glMultMatrixf(mat); 157 | glScalef(lambda[0],lambda[1],lambda[2]); 158 | glutWireSphere(1.,30,30); 159 | glPopMatrix(); 160 | glEnable(GL_LIGHTING); 161 | 162 | } 163 | else return; 164 | } 165 | 166 | 167 | void glCircle(float radius) { 168 | float ang,ux,uy; 169 | 170 | ux = 0.0f; 171 | uy = radius; 172 | 173 | glBegin(GL_LINE_STRIP); 174 | for (ang=0.0f; ang<=2*M_PI+0.2; ang+=0.2) { 175 | ux = radius*(float)sin((double)ang); 176 | uy = radius*(float)cos((double)ang); 177 | glVertex2f(ux,uy); 178 | } 179 | glEnd(); 180 | } 181 | 182 | 183 | void drawEllipse(pScene sc,pMesh mesh,int typel,int k) { 184 | pMaterial pm; 185 | pSolution ps; 186 | pPoint p0; 187 | double m[3],vp[2][2],lambda[2],dd1,dd2; 188 | float theta; 189 | 190 | /* draw ellipse at vertex */ 191 | if ( typel == LPoint ) { 192 | ps = &mesh->sol[k]; 193 | p0 = &mesh->point[k]; 194 | pm = &sc->material[refmat]; 195 | 196 | m[0] = ps->m[0]; 197 | m[1] = ps->m[1]; 198 | m[2] = ps->m[2]; 199 | if ( !eigen2(m,lambda,vp) ) return; 200 | 201 | /* consider eigenvalues as sizes */ 202 | dd1 = 1.0 / sqrt(fabs(lambda[0])); 203 | dd2 = 1.0 / sqrt(fabs(lambda[1])); 204 | 205 | glDisable(GL_LIGHTING); 206 | glPushMatrix(); 207 | glLineWidth(1.0); 208 | glBegin(GL_LINES); 209 | glColor3fv(pm->dif); 210 | glVertex3f(p0->c[0],p0->c[1],0.0); 211 | glColor3fv(pm->dif); 212 | glVertex3f(p0->c[0]+dd1*vp[0][0],p0->c[1]+dd1*vp[0][1],0.0); 213 | 214 | glColor3fv(pm->dif); 215 | glVertex3f(p0->c[0],p0->c[1],0.0); 216 | glColor3fv(pm->dif); 217 | glVertex3f(p0->c[0]+dd2*vp[1][0],p0->c[1]+dd2*vp[1][1],0.0); 218 | glEnd(); 219 | 220 | theta = atan2(vp[0][1],vp[0][0])*RTOD; 221 | glTranslatef(p0->c[0],p0->c[1],0.0); 222 | glRotatef(theta,0.0,0.0,1.0); 223 | glScaled(dd1,dd2,0.0); 224 | 225 | glColor3fv(pm->dif); 226 | glCircle(1.0); 227 | glLineWidth(1.0); 228 | glPopMatrix(); 229 | glEnable(GL_LIGHTING); 230 | 231 | /* print out info */ 232 | fprintf(stdout," Eigenvectors :\n"); 233 | fprintf(stdout," vp1 : %f %f\n",vp[0][0],vp[0][1]); 234 | fprintf(stdout," vp2 : %f %f\n",vp[1][0],vp[1][1]); 235 | fprintf(stdout," Eigenvalues : %f %f\n",lambda[0],lambda[1]); 236 | fprintf(stdout," Sizes : %f %f\n",dd1,dd2); 237 | } 238 | } 239 | 240 | 241 | GLuint drawAllEllipse(pScene sc,pMesh mesh) { 242 | GLuint dlist; 243 | pSolution ps; 244 | pMaterial pm; 245 | pTriangle pt; 246 | pPoint p0; 247 | double m[3],vp[2][2],lambda[2],dd1,dd2; 248 | float theta,cx,cy; 249 | int k,i,ref; 250 | 251 | dlist = glGenLists(1); 252 | glNewList(dlist,GL_COMPILE); 253 | if ( glGetError() ) return(0); 254 | 255 | /* draw ellipse at vertex */ 256 | glDisable(GL_LIGHTING); 257 | glLineWidth(1.0); 258 | 259 | if ( mesh->typage == 1 ) { 260 | for (k=1; k<=mesh->ne; k++) { 261 | ps = &mesh->sol[k]; 262 | pt = &mesh->tria[k]; 263 | if ( !pt->v[0] ) continue; 264 | 265 | ref = matRef(sc,pt->ref); 266 | pm = &sc->material[ref]; 267 | if ( pm->flag ) continue; 268 | 269 | cx = cy = 0.0; 270 | for (i=0; i<3; i++) { 271 | p0 = &mesh->point[pt->v[i]]; 272 | cx += p0->c[0]; 273 | cy += p0->c[1]; 274 | } 275 | cx *= 1. / 3.; 276 | cy *= 1. / 3.; 277 | 278 | m[0] = ps->m[0]; 279 | m[1] = ps->m[1]; 280 | m[2] = ps->m[2]; 281 | if ( !eigen2(m,lambda,vp) ) return(0); 282 | 283 | /* consider eigenvalues as sizes */ 284 | dd1 = 1.0 / sqrt(fabs(lambda[0])); 285 | dd2 = 1.0 / sqrt(fabs(lambda[1])); 286 | 287 | glPushMatrix(); 288 | theta = atan2(vp[0][1],vp[0][0])*RTOD; 289 | glTranslatef(cx,cy,0.0); 290 | glRotatef(theta,0.0,0.0,1.0); 291 | glScaled(dd1,dd2,0.0); 292 | glColor3fv(pm->dif); 293 | glCircle(1.0); 294 | glPopMatrix(); 295 | } 296 | } 297 | else { 298 | for (k=1; k<=mesh->np; k++) { 299 | ps = &mesh->sol[k]; 300 | p0 = &mesh->point[k]; 301 | 302 | ref = matRef(sc,p0->ref); 303 | pm = &sc->material[ref]; 304 | if ( pm->flag ) continue; 305 | 306 | m[0] = ps->m[0]; 307 | m[1] = ps->m[1]; 308 | m[2] = ps->m[2]; 309 | if ( !eigen2(m,lambda,vp) ) return(0); 310 | 311 | /* consider eigenvalues as sizes */ 312 | dd1 = 1.0 / sqrt(fabs(lambda[0])); 313 | dd2 = 1.0 / sqrt(fabs(lambda[1])); 314 | 315 | glPushMatrix(); 316 | theta = atan2(vp[0][1],vp[0][0])*RTOD; 317 | glTranslatef(p0->c[0],p0->c[1],0.0); 318 | glRotatef(theta,0.0,0.0,1.0); 319 | glScaled(dd1,dd2,0.0); 320 | glColor3fv(pm->dif); 321 | glCircle(1.0); 322 | glPopMatrix(); 323 | } 324 | } 325 | glEnable(GL_LIGHTING); 326 | 327 | glEndList(); 328 | return(dlist); 329 | } 330 | 331 | 332 | void circumSphere(pScene sc,pMesh mesh,int typel,int k) { 333 | pMaterial pm; 334 | double c[3],rad; 335 | 336 | cenrad(mesh,k,c,&rad); 337 | rad = sqrt(rad); 338 | pm = &sc->material[refmat]; 339 | 340 | glDisable(GL_LIGHTING); 341 | glPushMatrix(); 342 | glColor4fv(pm->dif); 343 | glTranslated(c[0],c[1],c[2]); 344 | glScalef(rad,rad,rad); 345 | glutWireSphere(1.,30,30); 346 | glPopMatrix(); 347 | glEnable(GL_LIGHTING); 348 | } 349 | 350 | 351 | void drawH2O() { 352 | static float h2o[3][3] = {0.0, 0.0, 0.2137, 0., 1.4161, -0.855, 0., -1.4161, -0.855 }; 353 | 354 | glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); 355 | glColor3f(0.8, 0.1, 0.1); 356 | glPushMatrix(); 357 | glTranslatef(h2o[0][0],h2o[0][1],h2o[0][2]); 358 | glScalef(.2,.2,.2); 359 | glutSolidSphere(1.,30,30); 360 | glPopMatrix(); 361 | 362 | glColor3f(0.8, 0.8, 0.8); 363 | glPushMatrix(); 364 | glTranslatef(h2o[1][0],h2o[1][1],h2o[1][2]); 365 | glScalef(.2,.2,.2); 366 | glutSolidSphere(1.,30,30); 367 | glPopMatrix(); 368 | 369 | glColor3f(0.8, 0.8, 0.8); 370 | glPushMatrix(); 371 | glTranslatef(h2o[2][0],h2o[2][1],h2o[2][2]); 372 | glScalef(.2,.2,.2); 373 | glutSolidSphere(1.,30,30); 374 | glPopMatrix(); 375 | 376 | glColor3f(0.5, 0.5, 0.5); 377 | glLineWidth(10); 378 | glBegin(GL_LINES); 379 | glVertex3d(h2o[0][0],h2o[0][1],h2o[0][2]); 380 | glVertex3d(h2o[1][0],h2o[1][1],h2o[1][2]); 381 | 382 | glVertex3d(h2o[0][0],h2o[0][1],h2o[0][2]); 383 | glVertex3d(h2o[2][0],h2o[2][1],h2o[2][2]); 384 | glEnd(); 385 | glLineWidth(1.); 386 | } 387 | 388 | 389 | -------------------------------------------------------------------------------- /src/extern.h: -------------------------------------------------------------------------------- 1 | #ifndef __MEDIT 2 | extern Canvas cv; 3 | extern ubyte ddebug,quiet,imprim,option,morphing,animate,saveimg,imgtype; 4 | extern int animdep,animfin; 5 | extern char *imgtyp[]; 6 | #endif 7 | -------------------------------------------------------------------------------- /src/geometry.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "extern.h" 3 | #include "sproto.h" 4 | 5 | extern int getIso(pScene sc,double norm,double *hsv); 6 | 7 | 8 | GLuint geomList(pScene sc,pMesh mesh) { 9 | GLuint list = 0; 10 | pMaterial pm; 11 | pEdge pr; 12 | pPoint ppt,pp0,pp1; 13 | pSolution ps0; 14 | double dd,rgb[3],val; 15 | float n[3]; 16 | int k,it = 0,nm; 17 | char nodata; 18 | static float green[4] = {0.0, 1.0, 0.0, 1.0}; 19 | static float rouge[4] = {1.0, 0.0, 0.0, 1.0}; 20 | static float jaune[4] = {1.0, 1.0, 0.0, 1.0}; 21 | static float orange[4]= {1.0, 0.65, 0.0, 1.0}; 22 | static double hsv[3] = { 0.0, 1.0, 0.8 }; 23 | 24 | /* default */ 25 | if ( mesh->na+mesh->nc+mesh->np == 0 ) return(0); 26 | nodata = egal(sc->iso.val[0],sc->iso.val[MAXISO-1]); 27 | 28 | /* create display list */ 29 | list = glGenLists(1); 30 | if ( !list ) return(0); 31 | glNewList(list,GL_COMPILE); 32 | if ( glGetError() ) return(0); 33 | 34 | /* draw corners, ridges and required items */ 35 | if ( ddebug ) printf("construct point list\n"); 36 | if ( mesh->ne ) { 37 | /*--- ancienne partie --- */ 38 | glPointSize(sc->par.pointsize); 39 | glBegin(GL_POINTS); 40 | for (k=1; k<=mesh->np; k++) { 41 | ppt = &mesh->point[k]; 42 | if ( ppt->tag & M_UNUSED ) 43 | continue; 44 | else if ( ppt->tag & M_CORNER ) 45 | glColor3fv(rouge); 46 | else if ( ppt->tag & M_REQUIRED ) 47 | glColor3fv(green); 48 | else if ( !(ppt->tag & M_RIDGE) ) 49 | continue; 50 | else if ( sc->par.linc == 1 ) 51 | glColor3fv(sc->par.edge); 52 | else 53 | glColor3fv(orange); 54 | it++; 55 | glVertex3f(ppt->c[0],ppt->c[1],ppt->c[2]); 56 | } 57 | glEnd(); 58 | /*-------------------------*/ 59 | glPointSize(1); 60 | } 61 | else { 62 | if ( nodata ) 63 | glPointSize(sc->par.pointsize); 64 | else 65 | glPointSize(2.0); 66 | glBegin(GL_POINTS); 67 | for (k=1; k<=mesh->np; k++) { 68 | ppt = &mesh->point[k]; 69 | n[0] = ppt->c[0] - sc->cx; 70 | n[1] = ppt->c[1] - sc->cy; 71 | n[2] = ppt->c[2] - sc->cz; 72 | dd = n[0]*n[0] + n[1]*n[1] + n[2]*n[2]; 73 | if ( dd > 0.0 ) { 74 | dd = 1.0 / sqrt(dd); 75 | n[0] *= dd; 76 | n[1] *= dd; 77 | n[2] *= dd; 78 | } 79 | if ( !nodata ) { 80 | ps0 = &mesh->sol[k]; 81 | val = ps0->bb; 82 | getIso(sc,val,hsv); 83 | hsvrgb(hsv,rgb); 84 | glColor3dv(rgb); 85 | glVertex3f(ppt->c[0],ppt->c[1],ppt->c[2]); 86 | } 87 | else { 88 | glColor3fv(rouge); 89 | glNormal3fv(n); 90 | glVertex3f(ppt->c[0],ppt->c[1],ppt->c[2]); 91 | } 92 | } 93 | glEnd(); 94 | 95 | /*if ( !nodata) { 96 | glPointSize(sc->par.pointsize); 97 | glBegin(GL_POINTS); 98 | for (k=1; k<=mesh->np; k++) { 99 | ppt = &mesh->point[k]; 100 | if ( !ppt->ref ) continue; 101 | ps0 = &mesh->sol[k]; 102 | val = ps0->bb; 103 | getIso(sc,val,hsv); 104 | hsvrgb(hsv,rgb); 105 | glColor3dv(rgb); 106 | glVertex3f(ppt->c[0],ppt->c[1],ppt->c[2]); 107 | } 108 | glEnd(); 109 | }*/ 110 | it = mesh->np; 111 | } 112 | 113 | /* draw edges */ 114 | if ( ddebug ) printf("construct edge list\n"); 115 | glLineWidth(sc->par.linewidth); 116 | glBegin(GL_LINES); 117 | for (k=1; k<=mesh->na; k++) { 118 | pr = &mesh->edge[k]; 119 | if ( pr->v[0] > mesh->np || pr->v[1] > mesh->np ) continue; 120 | 121 | if ( pr->tag & M_RIDGE ) { 122 | if ( pr->tag & M_TAG ) 123 | glColor3fv(jaune); /* ridge + ref en jaune */ 124 | else 125 | glColor3fv(rouge); /* ridges en rouge */ 126 | } 127 | else if ( !pr->ref ) { 128 | glColor3fv(sc->par.edge); 129 | } 130 | else { 131 | nm = matRef(sc,pr->ref); 132 | pm = &sc->material[nm]; 133 | glColor3fv(pm->dif); 134 | } 135 | if ( sc->par.linc == 1 ) glColor3fv(sc->par.edge); 136 | pp0 = &mesh->point[pr->v[0]]; 137 | pp1 = &mesh->point[pr->v[1]]; 138 | glVertex3f(pp0->c[0],pp0->c[1],pp0->c[2]); 139 | glVertex3f(pp1->c[0],pp1->c[1],pp1->c[2]); 140 | it++; 141 | } 142 | glEnd(); 143 | glLineWidth(1.0); 144 | glEndList(); 145 | 146 | if ( it == 0 ) { 147 | glDeleteLists(list,1); 148 | return(0); 149 | } 150 | else 151 | return(list); 152 | } 153 | 154 | -------------------------------------------------------------------------------- /src/gisfil.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "extern.h" 3 | #include "sproto.h" 4 | 5 | #define FLOAT_MAX 1.e20 6 | 7 | int loadGIS(pMesh mesh) { 8 | pQuad pq; 9 | pPoint ppt; 10 | pSolution ps; 11 | FILE *fp; 12 | double xxm,yym,ggx,ggy,hhz; 13 | float *te,cx,cy,cz,gu,hu,xmi,ymi,alt; 14 | int i,j,k,sx,sy,ni,ret,pos,ref; 15 | char *ptr,c,buf[256],data[256]; 16 | ubyte ityp; 17 | 18 | 19 | /* default */ 20 | strcpy(data,mesh->name); 21 | ptr = strstr(data,".gis"); 22 | if ( !ptr ) strcat(data,".gis"); 23 | fp = fopen(data,"rb"); 24 | if ( !fp ) return(0); 25 | fprintf(stdout," Reading %s\n",data); 26 | 27 | if ( !fgets(buf,sizeof(buf),fp) ) { 28 | fprintf(stderr," ## Invalid header.\n"); 29 | return(0); 30 | } 31 | 32 | /* remove leading spaces */ 33 | pos = 0; 34 | while ( (buf[0] == ' ') && (buf[0] != 0x0d) && (buf[0] != 0x0a) ) 35 | memmove(&buf[0],&buf[1],strlen(buf)); 36 | 37 | /* check header file */ 38 | if ( buf[0] != 'G' ) { 39 | fprintf(stderr," ## Invalid format.\n"); 40 | return(0); 41 | } 42 | if ( buf[1] == '1' ) ityp = 1; 43 | else if ( buf[1] == '2' ) ityp = 2; 44 | else { 45 | fprintf(stderr," ## Invalid format ('G?' expected).\n"); 46 | return(0); 47 | } 48 | 49 | /* check and strip comments */ 50 | do { 51 | ret = fscanf(fp,"%s",buf); 52 | if ( ret == EOF ) break; 53 | if ( buf[0] == '#' ) 54 | do 55 | c = getc(fp); 56 | while ( c != '\n' ); 57 | else break; 58 | } 59 | while (1); 60 | 61 | /* header */ 62 | ret = sscanf(buf,"%d",&sy); 63 | ret += fscanf(fp,"%d",&sx); 64 | ret += fscanf(fp,"%f %f %f",&cx,&cy,&cz); 65 | ret += fscanf(fp,"%f",&gu); 66 | ret += fscanf(fp,"%f",&hu); 67 | ret += fscanf(fp,"%f %f",&xmi,&ymi); 68 | if ( ret != 9 ) { 69 | fprintf(stderr," ## Error loading terrain.\n"); 70 | free(mesh); 71 | return(0); 72 | } 73 | 74 | if ( ddebug ) { 75 | fprintf(stdout," header: sx %7d sy %7d\n",sx,sy); 76 | fprintf(stdout," cx %7.2f cy %7.2f cz %7.2f\n",cx,cy,cz); 77 | fprintf(stdout," units: %7.2f %7.2f\n",gu,hu); 78 | fprintf(stdout," min: %7.3e %7.3e\n",xmi,ymi); 79 | fprintf(stdout," terrain size: %dx%d\n",sx,sy); 80 | } 81 | 82 | mesh->np = sx*sy; 83 | mesh->nt = 0; 84 | mesh->nq = (sx-1)*(sy-1); 85 | mesh->ne = mesh->nq; 86 | 87 | /* memory allocation for mesh */ 88 | if ( !zaldy1(mesh) ) { 89 | fclose(fp); 90 | return(0); 91 | } 92 | 93 | /* read data */ 94 | if ( ityp == 1 ) { 95 | xxm = xmi / cx; 96 | yym = ymi / cy; 97 | ggx = gu * cx; 98 | ggy = gu * cy; 99 | hhz = hu * cz; 100 | for (j=1; j<=sy; j++) 101 | for (i=1; i<=sx; i++) { 102 | k = (j-1)*sx + i; 103 | ppt = &mesh->point[k]; 104 | fscanf(fp,"%f",&alt); 105 | ppt->c[0] = ggx*(xxm + i-1); 106 | ppt->c[1] = ggy*(yym + j-1); 107 | ppt->c[2] = hhz*alt; 108 | } 109 | } 110 | else { 111 | te = (float*)malloc(sx*sizeof(float)); 112 | if ( !te ) exit(1); 113 | ni = 0; 114 | xxm = xmi / cx; 115 | yym = ymi / cy; 116 | ggx = gu / cx; 117 | ggy = gu / cy; 118 | hhz = hu / cz; 119 | for (j=1; j<=sy; j++) { 120 | ret = fread(te,sizeof(int),sx,fp); 121 | if ( ret != sx ) { 122 | fprintf(stderr," ## Error loading terrain.\n"); 123 | free(mesh->point); 124 | free(mesh); 125 | return(0); 126 | } 127 | for (i=1; i<=sx; i++) { 128 | k = (j-1)*sx + i; 129 | ppt = &mesh->point[k]; 130 | ppt->c[2] = hhz * te[ni++]; 131 | ppt->c[0] = ggx*(xxm + i-1); 132 | ppt->c[1] = ggy*(yym + j-1); 133 | ppt->tag &= ~M_UNUSED; 134 | } 135 | } 136 | free(te); 137 | } 138 | 139 | /* construct topology */ 140 | mesh->dim = 3; 141 | for (j=1; jquad[k]; 145 | pq->v[0] = (j-1)*sx+i; 146 | pq->v[1] = pq->v[0]+1; 147 | pq->v[2] = j*sx+i+1; 148 | pq->v[3] = pq->v[2]-1; 149 | pq->ref = 0; 150 | } 151 | 152 | /* read references, if any */ 153 | if ( ityp == 1 ) { 154 | pos = ftell(fp); 155 | ret = fscanf(fp,"%d",&i); 156 | if ( ret != EOF ) { 157 | fseek(fp,pos,SEEK_SET); 158 | for (j=1; jquad[k]; 162 | fscanf(fp,"%d",&ref); 163 | pq->ref = ref; 164 | } 165 | } 166 | } 167 | 168 | /* solution = elevations */ 169 | mesh->nbb = mesh->np; 170 | mesh->bbmin = FLOAT_MAX; 171 | mesh->bbmax = -FLOAT_MAX; 172 | mesh->typage = 2; 173 | mesh->nfield = 1; 174 | 175 | /* allocate memory */ 176 | if ( !zaldy2(mesh) ) { 177 | mesh->nbb = 0; 178 | fclose(fp); 179 | return(1); 180 | } 181 | 182 | for (j=1; j<=mesh->np; j++) { 183 | ps = &mesh->sol[j]; 184 | ppt = &mesh->point[j]; 185 | ps->bb = ppt->c[2]; 186 | if ( ps->bb < mesh->bbmin ) mesh->bbmin = ps->bb; 187 | if ( ps->bb > mesh->bbmax ) mesh->bbmax = ps->bb; 188 | } 189 | 190 | fclose(fp); 191 | return(1); 192 | } 193 | -------------------------------------------------------------------------------- /src/grafic.h: -------------------------------------------------------------------------------- 1 | #ifndef _GRAFIC_H 2 | #define _GRAFIC_H 3 | 4 | #define MAX_LIST 4 5 | #define MAXISO 5 6 | 7 | #define C_ON (1 << 0) 8 | #define C_EDIT (1 << 1) 9 | #define C_VOL (1 << 2) 10 | #define C_UPDATE (1 << 3) 11 | #define C_FREEZE (1 << 4) 12 | #define C_CAP (1 << 5) 13 | #define C_REDO (1 << 6) 14 | #define C_HIDE (1 << 7) 15 | 16 | /* view modes */ 17 | #define S_BDRY (1<<0) 18 | #define S_FILL (1<<1) 19 | #define S_COLOR (1<<2) 20 | #define S_MAP (1<<3) 21 | #define S_MATERIAL (1<<4) 22 | #define S_ALTITUDE (1<<5) 23 | #define S_DISPL (1<<6) 24 | 25 | #define MONO 0 26 | #define LEFT 1 27 | #define RIGHT 2 28 | 29 | enum {WIRE = S_BDRY, 30 | HIDDEN = S_BDRY + S_FILL, 31 | DEPTH = S_BDRY + S_COLOR, 32 | FILL = S_FILL + S_COLOR, 33 | SHADED = S_BDRY + S_FILL + S_COLOR, 34 | SIZEMAP= S_BDRY + S_FILL + S_MAP 35 | }; 36 | enum {LTria, LQuad, LTets, LHexa, LEdges, LPoint}; 37 | enum {PERSPECTIVE, CAMERA, ORTHO}; 38 | enum {X_AXIS=0, Y_AXIS, Z_AXIS}; 39 | enum {VECTOR,CONE}; 40 | 41 | /* items */ 42 | #define S_AXIS (1<<0) 43 | #define S_BOX (1<<1) 44 | #define S_GRID (1<<2) 45 | #define S_GEOM (1<<3) 46 | #define S_ISO (1<<4) 47 | #define S_PALETTE (1<<5) 48 | #define S_NUMP (1<<6) 49 | #define S_NUMF (1<<7) 50 | 51 | /* type */ 52 | #define S_FLAT (1<<0) /* render with facet normals */ 53 | #define S_SCISSOR (1<<1) /* scissoring mode */ 54 | #define S_FOLLOW (1<<2) /* picking mode */ 55 | #define S_NORMAL (1<<3) 56 | #define S_OPPOS (1<<4) 57 | #define S_DECO (1<<5) 58 | #define S_PATH (1<<6) 59 | #define S_RESET (1<<7) 60 | 61 | /* iso-values */ 62 | #define MAX_ISO 5 63 | #define S_ISOLINE (1<<1) 64 | #define S_ISOSURF (1<<2) 65 | #define S_STREAML (1<<3) 66 | #define S_STREAMR (1<<4) 67 | #define S_VECTOR (1<<5) 68 | #define S_CRITP (1<<6) 69 | #define S_PARTICLE (1<<7) 70 | 71 | #define MAX_PRT 10 72 | #define MAX_LST 1024 73 | #define MAX_CPT 5000 74 | #define HSIZ 0.05 75 | 76 | 77 | typedef struct sperspective { 78 | float fovy,depth; 79 | float matrix[16],alpha,gamma; 80 | int rubix,rubfx,rubiy,rubfy; 81 | ubyte pmode,rubber; 82 | } Persp; 83 | typedef Persp * pPersp; 84 | 85 | typedef struct triangle { 86 | float a[3],b[3],c[3]; 87 | float va,vb,vc; 88 | float na[3],nb[3],nc[3]; 89 | } triangle; 90 | 91 | typedef struct material { 92 | float amb[4],emi[4],dif[4],spe[4],shininess; 93 | float ext[6]; 94 | GLint list; 95 | int depmat[MAX_LIST]; 96 | int ref,sort; 97 | char name[128]; 98 | ubyte flag; 99 | } Material ; 100 | typedef Material * pMaterial; 101 | 102 | typedef struct _cell { 103 | int id; 104 | int x,y; 105 | float min,max; 106 | float value; 107 | float step; 108 | char* info; 109 | char* format; 110 | } cell; 111 | 112 | typedef struct transform { 113 | float pos[3]; /* current mouse position */ 114 | float angle,axis[3]; /* rotation angle + axis */ 115 | float panx,pany,opanx,opany; /* screen translation */ 116 | float matrix[16],oldmat[16]; /* transformation matrix */ 117 | float rot[16],tra[16]; 118 | int mstate,mbutton,manim; 119 | } Transform; 120 | typedef Transform * pTransform; 121 | 122 | typedef struct cube { 123 | pTransform cubetr; 124 | float cmi[3],cma[3]; 125 | ubyte active; 126 | } Cube; 127 | typedef Cube *pCube; 128 | 129 | typedef struct clip { 130 | pTransform cliptr; 131 | double eqn[4]; 132 | ubyte active; 133 | } Clip; 134 | typedef Clip *pClip; 135 | 136 | 137 | typedef struct camera { 138 | GLfloat eye[3]; /* Position of the camera */ 139 | GLfloat speed[3],spmod,altinc; 140 | int vecup; 141 | } Camera; 142 | typedef Camera * pCamera; 143 | 144 | /* scene parameters */ 145 | typedef struct sparam { 146 | float back[4],line[4],edge[4],sunpos[4],clip[6]; 147 | float cm,dpi,coeff,cumtim,cumpertime,maxtime,timdep,pertime,dt; 148 | float eyesep,linewidth,isowidth,pointsize; 149 | short xi,yi,xs,ys; 150 | int nbmat; 151 | char pscolor[10]; 152 | ubyte sunp,linc,advtim,nbpart; 153 | } Param; 154 | 155 | /* trajectoire */ 156 | typedef struct straj { 157 | int np; 158 | float *pt; 159 | float *tg; 160 | float sec; 161 | GLuint tlist; 162 | } Trajet; 163 | 164 | /* streamlines */ 165 | typedef struct sstream { 166 | double size,norm; 167 | float xmin,xmax,ymin,ymax,zmin,zmax; 168 | float *listp; 169 | float stpt[4][3],stcol[4]; 170 | int stnp,stiso[4]; 171 | short nbstl; 172 | ubyte typtrack; 173 | } Stream; 174 | typedef Stream * pStream; 175 | 176 | typedef struct strgrd { 177 | pTransform strtr; 178 | GLuint grid; 179 | ubyte active; 180 | } Strgrd; 181 | typedef Strgrd * pStrgrd; 182 | 183 | typedef struct spart { 184 | double cb[4]; 185 | float pos[MAX_PRT+1][3],col[MAX_PRT+1][3],size,norm,ct,step; 186 | int nsdep,cur; 187 | ubyte flag; 188 | } Particle; 189 | typedef Particle *pParticle; 190 | 191 | 192 | typedef struct siso { 193 | float val[MAXISO+2]; 194 | float col[MAXISO+2]; 195 | ubyte palette,ptyp; 196 | } Iso; 197 | 198 | typedef struct scene { 199 | pTransform view; 200 | pClip clip; 201 | pCube cube; 202 | pPersp persp; 203 | pCamera camera; 204 | pMaterial material; 205 | pStream stream; 206 | /*pStrgrd stg;*/ 207 | Param par; 208 | Trajet path; 209 | Iso iso; 210 | 211 | float dmin,dmax; /* scene size */ 212 | float shrink; /* shrink value */ 213 | float cx,cy,cz; /* center of scene */ 214 | 215 | GLuint dlist[MAX_LIST]; /* display lists */ 216 | GLuint mlist[MAX_LIST]; /* metric lists */ 217 | GLuint ilist[MAX_LIST]; /* iso-surfaces */ 218 | GLuint clist[MAX_LIST]; 219 | GLuint cmlist[MAX_LIST]; /* clipped elts */ 220 | GLuint vlist[MAX_LIST]; /* vector list */ 221 | GLuint *slist,cplist; /* streamlines */ 222 | GLuint glist,nlist; /* geometry lists */ 223 | GLuint grid; 224 | GLuint picklist; 225 | 226 | int *matsort; 227 | short idwin,idmesh; /* window, mesh id */ 228 | short master,slave; 229 | 230 | ubyte item; /* display items */ 231 | ubyte mode; /* render mode */ 232 | ubyte type; 233 | ubyte isotyp; 234 | ubyte picked; 235 | } Scene; 236 | typedef Scene * pScene; 237 | 238 | 239 | #endif 240 | -------------------------------------------------------------------------------- /src/hash.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "extern.h" 3 | #include "sproto.h" 4 | #include 5 | 6 | #define NC 32 7 | #define NC2 (NC*NC) 8 | #define NC3 (NC2*NC) 9 | 10 | #define KA 31 11 | #define KB 57 12 | #define KC 79 13 | 14 | static int ch[6][4] = { {0,1,2,3}, {4,5,6,7}, {0,1,5,4}, 15 | {1,2,6,5}, {2,3,7,6}, {0,3,7,4} }; 16 | static int idir[5] = {0,1,2,0,1}; 17 | static int idirt[7] = {0,1,2,3,0,1,2}; 18 | 19 | 20 | /* very sioux! (09/2002) */ 21 | int hashTetra(pMesh mesh) { 22 | pTetra pt,pt1; 23 | int k,kk,pp,l,ll,mins,mins1,maxs,maxs1,sum,sum1,iadr; 24 | int *hcode,*link,inival,hsize; 25 | char *hvoy; 26 | ubyte i,ii,i1,i2,i3; 27 | unsigned int key; 28 | 29 | /* avoid building */ 30 | if ( mesh->adja ) return(1); 31 | if ( 4*sizeof(char) != sizeof(int) ) exit(1); 32 | 33 | /* default */ 34 | if ( ddebug) { 35 | fprintf(stdout," Setting topology."); 36 | fflush(stdout); 37 | } 38 | 39 | /* memory alloc */ 40 | hcode = (int*)M_calloc(max(100,mesh->ntet+1),sizeof(int),"hash.tetra"); 41 | link = (int*)M_calloc(4*max(100,mesh->ntet+1),sizeof(int),"hash.tetra"); 42 | hsize = max(100,mesh->ntet); 43 | assert(hcode); 44 | assert(link); 45 | hvoy = (char*)hcode; 46 | 47 | /* init */ 48 | inival = 2147483647; 49 | for (k=0; k<=mesh->ntet; k++) 50 | hcode[k] = -inival; 51 | 52 | /* build hash table */ 53 | for (k=1; k<=mesh->ntet; k++) { 54 | pt = &mesh->tetra[k]; 55 | if ( !pt->v[0] ) continue; 56 | for (i=0; i<4; i++) { 57 | i1 = idirt[i+1]; 58 | i2 = idirt[i+2]; 59 | i3 = idirt[i+3]; 60 | mins = min(pt->v[i1],pt->v[i2]); 61 | mins = min(mins,pt->v[i3]); 62 | maxs = max(pt->v[i1],pt->v[i2]); 63 | maxs = max(maxs,pt->v[i3]); 64 | 65 | /* compute key */ 66 | sum = pt->v[i1] + pt->v[i2] + pt->v[i3]; 67 | key = KA*mins + KB*maxs + KC*sum; 68 | key = key % hsize + 1; 69 | /* insert */ 70 | iadr = 4*(k-1) + i+1; 71 | link[iadr] = hcode[key]; 72 | hcode[key] = -iadr; 73 | } 74 | } 75 | 76 | if ( ddebug ) { 77 | fprintf(stdout,"."); 78 | fflush(stdout); 79 | } 80 | 81 | /* set adjacency */ 82 | for (l=4*mesh->ntet; l>0; l--) { 83 | if ( link[l] >= 0 ) continue; 84 | k = (l-1) / 4 + 1; 85 | i = (l-1) % 4; 86 | i1 = idirt[i+1]; 87 | i2 = idirt[i+2]; 88 | i3 = idirt[i+3]; 89 | pt = &mesh->tetra[k]; 90 | sum = pt->v[i1] + pt->v[i2] + pt->v[i3]; 91 | mins = min(pt->v[i1],pt->v[i2]); 92 | mins = min(mins,pt->v[i3]); 93 | maxs = max(pt->v[i1],pt->v[i2]); 94 | maxs = max(maxs,pt->v[i3]); 95 | 96 | /* accross link */ 97 | ll = -link[l]; 98 | pp = 0; 99 | link[l] = 0; 100 | hvoy[l] = 0; 101 | while ( ll > 0 && ll != inival ) { 102 | kk = (ll-1) / 4 + 1; 103 | ii = (ll-1) % 4; 104 | i1 = idirt[ii+1]; 105 | i2 = idirt[ii+2]; 106 | i3 = idirt[ii+3]; 107 | pt1 = &mesh->tetra[kk]; 108 | sum1 = pt1->v[i1] + pt1->v[i2] + pt1->v[i3]; 109 | if ( sum1 == sum ) { 110 | mins1 = min(pt1->v[i1],pt1->v[i2]); 111 | mins1 = min(mins1,pt1->v[i3]); 112 | if ( mins1 == mins ) { 113 | maxs1 = max(pt1->v[i1],pt1->v[i2]); 114 | maxs1 = max(maxs1,pt1->v[i3]); 115 | if ( maxs1 == maxs ) { 116 | /* adjacent found */ 117 | if ( pp != 0 ) link[pp] = link[ll]; 118 | link[l] = kk; 119 | hvoy[l] = ii; 120 | link[ll]= k; 121 | hvoy[ll]= i; 122 | break; 123 | } 124 | } 125 | } 126 | pp = ll; 127 | ll = -link[ll]; 128 | } 129 | } 130 | mesh->adja = (int*)link; 131 | mesh->voy = (ubyte*)hcode; 132 | 133 | if ( ddebug ) 134 | fprintf(stdout,"..\n"); 135 | 136 | return(1); 137 | } 138 | 139 | 140 | /* very sioux! (09/2002) */ 141 | int hashHexa(pMesh mesh) { 142 | pHexa ph,ph1; 143 | int k,kk,iadr,pp,l,ll,v; 144 | int imin,mins,mins1,opps,opps1; 145 | int *hcode,*link,inival,hsize; 146 | char *hvoy; 147 | ubyte i,i1,ii; 148 | unsigned int key; 149 | 150 | /* avoid building again! */ 151 | if ( mesh->adja ) return(1); 152 | if ( 4*sizeof(char) != sizeof(int) ) exit(1); 153 | 154 | /* default */ 155 | if ( ddebug ) { 156 | fprintf(stdout," Setting topology."); 157 | fflush(stdout); 158 | } 159 | 160 | /* memory alloc */ 161 | /* bug fixe: 17/04/2007 162 | hcode = (int*)M_calloc(max(11,mesh->nhex+1),sizeof(int),"hash.hexa"); 163 | link = (int*)M_calloc(6*max(11,mesh->nhex+1),sizeof(int),"hash.hexa"); 164 | hsize = max(10,mesh->nhex); 165 | if ( !hcode || !link ) { 166 | myerror.coderr = 1000; 167 | return(0); 168 | } 169 | hvoy = (char*)hcode; 170 | */ 171 | hcode = (int*)M_calloc(max(10,6*mesh->nhex/4+1),sizeof(int),"hash.hexa"); 172 | assert(hcode); 173 | link = (int*)M_calloc(max(10,6*mesh->nhex+1),sizeof(int),"hash.hexa"); 174 | assert(link); 175 | hsize = max(2,mesh->nhex); 176 | hvoy = (char*)hcode; 177 | 178 | /* init */ 179 | inival = 2147483647; 180 | for (k=0; k<=6*mesh->nhex/4; k++) 181 | hcode[k] = -inival; 182 | 183 | /* build hash table */ 184 | for (k=1; k<=mesh->nhex; k++) { 185 | ph = &mesh->hexa[k]; 186 | if ( !ph->v[0] ) continue; 187 | for (i=0; i<6; i++) { 188 | mins = ph->v[ch[i][0]]; 189 | imin = 0; 190 | for (v=1; v<4; v++) 191 | if ( ph->v[ch[i][v]] < mins ) { 192 | mins = ph->v[ch[i][v]]; 193 | imin = v; 194 | } 195 | i1 = (imin+2) % 4; 196 | opps = ph->v[ch[i][i1]]; 197 | 198 | /* compute key */ 199 | key = KA*mins + KB*opps; 200 | key = key % hsize + 1; 201 | 202 | /* insert */ 203 | iadr = 6*(k-1) + i+1; 204 | link[iadr] = hcode[key]; 205 | hcode[key] = -iadr; 206 | } 207 | } 208 | if ( ddebug ) { 209 | fprintf(stdout,"."); 210 | fflush(stdout); 211 | } 212 | 213 | /* set adjacency */ 214 | for (l=6*mesh->nhex; l>0; l--) { 215 | if ( link[l] >= 0 ) continue; 216 | k = (l-1) / 6 + 1; 217 | i = (l-1) % 6; 218 | ph = &mesh->hexa[k]; 219 | mins = ph->v[ch[i][0]]; 220 | imin = 0; 221 | for (v=1; v<4; v++) 222 | if ( ph->v[ch[i][v]] < mins ) { 223 | mins = ph->v[ch[i][v]]; 224 | imin = v; 225 | } 226 | i1 = (imin+2) % 4; 227 | opps = ph->v[ch[i][i1]]; 228 | 229 | /* accross link */ 230 | ll = -link[l]; 231 | pp = 0; 232 | link[l] = 0; 233 | hvoy[l] = 0; 234 | /* Remark: test on ll positivity is needed because the part of 235 | * hcode array that is initialized (6*mesh->nhex/4) is not 236 | * consistent with the part of the array that can be accessed 237 | * through keys. In consequences, the travel accross links may end 238 | * on a 0 value instead the inival one. */ 239 | while ( ll>0 && ll != inival ) { 240 | kk = (ll-1) / 6 +1; 241 | ii = (ll-1) % 6; 242 | ph1 = &mesh->hexa[kk]; 243 | mins1 = ph1->v[ch[ii][0]]; 244 | imin = 0; 245 | for (v=1; v<4; v++) 246 | if ( ph1->v[ch[ii][v]] < mins1 ) { 247 | mins1 = ph1->v[ch[ii][v]]; 248 | imin = v; 249 | } 250 | i1 = (imin+2) % 4; 251 | opps1 = ph1->v[ch[ii][i1]]; 252 | 253 | /* adjacent found */ 254 | if ( mins1 == mins && opps1 == opps ) { 255 | if ( pp != 0 ) link[pp] = link[ll]; 256 | link[l] = kk; 257 | hvoy[l] = ii; 258 | link[ll]= k; 259 | hvoy[ll]= i; 260 | break; 261 | } 262 | pp = ll; 263 | ll = -link[ll]; 264 | } 265 | } 266 | mesh->adja = (int*)link; 267 | mesh->voy = (ubyte*)hcode; 268 | 269 | if ( ddebug ) 270 | fprintf(stdout,"..\n"); 271 | 272 | return(1); 273 | } 274 | 275 | 276 | /* very sioux! (09/2002) */ 277 | int hashTria(pMesh mesh) { 278 | pTriangle pt,pt1; 279 | int k,kk,l,ll,mins,maxs,mins1,maxs1,hsize; 280 | int *hcode,*link,inival,iadr,pp; 281 | char *hvoy; 282 | ubyte i,i1,i2,ii; 283 | unsigned int key; 284 | 285 | /* avoid building again! */ 286 | if ( mesh->adja ) return(1); 287 | if ( 4*sizeof(char) != sizeof(int) ) exit(1); 288 | 289 | /* default */ 290 | if ( ddebug) { 291 | fprintf(stdout," Setting topology."); 292 | fflush(stdout); 293 | } 294 | 295 | /* memory alloc */ 296 | hcode = (int*)M_calloc(max(1,3*mesh->nt/4)+1,sizeof(int),"hash.tria"); 297 | link = (int*)M_calloc(3*mesh->nt+1,sizeof(int),"hash.tria"); 298 | hsize = max(2,3*mesh->nt/4-1); 299 | assert(hcode); 300 | assert(link); 301 | hvoy = (char*)hcode; 302 | 303 | /* init */ 304 | inival = 2147483647; 305 | for (k=0; k<=3*mesh->nt/4; k++) 306 | hcode[k] = -inival; 307 | 308 | /* build hash table */ 309 | for (k=1; k<=mesh->nt; k++) { 310 | pt = &mesh->tria[k]; 311 | if ( !pt->v[0] ) continue; 312 | 313 | for (i=0; i<3; i++) { 314 | i1 = idir[i+1]; 315 | i2 = idir[i+2]; 316 | mins = min(pt->v[i1],pt->v[i2]); 317 | maxs = max(pt->v[i1],pt->v[i2]); 318 | 319 | /* compute key */ 320 | key = KA*mins + KB*maxs; 321 | key = key % hsize + 1; 322 | 323 | /* insert */ 324 | iadr = 3*(k-1) + i+1; 325 | link[iadr] = hcode[key]; 326 | hcode[key] = -iadr; 327 | } 328 | } 329 | if ( ddebug ) { 330 | fprintf(stdout,"."); 331 | fflush(stdout); 332 | } 333 | 334 | /* set adjacency */ 335 | for (l=3*mesh->nt; l>0; l--) { 336 | if ( link[l] >= 0 ) continue; 337 | k = (l-1) / 3 + 1; 338 | i = (l-1) % 3; 339 | i1 = idir[i+1]; 340 | i2 = idir[i+2]; 341 | pt = &mesh->tria[k]; 342 | 343 | mins = min(pt->v[i1],pt->v[i2]); 344 | maxs = max(pt->v[i1],pt->v[i2]); 345 | 346 | /* accross link */ 347 | ll = -link[l]; 348 | pp = 0; 349 | link[l] = 0; 350 | hvoy[l] = 0; 351 | while ( ll != inival ) { 352 | kk = (ll-1) / 3 + 1; 353 | ii = (ll-1) % 3; 354 | i1 = idir[ii+1]; 355 | i2 = idir[ii+2]; 356 | pt1 = &mesh->tria[kk]; 357 | mins1 = min(pt1->v[i1],pt1->v[i2]); 358 | maxs1 = max(pt1->v[i1],pt1->v[i2]); 359 | 360 | /* adjacent found */ 361 | if ( mins1 == mins && maxs1 == maxs ) { 362 | if ( pp != 0 ) link[pp] = link[ll]; 363 | link[l] = kk; 364 | hvoy[l] = ii; 365 | link[ll]= k; 366 | hvoy[ll]= i; 367 | break; 368 | } 369 | pp = ll; 370 | ll = -link[ll]; 371 | } 372 | } 373 | mesh->adja = (int*)link; 374 | mesh->voy = (ubyte*)hcode; 375 | 376 | if ( ddebug ) 377 | fprintf(stdout,".\n"); 378 | 379 | return(1); 380 | } 381 | -------------------------------------------------------------------------------- /src/image.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "sproto.h" 3 | #include "extern.h" 4 | 5 | 6 | PPMimage *loadPPM(const char *imgname,int *type) { 7 | pPPMimage result; 8 | FILE *fp; 9 | int i,k,typimg,ret,r,g,b,s,maxval,bitsize; 10 | char *ptr,c,buff[1024],data[256]; 11 | 12 | /* search for image */ 13 | ptr = strstr(imgname,".ppm"); 14 | if ( !ptr ) { 15 | strcpy(data,imgname); 16 | strcat(data,".ppm"); 17 | fp = fopen(data,"rb"); 18 | } 19 | else 20 | fp = fopen(imgname,"rb"); 21 | if ( !fp ) { 22 | fprintf(stderr," ## Unable to open file %s.\n",imgname); 23 | return(0); 24 | } 25 | 26 | if ( !fgets(buff,sizeof(buff),fp) ) { 27 | fprintf(stderr," ## Invalid file header.\n"); 28 | return(0); 29 | } 30 | 31 | /* check header file */ 32 | if ( buff[0] != 'P' ) { 33 | fprintf(stderr," ## Invalid image format.\n"); 34 | return(0); 35 | } 36 | 37 | switch(buff[1]) { 38 | case '2': typimg = P2; break; 39 | case '3': typimg = P3; break; 40 | case '5': typimg = P5; break; 41 | case '6': typimg = P6; break; 42 | default: 43 | fprintf(stderr," ## Invalid image format.\n"); 44 | return(0); 45 | } 46 | 47 | /* allocate memory to store imagee */ 48 | result = malloc(sizeof(PPMimage)); 49 | if ( !result ) { 50 | fprintf(stderr," ## Unable to load image.\n"); 51 | return(0); 52 | } 53 | 54 | do { 55 | ret = fscanf(fp,"%s",buff); 56 | if ( ret == EOF ) break; 57 | /* check and strip comments */ 58 | if ( buff[0] == '#' ) 59 | do 60 | c = getc(fp); 61 | while ( c != '\n' ); 62 | else break; 63 | } 64 | while (1); 65 | 66 | /* read columns + lines */ 67 | ret = sscanf(buff,"%d",&s); 68 | result->sizeX = (short)s; 69 | ret += fscanf(fp,"%d",&s); 70 | result->sizeY = (short)s; 71 | if ( ret != 2 ) { 72 | fprintf(stderr," ## Error loading image.\n"); 73 | free(result); 74 | return(0); 75 | } 76 | if ( !quiet ) 77 | fprintf(stdout," image size: %d x %d\n",result->sizeX,result->sizeY); 78 | 79 | if ( fscanf(fp,"%d",&maxval) != 1 ) { 80 | fprintf(stderr," ## Invalid image size.\n"); 81 | free(result); 82 | return(0); 83 | } 84 | 85 | /* strip line */ 86 | while ( fgetc(fp) != '\n' ) ; 87 | 88 | /* size based on type */ 89 | if ( typimg == P2 || typimg == P5 ) 90 | bitsize = result->sizeX*result->sizeY; 91 | else 92 | bitsize = 3*result->sizeX*result->sizeY; 93 | result->data = (ubyte*)malloc(bitsize*sizeof(ubyte)); 94 | if ( !result ) { 95 | fprintf(stderr," ## Unable to load image.\n"); 96 | free(result); 97 | return(0); 98 | } 99 | 100 | /* read data file */ 101 | switch( typimg ) { 102 | case P2: /* ascii file (grey) */ 103 | case P3: /* ascii file (color) */ 104 | for (i=0; idata[i] = (ubyte)r; 107 | } 108 | break; 109 | 110 | case P5: /* binary file (grey) */ 111 | case P6: /* binary file (color) */ 112 | ret = fread(result->data,sizeof(ubyte),bitsize,fp); 113 | if ( ret != bitsize ) { 114 | fprintf(stderr," ## Error loading image.\n"); 115 | free(result->data); 116 | free(result); 117 | return(0); 118 | } 119 | break; 120 | } 121 | fclose(fp); 122 | 123 | if ( *type == DEFAULT ) 124 | switch( typimg ) { 125 | case P2: 126 | case P5: 127 | *type = GREY; break; 128 | case P3: 129 | case P6: 130 | *type = RGB; break; 131 | } 132 | 133 | /* convert to grey levels */ 134 | else if ( *type == GREY && (typimg == P3 || typimg == P6) ) { 135 | fprintf(stdout," converting to grey levels\n"); 136 | for (i=0,k=0; idata[i]; 138 | g = (int)result->data[i+1]; 139 | b = (int)result->data[i+2]; 140 | result->data[k] = (ubyte)(0.3*r+0.59*g+0.11*b); 141 | } 142 | result->data = (ubyte*)realloc(result->data,sizeof(ubyte)*bitsize/3); 143 | } 144 | 145 | return(result); 146 | } 147 | 148 | 149 | int savePPM(const char *imgname,pPPMimage img,int typimg) { 150 | FILE *out; 151 | int i,c,bitsize; 152 | char *ptr,data[512]; 153 | 154 | strcpy(data,imgname); 155 | ptr = (char*)strstr(data,".ppm"); 156 | if ( !ptr ) strcat(data,".ppm"); 157 | out = fopen(data,"w"); 158 | if ( !out ) { 159 | fprintf(stderr," ## Unable to open file %s.\n",data); 160 | exit(1); 161 | } 162 | 163 | bitsize = img->sizeX*img->sizeY; 164 | switch(typimg) { 165 | case P2: 166 | fprintf(out,"P2\n"); 167 | fprintf(out,"# Created using medit %s %s, (c) INRIA\n",ME_VER,ME_REL); 168 | fprintf(out,"%d %d\n",img->sizeX,img->sizeY); 169 | fprintf(out,"255\n"); 170 | c = 0; 171 | for (i=0; isizeX*img->sizeY; i++) { 172 | fprintf(out,"%3d ",(int)img->data[i]); 173 | if ( ++c == 17 ) { 174 | c = 0; 175 | fprintf(out,"\n"); 176 | } 177 | } 178 | fprintf(out,"\n"); 179 | break; 180 | case P5: 181 | fprintf(out,"P5\n"); 182 | fprintf(out,"# Created using medit %s %s, (c) INRIA\n",ME_VER,ME_REL); 183 | fprintf(out,"%d %d\n",img->sizeX,img->sizeY); 184 | fprintf(out,"255\n"); 185 | fwrite(img->data,sizeof(ubyte),bitsize,out); 186 | break; 187 | case P6: 188 | fprintf(out,"P6\n"); 189 | fprintf(out,"# Created using medit %s %s, (c) INRIA\n",ME_VER,ME_REL); 190 | fprintf(out,"%d %d\n",img->sizeX,img->sizeY); 191 | fprintf(out,"255\n"); 192 | bitsize = (img->sizeX*24+7)/8*img->sizeY; 193 | if ( fwrite(img->data,sizeof(ubyte),bitsize,out) < bitsize ) 194 | fprintf(stderr," ## Data file corrupted.\n"); 195 | break; 196 | } 197 | fclose(out); 198 | 199 | return(1); 200 | } 201 | 202 | 203 | int saveTGA(const char *imgname,GLubyte *img,int w,int h) { 204 | TGAheader tga; 205 | int i; 206 | char *ptr,data[256]; 207 | FILE *out; 208 | 209 | strcpy(data,imgname); 210 | ptr = (char*)strstr(data,".tga"); 211 | if ( !ptr ) strcat(data,".tga"); 212 | out = fopen(data,"wb"); 213 | if ( !out ) { 214 | fprintf(stderr," ## UNABLE TO OPEN FILE %s.\n",data); 215 | exit(1); 216 | } 217 | 218 | tga.idfield_len = 0; 219 | tga.cmap_type = 0; 220 | tga.image_type = 2; 221 | for (i=0; i<5; i++) 222 | tga.cmap_spec[i] = 0; 223 | for (i=0; i<2; i++) { 224 | tga.x_orig[i] = 0; 225 | tga.y_orig[i] = 0; 226 | } 227 | /* Lo bits */ 228 | tga.width[0] = w & 0xFF; 229 | /* Hi bits */ 230 | tga.width[1] = (w >> 8) & 0xFF; 231 | tga.height[0] = h & 0xFF; 232 | tga.height[1] = (h >> 8) & 0xFF; 233 | tga.pixel_size = 24; 234 | tga.image_desc = 0; 235 | /* Output header */ 236 | fwrite(&tga,sizeof(TGAheader),1,out); 237 | 238 | /* Output image */ 239 | fwrite(img, sizeof(unsigned char),w*h*3,out); 240 | return(1); 241 | } 242 | 243 | void swapPixels(PPMimage *pixels) { 244 | GLubyte *row; 245 | int i,k,ck,bits; 246 | 247 | bits = 3*pixels->sizeX; 248 | row = (GLubyte*)malloc(bits*sizeof(GLubyte)); 249 | if ( !row ) return; 250 | 251 | /* exchange rows */ 252 | for (i=0; isizeY/2; i++) { 253 | k = 3*i*pixels->sizeX; 254 | ck = 3*(pixels->sizeY-i-1)*pixels->sizeX; 255 | memcpy(row,&pixels->data[k],bits); 256 | memcpy(&pixels->data[k],&pixels->data[ck],bits); 257 | memcpy(&pixels->data[ck],row,bits); 258 | } 259 | free(row); 260 | } 261 | 262 | 263 | int imgHard(pScene sc,char *data,char key) { 264 | PPMimage *pixels; 265 | GLint viewport[4]; 266 | pPersp p; 267 | int xx0,yy0,ww,hh; 268 | 269 | pixels = (PPMimage*)M_malloc(sizeof(PPMimage),"imgHard"); 270 | if ( !pixels ) { 271 | fprintf(stderr," ## UNABLE TO ALLOCATE MEMORY FOR IMAGE.\n"); 272 | return(0); 273 | } 274 | 275 | p = sc->persp; 276 | if ( abs(p->rubfx-p->rubix) > 0 ) { 277 | ww = abs(p->rubfx-p->rubix)-2; 278 | hh = abs(p->rubfy-p->rubiy)-2; 279 | xx0 = min(p->rubix,p->rubfx)+1; 280 | yy0 = min(p->rubiy,p->rubfy)+1; 281 | } 282 | else { 283 | glGetIntegerv(GL_VIEWPORT,viewport); 284 | ww = viewport[2]; 285 | hh = viewport[3]; 286 | xx0 = 0; 287 | yy0 = 0; 288 | } 289 | 290 | /* align to 8 bytes */ 291 | ww = ww & ~7; 292 | hh = hh & ~7; 293 | 294 | pixels->sizeX = (short)ww; 295 | pixels->sizeY = (short)hh; 296 | pixels->data = (ubyte*)M_calloc(3*ww*hh,sizeof(ubyte),"imgHard.data"); 297 | if ( !pixels->data ) { 298 | fprintf(stderr," ## Not enough memory to save image.\n"); 299 | M_free(pixels); 300 | return(0); 301 | } 302 | 303 | if ( ddebug ) fprintf(stdout,"size %d x %d\n",ww,hh); 304 | 305 | glFinish(); 306 | if ( saveimg ) 307 | glReadBuffer(GL_BACK_LEFT); 308 | else 309 | glReadBuffer(GL_FRONT); 310 | glPixelStorei(GL_PACK_ALIGNMENT,4); 311 | glPixelStorei(GL_PACK_ROW_LENGTH,0); 312 | glPixelStorei(GL_PACK_SKIP_ROWS,0); 313 | glPixelStorei(GL_PACK_SKIP_PIXELS,0); 314 | 315 | glReadPixels(xx0,yy0,ww,hh,GL_RGB,GL_UNSIGNED_BYTE,pixels->data); 316 | if ( glGetError() != GL_NO_ERROR ) { 317 | fprintf(stderr," ## Unable to save image\n"); 318 | M_free(pixels->data); 319 | M_free(pixels); 320 | return(0); 321 | } 322 | 323 | if ( key == 'H' ) { 324 | swapPixels(pixels); 325 | savePPM(data,pixels,P6); 326 | } 327 | else if ( key == 'T' ) 328 | saveTGA(data,pixels->data,ww,hh); 329 | 330 | M_free(pixels->data); 331 | M_free(pixels); 332 | return(1); 333 | } 334 | -------------------------------------------------------------------------------- /src/image.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | 5 | enum imgtyp {DEFAULT=0, P2,P3,P5,P6, PS, 6 | GREY,RGB,RED,GREEN,BLUE,COLOR}; 7 | 8 | typedef struct { 9 | int sizeX,sizeY; 10 | GLubyte *data; 11 | } PPMimage; 12 | typedef PPMimage *pPPMimage; 13 | 14 | typedef struct { 15 | unsigned char idfield_len; 16 | unsigned char cmap_type; 17 | unsigned char image_type; 18 | unsigned char cmap_spec[5]; 19 | unsigned char x_orig[2]; 20 | unsigned char y_orig[2]; 21 | unsigned char width[2]; 22 | unsigned char height[2]; 23 | unsigned char pixel_size; 24 | unsigned char image_desc; 25 | } TGAheader; 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | -------------------------------------------------------------------------------- /src/inmsh2.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "extern.h" 3 | #include "sproto.h" 4 | 5 | 6 | int inmsh2(pMesh mesh) { 7 | FILE *inp,*inf; 8 | pPoint ppt,pp0,pp1,pp2,pp3; 9 | pTriangle pt1; 10 | pQuad pq1; 11 | pEdge pr; 12 | int k,disc,ret,degree,dum,ref,tag; 13 | char *ptr,data[256],sx[128],sy[128],sz[128]; 14 | 15 | /* check for .points */ 16 | strcpy(data,mesh->name); 17 | strcat(data,".points"); 18 | inp = fopen(data,"r"); 19 | if ( !inp ) return(0); 20 | 21 | /* check for .faces */ 22 | strcpy(data,mesh->name); 23 | strcat(data,".faces"); 24 | inf = fopen(data,"r"); 25 | if ( !inf ) return(0); 26 | if ( !quiet ) fprintf(stdout," Reading %s.{points,.faces}\n",mesh->name); 27 | 28 | /* get number of elements */ 29 | /*fgets(data,255,inp); 30 | sscanf(data,"%d",&mesh->np);*/ 31 | fscanf(inp,"%d",&mesh->np); 32 | EatLine(inp); 33 | 34 | /*fgets(data,255,inf); 35 | sscanf(data,"%d",&mesh->ne);*/ 36 | fscanf(inf,"%d",&mesh->ne); 37 | EatLine(inf); 38 | if ( !mesh->np ) { /*|| (mesh->dim == 3 && !mesh->ne) ) {*/ 39 | fprintf(stdout," ## No vertex.\n"); 40 | fclose(inp); 41 | return(-1); 42 | } 43 | mesh->dim = 3; 44 | mesh->nt = mesh->nq = mesh->ntet = mesh->nhex = mesh->nvn = 0; 45 | 46 | /* first pass get number of faces */ 47 | for (k=1; k<=mesh->ne; k++) { 48 | fscanf(inf,"%d",°ree); 49 | if ( degree < 2 || degree > 4 ) { 50 | fprintf(stdout," ## Wrong degree\n"); 51 | fclose(inp); 52 | fclose(inf); 53 | return(0); 54 | } 55 | else if ( degree == 2 ) 56 | mesh->na++; 57 | else if ( degree == 3 ) 58 | mesh->nt++; 59 | else if ( degree == 4 ) 60 | mesh->nq++; 61 | /*fgets(data,80,inf);*/ 62 | EatLine(inf); 63 | } 64 | 65 | /* check if vertices and elements found */ 66 | if ( !mesh->np ) { /*|| mesh->ne == 0 ) {*/ 67 | fclose(inp); 68 | fclose(inf); 69 | return(0); 70 | } 71 | 72 | /* memory allocation for mesh */ 73 | if ( zaldy1(mesh) != TRUE ) { 74 | fclose(inp); 75 | fclose(inf); 76 | return(0); 77 | } 78 | 79 | /* read mesh vertices */ 80 | for(k=1; k<=mesh->np; k++) { 81 | ppt = &mesh->point[k]; 82 | /* parse coordinates into strings */ 83 | ret = fscanf(inp,"%s %s %s %d",sx,sy,sz,&ref); 84 | if ( ret != 4 ) { 85 | fclose(inp); 86 | fclose(inf); 87 | return(0); 88 | } 89 | ptr = strpbrk(sx,"dD"); 90 | if ( ptr ) *ptr = 'E'; 91 | ptr = strpbrk(sy,"dD"); 92 | if ( ptr ) *ptr = 'E'; 93 | ptr = strpbrk(sz,"dD"); 94 | if ( ptr ) *ptr = 'E'; 95 | sscanf(sx,"%lf",&ppt->c[0]); 96 | sscanf(sy,"%lf",&ppt->c[1]); 97 | sscanf(sz,"%lf",&ppt->c[2]); 98 | ppt->ref = ref; 99 | ppt->tag = M_UNUSED; 100 | } 101 | fclose(inp); 102 | 103 | /* allocate memory for mesh edges */ 104 | if ( mesh->na > 0 ) { 105 | mesh->edge = (pEdge)M_calloc(mesh->na+1,sizeof(Edge),"inmsh2.edge"); 106 | if ( !mesh->edge ) { 107 | fprintf(stderr," ## WARN 0004, INMESH, %d\n",mesh->na); 108 | fclose(inf); 109 | return(1); 110 | } 111 | } 112 | 113 | /* read mesh faces */ 114 | rewind(inf); 115 | /*fgets(data,255,inf); 116 | sscanf(data,"%d",&mesh->ne);*/ 117 | fscanf(inf,"%d",&mesh->ne); 118 | EatLine(inf); 119 | mesh->nt = 0; 120 | mesh->nq = 0; 121 | mesh->na = 0; 122 | disc = 0; 123 | for (k=1; k<=mesh->ne; k++) { 124 | fscanf(inf,"%d",°ree); 125 | 126 | if ( degree == 2 ) { 127 | pr = &mesh->edge[++mesh->na]; 128 | fscanf(inf,"%d %d %d %d %d\n",&pr->v[0],&pr->v[1],&tag,&dum,&dum); 129 | pr->tag = tag == 0 ? M_NOTAG : M_TAG; 130 | pp0 = &mesh->point[pr->v[0]]; 131 | pp1 = &mesh->point[pr->v[1]]; 132 | pp0->tag = M_NOTAG; 133 | pp1->tag = M_NOTAG; 134 | } 135 | else if ( degree == 3 ) { 136 | pt1 = &mesh->tria[++mesh->nt]; 137 | fscanf(inf,"%d %d %d %d %d %d %d\n",&pt1->v[0],&pt1->v[1],&pt1->v[2], 138 | &ref,&dum,&dum,&dum); 139 | if ( pt1->v[0] <= 0 || pt1->v[0] > mesh->np || 140 | pt1->v[1] <= 0 || pt1->v[1] > mesh->np || 141 | pt1->v[2] <= 0 || pt1->v[2] > mesh->np ) { 142 | fprintf(stdout," ## Wrong index\n"); 143 | disc++; 144 | pt1->v[0] = 0; 145 | continue; 146 | } 147 | pt1->ref = fabs(ref); 148 | pp0 = &mesh->point[pt1->v[0]]; 149 | pp1 = &mesh->point[pt1->v[1]]; 150 | pp2 = &mesh->point[pt1->v[2]]; 151 | pp0->tag = M_NOTAG; 152 | pp1->tag = M_NOTAG; 153 | pp2->tag = M_NOTAG; 154 | } 155 | else if ( degree == 4 ) { 156 | pq1 = &mesh->quad[++mesh->nq]; 157 | fscanf(inf,"%d %d %d %d",&pq1->v[0],&pq1->v[1],&pq1->v[2],&pq1->v[3]); 158 | fscanf(inf,"%d %d %d %d %d",&ref,&dum,&dum,&dum,&dum); 159 | if ( pq1->v[0] <= 0 || pq1->v[0] > mesh->np || 160 | pq1->v[1] <= 0 || pq1->v[1] > mesh->np || 161 | pq1->v[2] <= 0 || pq1->v[2] > mesh->np || 162 | pq1->v[3] <= 0 || pq1->v[3] > mesh->np ) { 163 | fprintf(stdout," ## Wrong index\n"); 164 | disc++; 165 | pq1->v[0] = 0; 166 | continue; 167 | } 168 | 169 | pq1->ref = fabs(ref); 170 | pp0 = &mesh->point[ pq1->v[0] ]; 171 | pp1 = &mesh->point[ pq1->v[1] ]; 172 | pp2 = &mesh->point[ pq1->v[2] ]; 173 | pp3 = &mesh->point[ pq1->v[3] ]; 174 | pp0->tag = M_NOTAG; 175 | pp1->tag = M_NOTAG; 176 | pp2->tag = M_NOTAG; 177 | pp3->tag = M_NOTAG; 178 | } 179 | } 180 | 181 | fclose(inf); 182 | if ( disc > 0 ) { 183 | fprintf(stdout," ## %d entities discarded\n",disc); 184 | } 185 | 186 | return(1); 187 | } 188 | -------------------------------------------------------------------------------- /src/insol.c.tmp: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | 5 | #include "medit.h" 6 | #include "extern.h" 7 | #include "sproto.h" 8 | #include "libmesh3.h" 9 | 10 | 11 | /* load sol i from file */ 12 | int loadSol(pMesh mesh,int soli) { 13 | LM_mesh_struct pm; 14 | float *buf; 15 | int ns; 16 | 17 | strcpy(tmp,mesh->name); 18 | ptr = (char *)strstr(tmp,".mesh"); 19 | if ( ptr ) *ptr = '\0'; 20 | 21 | if ( !LM_open_mesh(data,LM_READ,&pm) ) 22 | return(0); 23 | 24 | if ( !quiet ) 25 | fprintf(stdout," Reading data file %s\n",data); 26 | 27 | if ( pm.dimension != mesh->dim ) { 28 | fprintf(stderr," %%%% Dimension mismatch. Data ignored.\n"); 29 | return(0); 30 | } 31 | 32 | /* sol at vertices */ 33 | ns = pm.kw_counters[LM_SolAtVertices]; 34 | if ( ns ) { 35 | 36 | mesh->bbmin = 1.e10; 37 | mesh->bbmax = -1.e10; 38 | 39 | if ( !zaldy2(mesh) ) { 40 | mesh->nbb = 0; 41 | LM_close_mesh(&pm)) 42 | return(0); 43 | } 44 | 45 | } 46 | 47 | return(1); 48 | } 49 | 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | -------------------------------------------------------------------------------- /src/libmesh5.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | /*----------------------------------------------------------*/ 4 | /* */ 5 | /* LIBMESH V 5.3 */ 6 | /* */ 7 | /*----------------------------------------------------------*/ 8 | /* */ 9 | /* Description: handle .meshb file format I/O */ 10 | /* Author: Loic MARECHAL */ 11 | /* Creation date: feb 16 2007 */ 12 | /* Last modification: dec 12 2008 */ 13 | /* */ 14 | /*----------------------------------------------------------*/ 15 | 16 | 17 | /*----------------------------------------------------------*/ 18 | /* Defines */ 19 | /*----------------------------------------------------------*/ 20 | 21 | #define GmfStrSiz 1024 22 | #define GmfMaxTyp 20 23 | #define GmfMaxKwd 79 24 | #define GmfMshVer 1 25 | #define GmfRead 1 26 | #define GmfWrite 2 27 | #define GmfSca 1 28 | #define GmfVec 2 29 | #define GmfSymMat 3 30 | #define GmfMat 4 31 | #define GmfFloat 1 32 | #define GmfDouble 2 33 | 34 | enum GmfKwdCod 35 | { 36 | GmfReserved1, \ 37 | GmfVersionFormatted, \ 38 | GmfReserved2, \ 39 | GmfDimension, \ 40 | GmfVertices, \ 41 | GmfEdges, \ 42 | GmfTriangles, \ 43 | GmfQuadrilaterals, \ 44 | GmfTetrahedra, \ 45 | GmfPentahedra, \ 46 | GmfHexahedra, \ 47 | GmfReserved3, \ 48 | GmfReserved4, \ 49 | GmfCorners, \ 50 | GmfRidges, \ 51 | GmfRequiredVertices, \ 52 | GmfRequiredEdges, \ 53 | GmfRequiredTriangles, \ 54 | GmfRequiredQuadrilaterals, \ 55 | GmfTangentAtEdgeVertices, \ 56 | GmfNormalAtVertices, \ 57 | GmfNormalAtTriangleVertices, \ 58 | GmfNormalAtQuadrilateralVertices, \ 59 | GmfAngleOfCornerBound, \ 60 | GmfTrianglesP2, \ 61 | GmfTrianglesP3, \ 62 | GmfTrianglesP4, \ 63 | GmfQuadrilateralsP2, \ 64 | GmfQuadrilateralsP3, \ 65 | GmfQuadrilateralsP4, \ 66 | GmfTetrahedraP2, \ 67 | GmfTetrahedraP3, \ 68 | GmfTetrahedraP4, \ 69 | GmfHexahedraP2, \ 70 | GmfHexahedraP3, \ 71 | GmfHexahedraP4, \ 72 | GmfReserved17, \ 73 | GmfReserved18, \ 74 | GmfReserved19, \ 75 | GmfReserved20, \ 76 | GmfReserved21, \ 77 | GmfReserved22, \ 78 | GmfReserved23, \ 79 | GmfReserved24, \ 80 | GmfReserved25, \ 81 | GmfReserved26, \ 82 | GmfReserved27, \ 83 | GmfReserved28, \ 84 | GmfReserved29, \ 85 | GmfReserved30, \ 86 | GmfBoundingBox, \ 87 | GmfReserved31, \ 88 | GmfReserved32, \ 89 | GmfReserved33, \ 90 | GmfEnd, \ 91 | GmfReserved34, \ 92 | GmfReserved35, \ 93 | GmfReserved36, \ 94 | GmfReserved37, \ 95 | GmfTangents, \ 96 | GmfNormals, \ 97 | GmfTangentAtVertices, \ 98 | GmfSolAtVertices, \ 99 | GmfSolAtEdges, \ 100 | GmfSolAtTriangles, \ 101 | GmfSolAtQuadrilaterals, \ 102 | GmfSolAtTetrahedra, \ 103 | GmfSolAtPentahedra, \ 104 | GmfSolAtHexahedra, \ 105 | GmfDSolAtVertices, \ 106 | GmfISolAtVertices, \ 107 | GmfISolAtEdges, \ 108 | GmfISolAtTriangles, \ 109 | GmfISolAtQuadrilaterals, \ 110 | GmfISolAtTetrahedra, \ 111 | GmfISolAtPentahedra, \ 112 | GmfISolAtHexahedra, \ 113 | GmfIterations, \ 114 | GmfTime, \ 115 | GmfReserved38 116 | }; 117 | 118 | 119 | /*----------------------------------------------------------*/ 120 | /* External procedures */ 121 | /*----------------------------------------------------------*/ 122 | 123 | extern int GmfOpenMesh(char *, int, ...); 124 | extern int GmfCloseMesh(int); 125 | extern int GmfStatKwd(int, int, ...); 126 | extern int GmfGotoKwd(int, int); 127 | extern int GmfSetKwd(int, int, ...); 128 | extern void GmfGetLin(int, int, ...); 129 | extern void GmfSetLin(int, int, ...); 130 | 131 | 132 | /*----------------------------------------------------------*/ 133 | /* Fortran 77 API */ 134 | /*----------------------------------------------------------*/ 135 | 136 | #if defined(F77_NO_UNDER_SCORE) 137 | #define call(x) x 138 | #else 139 | #define call(x) x ## _ 140 | #endif 141 | 142 | 143 | /*----------------------------------------------------------*/ 144 | /* Transmesh private API */ 145 | /*----------------------------------------------------------*/ 146 | 147 | #ifdef TRANSMESH 148 | 149 | extern char *GmfKwdFmt[ GmfMaxKwd + 1 ][4]; 150 | extern int GmfCpyLin(int, int, int); 151 | 152 | #endif 153 | -------------------------------------------------------------------------------- /src/listnum.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "extern.h" 3 | #include "sproto.h" 4 | 5 | 6 | void updatePoints(pScene sc,pMesh mesh,int refmat) { 7 | pPoint ppt; 8 | pTriangle pt; 9 | pQuad pq; 10 | pTetra ptet; 11 | pHexa ph; 12 | pMaterial pm; 13 | int i,k,m; 14 | 15 | /* mark all points */ 16 | for (k=1; k<=mesh->np; k++) { 17 | ppt = &mesh->point[k]; 18 | ppt->tag = M_UNUSED; 19 | } 20 | 21 | /* unmark points */ 22 | for (m=0; mpar.nbmat; m++) { 23 | pm = &sc->material[m]; 24 | if ( pm->flag ) continue; 25 | 26 | /*triangles */ 27 | k = pm->depmat[LTria]; 28 | while ( k > 0 ) { 29 | pt = &mesh->tria[k]; 30 | if ( pt->v[0] ) { 31 | for (i=0; i<3; i++) { 32 | ppt = &mesh->point[pt->v[i]]; 33 | ppt->tag &= ~M_UNUSED; 34 | } 35 | } 36 | k = pt->nxt; 37 | } 38 | 39 | /* quads */ 40 | k = pm->depmat[LQuad]; 41 | while ( k > 0 ) { 42 | pq = &mesh->quad[k]; 43 | if ( pq->v[0] ) { 44 | for (i=0; i<4; i++) { 45 | ppt = &mesh->point[pq->v[i]]; 46 | ppt->tag &= ~M_UNUSED; 47 | } 48 | } 49 | k = pq->nxt; 50 | } 51 | 52 | /* tetras */ 53 | k = pm->depmat[LTets]; 54 | while ( k > 0 ) { 55 | ptet = &mesh->tetra[k]; 56 | if ( ptet->v[0] ) { 57 | for (i=0; i<4; i++) { 58 | ppt = &mesh->point[ptet->v[i]]; 59 | ppt->tag &= ~M_UNUSED; 60 | } 61 | } 62 | k = ptet->nxt; 63 | } 64 | 65 | /* hexas */ 66 | k = pm->depmat[LHexa]; 67 | while ( k > 0 ) { 68 | ph = &mesh->hexa[k]; 69 | if ( ph->v[0] ) { 70 | for ( i=0; i<8; i++) { 71 | ppt = &mesh->point[ph->v[i]]; 72 | ppt->tag &= ~M_UNUSED; 73 | } 74 | } 75 | k = ph->nxt; 76 | } 77 | } 78 | } 79 | 80 | void listNum(pScene sc,pMesh mesh) { 81 | pMaterial pm; 82 | pPoint ppt; 83 | pTriangle pt; 84 | pQuad pq; 85 | double cx,cy,cz; 86 | int k,i,m; 87 | 88 | glDisable(GL_LIGHTING); 89 | /* point numbers */ 90 | if ( sc->item & S_NUMP ) { 91 | 92 | for (k=1; k<=mesh->np; k++) { 93 | ppt = &mesh->point[k]; 94 | if ( mesh->ne && ppt->tag == M_UNUSED ) continue; 95 | if ( ppt->ref ) { 96 | m = matRef(sc,ppt->ref); 97 | pm = &sc->material[m]; 98 | glColor3f(pm->dif[0],pm->dif[1],pm->dif[2]); 99 | } 100 | else 101 | glColor3fv(sc->par.line); 102 | output3(ppt->c[0],ppt->c[1],ppt->c[2],"%d",k); 103 | } 104 | } 105 | 106 | /* facets numbers */ 107 | if ( sc->item & S_NUMF ) { 108 | glColor4fv(sc->par.line); 109 | for (m=0; mpar.nbmat; m++) { 110 | pm = &sc->material[m]; 111 | if ( pm->flag ) continue; 112 | 113 | /*triangles */ 114 | k = pm->depmat[LTria]; 115 | while ( k > 0 ) { 116 | pt = &mesh->tria[k]; 117 | if ( pt->v[0] ) { 118 | cx = cy = cz = 0.0f; 119 | for (i=0; i<3; i++) { 120 | ppt = &mesh->point[pt->v[i]]; 121 | cx += 0.333 * ppt->c[0]; 122 | cy += 0.333 * ppt->c[1]; 123 | cz += 0.333 * ppt->c[2]; 124 | } 125 | output3(cx,cy,cz,"%d",k); 126 | } 127 | k = pt->nxt; 128 | } 129 | 130 | /* quads */ 131 | k = pm->depmat[LQuad]; 132 | while ( k > 0 ) { 133 | pq = &mesh->quad[k]; 134 | if ( pq->v[0] ) { 135 | cx = cy = cz = 0.0f; 136 | for (i=0; i<4; i++) { 137 | ppt = &mesh->point[pq->v[i]]; 138 | cx += 0.25 * ppt->c[0]; 139 | cy += 0.25 * ppt->c[1]; 140 | cz += 0.25 * ppt->c[2]; 141 | } 142 | output3(cx,cy,cz,"%d",k); 143 | } 144 | k = pq->nxt; 145 | } 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/medit.c: -------------------------------------------------------------------------------- 1 | /* medit.c mesh visualization tool 2 | * 3 | * Written by Pascal Frey, LJLL 4 | * Copyright (c) Inria, 1999-2007. All rights reserved. */ 5 | 6 | #include "medit.h" 7 | #include "compil.date" 8 | #ifdef ppc 9 | #include 10 | #endif 11 | 12 | 13 | /* global variables (see extern.h) */ 14 | GLboolean hasStereo = 1; 15 | Canvas cv; 16 | mytime ctim[TIMEMAX]; 17 | ubyte ddebug,animate,saveimg,imgtype,infogl,fullscreen; 18 | ubyte quiet,option,morphing,stereoMode; 19 | int menu,amenu,fmenu,femenu,vmenu,mmenu,smenu; 20 | int clmenu,cmenu,vwmenu,txmenu,trmenu; 21 | int animdep,animfin; 22 | 23 | 24 | static void excfun(int sigid) { 25 | fprintf(stdout,"\n Unexpected error:"); fflush(stdout); 26 | switch(sigid) { 27 | case SIGABRT: 28 | fprintf(stdout," Abnormal stop\n"); break; 29 | case SIGFPE: 30 | fprintf(stdout," Floating-point exception\n"); break; 31 | case SIGILL: 32 | fprintf(stdout," Illegal instruction\n"); break; 33 | case SIGSEGV: 34 | fprintf(stdout," Segmentation fault\n"); break; 35 | case SIGTERM: 36 | case SIGINT: 37 | fprintf(stdout," Program killed\n"); break; 38 | } 39 | exit(1); 40 | } 41 | 42 | 43 | static void endcod() { 44 | chrono(OFF,&ctim[0]); 45 | fprintf(stdout,"\n Total running seconds: %.2f\n",gttime(ctim[0])); 46 | fprintf(stdout," Thank you for using Medit.\n"); 47 | } 48 | 49 | 50 | static void grInfo(void) { 51 | GLboolean b; 52 | GLint i,win; 53 | 54 | win = glutCreateWindow("Info"); 55 | fprintf(stdout,"Graphic info:\n"); 56 | fprintf(stdout," GL Vendor:\t%s\n",glGetString(GL_VENDOR)); 57 | fprintf(stdout," GL Version:\t%s\n",glGetString(GL_VERSION)); 58 | fprintf(stdout," GL Renderer:\t%s\n\n",glGetString(GL_RENDERER)); 59 | glGetBooleanv(GL_RGBA_MODE,&b); 60 | if ( b ) fprintf(stdout," RGBA Mode\n"); 61 | glGetBooleanv(GL_DOUBLEBUFFER,&b); 62 | if ( b ) fprintf(stdout," Double Buffer\n"); 63 | glGetBooleanv(GL_STEREO,&b); 64 | if ( b ) fprintf(stdout," Stereo\n"); 65 | glGetIntegerv(GL_AUX_BUFFERS,&i); 66 | if ( i ) fprintf(stdout," Auxilary Buffers\t%2d\n",(int)i); 67 | glGetIntegerv(GL_INDEX_BITS,&i); 68 | if ( i ) fprintf(stdout," Index Bits\t\t%2d\n",(int)i); 69 | glGetIntegerv(GL_RED_BITS,&i); 70 | fprintf(stdout," RGBA Bits\t\t%2d",(int)i); 71 | glGetIntegerv(GL_GREEN_BITS,&i); 72 | fprintf(stdout,"\t%2d",(int)i); 73 | glGetIntegerv(GL_BLUE_BITS,&i); 74 | fprintf(stdout,"\t%2d",(int)i); 75 | glGetIntegerv(GL_ALPHA_BITS,&i); 76 | fprintf(stdout,"\t%2d\n",(int)i); 77 | glGetIntegerv(GL_ACCUM_RED_BITS,&i); 78 | fprintf(stdout," Accum RGBA Bits\t%2d",(int)i); 79 | glGetIntegerv(GL_ACCUM_GREEN_BITS,&i); 80 | fprintf(stdout,"\t%2d",(int)i); 81 | glGetIntegerv(GL_ACCUM_BLUE_BITS,&i); 82 | fprintf(stdout,"\t%2d",(int)i); 83 | glGetIntegerv(GL_ACCUM_ALPHA_BITS,&i); 84 | fprintf(stdout,"\t%2d\n",(int)i); 85 | glGetIntegerv(GL_DEPTH_BITS,&i); 86 | fprintf(stdout," Depth Bits\t\t%2d\n",(int)i); 87 | glGetIntegerv(GL_STENCIL_BITS,&i); 88 | fprintf(stdout," Stencil Bits\t\t%2d\n",(int)i); 89 | 90 | exit(1); 91 | } 92 | 93 | 94 | int medit0() { 95 | pMesh mesh; 96 | char data[1024],*name; 97 | int k,l,ret; 98 | clock_t ct; 99 | 100 | /* default */ 101 | fprintf(stdout," Loading data file(s)\n"); 102 | ct = clock(); 103 | 104 | /* enter name */ 105 | if ( !cv.nbm ) { 106 | fprintf(stdout," File name(s) missing. Please enter : "); 107 | fflush(stdout); fflush(stdin); 108 | fgets(data,1020,stdin); 109 | if ( !strlen(data) ) { 110 | fprintf(stdout," ## No data\n"); 111 | return(0); 112 | } 113 | 114 | /* parse file name(s) */ 115 | name = strtok(data," \n"); 116 | while( name ) { 117 | if ( !cv.mesh[cv.nbm] ) { 118 | cv.mesh[cv.nbm] = (pMesh)M_calloc(1,sizeof(Mesh),"medit0.mesh"); 119 | if ( !cv.mesh[cv.nbm] ) return(0); 120 | } 121 | /*(cv.mesh[cv.nbm])->name = calloc(strlen(name)+1,sizeof(char));*/ 122 | strcpy(cv.mesh[cv.nbm]->name,name); 123 | name = strtok(NULL," \n\0"); 124 | if ( ++cv.nbm == MAX_MESH ) break; 125 | } 126 | if ( !cv.nbm ) return(0); 127 | } 128 | 129 | /* read mesh(es) */ 130 | k = 0; 131 | do { 132 | if ( !cv.mesh[k] ) { 133 | cv.mesh[k] = M_calloc(1,sizeof(Mesh),"medit0.mesh"); 134 | if ( !cv.mesh[k] ) return(0); 135 | } 136 | mesh = cv.mesh[k]; 137 | mesh->typ = 0; 138 | ret = loadMesh(mesh); 139 | if ( ret < 0 ) { 140 | mesh->typ = 1; 141 | ret = inmsh2(mesh); 142 | if ( !ret ) { 143 | mesh->typ = 2; 144 | ret = loadGIS(mesh); 145 | } 146 | } 147 | if ( ret <= 0 ) { 148 | for (l=k+1; lntet && !mesh->nt) || (mesh->nhex && !mesh->nq) ) 156 | meshSurf(mesh); 157 | meshBox(mesh,1); 158 | if ( !quiet ) meshInfo(mesh); 159 | 160 | /* read metric */ 161 | if ( !loadSol(mesh,mesh->name,1) ) 162 | bbfile(mesh); 163 | if ( !quiet && mesh->nbb ) 164 | fprintf(stdout," Solutions %8d\n",mesh->nbb); 165 | } 166 | while ( ++k < cv.nbm ); 167 | cv.nbs = cv.nbm; 168 | 169 | ct = difftime(clock(),ct); 170 | fprintf(stdout," Input seconds: %.2f\n", 171 | (double)ct/(double)CLOCKS_PER_SEC); 172 | 173 | return(cv.nbm); 174 | } 175 | 176 | 177 | int medit1() { 178 | pScene scene; 179 | pMesh mesh; 180 | int k; 181 | clock_t ct; 182 | 183 | /* create grafix */ 184 | fprintf(stdout,"\n Building scene(s)\n"); 185 | ct = clock(); 186 | for (k=0; knbb ) return(0); 205 | setupPalette(scene,mesh); 206 | tetraIsoPOVray(scene,mesh); 207 | } 208 | else if ( !createScene(scene,k) ) { 209 | fprintf(stderr," ## Unable to create scene\n"); 210 | return(0); 211 | } 212 | } 213 | ct = difftime(clock(),ct); 214 | fprintf(stdout," Scene seconds: %.2f\n",(double)ct/(double)CLOCKS_PER_SEC); 215 | 216 | return(1); 217 | } 218 | 219 | 220 | int main(int argc,char *argv[]) { 221 | int type; 222 | 223 | fprintf(stdout," -- Medit, Release %s (%s)\n",ME_VER,ME_REL); 224 | fprintf(stdout," %s.\n",ME_CPY); 225 | fprintf(stdout," compiled: %s.\n\n",COMPIL); 226 | 227 | /* trap exceptions */ 228 | signal(SIGABRT,excfun); 229 | signal(SIGFPE,excfun); 230 | signal(SIGILL,excfun); 231 | signal(SIGSEGV,excfun); 232 | signal(SIGTERM,excfun); 233 | signal(SIGINT,excfun); 234 | atexit(endcod); 235 | 236 | tminit(ctim,TIMEMAX); 237 | chrono(ON,&ctim[0]); 238 | 239 | /* default values */ 240 | option = STANDARD; 241 | saveimg = GL_FALSE; 242 | imgtype = P6; 243 | animate = FALSE; 244 | morphing = FALSE; 245 | fullscreen = FALSE; 246 | animdep = 0; 247 | animfin = 0; 248 | ddebug = FALSE; 249 | quiet = FALSE; 250 | stereoMode = 0; 251 | cv.nbm = cv.nbs = 0; 252 | 253 | /* init grafix */ 254 | parsar(argc,argv); 255 | 256 | if ( option == ISOSURF ) { 257 | if ( !medit0() ) exit(1); 258 | if ( !medit1() ) exit(1); 259 | return(0); 260 | } 261 | glutInit(&argc,argv); 262 | #ifdef ppc 263 | chdir(pwd); 264 | #endif 265 | 266 | chrono(ON,&ctim[0]); 267 | if ( stereoMode == MONO ) 268 | type = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH; 269 | else 270 | type = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_STEREO; 271 | glutInitDisplayMode(type); 272 | if ( infogl ) grInfo(); 273 | 274 | /* call animate or normal mode */ 275 | switch (option) { 276 | case STANDARD: 277 | case SCHNAUZER: 278 | if ( !medit0() ) exit(1); 279 | if ( !medit1() ) exit(1); 280 | break; 281 | 282 | case SEQUENCE: 283 | if ( !animat() ) exit(1); 284 | break; 285 | case SEQUENCE+PARTICLE: 286 | if ( !animat() ) exit(1); 287 | break; 288 | case MORPHING: 289 | if ( !medit0() ) exit(1); 290 | if ( !modeMorphing() ) exit(1); 291 | morphing = GL_FALSE; 292 | break; 293 | default: 294 | fprintf(stderr," ## Unrecognized option %d\n",option); 295 | exit(1); 296 | break; 297 | } 298 | 299 | /* main grafix loop */ 300 | fprintf(stdout,"\n Rendering scene(s)\n"); 301 | glGetBooleanv(GL_STEREO,&hasStereo); 302 | glutMainLoop(); 303 | 304 | return(0); 305 | } 306 | -------------------------------------------------------------------------------- /src/medit.h: -------------------------------------------------------------------------------- 1 | #ifndef _MEDIT_H 2 | #define _MEDIT_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #ifdef WIN32 16 | #include 17 | #endif 18 | #ifdef __APPLE__ 19 | #include 20 | #include 21 | #include 22 | #else 23 | #include 24 | #include 25 | #include 26 | #endif 27 | 28 | #include "chrono.h" 29 | #include "memory.h" 30 | #include "mesh.h" 31 | #include "grafic.h" 32 | #include "image.h" 33 | #include "sproto.h" 34 | 35 | #define ME_VER "4.1a" 36 | #define ME_REL "Mar. 30, 2012" 37 | #define ME_CPY "Copyright (c) LJLL, 1999-2012" 38 | #define ME_STR "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" 39 | #define DEFAULT_FILE "DEFAULT.medit" 40 | 41 | #define MAX_MESH 32 42 | #define MAX_SCENE 32 43 | #define MAX_OBJ 32 44 | #define MAX_MATERIAL 128 45 | #define DEFAULT_MAT 0 46 | 47 | #define DTOR 0.0174532925 48 | #define RTOD 57.29577951308232 49 | #define EPS 1.e-06 50 | #define EPS2 2.e-10 51 | 52 | #ifndef TRUE 53 | #define TRUE 1 54 | #define FALSE 0 55 | #endif 56 | #ifdef M_PI 57 | #undef M_PI 58 | #undef M_PI_2 59 | #endif 60 | #define M_PI 3.14159265358979323846 /* pi */ 61 | #define M_PI_2 1.57079632679489661923 /* pi/2 */ 62 | 63 | #ifdef min 64 | #undef min 65 | #undef max 66 | #endif 67 | #define min(a,b) ( ((a) < (b)) ? (a) : (b) ) 68 | #define max(a,b) ( ((b) > (a)) ? (b) : (a) ) 69 | 70 | /* check if numbers are equal */ 71 | #define egal(x,y) ( \ 72 | ( ((x) == 0.0f) ? (fabs(y) < EPS) : \ 73 | ( ((y) == 0.0f) ? (fabs(x) < EPS) : \ 74 | (fabs((x)-(y)) / (fabs(x) + fabs(y)) < EPS2) ) ) ) 75 | 76 | 77 | /* options */ 78 | enum { STANDARD=1, SEQUENCE, VERYBIG, MORPHING, SCHNAUZER, ISOSURF, PARTICLE}; 79 | 80 | 81 | /* structure canvas */ 82 | typedef struct canvas { 83 | pMesh mesh[MAX_MESH]; 84 | pScene scene[MAX_SCENE]; 85 | int nbm,nbs; 86 | } Canvas; 87 | typedef Canvas * pCanvas; 88 | 89 | 90 | 91 | #endif -------------------------------------------------------------------------------- /src/memory.c: -------------------------------------------------------------------------------- 1 | /* file : memory.c 2 | * C code for memory debugging, to be used in lieu 3 | * of standard memory functions 4 | */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "memory.h" 11 | 12 | 13 | typedef struct memstack { 14 | size_t size; 15 | void *ptr; 16 | int nxt; 17 | char call[30]; 18 | } Memstack; 19 | 20 | typedef Memstack * pMemstack; 21 | 22 | const int MAXMEM = 300; 23 | pMemstack mstack; 24 | int stack,cur; 25 | 26 | 27 | int M_memLeak() { 28 | int i,c=0; 29 | 30 | for (i=1; i<=MAXMEM; i++) 31 | if (mstack[i].ptr) c++; 32 | return(c); 33 | } 34 | 35 | /* print out allocated pointers */ 36 | void M_memDump() { 37 | size_t size; 38 | int i,c; 39 | static long mega = 1024 * 1024; 40 | static long kilo = 1024; 41 | 42 | fprintf(stdout,"\n -- MEMORY USAGE\n"); 43 | fprintf(stdout," Allocated pointers\n"); 44 | size = 0; 45 | c = 0; 46 | for (i=1; i<=MAXMEM; i++) 47 | if ( mstack[i].ptr ) { 48 | fprintf(stdout," %3d %3d Pointer %10p size ",++c,i,mstack[i].ptr); 49 | if (mstack[i].size > mega) 50 | fprintf(stdout," %10d Mbytes ",(int)(mstack[i].size/mega)); 51 | else if (mstack[i].size > kilo) 52 | fprintf(stdout," %10d Kbytes ",(int)(mstack[i].size/kilo)); 53 | else 54 | fprintf(stdout," %10d bytes ",(int)(mstack[i].size)); 55 | fprintf(stdout,"(%s)\n",mstack[i].call); 56 | size += mstack[i].size; 57 | } 58 | fprintf(stdout," Memory leaks "); 59 | if ( size > mega ) 60 | fprintf(stdout," %10d Mbytes %d pointers\n",(int)(size/mega),c); 61 | else if ( size > kilo ) 62 | fprintf(stdout," %10d Kbytes %d pointers\n",(int)(size/kilo),c); 63 | else if ( size ) 64 | fprintf(stdout," %10d bytes %d pointers\n",(int)size,c); 65 | } 66 | 67 | 68 | /* Returns allocated memory space in bytes */ 69 | size_t M_memSize() { 70 | size_t size; 71 | int i; 72 | 73 | size = 0; 74 | for (i=1; i<=MAXMEM; i++) 75 | if ( mstack[i].ptr ) 76 | size += mstack[i].size; 77 | return size; 78 | } 79 | 80 | 81 | /* Allocates space for a block of at least size bytes, 82 | but does not initialize the space. */ 83 | void *M_malloc(size_t size,char *call) { 84 | int i; 85 | 86 | /* check if first call */ 87 | if ( !mstack ) { 88 | mstack = (Memstack *)calloc((1+MAXMEM),sizeof(Memstack)); 89 | assert(mstack); 90 | for (i=1; i= nelem * elsize bytes. */ 124 | void *M_calloc(size_t nelem, size_t elsize,char *call) { 125 | int i; 126 | 127 | /* check if first call */ 128 | if ( !mstack ) { 129 | mstack = (Memstack *)calloc((1+MAXMEM),sizeof(Memstack)); 130 | assert(mstack); 131 | for (i=1; i 1024*1024) 231 | fprintf(stdout," Total size : %10d Mbytes",(int)(memsize/(1024.*1024.))); 232 | else if (memsize > 1024) 233 | fprintf(stdout," Total size : %10d Kbytes",(int)(memsize/1024.)); 234 | else 235 | fprintf(stdout," Total size : %10d bytes ",(int)memsize); 236 | fprintf(stdout," (i.e. %d bytes/point)\n",memsize / np); 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /src/memory.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | 5 | #include 6 | #include 7 | 8 | /* prototype (re)definitions */ 9 | void *M_malloc(size_t size,char *call); 10 | void *M_calloc(size_t nelem,size_t elsize,char *call); 11 | void *M_realloc(void *ptr, size_t size,char *call); 12 | void M_free(void *ptr); 13 | 14 | /* ptototypes : tools */ 15 | int M_memLeak(); 16 | void M_memDump(); 17 | size_t M_memSize(); 18 | 19 | 20 | #ifdef __cplusplus 21 | } 22 | #endif 23 | -------------------------------------------------------------------------------- /src/mesh.h: -------------------------------------------------------------------------------- 1 | #ifndef _MESH_H 2 | #define _MESH_H 3 | 4 | #define M_NOTAG 0 5 | #define M_CORNER (1 << 0) 6 | #define M_RIDGE (1 << 1) 7 | #define M_REQUIRED (1 << 2) 8 | #define M_TAG (1 << 3) 9 | #define M_UNUSED (1 << 5) 10 | 11 | #ifndef ubyte 12 | typedef unsigned char ubyte; 13 | #endif 14 | #ifndef ushort 15 | typedef unsigned short uShort; 16 | #endif 17 | 18 | 19 | typedef struct spoint { 20 | double c[3]; 21 | int tmp,mark; 22 | short ref; 23 | char tag,clip,flag; 24 | } Point; 25 | typedef Point * pPoint; 26 | 27 | typedef struct striangle { 28 | int v[3],nxt,mark,cpt; 29 | short ref; 30 | char clip; 31 | } Triangle; 32 | typedef Triangle * pTriangle; 33 | 34 | typedef struct striangle2 { 35 | int v[6],nxt,cpt; 36 | short ref; 37 | uShort mark; 38 | char clip; 39 | } Triangle2; 40 | typedef Triangle2 * pTriangle2; 41 | 42 | typedef struct squad { 43 | int v[4],nxt; 44 | short ref; 45 | char clip; 46 | } Quad; 47 | typedef Quad * pQuad; 48 | 49 | typedef struct edge { 50 | int v[2]; 51 | short ref; 52 | char tag; 53 | } Edge; 54 | typedef Edge * pEdge; 55 | 56 | typedef struct stetra { 57 | int v[4],nxt,mark,cpt; 58 | short ref; 59 | char clip; 60 | } Tetra; 61 | typedef Tetra * pTetra; 62 | 63 | typedef struct shexa { 64 | int v[8],nxt,mark; 65 | short ref,cpt; 66 | char clip; 67 | } Hexa; 68 | typedef Hexa * pHexa; 69 | 70 | typedef struct extra { 71 | float *n,*t; 72 | int *nv,*nt,*nq,*tv,*te; 73 | int iv,it,iq,jv,je; 74 | } Extra; 75 | typedef Extra * pExtra; 76 | 77 | typedef struct solu { 78 | float *m,bb,time; 79 | int ver,dim; 80 | } Solution; 81 | typedef Solution * pSolution; 82 | 83 | /* Mesh: mesh data structure */ 84 | typedef struct mesh { 85 | double xmin,ymin,zmin,xmax,ymax,zmax; 86 | double xtra,ytra,ztra; 87 | float bbmin,bbmax; 88 | int ne,ne2,nt,nt2,nq,ntet,ntet2,nhex; 89 | int np,nc,nr,na,nre,nri; 90 | int nvn,ntg,dim,ver,nbb,typage,nfield,mark; 91 | char name[256],typ; 92 | 93 | pPoint point; 94 | pTriangle tria; 95 | pTriangle2 tria2; 96 | pQuad quad; 97 | pEdge edge; 98 | pTetra tetra; 99 | pHexa hexa; 100 | 101 | int *adja; 102 | int *grid; 103 | ubyte *voy; 104 | 105 | pExtra extra; 106 | pSolution sol; 107 | } Mesh; 108 | typedef Mesh * pMesh; 109 | 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /src/morphing.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "extern.h" 3 | #include "sproto.h" 4 | 5 | #define MAX_MORPH 100 6 | 7 | int imstep,imreverse; 8 | 9 | int modeMorphing() { 10 | pScene scene; 11 | pMesh mesh1,mesh2; 12 | pPoint ppt1,ppt2; 13 | int k; 14 | clock_t ct; 15 | 16 | /* default */ 17 | cv.nbs = 1; 18 | imstep = 1; 19 | imreverse = 1; 20 | if ( ddebug ) printf("morphing: create window\n"); 21 | fprintf(stdout,"\n Building scene\n"); 22 | ct = clock(); 23 | 24 | /* create grafix */ 25 | scene = cv.scene[0]; 26 | mesh1 = cv.mesh[0]; 27 | iniopt(scene,mesh1); 28 | parsop(scene,mesh1); 29 | meshRef(scene,mesh1); 30 | matSort(scene); 31 | 32 | mesh2 = cv.mesh[1]; 33 | parsop(scene,mesh2); 34 | meshRef(scene,mesh2); 35 | for (k=1; k<=mesh2->np; k++) { 36 | ppt1 = &mesh1->point[k]; 37 | ppt2 = &mesh2->point[k]; 38 | ppt2->c[0] -= ppt1->c[0]; 39 | ppt2->c[1] -= ppt1->c[1]; 40 | ppt2->c[2] -= ppt1->c[2]; 41 | } 42 | 43 | if ( !createScene(scene,0) ) { 44 | fprintf(stderr," ## Unable to create scene\n"); 45 | return(0); 46 | } 47 | ct = difftime(clock(),ct); 48 | fprintf(stdout," Scene seconds: %.2f\n", 49 | (double)ct/(double)CLOCKS_PER_SEC); 50 | return(1); 51 | } 52 | 53 | 54 | int morphMesh(pScene sc,pMesh mesh1) { 55 | pMesh mesh2; 56 | pPoint ppt1,ppt2; 57 | int k; 58 | static float dt = 1.0 / MAX_MORPH; 59 | 60 | imstep++; 61 | if ( imstep == 0 ) { 62 | imstep = 2; 63 | dt = -dt; 64 | if ( !imreverse ) { 65 | glutIdleFunc(NULL); 66 | morphing = 0; 67 | return(0); 68 | } 69 | } 70 | else if ( imstep == MAX_MORPH+1 ) { 71 | imstep = -MAX_MORPH+1; 72 | dt = -dt; 73 | if ( !imreverse ) { 74 | glutIdleFunc(NULL); 75 | morphing = 0; 76 | return(0); 77 | } 78 | } 79 | 80 | mesh2 = cv.mesh[1]; 81 | 82 | for (k=1; k<=mesh1->np; k++) { 83 | ppt1 = &mesh1->point[k]; 84 | ppt2 = &mesh2->point[k]; 85 | ppt1->c[0] += dt*ppt2->c[0]; 86 | ppt1->c[1] += dt*ppt2->c[1]; 87 | ppt1->c[2] += dt*ppt2->c[2]; 88 | } 89 | 90 | doLists(sc,mesh1); 91 | return(1); 92 | } 93 | -------------------------------------------------------------------------------- /src/normal.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "extern.h" 3 | #include "sproto.h" 4 | 5 | 6 | GLuint drawNormals(pMesh mesh,pScene sc) { 7 | pTriangle pt; 8 | pQuad pq; 9 | pEdge pr; 10 | pPoint ppt; 11 | GLuint dlist = 0; 12 | double nn[3]; 13 | float *n,p[3],scal; 14 | int i,k,kk,ki,iadr; 15 | 16 | /* default */ 17 | if ( !mesh->nvn ) return(0); 18 | if ( ddebug ) printf("display normals, tangents\n"); 19 | 20 | /* build display list */ 21 | dlist = glGenLists(1); 22 | glNewList(dlist,GL_COMPILE); 23 | if ( glGetError() ) return(0); 24 | if ( sc->type & S_OPPOS ) 25 | scal = -0.015; 26 | else 27 | scal = 0.015; 28 | scal *= sc->dmax; 29 | 30 | glColor3f(0.8,0.2,0.6); 31 | glLineWidth(2.0); 32 | glBegin(GL_LINES); 33 | 34 | /* normals at vertices */ 35 | if ( mesh->extra->iv && mesh->extra->nv ) { 36 | for (k=1; k<=mesh->np; k++) { 37 | ppt = &mesh->point[k]; 38 | ki = mesh->extra->nv[k]; 39 | if ( ki > 0 ) { 40 | iadr = 3*(ki-1)+1; 41 | n = &mesh->extra->n[iadr]; 42 | p[0] = ppt->c[0]; 43 | p[1] = ppt->c[1]; 44 | p[2] = ppt->c[2]; 45 | nn[0] = n[0]; 46 | nn[1] = n[1]; 47 | nn[2] = n[2]; 48 | drawVector3D(p,nn,scal); 49 | } 50 | } 51 | } 52 | 53 | /* normal at triangle vertices */ 54 | if ( mesh->extra->it && mesh->extra->nt ) { 55 | for (k=1; k<=mesh->nt; k++) { 56 | pt = &mesh->tria[k]; 57 | if ( !pt->v[0] ) continue; 58 | for ( i=0; i<3; i++) { 59 | kk = 3*(k-1)+i+1; 60 | ki = mesh->extra->nt[kk]; 61 | if ( ki > 0 ) { 62 | ppt = &mesh->point[pt->v[i]]; 63 | iadr = 3*(ki-1)+1; 64 | n = &mesh->extra->n[iadr]; 65 | p[0] = ppt->c[0]; 66 | p[1] = ppt->c[1]; 67 | p[2] = ppt->c[2]; 68 | nn[0] = n[0]; 69 | nn[1] = n[1]; 70 | nn[2] = n[2]; 71 | drawVector3D(p,nn,scal); 72 | } 73 | } 74 | } 75 | } 76 | 77 | /* normal at quad vertices */ 78 | if ( mesh->extra->iq && mesh->extra->nq ) { 79 | for (k=1; k<=mesh->nq; k++) { 80 | pq = &mesh->quad[k]; 81 | if ( !pq->v[0] ) continue; 82 | for ( i=0; i<4; i++) { 83 | kk = 4*(k-1)+i+1; 84 | ki = mesh->extra->nq[kk]; 85 | if ( ki > 0 ) { 86 | ppt = &mesh->point[pq->v[i]]; 87 | iadr = 3*(ki-1)+1; 88 | n = &mesh->extra->n[iadr]; 89 | p[0] = ppt->c[0]; 90 | p[1] = ppt->c[1]; 91 | p[2] = ppt->c[2]; 92 | nn[0] = n[0]; 93 | nn[1] = n[1]; 94 | nn[2] = n[2]; 95 | drawVector3D(p,nn,scal); 96 | } 97 | } 98 | } 99 | } 100 | 101 | 102 | /* tangents at vertices */ 103 | if ( mesh->extra->jv && mesh->extra->tv ) { 104 | glColor3f(0.2,0.6,0.8); 105 | for (k=1; k<=mesh->np; k++) { 106 | ppt = &mesh->point[k]; 107 | ki = mesh->extra->tv[k]; 108 | if ( ki > 0 ) { 109 | iadr = 3*(ki-1)+1; 110 | n = &mesh->extra->t[iadr]; 111 | p[0] = ppt->c[0]; 112 | p[1] = ppt->c[1]; 113 | p[2] = ppt->c[2]; 114 | nn[0] = n[0]; 115 | nn[1] = n[1]; 116 | nn[2] = n[2]; 117 | drawVector3D(p,nn,scal); 118 | } 119 | } 120 | } 121 | 122 | /* tangent at edge vertices */ 123 | if ( mesh->extra->je && mesh->extra->te ) { 124 | for (k=1; k<=mesh->na; k++) { 125 | pr = &mesh->edge[k]; 126 | if ( !pr->v[0] ) continue; 127 | for ( i=0; i<2; i++) { 128 | kk = 2*(k-1)+i+1; 129 | ki = mesh->extra->te[kk]; 130 | if ( ki > 0 ) { 131 | ppt = &mesh->point[pr->v[i]]; 132 | iadr = 3*(ki-1)+1; 133 | n = &mesh->extra->t[iadr]; 134 | p[0] = ppt->c[0]; 135 | p[1] = ppt->c[1]; 136 | p[2] = ppt->c[2]; 137 | nn[0] = n[0]; 138 | nn[1] = n[1]; 139 | nn[2] = n[2]; 140 | drawVector3D(p,nn,scal); 141 | } 142 | } 143 | } 144 | } 145 | 146 | glEnd(); 147 | glLineWidth(1.0); 148 | glEndList(); 149 | return(dlist); 150 | } 151 | -------------------------------------------------------------------------------- /src/param.c: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | 5 | #include "medit.h" 6 | #include "extern.h" 7 | #include "sproto.h" 8 | 9 | #ifndef ON 10 | #define ON 1 11 | #define OFF 0 12 | #endif 13 | 14 | extern void ortho2D(pScene ,ubyte ); 15 | 16 | /* globals */ 17 | typedef struct sparval { 18 | int arg; 19 | } Parval; 20 | typedef Parval * pParval; 21 | 22 | 23 | static void parMotion(int x,int y) { 24 | pScene sc; 25 | 26 | sc = cv.scene[currentScene()]; 27 | glEnable(GL_COLOR_LOGIC_OP); 28 | glLogicOp(GL_XOR); 29 | 30 | glColor3ub(255,255,0); 31 | setFont("helvetica",10); 32 | drwstr(10,sc->par.ys-120,"Vector length"); 33 | glColor3ub(0,255,128); 34 | drwstr(150,sc->par.ys-120,"%g",10.1); 35 | glFlush(); 36 | glDisable(GL_COLOR_LOGIC_OP); 37 | } 38 | 39 | static void parMouse(int button,int state,int x,int y) { 40 | pScene sc; 41 | if ( button != GLUT_LEFT_BUTTON ) return; 42 | sc = cv.scene[currentScene()]; 43 | 44 | if ( state == GLUT_DOWN ) { 45 | glColor3ub(0,255,128); 46 | glDrawBuffer(GL_FRONT); 47 | ortho2D(sc,ON); 48 | glutMotionFunc(parMotion); 49 | } 50 | else { 51 | glDrawBuffer(GL_BACK); 52 | ortho2D(sc,OFF); 53 | glutMotionFunc(parMotion); 54 | } 55 | } 56 | 57 | 58 | 59 | void parEdit(pScene sc) { 60 | glutMouseFunc(parMouse); 61 | } 62 | 63 | 64 | #ifdef __cplusplus 65 | } 66 | #endif 67 | -------------------------------------------------------------------------------- /src/parsar.c: -------------------------------------------------------------------------------- 1 | /* 2 | * parse arguments from command line 3 | * 4 | * Written by Pascal J. Frey, 1998. 5 | * email: Pascal.Frey@inria.fr 6 | */ 7 | #include "medit.h" 8 | #include "extern.h" 9 | #include "sproto.h" 10 | 11 | short schw,schh; 12 | extern ubyte option,infogl,fullscreen,dosurf,stereoMode; 13 | 14 | void usage() { 15 | fprintf(stdout,"Usage: medit [options] [f1 .. fn]\n"); 16 | fprintf(stdout,"\n** Generic options :\n"); 17 | fprintf(stdout,"-d \t Debug mode (lot of info)\n"); 18 | fprintf(stdout,"-fs\t Fullscreen mode\n"); 19 | fprintf(stdout,"-h \t Print this message\n"); 20 | fprintf(stdout,"-i \t Print info on OpenGL configuration\n"); 21 | fprintf(stdout,"-l \t Process very large files\n"); 22 | fprintf(stdout,"-s \t Do no build surface\n"); 23 | fprintf(stdout,"-v \t Turn off quiet mode\n"); 24 | fprintf(stdout,"f1..fn\t Input data file(s)\n"); 25 | fprintf(stdout,"\n** Graphic options\n"); 26 | fprintf(stdout,"-a start stop\t Animation sequence\n"); 27 | fprintf(stdout,"-m Morphing\n"); 28 | fprintf(stdout,"-xv width height\t Visual Schnauzer\n"); 29 | fprintf(stdout,"-stereo\t Stereo mode\n"); 30 | fprintf(stdout,"\n"); 31 | 32 | exit(1); 33 | } 34 | 35 | 36 | int parsar(int argc,char *argv[]) { 37 | pMesh mesh; 38 | int i; 39 | 40 | /* default*/ 41 | cv.nbm = cv.nbs = 0; 42 | i = 1; 43 | infogl = FALSE; 44 | dosurf = 1; 45 | stereoMode = MONO; 46 | while (i < argc) { 47 | if ( !strcmp(argv[i],"-h") || !strcmp(argv[i],"-help") ) 48 | usage(); 49 | else if ( !strcmp(argv[i],"-d") || !strcmp(argv[i],"-debug") ) 50 | ddebug = TRUE; 51 | else if ( !strcmp(argv[i],"-i") ) 52 | infogl = TRUE; 53 | else if ( !strcmp(argv[i],"-fs") ) 54 | fullscreen = TRUE; 55 | else if ( !strcmp(argv[i],"-l") ) 56 | option = VERYBIG; 57 | else if ( !strcmp(argv[i],"-m") ) 58 | option = MORPHING; 59 | else if ( !strcmp(argv[i],"-iso") ) 60 | option = ISOSURF; 61 | else if ( !strcmp(argv[i],"-stereo") ) 62 | stereoMode = LEFT+RIGHT; 63 | else if ( !strcmp(argv[i],"-s") ) 64 | dosurf = 0; 65 | else if ( !strcmp(argv[i],"-v") ) 66 | quiet = 0; 67 | else if ( !strcmp(argv[i],"-xv") ) { 68 | if ( ++i < argc && isdigit(argv[i][0]) ) 69 | schw = atoi(argv[i]); 70 | else 71 | usage(); 72 | if ( ++i < argc && isdigit(argv[i][0]) ) 73 | schh = atoi(argv[i]); 74 | else 75 | usage(); 76 | option = SCHNAUZER; 77 | } 78 | else if ( !strcmp(argv[i],"-a") ) { 79 | option = SEQUENCE; 80 | if ( ++i < argc && isdigit(argv[i][0]) ) 81 | animdep = atoi(argv[i]); 82 | if ( ++i < argc && isdigit(argv[i][0]) ) 83 | animfin = atoi(argv[i]); 84 | } 85 | else if ( !strcmp(argv[i],"-p") ) { 86 | option = SEQUENCE + PARTICLE; 87 | if ( ++i < argc && isdigit(argv[i][0]) ) 88 | animdep = atoi(argv[i]); 89 | if ( ++i < argc && isdigit(argv[i][0]) ) 90 | animfin = atoi(argv[i]); 91 | } 92 | else { 93 | if ( !cv.mesh[cv.nbm] ) { 94 | cv.mesh[cv.nbm] = (pMesh)M_calloc(1,sizeof(Mesh),"parsar.mesh"); 95 | if ( !cv.mesh[cv.nbm] ) return(0); 96 | } 97 | mesh = cv.mesh[cv.nbm]; 98 | /*mesh->name = argv[i];*/ 99 | strcpy(mesh->name,argv[i]); 100 | if ( ddebug ) printf("parsar: mesh[%d] %s\n",cv.nbm,mesh->name); 101 | if ( ++cv.nbm == MAX_MESH ) return(1); 102 | } 103 | i++; 104 | } 105 | 106 | return(1); 107 | } 108 | -------------------------------------------------------------------------------- /src/particle.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "extern.h" 3 | #include "sproto.h" 4 | 5 | 6 | extern int reftype,refitem; 7 | Particle *tp; 8 | 9 | 10 | void colorParticle(pScene sc,pParticle pp) { 11 | double rgb[3],norm,kc; 12 | int i; 13 | static double hsv[3] = { 0.0, 1.0, 0.80 }; 14 | 15 | norm = pp->norm; 16 | if ( norm < sc->iso.val[0] ) 17 | norm = sc->iso.val[0]; 18 | else if ( norm > sc->iso.val[MAXISO-1] ) 19 | norm = sc->iso.val[MAXISO-1]; 20 | for (i=0; iiso.val[i] ) break; 22 | kc = (norm-sc->iso.val[i-1]) / (sc->iso.val[i] - sc->iso.val[i-1]); 23 | hsv[0] = sc->iso.col[i-1]*(1.0-kc)+sc->iso.col[i]*kc; 24 | 25 | hsvrgb(hsv,rgb); 26 | pp->col[pp->cur][0] = rgb[0]; 27 | pp->col[pp->cur][1] = rgb[1]; 28 | pp->col[pp->cur][2] = rgb[2]; 29 | } 30 | 31 | 32 | void drawParticle(pScene sc,pParticle pp) { 33 | float radius; 34 | int i; 35 | 36 | radius = 0.005*sc->dmax; 37 | 38 | for (i=1; i<=sc->par.nbpart; i++) { 39 | glPushMatrix(); 40 | glTranslatef(pp->pos[i][0],pp->pos[i][1],pp->pos[i][2]); 41 | glColor3fv(pp->col[i]); 42 | glutSolidSphere(radius,10,10); 43 | glPopMatrix(); 44 | } 45 | } 46 | 47 | 48 | void computeTetraParticle(pScene sc,pMesh mesh,int k) { 49 | pTetra pt; 50 | pStream st; 51 | pParticle pp; 52 | double dd,cb[4],v[4],ux,uy,uz,pos[3],ldt; 53 | int cur,nsfin,nsold,nbp; 54 | 55 | st = sc->stream; 56 | pp = &tp[k]; 57 | if ( pp->ct > sc->par.pertime ) return; 58 | 59 | ldt = 0.0; 60 | nbp = 0; 61 | nsold = pp->nsdep; 62 | 63 | pos[0] = pp->pos[pp->cur][0]; 64 | pos[1] = pp->pos[pp->cur][1]; 65 | pos[2] = pp->pos[pp->cur][2]; 66 | 67 | do { 68 | ux = pos[0]; 69 | uy = pos[1]; 70 | uz = pos[2]; 71 | if ( st->typtrack == 1 || !nxtPoint3D(mesh,pp->nsdep,pos,pp->step,v) ) { 72 | pos[0] += pp->step*v[0]; 73 | pos[1] += pp->step*v[1]; 74 | pos[2] += pp->step*v[2]; 75 | } 76 | if ( pos[0]xmin || pos[0]>st->xmax || 77 | pos[1]ymin || pos[1]>st->ymax || 78 | pos[2]zmin || pos[2]>st->zmax ) { 79 | pp->flag = 0; 80 | break; 81 | } 82 | ux -= pos[0]; 83 | uy -= pos[1]; 84 | uz -= pos[2]; 85 | 86 | dd = sqrt(ux*ux + uy*uy + uz*uz) / pp->norm; 87 | ldt += dd; 88 | pp->ct += dd; 89 | 90 | if ( pp->ct >= sc->par.pertime ) { 91 | pp->flag = 0; 92 | sc->par.cumpertime = sc->par.pertime+1.e-06; 93 | break; /*return;*/ 94 | } 95 | else if ( ldt >= sc->par.dt ) { 96 | pp->cur = 1 + (pp->cur % sc->par.nbpart); 97 | pp->pos[pp->cur][0] = pos[0]; 98 | pp->pos[pp->cur][1] = pos[1]; 99 | pp->pos[pp->cur][2] = pos[2]; 100 | colorParticle(sc,pp); 101 | break; /*return;*/ 102 | } 103 | 104 | /* find tet containing p */ 105 | nsfin = locateTetra(mesh,pp->nsdep,pos,cb); 106 | if ( !nsfin ) { 107 | pp->flag = 0; 108 | break; /*return;*/ 109 | } 110 | pp->nsdep = nsfin; 111 | pt = &mesh->tetra[pp->nsdep]; 112 | if ( pt->cpt > MAX_CPT ) break; 113 | 114 | /* adjust local stepsize */ 115 | if ( pp->nsdep != nsold ) { 116 | pp->size = sizeTetra(mesh,pp->nsdep); 117 | nsold = pp->nsdep; 118 | } 119 | 120 | /* vector field interpolation */ 121 | pp->norm = field3DInterp(mesh,pp->nsdep,pp->cb,v); 122 | pp->step = HSIZ*min(pp->size,pp->norm); 123 | if ( sc->par.maxtime < FLT_MAX ) 124 | pp->step = min(0.05*sc->par.dt,pp->step); 125 | if ( pp->step == 0.0 ) { 126 | pp->flag = 0; 127 | return; 128 | } 129 | nbp++; 130 | } 131 | while ( ldt <= sc->par.dt ); 132 | 133 | cur = (pp->cur % MAX_PRT) + 1; 134 | pp->pos[cur][0] = pp->pos[pp->cur][0]; 135 | pp->pos[cur][1] = pp->pos[pp->cur][1]; 136 | pp->pos[cur][2] = pp->pos[pp->cur][2]; 137 | pp->cur = cur; 138 | colorParticle(sc,pp); 139 | } 140 | 141 | 142 | int displayParticle(pScene sc,pMesh mesh) { 143 | pParticle pp; 144 | pStream st; 145 | int k; 146 | 147 | st = sc->stream; 148 | if ( sc->par.advtim ) 149 | for (k=1; k<=st->nbstl; k++) 150 | computeTetraParticle(sc,mesh,k); 151 | 152 | /* redraw particles */ 153 | for (k=1; k<=st->nbstl; k++) { 154 | pp = &tp[k]; 155 | if ( pp->flag ) 156 | drawParticle(sc,pp); 157 | } 158 | 159 | return(1); 160 | } 161 | 162 | 163 | int createParticle(pScene sc,pMesh mesh) { 164 | pParticle pp; 165 | pStream st; 166 | pMaterial pm; 167 | pTetra pt1; 168 | pTriangle pt; 169 | pPoint ppt; 170 | double v[4],cx,cy,cz,pl[3]; 171 | int i,j,k,l,nmat,nbp,base; 172 | 173 | if ( ddebug ) printf("create particles\n"); 174 | if ( egal(sc->iso.val[0],sc->iso.val[MAXISO-1]) ) return(0); 175 | 176 | if ( sc->stream ) { 177 | st = sc->stream; 178 | if ( st->listp ) free(st->listp); 179 | free(sc->stream); 180 | } 181 | sc->stream = createStream(sc,mesh); 182 | sc->par.cumtim = sc->par.timdep; 183 | sc->par.advtim = 0; 184 | assert(sc->stream); 185 | st = sc->stream; 186 | 187 | fprintf(stdout," Creating particles :"); fflush(stdout); 188 | st->nbstl = 0; 189 | 190 | base = ++mesh->mark; 191 | pt = &mesh->tria[refitem]; 192 | nmat = matRef(sc,pt->ref); 193 | pm = &sc->material[nmat]; 194 | k = pm->depmat[LTria]; 195 | if ( !k || pm->flag ) return(0); 196 | 197 | /* point positions */ 198 | for (i=1; i<=mesh->np; i++) { 199 | ppt = &mesh->point[i]; 200 | ppt->mark = base; 201 | } 202 | if ( sc->par.nbpart >= MAX_PRT ) 203 | sc->par.nbpart = MAX_PRT; 204 | 205 | ++base; 206 | l = 1; 207 | nbp = 0; 208 | while ( k != 0 && st->nbstl < MAX_LST-1 ) { 209 | pt = &mesh->tria[k]; 210 | if ( pt->v[0] ) { 211 | cx = cy = cz = 0.0; 212 | for (i=0; i<3; i++) { 213 | ppt = &mesh->point[pt->v[i]]; 214 | cx += 0.33 * ppt->c[0]; 215 | cy += 0.33 * ppt->c[1]; 216 | cz += 0.33 * ppt->c[2]; 217 | ppt->flag = 1; 218 | } 219 | st->listp[l++] = cx; 220 | st->listp[l++] = cy; 221 | st->listp[l++] = cz; 222 | ++st->nbstl; 223 | if ( st->nbstl > MAX_LST-1 ) break; 224 | k = pt->nxt; 225 | } 226 | } 227 | fprintf(stdout,"%d\n",st->nbstl); 228 | if ( !st->nbstl ) return(0); 229 | 230 | /* init positions */ 231 | tp = calloc((st->nbstl+1),sizeof(Particle)); 232 | assert(tp); 233 | for (k=1; k<=st->nbstl; k++) 234 | tp[k].nsdep = mesh->ntet / 2; 235 | 236 | for (k=1; k<=mesh->ntet; k++) 237 | mesh->tetra[k].cpt = 0; 238 | 239 | l = 1; 240 | for (k=1; k<=st->nbstl; k++) { 241 | pp = &tp[k]; 242 | pp->pos[1][0] = pl[0] = st->listp[l++]; 243 | pp->pos[1][1] = pl[1] = st->listp[l++]; 244 | pp->pos[1][2] = pl[2] = st->listp[l++]; 245 | 246 | tp[k].nsdep = locateTetra(mesh,pp->nsdep,pl,pp->cb); 247 | 248 | if ( !pp->nsdep ) { 249 | for (j=1; j<=mesh->ntet; j++) { 250 | pt1 = &mesh->tetra[j]; 251 | if ( pt1->mark != mesh->mark && inTetra(mesh,j,pl,pp->cb) ) 252 | break; 253 | } 254 | if ( j > mesh->ntet ) return(0); 255 | else 256 | pp->nsdep = j; 257 | } 258 | pp->norm = field3DInterp(mesh,tp[k].nsdep,tp[k].cb,v); 259 | pp->size = sizeTetra(mesh,tp[k].nsdep); 260 | if ( pp->size == 0.0 ) 261 | pp->step = EPS*sc->dmax; 262 | else 263 | pp->step = HSIZ * min(pp->size,pp->norm); 264 | pp->step = min(0.05*sc->par.dt,pp->step); 265 | pp->flag = 1; 266 | pp->cur = 1; 267 | colorParticle(sc,pp); 268 | 269 | for (i=2; i<=sc->par.nbpart; i++) { 270 | pp->pos[i][0] = pp->pos[1][0]; 271 | pp->pos[i][1] = pp->pos[1][1]; 272 | pp->pos[i][2] = pp->pos[1][2]; 273 | } 274 | } 275 | 276 | return(1); 277 | } 278 | 279 | 280 | int advectParticle(pScene sc,pMesh mesh) { 281 | pParticle pp; 282 | pStream st; 283 | pTetra pt1; 284 | pPoint ppt; 285 | double v[4],pl[3]; 286 | int i,j,k,l,base; 287 | 288 | if ( ddebug ) printf("advect particles\n"); 289 | if ( egal(sc->iso.val[0],sc->iso.val[MAXISO-1]) ) return(0); 290 | if ( !sc->stream ) return(0); 291 | st = sc->stream; 292 | 293 | if ( mesh->ntet && !hashTetra(mesh) ) return(0); 294 | 295 | st->xmin = mesh->xmin - mesh->xtra; 296 | st->ymin = mesh->ymin - mesh->ytra; 297 | st->zmin = mesh->zmin - mesh->ztra; 298 | st->xmax = mesh->xmax - mesh->xtra; 299 | st->ymax = mesh->ymax - mesh->ytra; 300 | st->zmax = mesh->zmax - mesh->ztra; 301 | 302 | sc->par.cumpertime = 0.0; 303 | sc->par.advtim = 0; 304 | 305 | /* init list */ 306 | sc->slist = (GLuint*)calloc(MAX_LST,sizeof(GLuint)); 307 | if ( !sc->slist ) return(0); 308 | 309 | /* point positions */ 310 | base = ++mesh->mark; 311 | for (i=1; i<=mesh->np; i++) { 312 | ppt = &mesh->point[i]; 313 | ppt->mark = base; 314 | } 315 | for (k=1; k<=mesh->ntet; k++) 316 | mesh->tetra[k].cpt = 0; 317 | 318 | l = 1; 319 | for (k=1; k<=st->nbstl; k++) { 320 | pp = &tp[k]; 321 | pp->ct = 0.0; 322 | st->listp[l++] = pp->pos[pp->cur][0]; 323 | st->listp[l++] = pp->pos[pp->cur][1]; 324 | st->listp[l++] = pp->pos[pp->cur][2]; 325 | pp->cur = 1; 326 | } 327 | 328 | ++base; 329 | l = 1; 330 | for (k=1; k<=st->nbstl; k++) { 331 | pp = &tp[k]; 332 | pp->pos[1][0] = pl[0] = st->listp[l++]; 333 | pp->pos[1][1] = pl[1] = st->listp[l++]; 334 | pp->pos[1][2] = pl[2] = st->listp[l++]; 335 | 336 | tp[k].nsdep = locateTetra(mesh,pp->nsdep,pl,pp->cb); 337 | if ( !pp->nsdep ) { 338 | for (j=1; j<=mesh->ntet; j++) { 339 | pt1 = &mesh->tetra[j]; 340 | if ( pt1->mark != mesh->mark && inTetra(mesh,j,pl,pp->cb) ) 341 | break; 342 | } 343 | if ( j > mesh->ntet ) continue; 344 | else 345 | pp->nsdep = j; 346 | } 347 | pp->norm = field3DInterp(mesh,tp[k].nsdep,tp[k].cb,v); 348 | pp->size = sizeTetra(mesh,tp[k].nsdep); 349 | if ( pp->size == 0.0 ) 350 | pp->step = EPS*sc->dmax; 351 | else 352 | pp->step = HSIZ * min(pp->size,pp->norm); 353 | pp->step = min(0.05*sc->par.dt,pp->step); 354 | pp->flag = 1; 355 | pp->cur = 1; 356 | colorParticle(sc,pp); 357 | 358 | for (i=2; i<=sc->par.nbpart; i++) { 359 | pp->pos[i][0] = pp->pos[1][0]; 360 | pp->pos[i][1] = pp->pos[1][1]; 361 | pp->pos[i][2] = pp->pos[1][2]; 362 | } 363 | } 364 | 365 | return(1); 366 | } 367 | 368 | -------------------------------------------------------------------------------- /src/path.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "extern.h" 3 | #include "sproto.h" 4 | 5 | #define MAX_PATH 1024 6 | #define IMG_PER_SEC 25 7 | 8 | /* add point to path */ 9 | int pathAdd(pScene sc,int x,int y) { 10 | GLdouble modelmat[16],projmat[16]; 11 | GLdouble ptx,pty,ptz; 12 | GLint viewport[4]; 13 | Trajet *path; 14 | pMesh mesh; 15 | pTransform view; 16 | float *p,*p1,*a; 17 | int k; 18 | 19 | if ( ddebug ) fprintf(stdout,"pathAdd"); 20 | path = &sc->path; 21 | mesh = cv.mesh[sc->idmesh]; 22 | view = sc->view; 23 | if ( path->np == MAX_PATH ) return(0); 24 | 25 | /* memory alloc */ 26 | if ( !path->np ) { 27 | path->pt = (float*)calloc(mesh->dim*(MAX_PATH+1),sizeof(float)); 28 | if ( !path->pt ) { 29 | fprintf(stderr," Not enough memory to store path.\n"); 30 | return(0); 31 | } 32 | path->tg = (float*)calloc(mesh->dim*(MAX_PATH+1),sizeof(float)); 33 | if ( !path->tg ) { 34 | fprintf(stderr," Not enough memory to store tangents.\n"); 35 | return(0); 36 | } 37 | } 38 | else if ( path->np > MAX_PATH-1 ) return(0); 39 | 40 | /* get 3D point */ 41 | glGetDoublev(GL_PROJECTION_MATRIX,projmat); 42 | glGetIntegerv(GL_VIEWPORT,viewport); 43 | for (k=0; k<16; k++) modelmat[k] = view->matrix[k]; 44 | gluUnProject(x,y,-100,modelmat,projmat,viewport,&ptx,&pty,&ptz); 45 | 46 | /* store point coords */ 47 | ++path->np; 48 | p = &path->pt[mesh->dim*path->np]; 49 | p[0] = ptx; 50 | p[1] = pty; 51 | p[2] = ptz; 52 | 53 | /* compute tangent at point-1 */ 54 | if ( path->np > 2 ) { 55 | p1 = &path->pt[mesh->dim*(path->np-2)]; 56 | a = &path->tg[mesh->dim*path->np]; 57 | a[0] = 0.5 * (p[0] - p1[0]); 58 | a[1] = 0.5 * (p[1] - p1[1]); 59 | a[2] = 0.5 * (p[2] - p1[2]); 60 | } 61 | 62 | if ( ddebug ) printf(" Point %d: (%f %f %f) added\n",path->np,p[0],p[1],p[2]); 63 | return(1); 64 | } 65 | 66 | /* build list of points */ 67 | GLuint pathList(pScene sc) { 68 | Trajet path; 69 | pMesh mesh; 70 | GLuint dlist; 71 | float *p; 72 | int k; 73 | static GLfloat green[3] = {0.2, 1.0, 0.2}; 74 | /*static GLfloat orang[3] = {1.0, 0.7, 0.1};*/ 75 | 76 | if ( ddebug ) fprintf(stdout,"pathList"); 77 | path = sc->path; 78 | mesh = cv.mesh[sc->idmesh]; 79 | 80 | /* build display list */ 81 | dlist = glGenLists(1); 82 | glNewList(dlist,GL_COMPILE); 83 | if ( glGetError() ) return(0); 84 | 85 | /* node positions */ 86 | glPointSize(5); 87 | glColor3f(1.0,0.3,0.3); 88 | glBegin(GL_POINTS); 89 | for (k=1; k<=path.np; k++) { 90 | p = &path.pt[mesh->dim*k]; 91 | glVertex3fv(p); 92 | } 93 | glEnd(); 94 | 95 | /* straight path */ 96 | glLineWidth(2.0); 97 | glColor3fv(green); 98 | glBegin(GL_LINE_STRIP); 99 | for (k=1; k<=path.np; k++) { 100 | p = &path.pt[mesh->dim*k]; 101 | glVertex3fv(p); 102 | } 103 | glEnd(); 104 | glLineWidth(1.0); 105 | 106 | /* curvilinear path */ 107 | /* 108 | glBegin(GL_LINE_STRIP); 109 | glColor3fv(orang); 110 | glEnd(); 111 | */ 112 | 113 | glEndList(); 114 | return(dlist); 115 | } 116 | 117 | /* follow path */ 118 | void pathFollow(pScene sc) { 119 | Trajet path; 120 | int nbp; 121 | 122 | if ( !sc->path.np ) return; 123 | if ( ddebug ) fprintf(stdout,"pathFollow %d\n",sc->path.np); 124 | path = sc->path; 125 | if ( sc->path.sec < 0 ) 126 | nbp = sc->path.np; 127 | else 128 | nbp = (sc->path.sec*IMG_PER_SEC); 129 | } 130 | 131 | int pathLoad(char *file,pScene sc) { 132 | FILE *in; 133 | char *ptr,data[256]; 134 | 135 | strcpy(data,file); 136 | ptr = (char *)strstr(data,".mesh"); 137 | if ( ptr ) *ptr = '\0'; 138 | if ( !strstr(data,".path") ) 139 | strcat(data,".path"); 140 | in = fopen(data,"r"); 141 | if ( !in ) { 142 | sscanf(data,"DEFAULT.path"); 143 | in = fopen(data,"r"); 144 | if ( !in ) return(0); 145 | } 146 | if ( !quiet ) fprintf(stdout," Loading %s\n",data); 147 | 148 | return(1); 149 | } 150 | 151 | int pathSave(char *file,pScene sc) { 152 | FILE *out; 153 | pMesh mesh; 154 | time_t timeptr; 155 | float *p; 156 | int i,k; 157 | char *ptr,data[256]; 158 | 159 | strcpy(data,file); 160 | ptr = (char *)strstr(data,".mesh"); 161 | if ( ptr ) *ptr = '\0'; 162 | if ( !strstr(data,".path") ) 163 | strcat(data,".path"); 164 | 165 | out = fopen(data,"w"); 166 | if ( !out ) { 167 | fprintf(stdout," ## Unable to open file\n");; 168 | return(0); 169 | } 170 | if ( !quiet ) fprintf(stdout," Writing %s\n",data); 171 | 172 | /* create standard path file */ 173 | fprintf(out,"# File created with Medit %s\n",ME_VER); 174 | fprintf(out,"# Release %s\n",ME_REL); 175 | time(&timeptr); 176 | fprintf(out,"# Created: %s",ctime(&timeptr)); 177 | 178 | mesh = cv.mesh[sc->idmesh]; 179 | fprintf(out,"NbPoints\n%d\n",sc->path.np); 180 | for (k=1; k<=sc->path.np; k++) { 181 | p = &sc->path.pt[mesh->dim*k]; 182 | for (i=0; idim; i++) 183 | fprintf(out,"%f ",p[i]); 184 | fprintf(out,"\n"); 185 | } 186 | fclose(out); 187 | return(1); 188 | } 189 | -------------------------------------------------------------------------------- /src/persp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "medit.h" 3 | #include "extern.h" 4 | #include "sproto.h" 5 | 6 | static float ident[16] = { 7 | 1.,0.,0.,0., 0.,1.,0.,0., 0.,0.,1.,0., 0.,0.,0.,1.}; 8 | 9 | 10 | void setPersp(pScene sc,pPersp p,int pmode) { 11 | float tgalpha,deltax,deltay,alphax,alphay,alpha,beta; 12 | float rapx,rapy,Deltax,Deltay,yy; 13 | 14 | 15 | /* defalut */ 16 | Deltax = sc->par.xs; 17 | Deltay = sc->par.ys; 18 | alphax = p->fovy / 2.0f; 19 | alphay = p->fovy / 2.0f; 20 | 21 | deltax = (p->rubix+p->rubfx-Deltax) / (float)Deltax; 22 | deltay = (p->rubiy+p->rubfy-Deltay) / (float)Deltay; 23 | 24 | alpha = atan(deltax * tan(alphax*DTOR)); 25 | beta = atan(deltay * tan(alphay*DTOR)); 26 | yy = cos(alpha)*cos(alpha)*sin(beta)*sin(beta); 27 | yy /= yy + cos(beta)*cos(beta); 28 | yy = sqrt(yy); 29 | 30 | p->gamma = asin(yy)*RTOD; 31 | if ( deltay < 0. ) 32 | p->gamma = -p->gamma; 33 | p->alpha = alpha*RTOD; 34 | 35 | /* new fovy */ 36 | tgalpha = tan(p->fovy*DTOR); 37 | rapx = fabs(p->rubfx-p->rubix) / (float)sc->par.xs; 38 | rapy = fabs(p->rubfy-p->rubiy) / (float)sc->par.ys; 39 | 40 | if ( pmode == 1 ) 41 | p->fovy = atan(tgalpha * rapy)*RTOD; 42 | else if ( pmode == 0 ) 43 | p->fovy = atan(tgalpha / rapy)*RTOD; 44 | 45 | p->rubix = p->rubfx = 0; 46 | p->rubiy = p->rubfy = 0; 47 | } 48 | 49 | 50 | pPersp initPersp(pPersp p,float dmax) { 51 | pPersp pp; 52 | 53 | if ( p ) { 54 | p->fovy = 35.0f; 55 | p->rubber = 0; 56 | p->rubix = p->rubfx = 0; 57 | p->rubiy = p->rubfy = 0; 58 | p->alpha = p->gamma = 0.0f; 59 | p->depth = -2.0*dmax; 60 | p->pmode = PERSPECTIVE; 61 | memcpy(p->matrix,ident,16*sizeof(float)); 62 | return(p); 63 | } 64 | else { 65 | pp = (pPersp)M_calloc(1,sizeof(struct sperspective),"persp"); 66 | assert(pp); 67 | 68 | pp->fovy = 35.0f; 69 | pp->rubber = 0; 70 | pp->rubix = pp->rubfx = 0; 71 | pp->rubiy = pp->rubfy = 0; 72 | pp->alpha = pp->gamma = 0.0f; 73 | pp->depth = -2.0*dmax; 74 | pp->pmode = PERSPECTIVE; 75 | memcpy(pp->matrix,ident,16*sizeof(float)); 76 | return(pp); 77 | } 78 | } 79 | 80 | 81 | #ifdef __cplusplus 82 | } 83 | #endif 84 | -------------------------------------------------------------------------------- /src/psfile.c: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | 5 | 6 | #include 7 | #include 8 | 9 | #ifndef ubyte 10 | typedef unsigned char ubyte; 11 | #endif 12 | 13 | #define CM2IN 0.3937 14 | 15 | 16 | void writeEPSheader(FILE *out,char *data,char key,int ww,int hh,float cm,float dpi) { 17 | int wpad; 18 | 19 | fprintf(out,"%%!PS-Adobe-2.0 EPSF-2.0\n"); 20 | fprintf(out,"%%LanguageLevel: 1\n"); 21 | fprintf(out,"%%%%Title: %s\n",data); 22 | fprintf(out,"%%%%Creator: medit - (C) INRIA-Rocquencourt, 1999-2001\n"); 23 | fprintf(out,"%%%%BoundingBox: 50 50 %d %d\n", 24 | (int)(ww*72./dpi+50.5),(int)(hh*72.0/dpi+50.5)); 25 | fprintf(out,"%%%%Pages: (atend)\n"); 26 | fprintf(out,"%%DocumentFonts:\n"); 27 | fprintf(out,"%%%%EndComments\n"); 28 | fprintf(out,"%%%%EndProlog\n"); 29 | fprintf(out,"\n%%%%Page: 1 1\n"); 30 | fprintf(out,"\n%% remember original state\n"); 31 | fprintf(out,"/origstate save def\n"); 32 | fprintf(out,"\n%% build a temporary dictionary\n"); 33 | fprintf(out,"20 dict begin\n"); 34 | 35 | fprintf(out,"\n%% define space for color conversions\n"); 36 | fprintf(out,"/grays %d string def %% space for gray scale line\n",ww); 37 | fprintf(out,"/npixls 0 def\n"); 38 | fprintf(out,"/rgbindx 0 def\n"); 39 | fprintf(out,"\n%% lower left corner\n"); 40 | fprintf(out,"50 50 translate\n"); 41 | 42 | fprintf(out,"\n%% size of image (on paper, in 1/72inch coords)\n"); 43 | fprintf(out,"%g %g scale\n",72.0*CM2IN*cm,72.0*CM2IN*cm*(float)hh/ww); 44 | fprintf(out,"\n%% define string to hold a scanline's worth of data\n"); 45 | 46 | /* write BW image */ 47 | if ( key == 'B') { 48 | wpad = (ww+7) & ~7; 49 | fprintf(out,"/pix %d string def\n",wpad/8); 50 | fprintf(out,"\n%% dimensions of data\n"); 51 | fprintf(out,"%d %d 1\n",ww,hh); 52 | fprintf(out,"\n%% mapping matrix\n"); 53 | fprintf(out,"[%d 0 0 %d 0 %d]\n",ww,-hh,hh); 54 | fprintf(out,"\n{currentfile pix readhexstring pop}\n"); 55 | fprintf(out,"image\n"); 56 | } 57 | /* write greyscale image */ 58 | else if ( key == 'G' ) { 59 | fprintf(out,"/pix %d string def\n",ww); 60 | fprintf(out,"\n%% dimensions of data\n"); 61 | fprintf(out,"%d %d 8\n",ww,hh); 62 | fprintf(out,"\n%% mapping matrix\n"); 63 | fprintf(out,"[%d 0 0 %d 0 %d]\n",ww,-hh,hh); 64 | fprintf(out,"\n{currentfile pix readhexstring pop}\n"); 65 | fprintf(out,"image\n"); 66 | } 67 | /* color image */ 68 | else if ( key == 'C' ) { 69 | fprintf(out,"/pix %d string def\n",3*ww); 70 | 71 | fprintf(out,"\n%% dimensions of data\n"); 72 | fprintf(out,"%d %d 8\n",ww,hh); 73 | fprintf(out,"\n%% mapping matrix\n"); 74 | fprintf(out,"[%d 0 0 %d 0 %d]\n",ww,-hh,hh); 75 | 76 | fprintf(out,"\n%% define 'colorimage' if it isn't defined\n"); 77 | fprintf(out,"/colorimage where %% do we know about 'colorimage'?\n"); 78 | fprintf(out," { pop } %% yes: pop off the 'dict' returned\n"); 79 | fprintf(out," { %% no: define one\n"); 80 | fprintf(out," /colortogray { %% define an RGB->I function\n"); 81 | fprintf(out," /rgbdata exch store %% call input 'rgbdata'\n"); 82 | fprintf(out," rgbdata length 3 idiv\n"); 83 | fprintf(out," /npixls exch store\n"); 84 | fprintf(out," /rgbindx 0 store\n"); 85 | fprintf(out," 0 1 npixls 1 sub {\n"); 86 | fprintf(out," grays exch\n"); 87 | fprintf(out," rgbdata rgbindx get 20 mul %% Red\n"); 88 | fprintf(out," rgbdata rgbindx 1 add get 32 mul %% Green\n"); 89 | fprintf(out," rgbdata rgbindx 2 add get 12 mul %% Blue\n"); 90 | fprintf(out," add add 64 idiv %% I = .5G + .31R + .18B\n"); 91 | fprintf(out," put\n"); 92 | fprintf(out," /rgbindx rgbindx 3 add store\n"); 93 | fprintf(out," } for\n"); 94 | fprintf(out," grays 0 npixls getinterval\n"); 95 | fprintf(out," } bind def\n"); 96 | 97 | fprintf(out,"\n %% Utility procedure for colorimage operator.\n"); 98 | fprintf(out," %% This procedure takes two procedures off the\n"); 99 | fprintf(out," %% stack and merges them into a single procedure.\n"); 100 | 101 | fprintf(out,"\n /mergeprocs { %% def\n"); 102 | fprintf(out," dup length\n"); 103 | fprintf(out," 3 -1 roll\n"); 104 | fprintf(out," dup\n"); 105 | fprintf(out," length\n"); 106 | fprintf(out," dup\n"); 107 | fprintf(out," 5 1 roll\n"); 108 | fprintf(out," 3 -1 roll\n"); 109 | fprintf(out," add\n"); 110 | fprintf(out," array cvx\n"); 111 | fprintf(out," dup\n"); 112 | fprintf(out," 3 -1 roll\n"); 113 | fprintf(out," 0 exch\n"); 114 | fprintf(out," putinterval\n"); 115 | fprintf(out," dup\n"); 116 | fprintf(out," 4 2 roll\n"); 117 | fprintf(out," putinterval\n"); 118 | fprintf(out," } bind def\n"); 119 | 120 | fprintf(out," /colorimage { %% def\n"); 121 | fprintf(out," pop pop %% remove 'false 3' operands\n"); 122 | fprintf(out," {colortogray} mergeprocs\n"); 123 | fprintf(out," image\n"); 124 | fprintf(out," } bind def\n"); 125 | fprintf(out," } ifelse %% end of 'false' case\n"); 126 | fprintf(out,"\n{currentfile pix readhexstring pop}\n"); 127 | fprintf(out,"false 3 colorimage\n\n"); 128 | } 129 | } 130 | 131 | void writeEPStrailer(FILE *out) { 132 | fprintf(out,"\nshowpage\n"); 133 | fprintf(out,"\n%% stop using temporary dictionary\n"); 134 | fprintf(out,"end\n"); 135 | fprintf(out,"\n%% restore original state\n"); 136 | fprintf(out,"origstate restore\n"); 137 | fprintf(out,"\n%%%%Trailer\n"); 138 | } 139 | 140 | void writeEPSRow(FILE *out,char key,ubyte *buffer,int size,ubyte bckbyt) { 141 | int c,k,l; 142 | ubyte byte,bbyte; 143 | 144 | l = 0; 145 | switch (key) { 146 | case 'B': /* black & white */ 147 | byte = 0x0; 148 | c = 0; 149 | for (k=0; k<3*size; k+=3) { 150 | bbyte = (ubyte)(0.30*buffer[k] + 0.59*buffer[k+1] 151 | + 0.11*buffer[k+2] + 0.5); 152 | if ( bbyte == bckbyt ) byte |= (1 << (7-c)); 153 | /* 154 | if ( bbyte > 253 ) byte |= (1 << (7-c)); 155 | 156 | if ( bbyte && bbyte != 255 ) { 157 | printf("buffer %d %d %d\n",buffer[k],buffer[k+1],buffer[k+2]); 158 | printf("bbyte %d byte %d\n",bbyte,byte); 159 | exit(1); 160 | } 161 | */ 162 | if ( ++c == 8 ) { 163 | fprintf(out,"%.2x",byte); 164 | if ( ++l == 36 ) { 165 | fprintf(out,"\n"); 166 | l = 0; 167 | } 168 | byte = 0x0; 169 | c = 0; 170 | } 171 | } 172 | /* padding */ 173 | if ( c ) { 174 | for (l=8; l>c; l--) byte |= (1 << l); 175 | fprintf(out,"%.2x",byte); 176 | } 177 | break; 178 | case 'G': /* greyscale */ 179 | for (k=0; k<3*size; k+=3) { 180 | byte = (ubyte)(0.30*buffer[k] + 0.59*buffer[k+1] + 0.11*buffer[k+2]); 181 | fprintf(out,"%.2x",byte); 182 | if ( ++l == 36 ) { 183 | fprintf(out,"\n"); 184 | l = 0; 185 | } 186 | } 187 | break; 188 | case 'C': /* color scale */ 189 | for (k=0; k<3*size; k++) { 190 | fprintf(out,"%.2x",buffer[k]); 191 | if ( ++l == 36 ) { 192 | fprintf(out,"\n"); 193 | l = 0; 194 | } 195 | } 196 | break; 197 | } 198 | fprintf(out,"\n"); 199 | } 200 | 201 | 202 | #ifdef __cplusplus 203 | } 204 | #endif 205 | -------------------------------------------------------------------------------- /src/scissor.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "extern.h" 3 | #include "sproto.h" 4 | 5 | 6 | void scissorScene() { 7 | pScene sc; 8 | pMesh mesh; 9 | pPersp p; 10 | pTransform view; 11 | int width,height; 12 | 13 | /* default */ 14 | if ( ddebug ) printf("enable scissoring\n"); 15 | sc = cv.scene[currentScene()]; 16 | mesh = cv.mesh[sc->idmesh]; 17 | view = sc->view; 18 | p = sc->persp; 19 | 20 | /* subdivide main window */ 21 | glViewport(0,0,sc->par.xs,sc->par.ys); 22 | glMatrixMode(GL_PROJECTION); 23 | glLoadIdentity(); 24 | gluOrtho2D(0,sc->par.xs,0,sc->par.ys); 25 | glMatrixMode(GL_MODELVIEW); 26 | glLoadIdentity(); 27 | glClearColor(sc->par.back[0],sc->par.back[1],sc->par.back[2],sc->par.back[3]); 28 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 29 | 30 | /* split window */ 31 | glDisable(GL_LIGHTING); 32 | glColor4fv(sc->par.line); 33 | glBegin(GL_LINES); 34 | glVertex2i(sc->par.xs/2,0); 35 | glVertex2i(sc->par.xs/2,sc->par.ys); 36 | glVertex2i(0,sc->par.ys/2); 37 | glVertex2i(sc->par.xs,sc->par.ys/2); 38 | glEnd(); 39 | glEnable(GL_LIGHTING); 40 | 41 | width = (sc->par.xs + 1)/2; 42 | height = (sc->par.ys + 1)/2; 43 | 44 | glDisable(GL_LIGHTING); 45 | glColor4fv(sc->par.line); 46 | output2(5,sc->par.ys/2+5,"Top"); 47 | output2(5,5,"Front"); 48 | output2(sc->par.xs/2+5,5,"Right"); 49 | 50 | glEnable(GL_SCISSOR_TEST); 51 | 52 | /* draw top right : normal */ 53 | glViewport(width,height,width,height); 54 | glScissor(width,height,width,height); 55 | farclip(1); 56 | 57 | glMatrixMode(GL_MODELVIEW); 58 | glLoadIdentity(); 59 | gluLookAt(0.,0.,-p->depth, 0.,0.,0., 0.0,1.0,0.0); 60 | setupView(sc); 61 | glMultMatrixf(view->matrix); 62 | glTranslatef(sc->cx,sc->cy,sc->cz); 63 | drawModel(sc); 64 | if ( sc->type & S_DECO ) redrawStatusBar(sc); 65 | 66 | /* draw top left : top view */ 67 | glViewport(0,height,width,height); 68 | glScissor(0,height,width,height); 69 | farclip(1); 70 | 71 | glMatrixMode(GL_MODELVIEW); 72 | glLoadIdentity(); 73 | gluLookAt(0.,0.,-p->depth, 0.,0.,0., 0.0,1.0,0.0); 74 | setupView(sc); 75 | glTranslatef(sc->cx,sc->cy,sc->cz); 76 | glRotatef(-90,0.0,0.0,1.0); 77 | glTranslatef(view->opanx,0.,0.); 78 | drawModel(sc); 79 | 80 | /* draw bottom left : front */ 81 | glViewport(0,0,width,height); 82 | glScissor(0,0,width,height); 83 | farclip(1); 84 | 85 | glMatrixMode(GL_MODELVIEW); 86 | glLoadIdentity(); 87 | gluLookAt(0.,0.,-p->depth, 0.,0.,0., 0.0,1.0,0.0); 88 | setupView(sc); 89 | glTranslatef(sc->cx,sc->cy,sc->cz); 90 | glRotatef(-90.0,1.0,0.0,0.0); 91 | glTranslatef(view->opanx,0.,0.); 92 | drawModel(sc); 93 | 94 | /* draw bottom right : right */ 95 | glViewport(width,0,width,height); 96 | glScissor(width,0,width,height); 97 | farclip(1); 98 | 99 | glMatrixMode(GL_MODELVIEW); 100 | glLoadIdentity(); 101 | gluLookAt(0.,0.,-p->depth, 0.,0.,0., 0.0,1.0,0.0); 102 | setupView(sc); 103 | glRotatef(-90.0,1.0,0.0,0.0); 104 | glRotatef(-90.0,0.0,0.0,1.0); 105 | glTranslatef(0.,view->opany,0.); 106 | drawModel(sc); 107 | 108 | glutSwapBuffers(); 109 | glDisable(GL_SCISSOR_TEST); 110 | glViewport(0,0,sc->par.xs,sc->par.ys); 111 | 112 | if ( saveimg ) keyFile('H',0,0); 113 | } 114 | -------------------------------------------------------------------------------- /src/sftcpy.c: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | 5 | #include "medit.h" 6 | #include "extern.h" 7 | #include "sproto.h" 8 | 9 | 10 | /* OpenGL's GL_3D_COLOR feedback vertex format */ 11 | typedef struct Feedback3Dcolor { 12 | GLfloat x,y,z; 13 | GLfloat r,g,b,a; 14 | } Feedback3Dcolor; 15 | 16 | typedef struct Token { 17 | GLfloat depth; 18 | GLfloat *ptr; 19 | } Token; 20 | 21 | 22 | static int compare(const void *a, const void *b) { 23 | Token *p1 = (Token *)a; 24 | Token *p2 = (Token *)b; 25 | GLfloat diff = p2->depth - p1->depth; 26 | 27 | if ( diff > 0.0f ) 28 | return 1; 29 | else if ( diff < 0.0f ) 30 | return -1; 31 | else 32 | return 0; 33 | } 34 | 35 | 36 | void headps(FILE *file) { 37 | GLfloat color[4],viewport[4]; 38 | GLfloat linewidth = 0.1; 39 | GLfloat pointsize; 40 | 41 | 42 | glGetFloatv(GL_VIEWPORT,viewport); 43 | glGetFloatv(GL_COLOR_CLEAR_VALUE,color); 44 | glGetFloatv(GL_LINE_WIDTH,&linewidth); 45 | glGetFloatv(GL_POINT_SIZE,&pointsize); 46 | 47 | /* write EPS header */ 48 | fprintf(file,"%%!PS-Adobe-2.0 EPSF-2.0\n"); 49 | fprintf(file,"%%LanguageLevel: 1\n"); 50 | fprintf(file,"%%%%Creator: Medit (via OpenGL feedback)\n"); 51 | fprintf(file,"%%%%Pages: (atend)\n"); 52 | fprintf(file,"%%%%BoundingBox: %g %g %g %g\n", 53 | viewport[0],viewport[1],viewport[2],viewport[3]); 54 | fprintf(file,"%%EndComments\n\n"); 55 | 56 | /* define macros */ 57 | /* fprintf(file,"100 dict begin\n"); */ 58 | fprintf(file,"%%%%BeginProlog\n"); 59 | fprintf(file,"/sgm {moveto lineto stroke } def\n"); 60 | fprintf(file,"/stg {setgray} def\n"); 61 | fprintf(file,"/stc {setrgbcolor} def\n"); 62 | fprintf(file,"/mt {moveto} def\n"); 63 | fprintf(file,"/lt {lineto} def\n"); 64 | fprintf(file,"/dc {currentrgbcolor mark} def\n"); 65 | fprintf(file,"/fc {stc newpath moveto\n"); 66 | fprintf(file," counttomark 2 idiv {lineto} repeat\n"); 67 | fprintf(file," closepath fill cleartomark stc} def\n"); 68 | fprintf(file,"%%%%EndProlog\n\n"); 69 | 70 | fprintf(file,"gsave\n\n"); 71 | 72 | /* set background color */ 73 | fprintf(file,"%g %g %g setrgbcolor\n",color[0],color[1],color[2]); 74 | fprintf(file,"%g %g %g %g rectfill\n\n", 75 | viewport[0],viewport[1],viewport[2],viewport[3]); 76 | fprintf(file, "%g setlinewidth\n\n",0.01*linewidth); 77 | } 78 | 79 | void tailps(FILE *file) { 80 | /* write EPS tail */ 81 | fprintf(file,"\n"); 82 | fprintf(file,"%%%%Trailer\n"); 83 | fprintf(file,"%%%%Pages: 1\n"); 84 | fprintf(file,"grestore\n\n"); 85 | fprintf(file,"showpage\n\n"); 86 | fclose(file); 87 | } 88 | 89 | int coreps(FILE *file,GLsizei size,GLfloat *buffer) { 90 | Token *ttoken; 91 | pScene sc; 92 | Feedback3Dcolor *v; 93 | GLfloat *ptr; 94 | int i,k,idw,token,nit,nbv,sorting=TRUE; 95 | 96 | /* default */ 97 | if ( ddebug ) printf("dump EPS file\n"); 98 | idw = currentScene(); 99 | sc = cv.scene[idw]; 100 | 101 | /* Count tokens */ 102 | nit = 0; 103 | ptr = buffer; 104 | while ( *ptr && ptr < buffer+size ) { 105 | token = (int)*ptr; 106 | switch (token) { 107 | case GL_LINE_TOKEN: 108 | case GL_LINE_RESET_TOKEN: 109 | nit++; 110 | ptr += 14; 111 | break; 112 | 113 | case GL_POLYGON_TOKEN: 114 | nit++; 115 | ++ptr; 116 | nbv = *ptr; 117 | ptr += (7 * nbv); 118 | break; 119 | 120 | case GL_POINT_TOKEN: 121 | ptr += 7; 122 | break; 123 | 124 | case GL_BITMAP_TOKEN: 125 | puts("BITMAP"); 126 | nit++; 127 | ++ptr; 128 | nbv = *ptr; 129 | printf("nbv = %d\n",nbv); 130 | break; 131 | 132 | default: 133 | fprintf(stdout," Unrecognized token %d\n",token); 134 | break; 135 | } 136 | ptr++; 137 | } 138 | 139 | if ( ddebug ) 140 | printf("size = %d ptr = %p buffer = %p -> size = %ld\n",size,ptr,buffer,ptr-buffer); 141 | 142 | /* allocate mem to store tokens */ 143 | if ( ddebug ) printf("%d tokens found\n",nit); 144 | ttoken = (Token *)malloc((1+nit)*sizeof(struct Token)); 145 | assert(ttoken); 146 | 147 | /* store tokens */ 148 | nit = 0; 149 | ptr = buffer; 150 | while ( *ptr && ptr < buffer+size ) { 151 | ttoken[++nit].ptr = ptr; 152 | token = (int)*ptr; 153 | ptr++; 154 | switch (token) { 155 | case GL_LINE_TOKEN: 156 | case GL_LINE_RESET_TOKEN: 157 | v = (Feedback3Dcolor *)ptr; 158 | ttoken[nit].depth = 0.5*(v[0].z+v[1].z); 159 | ptr += 14; 160 | break; 161 | 162 | case GL_POLYGON_TOKEN: 163 | nbv = *ptr; 164 | ptr++; 165 | v = (Feedback3Dcolor *)ptr; 166 | ttoken[nit].depth = v[0].z; 167 | for (k=1; kmode == WIRE || sc->mode == WIRE+S_MATERIAL ) 186 | sorting = FALSE; 187 | if ( ddebug ) printf("prim = %d size = %ld, %d\n",nit,ptr-buffer-1,size); 188 | 189 | if ( sorting == TRUE ) { 190 | if ( ddebug ) printf("start sorting %d tokens...\n",nit); 191 | qsort(ttoken+1,nit,sizeof(struct Token),compare); 192 | if ( ddebug ) printf("end sorting\n"); 193 | } 194 | 195 | /* write tokens in EPS file */ 196 | for (k=1; k<=nit; k++) { 197 | ptr = ttoken[k].ptr; 198 | if ( *ptr == 0 ) continue; 199 | token = *ptr; 200 | ptr++; 201 | switch(token) { 202 | case GL_LINE_RESET_TOKEN: 203 | case GL_LINE_TOKEN: 204 | v = (Feedback3Dcolor *)ptr; 205 | fprintf(file,"%g %g %g stc\n",v[0].r,v[0].g,v[0].b); 206 | fprintf(file,"%g %g %g %g sgm\n",v[0].x,v[0].y,v[1].x,v[1].y); 207 | ptr += 14; 208 | break; 209 | 210 | case GL_POLYGON_TOKEN: 211 | nbv = *ptr; 212 | ptr++; 213 | v = (Feedback3Dcolor *)ptr; 214 | 215 | /* draw filled polygon */ 216 | if ( sorting == TRUE ) { 217 | /* fprintf(file,"1. stg\n"); */ 218 | fprintf(file, "dc "); 219 | for (i=0; imode & S_BDRY ) { 226 | fprintf(file,"0. stg\n"); 227 | for (i=0; iname); 261 | ptr = (char*)strstr(data,".mesh"); 262 | if ( ptr ) *ptr = '\0'; 263 | nfree = filnum(data,nfree,"ps"); 264 | if ( nfree == -1 ) return(0); 265 | 266 | /* open PS file */ 267 | sprintf(data,"%s.%.3d.ps",data,nfree); 268 | file = fopen(data,"w"); 269 | if ( !file ) { 270 | fprintf(stdout," Unable to open %s\n",data); 271 | return(0); 272 | } 273 | 274 | /* size for feedback buffer */ 275 | size = 0; 276 | nvalues = -1; 277 | do { 278 | size += 1024*1024; 279 | fbbuffer = (GLfloat *)calloc(1+size,sizeof(GLfloat)); 280 | if ( !fbbuffer ) { 281 | return(0); 282 | } 283 | if ( ddebug ) printf("feedback pointer = %p\n",fbbuffer); 284 | 285 | /* draw scene in back buffer */ 286 | glFeedbackBuffer(size,GL_3D_COLOR,fbbuffer); 287 | (void)glRenderMode(GL_FEEDBACK); 288 | /* 289 | glMatrixMode(GL_MODELVIEW); 290 | glLoadIdentity(); 291 | gluLookAt(0.,0.,-sc->persp->depth, 0.,0.,0., 0.0,1.0,0.0); 292 | 293 | setupView(sc); 294 | glMultMatrixf(sc->view->matrix); 295 | glTranslatef(sc->cx,sc->cy,sc->cz); 296 | */ 297 | drawModel(sc); 298 | if ( sc->type & S_DECO ) redrawStatusBar(sc); 299 | 300 | /*drawModel(sc);*/ 301 | nvalues = (GLint)glRenderMode(GL_RENDER); 302 | if ( nvalues < 0 ) 303 | free(fbbuffer); 304 | } 305 | while ( nvalues < 0 ); 306 | 307 | if ( nvalues < 1 ) { 308 | return(0); 309 | } 310 | else if ( ddebug ) printf("nvalues = %d size = %d\n",nvalues,size); 311 | 312 | /* write EPS file */ 313 | glutSetCursor(GLUT_CURSOR_WAIT); 314 | 315 | headps(file); 316 | coreps(file,size,fbbuffer); 317 | tailps(file); 318 | 319 | if ( ddebug ) fprintf(stdout,"%s written\n",data); 320 | glutSetCursor(GLUT_CURSOR_INHERIT); 321 | 322 | return(1); 323 | } 324 | 325 | 326 | #ifdef __cplusplus 327 | } 328 | #endif 329 | -------------------------------------------------------------------------------- /src/sproto.h: -------------------------------------------------------------------------------- 1 | /* animat.c */ 2 | int loadNextMesh(pMesh ,int ,int ,int ); 3 | int animat(); 4 | int playAnim(pScene ,pMesh ,int ,int ); 5 | void glutIdle(void); 6 | 7 | /* camera.c */ 8 | double Azimuth(pCamera ); 9 | double Elevation(pCamera ); 10 | void updateSun(pScene ,pCamera ); 11 | void updateCamera(pScene ,pCamera ,double ,double ); 12 | pCamera initCamera(pScene ,int ); 13 | 14 | /* clip.c */ 15 | void updateClip(pClip ,pMesh ); 16 | void clipVertices(pMesh ,pScene ,pClip ); 17 | void invertClip(pScene sc,pClip ); 18 | void drawClip(pScene ,pClip ,pMesh ,GLboolean ); 19 | void copyClip(pClip ); 20 | int pasteClip(pClip ); 21 | void resetClip(pScene ,pClip ,pMesh ); 22 | pClip createClip(pScene ,pMesh ); 23 | 24 | void updateCube(pCube ,pMesh ); 25 | pCube createCube(pScene ,pMesh ); 26 | 27 | /* clipvol.c */ 28 | GLuint capTetra(pMesh ); 29 | GLuint capTetraMap(pMesh ); 30 | GLuint capTetraIso(pMesh ); 31 | 32 | /* critip.c */ 33 | GLuint listCritPoint(pScene ,pMesh ); 34 | 35 | /* dlists.c */ 36 | GLuint listTria(pScene ,pMesh ); 37 | GLuint listQuad(pScene ,pMesh ); 38 | GLuint listTetra(pScene ,pMesh ,ubyte ); 39 | GLuint listHexa(pScene ,pMesh ,ubyte ); 40 | 41 | /* ellipse.c */ 42 | void drawEllipse(pScene sc,pMesh mesh,int typel,int k); 43 | void drawEllipsoid(pScene sc,pMesh mesh,int typel,int k); 44 | GLuint drawAllEllipse(pScene sc,pMesh mesh); 45 | 46 | /* geometry.c */ 47 | GLuint geomList(pScene ,pMesh ); 48 | 49 | /* gisfil.c */ 50 | int loadGIS(pMesh ); 51 | 52 | /* hash.c */ 53 | int hashTria(pMesh ); 54 | int hashTetra(pMesh ); 55 | int hashHexa(pMesh mesh); 56 | 57 | /* image.c */ 58 | PPMimage *loadPPM(const char *imgname,int *type); 59 | int savePPM(const char *imgname,pPPMimage img,int typimg); 60 | void saveEPS(pScene sc,const char *imgname,pPPMimage pixels); 61 | int imgHard(pScene sc,char *data,char key); 62 | 63 | /* input/output */ 64 | int EatLine(FILE *in); 65 | int EatSpace(FILE *in); 66 | int inmsh2(pMesh mesh); 67 | int bbfile(pMesh ); 68 | int loadMesh(pMesh ); 69 | int saveMesh(pScene ,pMesh ,char *,ubyte ); 70 | int loadSol(pMesh mesh,char *filename,int numsol); 71 | 72 | /* ilists.c */ 73 | GLuint listTriaIso(pScene ,pMesh ); 74 | GLuint listTriaIso2(pScene ,pMesh ); 75 | GLuint listQuadIso(pScene ,pMesh ); 76 | GLuint listTetraIso(pScene ,pMesh ); 77 | 78 | /* items.c */ 79 | void drawAxis(pScene ,int ); 80 | void drawBox(pScene ,pMesh ,int ); 81 | void drawCube(pScene ,pMesh ); 82 | void drawGrid(pScene ,pMesh ); 83 | void rubberBand(pPersp ); 84 | void drawBase(pScene ,pMesh ); 85 | void drawIso(pScene ); 86 | 87 | /* keyboard.c */ 88 | void specCamera(pScene ,int ); 89 | void special(int ,int ,int ); 90 | void keyScene(unsigned char ,int ,int ); 91 | 92 | /* listnum.c */ 93 | void updatePoints(pScene sc,pMesh mesh,int refmat); 94 | void listNum(pScene sc,pMesh mesh); 95 | 96 | /* material.c */ 97 | void matInit(pScene ); 98 | void matSort(pScene ); 99 | int matRef(pScene ,int ); 100 | void matReshape(int ,int ); 101 | void matsubReshape(int ,int ); 102 | void matsubDisplay(); 103 | void matDisplay(); 104 | void matMouse(int ,int ,int ,int ); 105 | void matKeyboard(unsigned char ,int ,int ); 106 | void matEdit(pScene ); 107 | 108 | /* medit.c */ 109 | int medit0(); 110 | int medit1(); 111 | 112 | /* menus.c */ 113 | void doLists(pScene ,pMesh ); 114 | void doMapLists(pScene ,pMesh ,int ); 115 | void doIsoLists(pScene ,pMesh ,int ); 116 | void keyFile(unsigned char ,int ,int ); 117 | void menuFile(int ); 118 | void keyItem(unsigned char ,int ,int ); 119 | void menuItem(int ); 120 | void keyAnim(unsigned char ,int ,int ); 121 | void menuAnim(int ); 122 | void keyTrajet(unsigned char ,int ,int ); 123 | void menuTrajet(int ); 124 | void keyMode(unsigned char ,int ,int ); 125 | void menuMode(int ); 126 | void menuScene(int ); 127 | void keyView(unsigned char ,int ,int ); 128 | void menuView(int ); 129 | void keyColor(unsigned char ,int ,int ); 130 | void menuColor(int ); 131 | void keyClip(unsigned char ,int ,int ); 132 | void menuClip(int ); 133 | void keyFeature(unsigned char ,int ,int ); 134 | void menuFeature(int ); 135 | void menuImage(int ); 136 | void keyMetric(unsigned char key,int x,int y); 137 | int createMenus(pScene ,pMesh ); 138 | 139 | /* mesh.c */ 140 | void meshInfo(pMesh ); 141 | int meshSurf(pMesh ); 142 | void meshCoord(pMesh ,int ); 143 | void meshBox(pMesh mesh,int bb); 144 | void meshRef(pScene sc,pMesh mesh); 145 | int meshUpdate(pScene sc,pMesh mesh); 146 | 147 | /* mlists.c */ 148 | GLuint listTriaMap(pScene ,pMesh ); 149 | GLuint listQuadMap(pScene ,pMesh ); 150 | GLuint listTetraMap(pScene ,pMesh ,ubyte ); 151 | GLuint listHexaMap(pScene ,pMesh ,ubyte ); 152 | void cutTriangle(pScene ,triangle ); 153 | GLuint alt2dList(pScene ,pMesh ,int ,float ,float ); 154 | void setupPalette(pScene ,pMesh ); 155 | GLuint drawPalette(pScene ); 156 | 157 | /* morphing */ 158 | int morphMesh(pScene sc,pMesh mesh1); 159 | int modeMorphing(); 160 | 161 | /* mouse.c */ 162 | void mouse(int button,int state,int x,int y); 163 | void motion(int x,int y); 164 | void redrawOverlay(int stretchX,int stretchY); 165 | void motionCamera(int x,int y); 166 | void mouseCamera(int button,int state,int x,int y); 167 | void animateCamera(); 168 | 169 | /* normal.c */ 170 | GLuint drawNormals(pMesh mesh,pScene sc); 171 | 172 | /* outmsh.c */ 173 | int outmsh(pScene ,pMesh ,char *name,ubyte clipon); 174 | 175 | /* parsar.c */ 176 | int parsar(int argc,char *argv[]); 177 | 178 | /* parsop.c */ 179 | int saveMeditFile(char *,pScene ); 180 | void iniopt(pScene ,pMesh ); 181 | int parsop(pScene ,pMesh ); 182 | 183 | /* particle.c */ 184 | int createParticle(pScene ,pMesh ); 185 | int advectParticle(pScene sc,pMesh mesh); 186 | int animParticle(pScene sc,pMesh mesh); 187 | int displayParticle(pScene sc,pMesh mesh); 188 | 189 | /* path.c */ 190 | int pathAdd(pScene ,int, int); 191 | GLuint pathList(pScene ); 192 | int pathLoad(char *data,pScene ); 193 | int pathSave(char *file,pScene ); 194 | void pathFollow(pScene ); 195 | 196 | /* persp.c */ 197 | void setPersp(pScene ,pPersp ,int ); 198 | pPersp initPersp(pPersp ,float ); 199 | 200 | /* picking.c */ 201 | GLuint pickingList(pScene ,int ,int ); 202 | GLuint pickingPoint(pScene sc,int x,int y); 203 | GLuint pickItem(pMesh ,pScene ,int ); 204 | GLuint pickingScene(pScene sc,int x,int y,int ident); 205 | 206 | /* prierr.c */ 207 | void prierr(int typerr,int indice); 208 | 209 | /* psfile.c */ 210 | void writeEPSheader(FILE *,char *,char ,int ,int ,float ,float); 211 | void writeEPStrailer(FILE *); 212 | void writeEPSRow(FILE *,char ,ubyte *,int ,ubyte ); 213 | 214 | /* scene.c */ 215 | int currentScene(); 216 | void checkErrors(void); 217 | void oglerr(GLenum error); 218 | void farclip(GLboolean ); 219 | void reshapeScene(int width,int height); 220 | void setupView(pScene sc); 221 | void drawBackTex(pScene sc); 222 | void drawModel(pScene sc); 223 | void drawScene(pScene ); 224 | void redrawScene(); 225 | void deleteScene(pScene sc); 226 | void initGrafix(pScene sc,pMesh mesh); 227 | int createScene(pScene sc,int idmesh); 228 | void streamIdle(); 229 | 230 | /* scissor.c */ 231 | void scissorScene(); 232 | 233 | /* status.c */ 234 | void reshapeStatusBar(pScene sc,int width,int height); 235 | void redrawStatusBar(pScene sc); 236 | void mouseStatus(int button,int state,int x,int y); 237 | 238 | /* stream.c */ 239 | int nxtPoint3D(pMesh mesh,int nsdep,double *p,double step,double *v); 240 | double sizeTetra(pMesh ,int ); 241 | double sizeHexa(pMesh ,int ); 242 | double sizeTria(pMesh ,int ); 243 | int locateTria(pMesh mesh,int nsdep,double *p,double *cb); 244 | int locateTetra(pMesh mesh,int nsdep,double *p,double *cb); 245 | int inTria(pMesh ,int ,double *,double *); 246 | int inTetra(pMesh mesh,int nsdep,double *p,double *cb); 247 | int listTetraStream(pScene ,pMesh ,float *,int ,double *,char ); 248 | int listHexaStream(pScene ,pMesh ,float *,int ); 249 | int listTriaStream(pScene ,pMesh ,float *,int ); 250 | pStream createStream(pScene ,pMesh ); 251 | int streamRefTria(pScene sc,pMesh mesh); 252 | int streamRefQuad(pScene sc,pMesh mesh); 253 | int streamRefPoint(pScene sc,pMesh mesh); 254 | int streamIsoPoint(pScene sc,pMesh mesh); 255 | int listSaddleStream(pScene sc,pMesh mesh,int depart,float *pp,float *vv,double lambda); 256 | double field2DInterp(pMesh mesh,int iel,double *cb,double *v); 257 | double vector3DInterp(pMesh mesh,pPoint pt[4],double *cb,double *v); 258 | double field3DInterp(pMesh mesh,int iel,double *cb,double *v); 259 | double sizeTria(pMesh mesh,int k); 260 | double sizeQuad(pMesh mesh,int k); 261 | double sizeTetra(pMesh mesh,int k); 262 | 263 | /* tensor.c */ 264 | GLuint listPointVector(pMesh ,ubyte ); 265 | 266 | /* texture.c */ 267 | pPPMimage texDistortion(pPPMimage ); 268 | 269 | /* tiles.c */ 270 | int imgTiling(pScene sc,char *data,char key); 271 | 272 | /* transform.c */ 273 | void resetTransform(pTransform ); 274 | pTransform createTransform(); 275 | 276 | /* util.c */ 277 | void setFont(char* name,int size); 278 | void drwstr(GLuint x,GLuint y,char* format, ...); 279 | void output2(GLfloat x,GLfloat y,char *format,...); 280 | void output3(GLfloat x,GLfloat y,GLfloat z,char *format,...); 281 | void hsvrgb(double *hsv,double *rgb); 282 | void transformPoint(double u[4],float v[4],float m[16]); 283 | void transformPointd(double u[4],double v[4],double m[16]); 284 | void transformPoint2(double u[4],float v[4],float m[16]); 285 | void transformVector(float u[4],float v[4],float m[16]); 286 | void multMatrix(GLfloat *p,GLfloat *a,GLfloat *b); 287 | void rotateMatrix(GLfloat angle,GLfloat x,GLfloat y,GLfloat z,GLfloat rm[16]); 288 | int invertMatrix(float src[16],float inverse[16]); 289 | int filnum(char *data,int numdep,char *ext); 290 | 291 | /* vector.c */ 292 | void drawVector2D(float p[2],double u[2],double scal); 293 | void drawVector3D(float p[3],double u[3],double scal); 294 | GLuint listTria2dVector(pMesh mesh); 295 | GLuint listTria3dVector(pMesh mesh); 296 | GLuint listClipTetraVector(pMesh mesh); 297 | GLuint listClipHexaVector(pMesh mesh); 298 | 299 | /* view.c */ 300 | void copyView(pTransform view,pCamera cam,pPersp persp); 301 | int pasteView(pTransform view,pCamera cam,pPersp persp); 302 | int linkView(pScene sc1); 303 | void unlinkView(pScene sc1); 304 | 305 | /* zaldy.c */ 306 | int zaldy1(pMesh mesh); 307 | int zaldy2(pMesh mesh); 308 | 309 | void keyCube(unsigned char key,int x,int y); 310 | void dumpCube(pScene sc,pMesh mesh,pCube cube); 311 | void resetCube(pScene sc,pCube cube,pMesh mesh); 312 | void tiltClip(pScene sc,pClip clip); 313 | void parEdit(pScene sc); 314 | int tetraIsoPOVray(pScene sc,pMesh mesh); 315 | GLuint listQuad2dVector(pMesh mesh); 316 | int sftcpy(pScene sc,pMesh mesh); 317 | int cenrad(pMesh mesh,int iel,double *c,double *rad); 318 | void circumSphere(pScene sc,pMesh mesh,int typel,int k); 319 | GLuint drawAllEllipse(pScene sc,pMesh mesh); 320 | void drawEllipsoid(pScene sc,pMesh mesh,int typel,int k); 321 | -------------------------------------------------------------------------------- /src/status.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "extern.h" 3 | #include "sproto.h" 4 | 5 | 6 | extern void drawHUD(pScene ); 7 | extern int refmat,imstep; 8 | 9 | 10 | void initTexture(void) { 11 | PPMimage *imgtex; 12 | int typimg; 13 | ubyte iquiet; 14 | GLuint texname; 15 | 16 | iquiet = quiet; 17 | quiet = 1; 18 | imgtex = loadPPM("Lions.ppm",&typimg); 19 | quiet = iquiet; 20 | if ( !imgtex ) return; 21 | 22 | glPixelStorei(GL_UNPACK_ALIGNMENT,1); 23 | glGenTextures(1,&texname); 24 | glBindTexture(GL_TEXTURE_2D,texname); 25 | 26 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 27 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 28 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 29 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 30 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 31 | 32 | glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,imgtex->sizeX,imgtex->sizeY, 33 | 0,GL_RGB,GL_UNSIGNED_BYTE,imgtex->data); 34 | free(imgtex); 35 | } 36 | 37 | void backTexture(pScene sc) { 38 | glEnable(GL_TEXTURE_2D); 39 | glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); 40 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 41 | 42 | glPushAttrib(GL_ENABLE_BIT); 43 | glEnable(GL_TEXTURE_2D); 44 | glDisable(GL_LIGHTING); 45 | glBegin(GL_QUADS); 46 | glTexCoord2f(0.0f, 0.0f); 47 | glVertex2f(0.0,0.0); 48 | 49 | glTexCoord2f(sc->par.xs,0.0); 50 | glVertex2f(sc->par.xs,0.0); 51 | 52 | glTexCoord2f(sc->par.xs,sc->par.ys); 53 | glVertex2f(sc->par.xs,sc->par.ys); 54 | 55 | glTexCoord2f(0.0,sc->par.ys); 56 | glVertex2f(0.0,sc->par.ys); 57 | glEnd(); 58 | glPopAttrib(); 59 | 60 | glDisable(GL_TEXTURE_2D); 61 | } 62 | 63 | 64 | void redrawStatusBar(pScene sc) { 65 | pClip clip = sc->clip; 66 | pMesh mesh = cv.mesh[sc->idmesh]; 67 | double dd; 68 | char buf[128]; 69 | float frame,elpms; 70 | static float fps=0.0,lastfr = 0.0; 71 | static int nfr = 0,pps = 0; 72 | 73 | if ( sc->par.xs < 100 ) return; 74 | if ( ddebug ) fprintf(stdout,"redrawStatusBar\n"); 75 | glDisable(GL_DEPTH_TEST); 76 | glDisable(GL_LIGHTING); 77 | 78 | glMatrixMode(GL_PROJECTION); 79 | glPushMatrix(); 80 | glLoadIdentity(); 81 | gluOrtho2D(1.,sc->par.xs,1.,sc->par.ys); 82 | 83 | glMatrixMode(GL_MODELVIEW); 84 | glPushMatrix(); 85 | glLoadIdentity(); 86 | 87 | /* other info */ 88 | glColor3f(1.0-sc->par.back[0],1.0-sc->par.back[1],1.0-sc->par.back[2]); 89 | if ( animate && !(sc->isotyp & S_PARTICLE) ) { 90 | nfr++; 91 | frame = glutGet(GLUT_ELAPSED_TIME) / 1000.0; 92 | elpms = frame - lastfr; 93 | if ( elpms > 0.999 ) { 94 | fps = nfr / elpms; 95 | if ( mesh->nt+mesh->nq ) 96 | pps = fps * (mesh->nt+mesh->nq); 97 | else if (mesh->ntet+mesh->nhex ) 98 | pps = fps * (mesh->ntet+mesh->nhex); 99 | else 100 | pps = fps * mesh->np; 101 | nfr = 0; 102 | lastfr = frame; 103 | } 104 | output2(15,8,"Fps: %6.2f Pps: %8d",fps,pps); 105 | } 106 | if ( option == MORPHING ) 107 | output2(15,28,"%d",abs(imstep)); 108 | 109 | if ( sc->isotyp & S_STREAML && sc->par.maxtime < FLT_MAX ) 110 | output2(15,8,"t= %8,3f",sc->par.cumtim); 111 | else if ( sc->isotyp & S_PARTICLE ) 112 | output2(15,8,"t= %8.3f",sc->par.cumtim); 113 | else if ( sc->type & S_DECO && sc->par.dt > 1.0e-5) { 114 | output2(15,8,"t= %8.3f",sc->par.cumtim); 115 | } 116 | else if ( sc->type & S_DECO && mesh->sol && mesh->sol->time > 0.0 ) { 117 | output2(15,8,"t= %8.3f",mesh->sol->time); 118 | } 119 | 120 | /* clip eqn */ 121 | if ( clip->active & C_ON && !(clip->active & C_HIDE) ) { 122 | sprintf(buf,"Eqn: "); 123 | if ( fabs(clip->eqn[0]) > EPS ) 124 | sprintf(buf,"%s %+.2gx",buf,clip->eqn[0]); 125 | if ( fabs(clip->eqn[1]) > EPS ) 126 | sprintf(buf,"%s %+.2gy",buf,clip->eqn[1]); 127 | if ( fabs(clip->eqn[2]) > EPS ) 128 | sprintf(buf,"%s %+.2gz",buf,clip->eqn[2]); 129 | dd = clip->eqn[3]-clip->eqn[0]*mesh->xtra \ 130 | - clip->eqn[1]*mesh->ytra-clip->eqn[2]*mesh->ztra; 131 | if ( dd ) sprintf(buf,"%s %+.2g",buf,dd); 132 | if ( sc->par.xs > 180 ) 133 | output2(150,8,"%s = 0",buf); 134 | } 135 | 136 | if ( sc->picklist && sc->par.xs > 390 && !sc->isotyp & S_PARTICLE ) 137 | output2(350,8,"%15s",sc->material[refmat].name); 138 | 139 | if ( sc->persp->pmode == PERSPECTIVE && sc->item & S_PALETTE ) 140 | drawPalette(sc); 141 | 142 | if ( sc->persp->pmode == CAMERA ) drawHUD(sc); 143 | glPopMatrix(); 144 | 145 | glMatrixMode(GL_PROJECTION); 146 | glPopMatrix(); 147 | glEnable(GL_LIGHTING); 148 | glEnable(GL_DEPTH_TEST); 149 | } 150 | 151 | void mouseStatus(int button,int state,int x,int y) { 152 | pScene sc = cv.scene[currentScene()]; 153 | pTransform view = sc->view; 154 | ubyte axis = X_AXIS; 155 | 156 | /* default */ 157 | if ( ddebug ) printf("control mouse %d\n",state); 158 | if ( button == GLUT_LEFT_BUTTON ) { 159 | if ( x < 16 && x > 5 ) axis = X_AXIS; 160 | else if ( x < 26 && x > 15 ) axis = Y_AXIS; 161 | else if ( x < 36 && x > 25 ) axis = Z_AXIS; 162 | switch (axis) { 163 | case X_AXIS: 164 | view->angle = 90.0; 165 | break; 166 | case Y_AXIS: 167 | view->angle = 90.0; 168 | view->axis[0] = 1.0; 169 | view->axis[1] = view->axis[2] = 0.0f; 170 | break; 171 | case Z_AXIS: 172 | view->angle = 90.0; 173 | view->axis[1] = 0.0f; 174 | view->axis[0] = view->axis[2] = 0.0f; 175 | break; 176 | } 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /src/tiles.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "sproto.h" 3 | #include "extern.h" 4 | 5 | extern ubyte ddebug; 6 | ubyte tiling; 7 | 8 | #define IN2CM 2.54 9 | #define CM2IN 0.3937 10 | 11 | 12 | void dumpTile(char *data,int width,int height,GLubyte *buffer) { 13 | FILE *out2; 14 | 15 | out2 = fopen(data,"w"); 16 | fprintf(out2,"P6\n"); 17 | fprintf(out2,"# Created using medit %s %s, (c) INRIA\n",ME_VER,ME_REL); 18 | fprintf(out2,"%d %d\n",width,height); 19 | fprintf(out2,"255\n"); 20 | fwrite(buffer,sizeof(GLubyte),width*height*3,out2); 21 | fclose(out2); 22 | } 23 | 24 | 25 | /* dump big image */ 26 | int imgTiling(pScene sc,char *data,char key) { 27 | FILE *out; 28 | pCamera c = sc->camera; 29 | GLubyte *tile,*buffer,*rowPtr; 30 | GLint matmode,viewport[4]; 31 | double xmin,xmax,ymin,ymax,left,right,top,bottom,ratio; 32 | float debhaut,finhaut,deblarg,finlarg,look[3]; 33 | int i,tw,th,col,row,nbcol,nbrow; 34 | int imgWidth,imgHeight,tileWidth,tileHeight,tileWidthNB,tileHeightNB; 35 | int bitsTileRow,bitsImgOffset,bitsCurTileRow,border; 36 | int bitsTileOffset,bitsPixel,imgRowSize; 37 | char *ptr,name[256]; 38 | ubyte bckbyte; 39 | static GLfloat up[3] = { 0.0, 1.0, 0.0}; 40 | 41 | glPixelStorei(GL_PACK_ALIGNMENT, 1); 42 | 43 | bckbyte = (ubyte)(255*(0.30*sc->par.back[0] + 44 | 0.59*sc->par.back[1] + 45 | 0.11*sc->par.back[2])+ 0.5); 46 | 47 | /* compute image size */ 48 | ratio = (double)sc->par.xs/(double)sc->par.ys; 49 | ymax = 0.1f*sc->dmax * tan(sc->persp->fovy * M_PI/360.0); 50 | ymin = -ymax; 51 | xmin = ymin * ratio; 52 | xmax = ymax * ratio; 53 | 54 | bitsPixel = 3 * sizeof(GLubyte); 55 | imgWidth = (int)(sc->par.dpi*CM2IN*sc->par.cm+0.5); 56 | imgHeight = (int)((double)imgWidth / ratio +0.5); 57 | imgRowSize = imgWidth * bitsPixel; 58 | 59 | tileWidth = sc->par.xs; 60 | tileHeight = sc->par.ys; 61 | border = sc->mode & S_BDRY ? 1 : 0; 62 | tileWidthNB = tileWidth - 2*border; 63 | tileHeightNB = tileHeight - 2*border; 64 | 65 | if ( ddebug ) { 66 | fprintf(stdout," Generating %d by %d image\n",imgWidth,imgHeight); 67 | fprintf(stdout," tile %d x %d\n",tileWidth,tileHeight); 68 | fprintf(stdout," image size %f x %f cm\n", 69 | sc->par.cm,(double)imgHeight/sc->par.dpi/CM2IN); 70 | } 71 | 72 | /* buffer to store one tile */ 73 | tile = (GLubyte*)calloc(tileWidthNB*tileHeightNB,bitsPixel); 74 | if ( !tile ) { 75 | fprintf(stderr," ## Unable to store buffer!\n"); 76 | return(0); 77 | } 78 | 79 | /* buffer for a row of tiles */ 80 | buffer = (GLubyte*)calloc(imgWidth*tileHeightNB,bitsPixel); 81 | if ( !buffer ) { 82 | free(tile); 83 | fprintf(stderr," ## Unable to store a row of tiles!\n"); 84 | return(0); 85 | } 86 | 87 | /* open EPS file */ 88 | strcpy(name,data); 89 | ptr = (char*)strstr(name,".ps"); 90 | if ( !ptr ) strcat(name,".ps"); 91 | out = fopen(name,"w"); 92 | if ( !out ) { 93 | fprintf(stderr," ## Unable to open file %s.\n",name); 94 | free(tile); 95 | return(0); 96 | } 97 | writeEPSheader(out,name,key,imgWidth,imgHeight,sc->par.cm,sc->par.dpi); 98 | 99 | /* save current viewport */ 100 | glGetIntegerv(GL_VIEWPORT,viewport); 101 | glDrawBuffer(GL_BACK_LEFT); 102 | glReadBuffer(GL_BACK_LEFT); 103 | 104 | /* dump tiles */ 105 | nbcol = (int)((float)imgWidth / tileWidthNB) + 1; 106 | nbrow = (int)((float)imgHeight/ tileHeightNB) + 1; 107 | tiling = 1; 108 | th = tileHeightNB; 109 | finhaut = sc->par.ys; 110 | 111 | for (row=nbrow-1; row>=0; row--) { 112 | if ( row < nbrow-1 ) 113 | th = tileHeightNB; 114 | else 115 | th = imgHeight - row*tileHeightNB; 116 | debhaut = finhaut - sc->par.ys * th / imgHeight; 117 | deblarg = 0; 118 | 119 | for (col=0; col tileHeightNB || tw > tileWidthNB ) { 125 | fprintf(stderr," %%%% Wrong tile size (%d,%d).\n",th,tw); 126 | free(buffer); 127 | free(tile); 128 | return(0); 129 | } 130 | finlarg = deblarg + sc->par.xs * tw / imgWidth; 131 | 132 | /* set viewport to tilesize (with border) */ 133 | glViewport(0,0,tw+2*border,th+2*border); 134 | 135 | /* current matrix */ 136 | glGetIntegerv(GL_MATRIX_MODE,&matmode); 137 | glMatrixMode(GL_PROJECTION); 138 | glLoadIdentity(); 139 | glMultMatrixf(sc->persp->matrix); 140 | 141 | /* compute projection parameters */ 142 | if ( sc->persp->pmode == PERSPECTIVE ) { 143 | left = xmin + (xmax-xmin) * (col*tileWidthNB) / imgWidth; 144 | right = left + (xmax-xmin) * tw / imgWidth; 145 | bottom = ymin + (ymax-ymin) * (row*tileHeightNB) / imgHeight; 146 | top = bottom + (ymax-ymin) * th / imgHeight; 147 | 148 | glFrustum(left,right,bottom,top,0.1*sc->dmax,10.0f*sc->dmax); 149 | glTranslatef(0.0f,0.0,sc->persp->depth); 150 | } 151 | else if ( sc->persp->pmode == CAMERA ) { 152 | left = xmin + (xmax-xmin) * (col*tileWidthNB) / imgWidth; 153 | right = left + (xmax-xmin) * tw / imgWidth; 154 | bottom = ymin + (ymax-ymin) * (row*tileHeightNB) / imgHeight; 155 | top = bottom + (ymax-ymin) * th / imgHeight; 156 | 157 | glFrustum(left,right,bottom,top,0.1f*sc->dmax,10.0f*sc->dmax); 158 | 159 | look[0] = c->eye[0] + 0.001*sc->dmax*c->speed[0]; 160 | look[1] = c->eye[1] + 0.001*sc->dmax*c->speed[1]; 161 | look[2] = c->eye[2] + 0.001*sc->dmax*c->speed[2]; 162 | gluLookAt(c->eye[0],c->eye[1],c->eye[2], 163 | look[0],look[1],look[2], 164 | up[0],up[1],up[2]); 165 | glTranslatef(0.0f,0.0f,0.5*sc->persp->depth); 166 | } 167 | else if ( sc->persp->pmode == ORTHO ) { 168 | glOrtho(-1.,1.,-1.,0.1,0.01,0.01); 169 | glTranslatef(0.0,0.0,sc->persp->depth); 170 | } 171 | 172 | /* redraw scene */ 173 | glDisable(GL_LIGHTING); 174 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 175 | glMatrixMode(GL_MODELVIEW); 176 | glLoadIdentity(); 177 | /*gluLookAt(0.,0.,-sc->persp->depth, 0.,0.,0., 0.0,1.0,0.0);*/ 178 | 179 | glMultMatrixf(sc->view->matrix); 180 | glTranslatef(sc->cx,sc->cy,sc->cz); 181 | drawModel(sc); 182 | 183 | /* read buffer */ 184 | glFlush(); 185 | glReadPixels(border,border,tileWidthNB,tileHeightNB, 186 | GL_RGB,GL_UNSIGNED_BYTE,tile); 187 | 188 | /* store to row buffer */ 189 | bitsImgOffset = col * tileWidthNB * bitsPixel; 190 | bitsTileRow = tileWidthNB * bitsPixel; 191 | bitsCurTileRow = tw * bitsPixel; 192 | bitsTileOffset = border*bitsPixel; 193 | bitsTileOffset = 0; 194 | for (i=0; ipar.coeff > 0.0f ) { 205 | for (i=0; i 10 ) 207 | buffer[i] += (255-buffer[i]) * sc->par.coeff; 208 | else 209 | buffer[i] += buffer[i] * sc->par.coeff; 210 | } 211 | 212 | /* write row of tiles */ 213 | for (i=0; ipos[0] = tr->pos[1] = tr->pos[2] = 0.0f; 11 | tr->angle = 0.0f; 12 | tr->panx = tr->pany = 0.0f; 13 | tr->opanx = tr->opany = 0.0f; 14 | tr->mstate = 1; 15 | tr->manim = GL_FALSE; 16 | 17 | memcpy(tr->matrix,itransf,16*sizeof(float)); 18 | memcpy(tr->rot,itransf,16*sizeof(float)); 19 | memcpy(tr->tra,itransf,16*sizeof(float)); 20 | } 21 | 22 | pTransform createTransform() { 23 | pTransform tr; 24 | 25 | /* default */ 26 | if ( ddebug) printf("create transformation\n"); 27 | 28 | tr = (pTransform)M_calloc(1,sizeof(struct transform),"transform") ; 29 | assert(tr); 30 | 31 | /* set default values */ 32 | resetTransform(tr); 33 | tr->mbutton = 0; 34 | 35 | return(tr); 36 | } 37 | -------------------------------------------------------------------------------- /src/util.c: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | 5 | #include 6 | #include 7 | #include "medit.h" 8 | #include "extern.h" 9 | #include "sproto.h" 10 | 11 | 12 | static GLfloat IdMatrix[16] = { 13 | 1.0, 0.0, 0.0, 0.0, 14 | 0.0, 1.0, 0.0, 0.0, 15 | 0.0, 0.0, 1.0, 0.0, 16 | 0.0, 0.0, 0.0, 1.0 17 | }; 18 | 19 | /* set font style and size */ 20 | void setFont(char* name,int size) { 21 | GLvoid *font_style = GLUT_BITMAP_HELVETICA_10; 22 | 23 | if ( !strcmp(name,"helvetica") ) { 24 | if (size == 12) 25 | font_style = GLUT_BITMAP_HELVETICA_12; 26 | else if (size == 18) 27 | font_style = GLUT_BITMAP_HELVETICA_18; 28 | } 29 | else if (strcmp(name, "times roman") == 0) { 30 | font_style = GLUT_BITMAP_TIMES_ROMAN_10; 31 | if (size == 24) 32 | font_style = GLUT_BITMAP_TIMES_ROMAN_24; 33 | } 34 | /* 35 | else if (strcmp(name, "8x13") == 0) 36 | font_style = GLUT_BITMAP_8_BY_13; 37 | */ 38 | else if (strcmp(name, "9x15") == 0) 39 | font_style = GLUT_BITMAP_9_BY_15; 40 | } 41 | 42 | /* display string format at pos(x,y) */ 43 | void drwstr(GLuint x,GLuint y,char* format, ...) { 44 | va_list args; 45 | char *s,buffer[255]; 46 | 47 | va_start(args,format); 48 | vsprintf(buffer,format,args); 49 | va_end(args); 50 | 51 | glRasterPos2i(x,y); 52 | for (s=buffer; *s; s++) 53 | glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18,*s); 54 | } 55 | 56 | void output2(GLfloat x,GLfloat y,char *format,...) { 57 | va_list args; 58 | char *s,buffer[255]; 59 | 60 | /*strcpy(myerror.procname,"output2");*/ 61 | va_start(args,format); 62 | vsprintf(buffer,format,args); 63 | va_end(args); 64 | 65 | glRasterPos2f(x,y); 66 | for (s=buffer; *s; s++) { 67 | /*glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_10,*s);*/ 68 | /*glutBitmapCharacter(font_style,*s);*/ 69 | glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10,*s); 70 | } 71 | } 72 | 73 | void output3(GLfloat x,GLfloat y,GLfloat z,char *format,...) { 74 | va_list args; 75 | char buffer[255], *s; 76 | 77 | /*strcpy(myerror.procname,"output3");*/ 78 | va_start(args,format); 79 | vsprintf(buffer,format,args); 80 | va_end(args); 81 | glRasterPos3f(x,y,z); 82 | for (s=buffer; *s; s++) 83 | glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10,*s); 84 | } 85 | 86 | /* color converter */ 87 | void hsvrgb(double *hsv,double *rgb) { 88 | double f,p,q,t; 89 | int i; 90 | 91 | hsv[0] = ((int)hsv[0] % 360) / 60.; 92 | i = (int)floor((double)hsv[0]); /* largest int <= h */ 93 | f = hsv[0] - i; /* fractional part of h */ 94 | p = hsv[2] * (1.0 - hsv[1]); 95 | q = hsv[2] * (1.0 - (hsv[1] * f)); 96 | t = hsv[2] * (1.0 - (hsv[1] * (1.0 - f))); 97 | 98 | switch(i) { 99 | case 0: rgb[0] = hsv[2]; rgb[1] = t; rgb[2] = p; break; 100 | case 1: rgb[0] = q; rgb[1] = hsv[2]; rgb[2] = p; break; 101 | case 2: rgb[0] = p; rgb[1] = hsv[2]; rgb[2] = t; break; 102 | case 3: rgb[0] = p; rgb[1] = q; rgb[2] = hsv[2]; break; 103 | case 4: rgb[0] = t; rgb[1] = p; rgb[2] = hsv[2]; break; 104 | case 5: rgb[0] = hsv[2]; rgb[1] = p; rgb[2] = q; break; 105 | } 106 | } 107 | 108 | /* transform: u = MxV */ 109 | void transformPoint(double u[4],float v[4],float m[16]) { 110 | u[0] = v[0] * m[0] + v[1] * m[1] + v[2] * m[2] + v[3] * m[3]; 111 | u[1] = v[0] * m[4] + v[1] * m[5] + v[2] * m[6] + v[3] * m[7]; 112 | u[2] = v[0] * m[8] + v[1] * m[9] + v[2] * m[10] + v[3] * m[11]; 113 | u[3] = v[0] * m[12] + v[1] * m[13] + v[2] * m[14] + v[3] * m[15]; 114 | } 115 | 116 | void transformPoint2(double u[4],float v[4],float m[16]) { 117 | u[0] = v[0] * m[0] + v[1] * m[4] + v[2] * m[8] + v[3] * m[12]; 118 | u[1] = v[0] * m[1] + v[1] * m[5] + v[2] * m[9] + v[3] * m[13]; 119 | u[2] = v[0] * m[2] + v[1] * m[6] + v[2] * m[10] + v[3] * m[14]; 120 | u[3] = v[0] * m[3] + v[1] * m[7] + v[2] * m[11] + v[3] * m[15]; 121 | } 122 | 123 | void transformPointd(double u[3],double v[3],double m[16]) { 124 | u[0] = v[0] * m[0] + v[1] * m[1] + v[2] * m[2]; 125 | u[1] = v[0] * m[4] + v[1] * m[5] + v[2] * m[6]; 126 | u[2] = v[0] * m[8] + v[1] * m[9] + v[2] * m[10]; 127 | } 128 | 129 | void transformVector(float u[4],float v[4],float m[16]) { 130 | u[0] = v[0] * m[0] + v[1] * m[4] + v[2] * m[8]; 131 | u[1] = v[0] * m[1] + v[1] * m[5] + v[2] * m[9]; 132 | u[2] = v[0] * m[2] + v[1] * m[6] + v[2] * m[10]; 133 | u[3] = v[0] * m[3] + v[1] * m[7] + v[2] * m[11]; 134 | } 135 | 136 | 137 | /* p = axb */ 138 | void multMatrix(GLfloat *p,GLfloat *a,GLfloat *b) { 139 | GLint i,row; 140 | 141 | for (i=0; i<4; i++) { 142 | row = i*4; 143 | p[row+0] = a[row] * b[0] + a[row+1] * b[4] + a[row+2] * b[8] + a[row+3] * b[12]; 144 | p[row+1] = a[row] * b[1] + a[row+1] * b[5] + a[row+2] * b[9] + a[row+3] * b[13]; 145 | p[row+2] = a[row] * b[2] + a[row+1] * b[6] + a[row+2] * b[10] + a[row+3] * b[14]; 146 | p[row+3] = a[row] * b[3] + a[row+1] * b[7] + a[row+2] * b[11] + a[row+3] * b[15]; 147 | } 148 | } 149 | 150 | void rotateMatrix(GLfloat angle,GLfloat x,GLfloat y,GLfloat z,GLfloat rm[16]) { 151 | GLfloat mag,s,c; 152 | GLfloat xx,yy,zz,xy,yz,zx,xs,ys,zs,one_c; 153 | 154 | if ( angle == 0.0f ) { 155 | memcpy(rm,IdMatrix,16*sizeof(GLfloat)); 156 | return; 157 | } 158 | mag = x*x + y*y + z*z; 159 | 160 | if ( mag == 0.0f ) { 161 | memcpy(rm,IdMatrix,16*sizeof(GLfloat)); 162 | return; 163 | } 164 | mag = 1.0f / sqrt(mag); 165 | x *= mag; 166 | y *= mag; 167 | z *= mag; 168 | s = sin(angle * DTOR); 169 | c = cos(angle * DTOR); 170 | xx = x*x; yy = y*y; zz = z*z; 171 | xy = x*y; yz = y*z; zx = z*x; 172 | xs = x*s; ys = y*s; zs = z*s; 173 | one_c = 1.0f - c; 174 | 175 | rm[0] = (one_c * xx) + c; 176 | rm[1] = (one_c * xy) - zs; 177 | rm[2] = (one_c * zx) + ys; 178 | rm[3] = 0.0f; 179 | 180 | rm[4] = (one_c * xy) + zs; 181 | rm[5] = (one_c * yy) + c; 182 | rm[6] = (one_c * yz) - xs; 183 | rm[7] = 0.0f; 184 | 185 | rm[8] = (one_c * zx) - ys; 186 | rm[9] = (one_c * yz) + xs; 187 | rm[10] = (one_c * zz) + c; 188 | rm[11] = 0.0f; 189 | 190 | rm[12] = rm[13] = rm[14] = 0.0f; 191 | rm[15] = 1.0f; 192 | } 193 | 194 | int invertMatrix(float src[16],float inverse[16]) { 195 | double t; 196 | int i, j, k, swap; 197 | double tmp[4][4]; 198 | 199 | memcpy(inverse,IdMatrix,16*sizeof(GLfloat)); 200 | for (i=0; i<4; i++) 201 | for (j=0; j<4; j++) 202 | tmp[i][j] = src[i*4+j]; 203 | 204 | for (i=0; i<4; i++) { 205 | /* look for largest element in column. */ 206 | swap = i; 207 | for (j=i+1; j<4; j++) { 208 | if ( fabs(tmp[j][i]) > fabs(tmp[i][i]) ) 209 | swap = j; 210 | } 211 | if ( swap != i ) { 212 | /* swap rows. */ 213 | for (k=0; k<4; k++) { 214 | t = tmp[i][k]; 215 | tmp[i][k] = tmp[swap][k]; 216 | tmp[swap][k] = t; 217 | t = inverse[i*4+k]; 218 | inverse[i*4+k] = inverse[swap*4+k]; 219 | inverse[swap*4+k] = t; 220 | } 221 | } 222 | /* The matrix is singular. */ 223 | if ( tmp[i][i] == 0 ) 224 | return(0); 225 | 226 | t = tmp[i][i]; 227 | for (k=0; k<4; k++) { 228 | tmp[i][k] /= t; 229 | inverse[i*4+k] /= t; 230 | } 231 | for (j=0; j<4; j++) { 232 | if ( j != i ) { 233 | t = tmp[j][i]; 234 | for (k=0; k<4; k++) { 235 | tmp[j][k] -= tmp[i][k]*t; 236 | inverse[j*4+k] -= inverse[i*4+k]*t; 237 | } 238 | } 239 | } 240 | } 241 | 242 | return(1); 243 | } 244 | 245 | void print_matrix(const GLfloat m[16],const char *ligne) { 246 | int i; 247 | 248 | printf("---- %s ----\n",ligne); 249 | for (i=0; i<4; i++) 250 | printf("%f %f %f %f\n",m[i],m[4+i],m[8+i],m[12+i]); 251 | printf("---------------------------------\n"); 252 | } 253 | 254 | void print_matrixd(const GLdouble m[16],const char *ligne) { 255 | int i; 256 | 257 | printf("---- %s ----\n",ligne); 258 | for (i=0; i<4; i++) 259 | printf("%f %f %f %f\n",m[i],m[4+i],m[8+i],m[12+i]); 260 | printf("---------------------------------\n"); 261 | } 262 | int filnum(char *data,int numdep,char *ext) { 263 | FILE *in; 264 | char tmpstr[256]; 265 | 266 | do { 267 | sprintf(tmpstr,"%s.%.3d.%s",data,numdep,ext); 268 | in = fopen(tmpstr,"r"); 269 | if ( !in ) return(numdep); 270 | fclose(in); 271 | } 272 | while ( ++numdep < 999 ); 273 | return(-1); 274 | } 275 | 276 | #ifdef __cplusplus 277 | } 278 | #endif 279 | -------------------------------------------------------------------------------- /src/view.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "sproto.h" 3 | #include "extern.h" 4 | 5 | static pTransform cview = 0; 6 | static pCamera ccam = 0; 7 | static pPersp cpersp = 0; 8 | static int cscene = 0; 9 | static ubyte curview = 0; 10 | 11 | 12 | void copyView(pTransform view,pCamera cam,pPersp persp) { 13 | cscene = currentScene(); 14 | 15 | if ( !cview ) { 16 | cview = (pTransform)calloc(1,sizeof(struct transform)); 17 | if ( !cview ) exit(2); 18 | } 19 | cview = (pTransform)memcpy(cview,view,sizeof(struct transform)); 20 | if ( !cview ) exit(2); 21 | 22 | if ( !ccam ) { 23 | ccam = (pCamera)calloc(1,sizeof(struct camera)); 24 | if ( !ccam ) exit(2); 25 | } 26 | ccam = (pCamera)memcpy(ccam,cam,sizeof(struct camera)); 27 | if ( !ccam ) exit(2); 28 | 29 | if ( !cpersp ) { 30 | cpersp = (pPersp)calloc(1,sizeof(struct sperspective)); 31 | if ( !cpersp ) exit(2); 32 | } 33 | cpersp = (pPersp)memcpy(cpersp,persp,sizeof(struct sperspective)); 34 | if ( !cpersp ) exit(2); 35 | 36 | curview = 1; 37 | } 38 | 39 | int pasteView(pTransform view,pCamera cam,pPersp persp) { 40 | if ( !curview && !ccam && !persp ) return(0); 41 | 42 | view = (pTransform)memcpy(view,cview,sizeof(struct transform)); 43 | cam = (pCamera)memcpy(cam,ccam,sizeof(struct camera)); 44 | persp = memcpy(persp,cpersp,sizeof(struct sperspective)); 45 | 46 | if ( !view || !cam || !persp ) exit(2); 47 | curview = 0; 48 | 49 | return(1); 50 | } 51 | 52 | /* link scene 1 (slave) to scene 2 (master) */ 53 | int linkView(pScene slave) { 54 | pScene master; 55 | int idw = currentScene(); 56 | 57 | /* default */ 58 | if ( ddebug ) printf("link view\n"); 59 | 60 | if ( !curview || idw == cscene ) return(0); 61 | 62 | /* link 2 scenes */ 63 | master = cv.scene[cscene]; 64 | master->slave = idw; 65 | master->master = -1; 66 | memcpy(slave->view,master->view,sizeof(struct transform)); 67 | memcpy(slave->camera,master->camera,sizeof(struct camera)); 68 | memcpy(slave->persp,master->persp,sizeof(struct sperspective)); 69 | memcpy(slave->clip->eqn,master->clip->eqn,4*sizeof(float)); 70 | memcpy(slave->clip->cliptr,master->clip->cliptr,sizeof(struct transform)); 71 | slave->slave = -1; 72 | slave->master = cscene; 73 | curview = 0; 74 | 75 | return(1); 76 | } 77 | 78 | void unlinkView(pScene sc1) { 79 | pScene sc2; 80 | 81 | if ( sc1->master == -1 ) return; 82 | 83 | /* copy master view */ 84 | sc2 = cv.scene[sc1->master]; 85 | sc1->view = (pTransform)createTransform(); 86 | memcpy(sc1->view,sc2->view,sizeof(struct transform)); 87 | 88 | /* remove link */ 89 | sc1->master = -1; 90 | sc2->slave = -1; 91 | } 92 | -------------------------------------------------------------------------------- /src/zaldy1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "medit.h" 3 | #include "extern.h" 4 | #include "sproto.h" 5 | 6 | 7 | int zaldy1(pMesh mesh) { 8 | 9 | /* default */ 10 | if ( ddebug ) printf("allocate %d points\n",mesh->np); 11 | mesh->point = (pPoint)M_calloc(mesh->np+1,sizeof(Point),"zaldy1.point"); 12 | assert(mesh->point); 13 | 14 | if ( ddebug ) printf("allocate %d tria\n",mesh->nt); 15 | if ( mesh->nt ) { 16 | mesh->tria = (pTriangle)M_calloc(mesh->nt+1,sizeof(Triangle),"zaldy1.tria"); 17 | assert(mesh->tria); 18 | } 19 | if ( mesh->nt2 ) { 20 | mesh->tria2 = (pTriangle2)M_calloc(mesh->nt2+1,sizeof(Triangle2),"zaldy1.tria2"); 21 | assert(mesh->tria2); 22 | } 23 | 24 | if ( ddebug ) printf("allocate %d quad\n",mesh->nq); 25 | if ( mesh->nq ) { 26 | mesh->quad = (pQuad)M_calloc(mesh->nq+1,sizeof(Quad),"zaldy1.quad"); 27 | assert(mesh->quad); 28 | } 29 | 30 | if ( mesh->ntet ) { 31 | if ( ddebug ) printf("allocate %d tetra\n",mesh->ntet); 32 | mesh->tetra = (pTetra)M_calloc(mesh->ntet+1,sizeof(Tetra),"zaldy1.tetra"); 33 | assert(mesh->tetra); 34 | } 35 | 36 | if ( mesh->nhex ) { 37 | if ( ddebug ) printf("allocate %d hexa\n",mesh->nhex); 38 | mesh->hexa = (pHexa)M_calloc(mesh->nhex+1,sizeof(Hexa),"zaldy1.hexa"); 39 | assert(mesh->hexa); 40 | } 41 | 42 | if ( mesh->na ) { 43 | if ( ddebug ) printf("allocate %d edges\n",mesh->na); 44 | mesh->edge = (pEdge)M_calloc(mesh->na+1,sizeof(Edge),"zaldy1.edge"); 45 | assert(mesh->edge); 46 | } 47 | 48 | if ( mesh->nvn || mesh->ntg ) { 49 | mesh->extra = (pExtra)M_calloc(1,sizeof(Extra),"zaldy1.extra"); 50 | assert(mesh->extra); 51 | 52 | if ( mesh->nvn ) { 53 | mesh->extra->n = (float*)M_calloc(3*mesh->nvn+1,sizeof(float),"inmesh"); 54 | assert(mesh->extra->n); 55 | } 56 | 57 | if ( mesh->ntg ) { 58 | mesh->extra->t = (float*)M_calloc(3*mesh->ntg+1,sizeof(float),"inmesh"); 59 | assert(mesh->extra->t); 60 | } 61 | } 62 | 63 | return(1); 64 | } 65 | -------------------------------------------------------------------------------- /src/zaldy2.c: -------------------------------------------------------------------------------- 1 | #include "medit.h" 2 | #include "extern.h" 3 | #include "sproto.h" 4 | 5 | 6 | int zaldy2(pMesh mesh) { 7 | pSolution ps; 8 | int k,nbf; 9 | 10 | /* memory alloc. */ 11 | mesh->sol = (pSolution)M_calloc(mesh->nbb+1,sizeof(struct solu),"zaldy2"); 12 | assert(mesh->sol); 13 | 14 | if ( mesh->nfield == 1 ) return(1); 15 | if ( mesh->nfield == mesh->dim ) 16 | nbf = mesh->dim; /* vector field */ 17 | else 18 | nbf = mesh->dim*(mesh->dim+1)/2; /* d*d matrix */ 19 | 20 | for (k=1; k<=mesh->nbb; k++) { 21 | ps = &mesh->sol[k]; 22 | ps->m = (float*)malloc(nbf*sizeof(float)); 23 | } 24 | 25 | return(1); 26 | } 27 | --------------------------------------------------------------------------------