/* ============================================================================= ** This file is part of the mmg software package for the tetrahedral ** mesh modification. ** Copyright (c) Bx INP/CNRS/Inria/UBordeaux/UPMC, 2004- ** ** mmg is free software: you can redistribute it and/or modify it ** under the terms of the GNU Lesser General Public License as published ** by the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** mmg is distributed in the hope that it will be useful, but WITHOUT ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ** FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public ** License for more details. ** ** You should have received a copy of the GNU Lesser General Public ** License and of the GNU General Public License along with mmg (in ** files COPYING.LESSER and COPYING). If not, see ** <http://www.gnu.org/licenses/>. Please read their terms carefully and ** use this copy of the mmg distribution only if you accept them. ** ============================================================================= */ /** * \file common/API_functions.c * \brief C API functions definitions for MMG library. * \author Charles Dapogny (UPMC) * \author Cécile Dobrzynski (Bx INP/Inria/UBordeaux) * \author Pascal Frey (UPMC) * \author Algiane Froehly (Inria/UBordeaux) * \version 5 * \date 03 2014 * \copyright GNU Lesser General Public License. * * \note This file contains some internal functions for the API, see the \a * common/libmmgcommon_private.h, \a mmgs/libmmgs.h and \a mmg3d/libmmg3d.h header files * for the documentation of all the usefull user's API functions. * * C API for MMG library. * */ #include "mmgcommon_private.h" /** * \param mesh pointer to the mesh structure. * * Initialization of the input parameters. * */ void MMG5_Init_parameters(MMG5_pMesh mesh) { memset(&mesh->info,0, sizeof(MMG5_Info)); /* default values for integers */ /* [-1..10], Tune level of imprim */ mesh->info.imprim = 1; /* [0/1] ,Turn on/off levelset meshing */ mesh->info.iso = MMG5_OFF; /* [0/1] ,Turn on/off levelset meshing */ mesh->info.isosurf = MMG5_OFF; /* [n/10] ,Value for isosurface boundary reference */ mesh->info.isoref = MG_ISO; /* [n/-1] ,Set memory size to n Mbytes/keep the default value */ mesh->info.mem = MMG5_NONSET_MEM; /* [0/1] ,Turn on/off debug mode */ mesh->info.ddebug = MMG5_OFF; /* [n] ,number of local parameters */ mesh->info.npar = MMG5_OFF; /* [0/1] ,avoid/allow point insertion/deletion */ mesh->info.noinsert = MMG5_OFF; /* [0/1] ,avoid/allow edge or face flipping */ mesh->info.noswap = MMG5_OFF; /* [0/1] ,avoid/allow point relocation */ mesh->info.nomove = MMG5_OFF; /* [n] ,number of user-defined references */ mesh->info.nmat = MMG5_OFF; /* [-1/val] ,Turn off/on the removal of small bubles in levelset meshing */ mesh->info.rmc = MMG5_NONSET; /* [0/1] ,avoid/allow */ mesh->info.nosizreq = MMG5_OFF; /* default values for doubles */ /* angle detection */ mesh->info.dhd = MMG5_ANGEDG; /* minimal mesh size */ mesh->info.hmin = MMG5_NONSET_HMIN; /* maximal mesh size */ mesh->info.hmax = MMG5_NONSET_HMAX; /* constant mesh size */ mesh->info.hsiz = MMG5_NONSET_HSIZ; /* control Hausdorff */ mesh->info.hausd = MMG5_HAUSD; /* control gradation */ mesh->info.hgrad = MMG5_HGRAD; /* control gradation on required entities */ mesh->info.hgradreq = MMG5_HGRADREQ; /* xreg relaxation parameter value */ mesh->info.lxreg = MMG5_XREG; /* default values for pointers */ /* list of user-defined references */ mesh->info.mat = NULL; /** MMG3D_IPARAM_lag is used by mmg3d only but need to be negative in the * scaleMesh function */ mesh->info.lag = MMG5_LAG; /* initial value for memMax and gap */ mesh->gap = MMG5_GAP; mesh->memMax = MMG5_memSize(); if ( mesh->memMax ) { /* maximal memory = 50% of total physical memory */ mesh->memMax = (size_t)(mesh->memMax*MMG5_MEMPERCENT); } else { /* default value = 800 MB */ printf(" Maximum memory set to default value: %d MB.\n",MMG5_MEMMAX); mesh->memMax = MMG5_MEMMAX << MMG5_BITWIZE_MB_TO_B; } } /** * \param mesh pointer to the mesh structure. * \param sol pointer to the sol structure. * * Initialize file names to their default values. * */ void MMG5_Init_fileNames(MMG5_pMesh mesh,MMG5_pSol sol ) { MMG5_Set_inputMeshName(mesh,""); MMG5_Set_outputMeshName(mesh,""); if ( sol ) { MMG5_Set_inputSolName(mesh,sol,""); MMG5_Set_outputSolName(mesh,sol,""); } return; } /** * \param mesh pointer to the mesh structure. * \param meshin input mesh name. * \return 1 if success, 0 if fail * * Set the name of input mesh. * */ int MMG5_Set_inputMeshName(MMG5_pMesh mesh, const char* meshin) { if ( mesh->namein ){ MMG5_DEL_MEM(mesh,mesh->namein); } if ( meshin && strlen(meshin) ) { MMG5_ADD_MEM(mesh,(strlen(meshin)+1)*sizeof(char),"input mesh name", fprintf(stderr," Exit program.\n"); return 0); MMG5_SAFE_CALLOC(mesh->namein,strlen(meshin)+1,char,return 0); strcpy(mesh->namein,meshin); } else { MMG5_ADD_MEM(mesh,10*sizeof(char),"input mesh name", fprintf(stderr," Exit program.\n"); return 0); MMG5_SAFE_CALLOC(mesh->namein,10,char,return 0); strcpy(mesh->namein,"mesh.mesh"); if ( (mesh->info.imprim > 5) || mesh->info.ddebug ) { fprintf(stderr,"\n ## Warning: %s: no name given for input mesh.\n",__func__); fprintf(stderr," Use of default value \"mesh.mesh\".\n"); } } return 1; } /** * \param mesh pointer to the mesh structure. * \param sol pointer to the sol structure. * \param solin name of the input solution file. * \return 1 if success, 0 if fail * * Set the name of input solution file. * */ int MMG5_Set_inputSolName(MMG5_pMesh mesh,MMG5_pSol sol, const char* solin) { char *ptr; if ( sol->namein ) MMG5_DEL_MEM(mesh,sol->namein); if ( solin && strlen(solin) ) { MMG5_ADD_MEM(mesh,(strlen(solin)+1)*sizeof(char),"input sol name", fprintf(stderr," Exit program.\n"); return 0); MMG5_SAFE_CALLOC(sol->namein,strlen(solin)+1,char,return 0); strcpy(sol->namein,solin); } else { if ( mesh->namein && strlen(mesh->namein) ) { int mesh_len = strlen(mesh->namein)+1; MMG5_SAFE_CALLOC(sol->namein,mesh_len,char,return 0); strcpy(sol->namein,mesh->namein); /* Get last dot character to avoid issues with <basename>.mesh.mesh files */ char *dot = strrchr(sol->namein,'.'); ptr = NULL; if ( dot) { ptr = strstr(dot,".mesh"); } if ( ptr ) { /* the sol file is renamed concatening the mesh basename and the sol extension */ *ptr = '\0'; } MMG5_SAFE_REALLOC(sol->namein,mesh_len,(strlen(sol->namein)+5),char, "input sol name",return 0); MMG5_ADD_MEM(mesh,(strlen(sol->namein)+5)*sizeof(char),"input sol name", fprintf(stderr," Exit program.\n"); return 0); strcat(sol->namein,".sol"); } else { MMG5_ADD_MEM(mesh,9*sizeof(char),"input sol name", fprintf(stderr," Exit program.\n"); return 0); MMG5_SAFE_CALLOC(sol->namein,9,char,return 0); strcpy(sol->namein,"mesh.sol"); } } return 1; } /** * \param mesh pointer to the mesh structure. * \param fparamin name of the input solution file. * \return 1 if success, 0 if fail * * Set the name of input parameter file. * */ int MMG5_Set_inputParamName(MMG5_pMesh mesh, const char* fparamin) { if ( mesh->info.fparam ) MMG5_DEL_MEM(mesh,mesh->info.fparam); if ( fparamin && strlen(fparamin) ) { MMG5_ADD_MEM(mesh,(strlen(fparamin)+1)*sizeof(char),"input param name", fprintf(stderr," Exit program.\n"); return 0); MMG5_SAFE_CALLOC(mesh->info.fparam,strlen(fparamin)+1,char,return 0); strcpy(mesh->info.fparam,fparamin); } else { fprintf(stderr,"\n ## Warning: %s: no name given for the parameter file.\n",__func__); fprintf(stderr," We should have never end here.\n"); return 0; } return 1; } /** * \param mesh pointer to the mesh structure. * \param meshout name of the output mesh file. * \return 1 if success, 0 if fail. * * Set the name of output mesh file. * */ int MMG5_Set_outputMeshName(MMG5_pMesh mesh, const char* meshout) { int fmt = MMG5_FMT_MeditASCII,fmtin; char *ptr,*ptrin; if ( mesh->nameout ) MMG5_DEL_MEM(mesh,mesh->nameout); if ( meshout && strlen(meshout) ) { ptr = strrchr(meshout, '.'); MMG5_ADD_MEM(mesh,(strlen(meshout)+7)*sizeof(char),"output mesh name", fprintf(stderr," Exit program.\n"); return 0); MMG5_SAFE_CALLOC(mesh->nameout,strlen(meshout)+7,char,return 0); strcpy(mesh->nameout,meshout); if ( ( ptr && MMG5_Get_format(ptr,0)==MMG5_FMT_Unknown ) || (!ptr) || ptr == meshout ) { /* No extension */ ptrin = MMG5_Get_filenameExt(mesh->namein); fmtin = MMG5_Get_format(ptrin,MMG5_FMT_MeditASCII); fmt = MMG5_FMT_Unknown; } strcpy(mesh->nameout,meshout); if ( fmt == MMG5_FMT_Unknown ) { /* No extension */ switch ( fmtin ) { case ( MMG5_FMT_GmshASCII ): strcat(mesh->nameout,".msh"); break; case ( MMG5_FMT_GmshBinary ): strcat(mesh->nameout,".mshb"); break; case ( MMG5_FMT_VtkVtu ): strcat(mesh->nameout,".vtu"); break; case ( MMG5_FMT_VtkVtp ): strcat(mesh->nameout,".vtp"); break; case ( MMG5_FMT_VtkVtk ): strcat(mesh->nameout,".vtk"); break; case ( MMG5_FMT_MeditBinary ): strcat(mesh->nameout,".meshb"); break; case ( MMG5_FMT_MeditASCII ): default: strcat(mesh->nameout,".mesh"); break; } } } else { if ( mesh->namein && strlen(mesh->namein) ) { MMG5_ADD_MEM(mesh,(strlen(mesh->namein)+9)*sizeof(char),"output mesh name", fprintf(stderr," Exit program.\n"); return 0); MMG5_SAFE_CALLOC(mesh->nameout,strlen(mesh->namein)+9,char,return 0); strcpy(mesh->nameout,mesh->namein); ptr = MMG5_Get_filenameExt(mesh->nameout); fmt = MMG5_Get_format(ptr,MMG5_FMT_MeditASCII); if ( ptr ) *ptr = '\0'; switch ( fmt ) { case ( MMG5_FMT_GmshASCII ): strcat(mesh->nameout,".o.msh"); break; case ( MMG5_FMT_GmshBinary ): strcat(mesh->nameout,".o.mshb"); break; case ( MMG5_FMT_VtkVtu ): strcat(mesh->nameout,".o.vtu"); break; case ( MMG5_FMT_VtkVtp ): strcat(mesh->nameout,".o.vtp"); break; case ( MMG5_FMT_VtkVtk ): strcat(mesh->nameout,".o.vtk"); break; case ( MMG5_FMT_MeditBinary ): strcat(mesh->nameout,".o.meshb"); break; case ( MMG5_FMT_MeditASCII ): default: strcat(mesh->nameout,".o.mesh"); break; } } else { MMG5_ADD_MEM(mesh,12*sizeof(char),"output mesh name", fprintf(stderr," Exit program.\n"); return 0); MMG5_SAFE_CALLOC(mesh->nameout,12,char,return 0); if ( (mesh->info.imprim > 5) || mesh->info.ddebug ) { fprintf(stderr,"\n ## Warning: %s: no name given for output mesh.\n", __func__); fprintf(stderr," Use of default value \"mesh.o.mesh\".\n"); } strcpy(mesh->nameout,"mesh.o.mesh"); } } return 1; } /** * \param mesh pointer to the mesh structure. * \param sol pointer to the sol structure. * \param solout name of the output solution file. * \return 0 if failed, 1 otherwise. * * Set the name of output solution file. * */ int MMG5_Set_outputSolName(MMG5_pMesh mesh,MMG5_pSol sol, const char* solout) { char *ptr; int oldsize; if ( sol->nameout ) MMG5_DEL_MEM(mesh,sol->nameout); if ( solout && strlen(solout) ) { MMG5_ADD_MEM(mesh,(strlen(solout)+1)*sizeof(char),"output sol name", fprintf(stderr," Exit program.\n"); return 0); MMG5_SAFE_CALLOC(sol->nameout,strlen(solout)+1,char,return 0); strcpy(sol->nameout,solout); } else { if ( mesh->nameout && strlen(mesh->nameout) ) { /* Get last dot character to avoid issues with <basename>.mesh.mesh files */ char *dot = strrchr(mesh->nameout,'.'); ptr = NULL; if ( dot) { ptr = strstr(dot,".mesh"); } if ( ptr ) { MMG5_SAFE_CALLOC(sol->nameout,strlen(mesh->nameout)+1,char,return 0); oldsize = strlen(mesh->nameout)+1; } else { MMG5_SAFE_CALLOC(sol->nameout,strlen(mesh->nameout)+6,char,return 0); oldsize = strlen(mesh->nameout)+6; } strcpy(sol->nameout,mesh->nameout); dot = strrchr(sol->nameout,'.'); ptr = NULL; if ( dot) { ptr = strstr(dot,".mesh"); } if ( ptr ) /* the sol file is renamed with the meshfile basename and .sol ext */ *ptr = '\0'; MMG5_ADD_MEM(mesh,(strlen(sol->nameout)+5)*sizeof(char),"output sol name", fprintf(stderr," Exit program.\n"); return 0); MMG5_SAFE_REALLOC(sol->nameout,oldsize,(strlen(sol->nameout)+5),char, "output sol name",return 0); strcat(sol->nameout,".sol"); } else { fprintf(stderr,"\n ## Error: %s: no name for output mesh. please, use", __func__); fprintf(stderr," the MMG5_Set_outputMeshName to set the mesh name.\n"); return 0; } } return 1; } void MMG5_Set_constantSize(MMG5_pMesh mesh,MMG5_pSol met,double hsiz) { MMG5_pPoint ppt; MMG5_int k,iadr; if ( met->size == 1 ) { for (k=1; k<=mesh->np; k++) { ppt = &mesh->point[k]; if ( !MG_VOK(ppt) ) continue; met->m[k] = hsiz; } } else { hsiz = 1./(hsiz*hsiz); if ( mesh->dim==2 ) { for (k=1; k<=mesh->np; k++) { ppt = &mesh->point[k]; if ( !MG_VOK(ppt) ) continue; iadr = 3*k; met->m[iadr] = hsiz; met->m[iadr+1] = 0.; met->m[iadr+2] = hsiz; } } else { assert ( mesh->dim==3 ); for (k=1; k<=mesh->np; k++) { ppt = &mesh->point[k]; if ( !MG_VOK(ppt) ) continue; iadr = 6*k; met->m[iadr] = hsiz; met->m[iadr+1] = 0.; met->m[iadr+2] = 0.; met->m[iadr+3] = hsiz; met->m[iadr+4] = 0.; met->m[iadr+5] = hsiz; } } } return; } int MMG5_Free_allSols(MMG5_pMesh mesh,MMG5_pSol *sol) { int i; if ( sol ) { if ( mesh->nsols ) { for ( i=0; i<mesh->nsols; ++i ) { MMG5_DEL_MEM(mesh,(*sol)[i].m); } } MMG5_DEL_MEM(mesh,(*sol)); } return 1; } /** * \param mesh pointer to the mesh structure. * \param sol pointer to the sol structure. * * Structures unallocation before return (common structures between all codes). * */ void MMG5_Free_structures(MMG5_pMesh mesh,MMG5_pSol sol){ if ( mesh->point ) MMG5_DEL_MEM(mesh,mesh->point); if ( mesh->xpoint ) MMG5_DEL_MEM(mesh,mesh->xpoint); if ( mesh->edge ) MMG5_DEL_MEM(mesh,mesh->edge); if ( mesh->adja ) MMG5_DEL_MEM(mesh,mesh->adja); if ( mesh->tria ) MMG5_DEL_MEM(mesh,mesh->tria); if ( mesh->adjt ) MMG5_DEL_MEM(mesh,mesh->adjt); /* sol */ if ( sol && sol->m ) MMG5_DEL_MEM(mesh,sol->m); /* mesh->info */ if ( mesh->info.npar && mesh->info.par ) MMG5_DEL_MEM(mesh,mesh->info.par); if ( mesh->info.nmat ) { if( mesh->info.mat ) MMG5_DEL_MEM(mesh,mesh->info.mat); if( mesh->info.invmat.lookup ) MMG5_DEL_MEM(mesh,mesh->info.invmat.lookup); } if ( mesh->info.imprim>5 || mesh->info.ddebug ) { printf(" MEMORY USED AT END (Bytes) %zu\n",mesh->memCur); } return; } /** * \param mesh pointer to the mesh structure. * \param met pointer to the sol structure. * * File name deallocations before return. * */ void MMG5_mmgFree_names(MMG5_pMesh mesh,MMG5_pSol met){ /* mesh */ if ( mesh->nameout ) { MMG5_DEL_MEM(mesh,mesh->nameout); } if ( mesh->namein ) { MMG5_DEL_MEM(mesh,mesh->namein); } /* met */ if ( met ) { if ( met->namein ) { MMG5_DEL_MEM(mesh,met->namein); } if ( met->nameout ) { MMG5_DEL_MEM(mesh,met->nameout); } } } inline int MMG5_Set_defaultTruncatureSizes(MMG5_pMesh mesh,int8_t sethmin,int8_t sethmax) { if ( !sethmin ) { if ( sethmax ) { mesh->info.hmin = MG_MIN ( MMG5_HMINCOE, MMG5_HMINCOE * mesh->info.hmax); } else { mesh->info.hmin = MMG5_HMINCOE; } } if ( !sethmax ) { if ( sethmin ) { mesh->info.hmax = MG_MAX ( MMG5_HMAXCOE, 1./MMG5_HMINCOE * mesh->info.hmin); } else { mesh->info.hmax = MMG5_HMAXCOE; } } if ( mesh->info.hmax < mesh->info.hmin ) { assert ( sethmin && sethmax ); fprintf(stderr,"\n ## Error: %s: Mismatched options:" " minimal mesh size larger than maximal one.\n",__func__); return 0; } if ( mesh->info.ddebug ) { /* print unscaled values for debug purpose */ fprintf(stdout," After truncature computation: hmin %lf (user setted %d)\n" " hmax %lf (user setted %d)\n", mesh->info.delta * mesh->info.hmin,mesh->info.sethmin, mesh->info.delta * mesh->info.hmax,mesh->info.sethmax); } return 1; } int MMG5_Compute_constantSize(MMG5_pMesh mesh,MMG5_pSol met,double *hsiz) { if ( mesh->info.hmin > mesh->info.hsiz ) { fprintf(stderr,"\n ## Error: %s: Mismatched options: hmin (%e) is greater" " than hsiz (%e). Exit Program.\n",__func__, mesh->info.hmin,mesh->info.hsiz); return 0; } if ( mesh->info.hmax > 0. && mesh->info.hmax < mesh->info.hsiz ) { fprintf(stderr,"\n ## Error: %s: Mismatched options: hmax (%e) is lower" " than hsiz (%e). Exit Program.\n",__func__, mesh->info.hmax,mesh->info.hsiz); return 0; } *hsiz = mesh->info.hsiz; if ( !MMG5_check_setted_hminhmax(mesh) ) { return 0; } if ( mesh->info.sethmin ) { *hsiz = MG_MAX(mesh->info.hmin,*hsiz); } if ( mesh->info.sethmax ) { *hsiz = MG_MIN(mesh->info.hmax,*hsiz); } /* Set hmin */ if ( !mesh->info.sethmin ) { if ( mesh->info.sethmax ) { mesh->info.hmin = MG_MIN(0.1*(*hsiz),0.1*mesh->info.hmax); } else { mesh->info.hmin = 0.1*(*hsiz); } } /* Set hmax */ if ( !mesh->info.sethmax ) { if ( mesh->info.sethmin ) { mesh->info.hmax = MG_MAX(10.*(*hsiz),10.*mesh->info.hmin); } else { mesh->info.hmax = 10.*(*hsiz); } } if ( mesh->info.ddebug ) { /* print unscaled values for debug purpose */ fprintf(stdout," After hsiz computation: hmin %lf (user setted %d)\n" " hmax %lf (user setted %d)\n", mesh->info.delta * mesh->info.hmin,mesh->info.sethmin, mesh->info.delta * mesh->info.hmax,mesh->info.sethmax); } return 1; } /* Useful tools to manage C strings */ char *MMG5_Get_basename(char *path) { char *s = strrchr(path, '/'); if (!s) return strdup(path); else return strdup(s + 1); } const char* MMG5_Get_entitiesName(enum MMG5_entities ent) { switch (ent) { case MMG5_Noentity: return "MMG5_Noentity"; break; case MMG5_Vertex: return "MMG5_Vertex"; break; case MMG5_Edg: return "MMG5_Edg"; break; case MMG5_Triangle: return "MMG5_Triangle"; break; case MMG5_Tetrahedron: return "MMG5_Tetrahedron"; break; default: return"MMG5_Unknown"; } } const char* MMG5_Get_typeName(enum MMG5_type typ) { switch (typ) { case MMG5_Notype: return "MMG5_Notype"; break; case MMG5_Scalar: return "MMG5_Scalar"; break; case MMG5_Vector: return "MMG5_Vector"; break; case MMG5_Tensor: return "MMG5_Tensor"; break; default: return "MMG5_Unknown"; } } const char* MMG5_Get_tagName(uint16_t tag) { static char tags_name[1024]; if ( !tag ) { return "No tag"; } if ( tag & MG_NUL ) { return "Removed"; } strcpy(tags_name, "\0"); if ( tag & MG_REF ) { strcat(tags_name,"Reference "); } if ( tag & MG_GEO) { strcat(tags_name,"Ridge "); } if ( tag & MG_REQ) { strcat(tags_name,"Required "); } if ( tag & MG_NOM) { strcat(tags_name,"Non-manifold "); } if ( tag & MG_BDY) { strcat(tags_name,"Boundary "); } if ( tag & MG_CRN) { strcat(tags_name,"Corner "); } if ( tag & MG_NOSURF) { strcat(tags_name,"Nosurf "); } if ( tag & MG_OPNBDY) { strcat(tags_name,"Opnbdy "); } if ( tag & MG_OLDPARBDY) { strcat(tags_name,"Old-parbdy "); } if ( tag & MG_PARBDYBDY) { strcat(tags_name,"Parbdybdy "); } if ( tag & MG_PARBDY) { strcat(tags_name,"Parbdy "); } if ( tag & MG_OVERLAP) { strcat(tags_name,"Overlap "); } strcat(tags_name,"tag(s)."); return tags_name; } /** * \param ptr pointer to the file extension (dot included) * \param fmt default file format. * * \return and index associated to the file format detected from the extension. * * Get the wanted file format from the mesh extension. If \a fmt is provided, it * is used as default file format (\a ptr==NULL), otherwise, the default file * format is the medit one. * */ int MMG5_Get_format( char *ptr, int fmt ) { /* Default is the Medit file format or a format given as input */ int defFmt = fmt; if ( !ptr ) return defFmt; if ( !strncmp ( ptr,".meshb",strlen(".meshb") ) ) { return MMG5_FMT_MeditBinary; } else if ( !strncmp( ptr,".mesh",strlen(".mesh") ) ) { return MMG5_FMT_MeditASCII; } else if ( !strncmp( ptr,".mshb",strlen(".mshb") ) ) { return MMG5_FMT_GmshBinary; } else if ( !strncmp( ptr,".msh",strlen(".msh") ) ) { return MMG5_FMT_GmshASCII; } else if ( !strncmp ( ptr,".pvtu",strlen(".pvtu") ) ) { return MMG5_FMT_VtkPvtu; } else if ( !strncmp ( ptr,".vtu",strlen(".vtu") ) ) { return MMG5_FMT_VtkVtu; } else if ( !strncmp ( ptr,".pvtp",strlen(".pvtu") ) ) { return MMG5_FMT_VtkPvtp; } else if ( !strncmp ( ptr,".vtp",strlen(".vtp") ) ) { return MMG5_FMT_VtkVtp; } else if ( !strncmp ( ptr,".vtk",strlen(".vtk") ) ) { return MMG5_FMT_VtkVtk; } else if ( !strncmp ( ptr,".node",strlen(".node") ) ) { return MMG5_FMT_Tetgen; } return defFmt; } /** * \param fmt file format. * * \return The name of the file format in a string. * * Print the name of the file format associated to \a fmt. * */ const char* MMG5_Get_formatName(enum MMG5_Format fmt) { switch (fmt) { case MMG5_FMT_MeditASCII: return "MMG5_FMT_MeditASCII"; break; case MMG5_FMT_MeditBinary: return "MMG5_FMT_MeditBinary"; break; case MMG5_FMT_VtkVtu: return "MMG5_FMT_VtkVtu"; break; case MMG5_FMT_VtkVtp: return "MMG5_FMT_VtkVtp"; break; case MMG5_FMT_VtkPvtu: return "MMG5_FMT_VtkPvtu"; break; case MMG5_FMT_VtkPvtp: return "MMG5_FMT_VtkPvtp"; break; case MMG5_FMT_VtkVtk: return "MMG5_FMT_VtkVtk"; break; case MMG5_FMT_GmshASCII: return "MMG5_FMT_GmshASCII"; break; case MMG5_FMT_GmshBinary: return "MMG5_FMT_GmshBinary"; break; case MMG5_FMT_Tetgen: return "MMG5_FMT_Tetgen"; break; default: return "MMG5_Unknown"; } } /** * \param filename string containing a filename * * \return pointer to the filename extension or toward the end of the string * if no extension have been founded * * Get the extension of the filename string. Do not consider '.o' as an extension. * */ char *MMG5_Get_filenameExt( char *filename ) { const char pathsep='/'; char *dot,*lastpath; if ( !filename ) { return NULL; } dot = strrchr(filename, '.'); lastpath = (pathsep == 0) ? NULL : strrchr (filename, pathsep); if ( (!dot) || dot == filename || (lastpath>dot) || (!strcmp(dot,".o")) ) { /* No extension */ return filename + strlen(filename); } return dot; } /** * \param path string containing a filename and its path * * \return a pointer to the path allocated here * * Remove filename from a path and return the path in a newly allocated string. * */ char *MMG5_Get_path(char *path) { char *lastpath,*retpath; int len; if ( path == NULL) return NULL; lastpath = (MMG5_PATHSEP == 0) ? NULL : strrchr (path, MMG5_PATHSEP); if ( !lastpath ) { return NULL; } len = 0; while ( path+len != lastpath ) { ++len; } MMG5_SAFE_MALLOC(retpath,len+1,char,return NULL); /* Copy the string without the extension and add \0 */ strncpy ( retpath, path, len ); retpath[len] = '\0'; return retpath; } /** * \param path path from which we want to remove the extension. * * \return allocated string or NULL if the allocation fail. * * Allocate a new string and copy \a path without extension in it. * */ char *MMG5_Remove_ext (char* path,char *ext) { int len; char *retpath, *lastext, *lastpath; char *extloc; /* Default extension if not provided */ if ( (!ext) || !*ext ) { extloc = "."; } else { extloc = ext; } /* Error checks and string allocation. */ if ( path == NULL) return NULL; /* Find the relevant characters and the length of the string without * extension */ lastext = strstr (path, extloc); lastpath = (MMG5_PATHSEP == 0) ? NULL : strrchr (path, MMG5_PATHSEP); if ( lastext == NULL || (lastpath != NULL && lastpath > lastext) ) { /* No extension or the extension is left from a separator (i.e. it is not an * extension) */ len = strlen(path); } else { /* An extension is found */ len = 0; while ( path+len != lastext ) { ++len; } } MMG5_SAFE_MALLOC(retpath,len+1,char,return NULL); /* Copy the string without the extension and add \0 */ strncpy ( retpath, path, len ); retpath[len] = '\0'; return retpath; }