Skip to content

Commit e34b29a

Browse files
committed
Correction of a bug: hashTria was bad at eliminating duplicated faces in NOM situation; added function remdup
1 parent f7b527b commit e34b29a

File tree

9 files changed

+130
-11
lines changed

9 files changed

+130
-11
lines changed

src/common/hash.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
*
4545
* Create surface adjacency
4646
*
47-
* \remark the ph->s field computation is useless in mmgs.
47+
* \remark the ph->s field computation (containing the number of triangles shared by a hashed edge) is useless in mmgs.
4848
*
4949
*
5050
* \remark: as all triangles are mesh boundaries, we do not need to mark their

src/mmg3d/API_functions_3d.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2153,6 +2153,9 @@ int MMG3D_Set_iparameter(MMG5_pMesh mesh, MMG5_pSol sol, int iparam,MMG5_int val
21532153
mesh->info.dhd = MMG5_ANGEDG;
21542154
}
21552155
break;
2156+
case MMG3D_IPARAM_kiso :
2157+
mesh->info.kiso = val;
2158+
break;
21562159
case MMG3D_IPARAM_nofem :
21572160
mesh->info.setfem = (val==1)? 0 : 1;
21582161
break;

src/mmg3d/analys_3d.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,6 +1368,14 @@ int MMG3D_analys(MMG5_pMesh mesh) {
13681368

13691369
/* Set surface triangles to required in nosurf mode or for parallel boundaries */
13701370
MMG3D_set_reqBoundaries(mesh);
1371+
1372+
/* Remove duplicate triangles */
1373+
memset ( &hash, 0x0, sizeof(MMG5_Hash));
1374+
if ( !MMG5_remdup(mesh,&hash) ) {
1375+
MMG5_DEL_MEM(mesh,hash.item);
1376+
fprintf(stderr,"\n ## Problem in removing duplicate faces. Exit program.\n");
1377+
return 0;
1378+
}
13711379

13721380
/* create surface adjacency */
13731381
memset ( &hash, 0x0, sizeof(MMG5_Hash));
@@ -1449,6 +1457,11 @@ int MMG3D_analys(MMG5_pMesh mesh) {
14491457
MMG5_DEL_MEM(mesh,mesh->xpoint);
14501458
return 0;
14511459
}
1460+
1461+
/* printf("On est bien ici maintenant??\n");
1462+
MMG3D_packMesh(mesh,NULL,NULL);
1463+
MMG3D_saveMesh(mesh,mesh->nameout);
1464+
exit(0);*/
14521465

14531466
/* check subdomains connected by a vertex and mark these vertex as corner and
14541467
required */

src/mmg3d/hash_3d.c

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -504,11 +504,10 @@ int MMG5_setEdgeNmTag(MMG5_pMesh mesh, MMG5_Hash *hash) {
504504
/* Set edge tag and point tags to MG_REQ if the non-manifold edge shared
505505
* separated domains */
506506
if ( ph->s > 3 ) {
507-
start = ptt->cc/4;
507+
start = ptt->cc/4; // ptt->cc contains information about a supporting tetrahedron
508508
assert(start);
509509
pt = &mesh->tetra[start];
510510

511-
512511
for (ia=0; ia<6; ++ia) {
513512
ipa = MMG5_iare[ia][0];
514513
ipb = MMG5_iare[ia][1];
@@ -517,7 +516,6 @@ int MMG5_setEdgeNmTag(MMG5_pMesh mesh, MMG5_Hash *hash) {
517516
}
518517
assert(ia<6);
519518

520-
521519
/* Travel throug the shell of the edge until reaching a tetra without adjacent
522520
* or until reaching the starting tetra */
523521
iface = ptt->cc%4;
@@ -802,6 +800,102 @@ int MMG5_setVertexNmTag(MMG5_pMesh mesh,uint16_t func(uint16_t) ) {
802800
return 1;
803801
}
804802

803+
/**
804+
* \param mesh pointer towar the mesh structure.
805+
* \param hash hash table.
806+
* \return 1 if success, 0 if failed.
807+
*
808+
* Remove duplicate faces from the triangle mesh
809+
*
810+
*/
811+
int MMG5_remdup(MMG5_pMesh mesh,MMG5_Hash *hash) {
812+
MMG5_pTria pt;
813+
MMG5_hedge *ph;
814+
MMG5_int dup,k,kk,hmax,ip0,ip1,ip2,min,max,sum,key;
815+
816+
dup = 0;
817+
818+
/* Allocate hash table params */
819+
hash->siz = mesh->np;
820+
hmax = MG_MAX(hash->siz,mesh->nt);
821+
hash->max = hmax + 1;
822+
hash->nxt = hash->siz;
823+
MMG5_ADD_MEM(mesh,(hash->max+1)*sizeof(MMG5_hedge),"hash table",return 0);
824+
MMG5_SAFE_CALLOC(hash->item,hash->max+1,MMG5_hedge,return 0);
825+
826+
/* Hash triangles */
827+
for(k=1; k<=mesh->nt; k++) {
828+
pt = &mesh->tria[k];
829+
if ( !MG_EOK(pt) ) continue;
830+
831+
ip0 = pt->v[0];
832+
ip1 = pt->v[1];
833+
ip2 = pt->v[2];
834+
835+
min = MG_MIN(ip0,MG_MIN(ip1,ip2));
836+
max = MG_MAX(ip0,MG_MAX(ip1,ip2));
837+
sum = ip0 + ip1 + ip2;
838+
839+
key = (MMG5_KA*(int64_t)min + MMG5_KB*(int64_t)max + MMG5_KC*(int64_t)sum) % hash->siz;
840+
ph = &hash->item[key];
841+
842+
/* Empty cell: store tria */
843+
if ( ph->a == 0 ) {
844+
ph->a = min;
845+
ph->b = max;
846+
ph->k = sum;
847+
ph->nxt = 0;
848+
continue;
849+
}
850+
851+
while ( ph->a ) {
852+
/* Remove duplicate */
853+
if ( ph->a == min && ph->b == max && ph->k == sum ) {
854+
pt->v[0] = 0;
855+
dup++;
856+
break;
857+
}
858+
else if ( !ph->nxt ) {
859+
ph->nxt = hash->nxt;
860+
hash->nxt++;
861+
ph = &hash->item[ph->nxt];
862+
assert(ph);
863+
864+
if ( hash->nxt >= hash->max-1 ) {
865+
if ( mesh->info.ddebug ) {
866+
fprintf(stderr,"\n ## Warning: %s: memory alloc problem (edge):"
867+
" %" MMG5_PRId "\n",__func__,hash->max);
868+
}
869+
MMG5_TAB_RECALLOC(mesh,hash->item,hash->max,MMG5_GAP,MMG5_hedge,
870+
"MMG5_edge",
871+
MMG5_DEL_MEM(mesh,hash->item);
872+
return 0);
873+
874+
ph = &hash->item[hash->nxt];
875+
}
876+
877+
ph->a = min;
878+
ph->b = max;
879+
ph->k = sum;
880+
ph->nxt = 0;
881+
break;
882+
}
883+
else {
884+
ph = &hash->item[ph->nxt];
885+
}
886+
}
887+
}
888+
889+
/* Display information */
890+
if ( abs(mesh->info.imprim) > 5 && dup > 0 ) {
891+
fprintf(stdout," ## "); fflush(stdout);
892+
if ( dup > 0 ) fprintf(stdout," %" MMG5_PRId " duplicate removed",dup);
893+
fprintf(stdout,"\n");
894+
}
895+
896+
return 1;
897+
}
898+
805899
/**
806900
* \param mesh pointer towar the mesh structure.
807901
* \param hash edges hash table.

src/mmg3d/inout_3d.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@ int MMG3D_loadMesh_opened(MMG5_pMesh mesh,FILE *inm,int bin) {
140140
mesh->np = mesh->nt = mesh->ne = 0;
141141
nref = 0;
142142

143-
144143
if (!bin) {
145144
strcpy(chaine,"D");
146145
while(fscanf(inm,"%127s",&chaine[0])!=EOF && strncmp(chaine,"End",strlen("End")) ) {
@@ -523,7 +522,6 @@ int MMG3D_loadMesh_opened(MMG5_pMesh mesh,FILE *inm,int bin) {
523522
}
524523
}
525524

526-
527525
/* get corners */
528526
if(ncor) {
529527
rewind(inm);
@@ -1056,6 +1054,7 @@ int MMG3D_loadMesh(MMG5_pMesh mesh,const char *filename) {
10561054
if( ier < 1 ) return ier;
10571055

10581056
fclose(inm);
1057+
10591058
return 1;
10601059
}
10611060

src/mmg3d/libmmg3d.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ MMG5_int MMG3D_bdryBuild(MMG5_pMesh mesh) {
101101
MMG5_hgeom *ph;
102102
MMG5_int k,nr;
103103
int i;
104-
104+
105105
/* rebuild triangles*/
106106
if ( mesh->tria )
107107
MMG5_DEL_MEM(mesh,mesh->tria);
@@ -1296,9 +1296,11 @@ int MMG3D_mmg3dls(MMG5_pMesh mesh,MMG5_pSol sol,MMG5_pSol umet) {
12961296
}
12971297

12981298
/* clean old isosurface */
1299-
if ( !MMG3D_Clean_isoSurf(mesh) ) {
1300-
fprintf(stderr,"\n ## Unable to clean old isosurface.\n");
1301-
_LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE);
1299+
if ( ! mesh->info.kiso ) {
1300+
if ( !MMG3D_Clean_isoSurf(mesh) ) {
1301+
fprintf(stderr,"\n ## Unable to clean old isosurface.\n");
1302+
_LIBMMG5_RETURN(mesh,met,sol,MMG5_STRONGFAILURE);
1303+
}
13021304
}
13031305

13041306
chrono(OFF,&(ctim[1]));

src/mmg3d/libmmg3d.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ enum MMG3D_Param {
167167
MMG3D_IPARAM_anisosize, /*!< [1/0], Turn on/off anisotropic metric creation when no metric is provided */
168168
MMG3D_IPARAM_octree, /*!< [n], Max number of vertices per PROctree cell (DELAUNAY) */
169169
MMG3D_IPARAM_nosizreq, /*!< [0/1], Allow/avoid overwriting of sizes at required vertices (advanced usage) */
170+
MMG3D_IPARAM_kiso, /*!< [1/0], Keep previous isoline in mesh (in ls mode) */
170171
MMG3D_IPARAM_isoref, /*!< [0/n], Isosurface boundary material reference */
171172
MMG3D_DPARAM_angleDetection, /*!< [val], Value for angle detection (degrees) */
172173
MMG3D_DPARAM_hmin, /*!< [val], Minimal edge length */

src/mmg3d/libmmg3d_private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ int16_t MMG5_openCoquilTravel(MMG5_pMesh,MMG5_int,MMG5_int,MMG5_int*,MMG5_int*,i
278278
int MMG3D_get_shellEdgeTag(MMG5_pMesh,MMG5_int,int8_t,uint16_t*,MMG5_int *);
279279
int MMG5_settag(MMG5_pMesh,MMG5_int,int,uint16_t,int);
280280
int MMG5_deltag(MMG5_pMesh,MMG5_int,int,uint16_t);
281+
int MMG5_remdup(MMG5_pMesh mesh, MMG5_Hash *hash);
281282
int MMG5_setNmTag(MMG5_pMesh mesh, MMG5_Hash *hash);
282283
int MMG5_setVertexNmTag(MMG5_pMesh mesh,uint16_t func(uint16_t) );
283284
int MMG5_chkcol_int(MMG5_pMesh,MMG5_pSol,MMG5_int,int8_t,int8_t,int64_t*,int,int8_t);

src/mmg3d/libmmg3d_tools.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,12 @@ int MMG3D_storeknownar(int argc,char *argv[],MMG5_pMesh mesh,MMG5_pSol met,
382382
MMG_ARGV_APPEND(argv, mmgArgv, i, *mmgArgc,return 0);
383383
}
384384
break;
385+
case 'k':
386+
if ( !strcmp(argv[i],"-kiso") ) {
387+
if ( !MMG3D_Set_iparameter(mesh,met,MMG3D_IPARAM_kiso,1) )
388+
return 0;
389+
}
390+
break;
385391
case 'l':
386392
if ( !strcmp(argv[i],"-lag") ) {
387393
if ( ++i < argc && isdigit(argv[i][0]) ) {
@@ -719,7 +725,7 @@ int MMG3D_parsar(int argc,char *argv[],MMG5_pMesh mesh,MMG5_pSol met,MMG5_pSol s
719725
MMG5_SAFE_MALLOC( mmgArgv, argc, char*,return 0);
720726
MMG_ARGV_APPEND ( argv, mmgArgv, 0, mmgArgc,return 0);
721727

722-
int ier = MMG3D_storeknownar( argc,argv,mesh,met,sol,&mmgArgc,mmgArgv);
728+
int ier = MMG3D_storeknownar(argc,argv,mesh,met,sol,&mmgArgc,mmgArgv);
723729

724730
/* Third step: treat unknown args */
725731
if ( ier ) {

0 commit comments

Comments
 (0)