Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/common/libmmgtypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,50 @@
#ifndef _LIBMMGTYPES_H
#define _LIBMMGTYPES_H

/**
* \enum MMG5_progressPhase
* \brief Phases reported by the progress callback.
*/
enum MMG5_progressPhase {
MMG5_PHASE_GEOMETRIC_MESH, /*!< Geometric mesh analysis and splitting */
MMG5_PHASE_COMPUTATIONAL_MESH, /*!< Metric definition and gradation */
MMG5_PHASE_ADAPTATION, /*!< Main adaptation loop
(split/collapse/swap/move) */
MMG5_PHASE_OPTIMIZATION /*!< Final quality optimization (swap/move) */
};

/**
* \typedef MMG5_progressCallback
* \brief Callback function type for progress reporting.
*
* Called at each iteration within a phase to report progress.
*
* \param mesh pointer to the mesh structure (opaque to caller).
* \param phase current phase (\ref MMG5_progressPhase).
* \param iteration current iteration within the phase (0-based).
* \param max_iterations maximum iterations for this phase.
* \param n_split number of edge splits performed in this iteration.
* \param n_collapse number of edge collapses performed in this iteration.
* \param n_swap number of edge swaps performed in this iteration.
* \param n_move number of vertex moves performed in this iteration.
* \param user_data opaque pointer passed by the user.
*
* \return 1 to continue, 0 to request cancellation.
*
* \remark The callback is only invoked when set (non-NULL). When not set,
* there is zero overhead — no function pointer check occurs in the hot
* loops.
*/
typedef int (*MMG5_progressCallback)(void *mesh,
int phase,
int iteration,
int max_iterations,
int64_t n_split,
int64_t n_collapse,
int64_t n_swap,
int64_t n_move,
void *user_data);

/**
* \def MMG5_SUCCESS
*
Expand Down Expand Up @@ -561,6 +605,12 @@ typedef struct {

MMG5_pMat mat;
MMG5_InvMat invmat;

/* Progress callback (optional, NULL by default) */
MMG5_progressCallback progressCb; /**< Progress callback (NULL =
disabled, zero overhead) */
void *progressData; /**< Opaque user data forwarded
to progressCb */
} MMG5_Info;

/**
Expand Down
8 changes: 8 additions & 0 deletions src/mmg2d/API_functions_2d.c
Original file line number Diff line number Diff line change
Expand Up @@ -1950,3 +1950,11 @@ int MMG2D_Free_names(const int starter,...)

return ier;
}

int MMG2D_Set_progressCallback(MMG5_pMesh mesh,
MMG5_progressCallback callback,
void *user_data) {
mesh->info.progressCb = callback;
mesh->info.progressData = user_data;
return 1;
}
15 changes: 15 additions & 0 deletions src/mmg2d/libmmg2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -2769,6 +2769,21 @@ LIBMMG2D_EXPORT int MMG2D_Free_all(const int starter,...);
*/
LIBMMG2D_EXPORT int MMG2D_scaleMesh(MMG5_pMesh mesh,MMG5_pSol met,MMG5_pSol ls);

/**
* \brief Set a progress callback for the remeshing process.
*
* \param mesh pointer to the mesh structure.
* \param callback progress callback function (NULL to disable).
* \param user_data opaque pointer forwarded to every callback invocation.
*
* \return 1 on success.
*
* \sa MMG5_progressCallback, MMG3D_Set_progressCallback.
*/
LIBMMG2D_EXPORT int MMG2D_Set_progressCallback(MMG5_pMesh mesh,
MMG5_progressCallback callback,
void *user_data);

#ifdef __cplusplus
}
#endif
Expand Down
30 changes: 30 additions & 0 deletions src/mmg2d/mmg2d1.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,25 @@ int MMG2D_anatri(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk) {

if ( (abs(mesh->info.imprim) > 4 || mesh->info.ddebug) && ns+nc > 0 )
fprintf(stdout," %8" MMG5_PRId " splitted, %8" MMG5_PRId " collapsed, %8" MMG5_PRId " swapped\n",ns,nc,nsw);

/* Progress callback */
if ( mesh->info.progressCb ) {
int phase = (typchk == 1) ?
MMG5_PHASE_GEOMETRIC_MESH :
MMG5_PHASE_COMPUTATIONAL_MESH;
if ( !mesh->info.progressCb(
mesh, phase, it, maxit,
(int64_t)ns, (int64_t)nc,
(int64_t)nsw, 0,
mesh->info.progressData) ) {
fprintf(stderr,
"\n ## %s cancelled by user callback.\n",
(typchk == 1) ?
"Geometric mesh" : "Computational mesh");
return 0;
}
}

if ( it > 3 && MMG5_abs(nc-ns) < 0.1 * MG_MAX(nc,ns) ) break;
}
while ( ++it < maxit && ns+nc+nsw >0 );
Expand Down Expand Up @@ -606,6 +625,17 @@ int MMG2D_adptri(MMG5_pMesh mesh,MMG5_pSol met) {

if ( (abs(mesh->info.imprim) > 4 || mesh->info.ddebug) && ns+nc+nsw+nm > 0 )
fprintf(stdout," %8" MMG5_PRId " splitted, %8" MMG5_PRId " collapsed, %8" MMG5_PRId " swapped, %8" MMG5_PRId " moved\n",ns,nc,nsw,nm);

/* Progress callback */
if ( mesh->info.progressCb ) {
if ( !mesh->info.progressCb(mesh, MMG5_PHASE_ADAPTATION, it, maxit,
(int64_t)ns, (int64_t)nc, (int64_t)nsw,
(int64_t)nm, mesh->info.progressData) ) {
fprintf(stderr,"\n ## Remeshing cancelled by user callback.\n");
return 0;
}
}

if ( ns < 10 && MMG5_abs(nc-ns) < 3 ) break;
else if ( it > 3 && MMG5_abs(nc-ns) < 0.3 * MG_MAX(nc,ns) ) break;
}
Expand Down
8 changes: 8 additions & 0 deletions src/mmg3d/API_functions_3d.c
Original file line number Diff line number Diff line change
Expand Up @@ -2585,3 +2585,11 @@ int MMG3D_Free_names(const int starter,...)

return ier;
}

int MMG3D_Set_progressCallback(MMG5_pMesh mesh,
MMG5_progressCallback callback,
void *user_data) {
mesh->info.progressCb = callback;
mesh->info.progressData = user_data;
return 1;
}
25 changes: 25 additions & 0 deletions src/mmg3d/libmmg3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -3458,6 +3458,31 @@ LIBMMG3D_EXPORT int MMG3D_loadVtuMesh_and_allData(MMG5_pMesh mesh,MMG5_pSol *sol
* functions.
*/
LIBMMG3D_EXPORT void MMG3D_Set_commonFunc(void);

/**
* \brief Set a progress callback for the remeshing process.
*
* \param mesh pointer to the mesh structure.
* \param callback progress callback function (NULL to disable).
* \param user_data opaque pointer forwarded to every callback invocation.
*
* \return 1 on success.
*
* The callback is invoked at each iteration of every remeshing phase:
* geometric mesh, computational mesh, adaptation loop, and optimization.
* Returning 0 from the callback requests graceful cancellation.
*
* When \a callback is NULL (the default), no function-pointer check is
* performed in the hot loops, so there is zero overhead.
*
* \remark No Fortran interface.
*
* \sa MMG5_progressCallback for the callback signature.
*/
LIBMMG3D_EXPORT int MMG3D_Set_progressCallback(MMG5_pMesh mesh,
MMG5_progressCallback callback,
void *user_data);

#ifdef __cplusplus
}
#endif
Expand Down
18 changes: 18 additions & 0 deletions src/mmg3d/mmg3d1.c
Original file line number Diff line number Diff line change
Expand Up @@ -3263,6 +3263,24 @@ int MMG5_anatet(MMG5_pMesh mesh,MMG5_pSol met,int8_t typchk, int patternMode) {
fprintf(stdout," %8" MMG5_PRId " splitted, %8" MMG5_PRId " collapsed, %8" MMG5_PRId " swapped\n",ns,nc,nf);
}

/* Progress callback */
if ( mesh->info.progressCb ) {
int phase = (typchk == 1) ?
MMG5_PHASE_GEOMETRIC_MESH :
MMG5_PHASE_COMPUTATIONAL_MESH;
if ( !mesh->info.progressCb(
mesh, phase, it, maxit,
(int64_t)ns, (int64_t)nc,
(int64_t)nf, 0,
mesh->info.progressData) ) {
fprintf(stderr,
"\n ## %s cancelled by user callback.\n",
(typchk == 1) ?
"Geometric mesh" : "Computational mesh");
return 0;
}
}

if ( it > minit-1 && ( !(ns+nc) || (MMG5_abs(nc-ns) < 0.1 * MG_MAX(nc,ns)) ) ) {
++lastit;
if ( it > minit && lastit>2 ) break;
Expand Down
44 changes: 43 additions & 1 deletion src/mmg3d/mmg3d1_delone.c
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,16 @@ int MMG5_optbad(MMG5_pMesh mesh, MMG5_pSol met,MMG3D_pPROctree PROctree) {
fprintf(stdout," ");
fprintf(stdout," %8" MMG5_PRId " improved, %8" MMG5_PRId " swapped, %8" MMG5_PRId " moved\n",nw,nf,nm);
}

/* Progress callback */
if ( mesh->info.progressCb ) {
if ( !mesh->info.progressCb(mesh, MMG5_PHASE_OPTIMIZATION, it, maxit,
0, 0, (int64_t)nf, (int64_t)nm,
mesh->info.progressData) ) {
fprintf(stderr,"\n ## Optimization cancelled by user callback.\n");
return 0;
}
}
}
while( ++it < maxit && nw+nm+nf > 0 );

Expand Down Expand Up @@ -716,10 +726,22 @@ int MMG5_adpdel(MMG5_pMesh mesh,MMG5_pSol met,MMG3D_pPROctree *PROctree, int* wa
fprintf(stdout," %8"MMG5_PRId" filtered, %8" MMG5_PRId " splitted, %8" MMG5_PRId " collapsed,"
" %8" MMG5_PRId " swapped, %8" MMG5_PRId " moved\n",ifilt,ns,nc,nf,nm);

/* Progress callback */
if ( mesh->info.progressCb ) {
if ( !mesh->info.progressCb(mesh, MMG5_PHASE_ADAPTATION, it, maxit,
(int64_t)ns, (int64_t)nc, (int64_t)nf,
(int64_t)nm, mesh->info.progressData) ) {
fprintf(stderr,"\n ## Remeshing cancelled by user callback.\n");
return 0;
}
}

/*optimization*/
dd = MMG5_abs(nc-ns);
if ( !noptim && (it==5 || ((dd < 5) || (dd < 0.05*MG_MAX(nc,ns)) || !(ns+nc))) ) {
MMG5_optbad(mesh,met,*PROctree);
if ( !MMG5_optbad(mesh,met,*PROctree) ) {
return 0;
}
noptim = 1;
}

Expand Down Expand Up @@ -806,6 +828,16 @@ int MMG5_optetLES(MMG5_pMesh mesh, MMG5_pSol met,MMG3D_pPROctree PROctree) {
fprintf(stdout," ");
fprintf(stdout," %8" MMG5_PRId " improved, %8" MMG5_PRId " swapped, %8" MMG5_PRId " moved\n",nw,nf,nm);
}

/* Progress callback */
if ( mesh->info.progressCb ) {
if ( !mesh->info.progressCb(mesh, MMG5_PHASE_OPTIMIZATION, it, maxit,
0, 0, (int64_t)nf, (int64_t)nm,
mesh->info.progressData) ) {
fprintf(stderr,"\n ## Optimization cancelled by user callback.\n");
return 0;
}
}
}
while( ++it < maxit && nw+nm+nf > 0 );

Expand Down Expand Up @@ -911,6 +943,16 @@ int MMG5_optet(MMG5_pMesh mesh, MMG5_pSol met,MMG3D_pPROctree PROctree) {
fprintf(stdout," %8" MMG5_PRId " improved, %8" MMG5_PRId " swapped, %8" MMG5_PRId " moved\n",nw,nf,nm);
}

/* Progress callback */
if ( mesh->info.progressCb ) {
if ( !mesh->info.progressCb(mesh, MMG5_PHASE_OPTIMIZATION, it, maxit,
0, 0, (int64_t)nf, (int64_t)nm,
mesh->info.progressData) ) {
fprintf(stderr,"\n ## Optimization cancelled by user callback.\n");
return 0;
}
}

if ( it > 3 ) {
if ( !nw && (!nm || !nf) ) break;
}
Expand Down
21 changes: 21 additions & 0 deletions src/mmg3d/mmg3d1_pattern.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,17 @@ static int MMG5_adptet(MMG5_pMesh mesh,MMG5_pSol met,MMG5_int *permNodGlob) {

if ( (abs(mesh->info.imprim) > 4 || mesh->info.ddebug) && ns+nc > 0 )
fprintf(stdout," %8" MMG5_PRId " splitted, %8" MMG5_PRId " collapsed, %8" MMG5_PRId " swapped, %8" MMG5_PRId " moved\n",ns,nc,nf,nm);

/* Progress callback */
if ( mesh->info.progressCb ) {
if ( !mesh->info.progressCb(mesh, MMG5_PHASE_ADAPTATION, it, maxit,
(int64_t)ns, (int64_t)nc, (int64_t)nf,
(int64_t)nm, mesh->info.progressData) ) {
fprintf(stderr,"\n ## Remeshing cancelled by user callback.\n");
return 0;
}
}

if ( ns < 10 && MMG5_abs(nc-ns) < 3 ) break;
else if ( it > 3 && MMG5_abs(nc-ns) < 0.3 * MG_MAX(nc,ns) ) break;
}
Expand Down Expand Up @@ -387,6 +398,16 @@ static int MMG5_adptet(MMG5_pMesh mesh,MMG5_pSol met,MMG5_int *permNodGlob) {
fprintf(stdout," ");
fprintf(stdout,"%8" MMG5_PRId " swapped, %8" MMG5_PRId " moved\n",nf,nm);
}

/* Progress callback */
if ( mesh->info.progressCb ) {
if ( !mesh->info.progressCb(mesh, MMG5_PHASE_OPTIMIZATION, it, maxit,
0, 0, (int64_t)nf, (int64_t)nm,
mesh->info.progressData) ) {
fprintf(stderr,"\n ## Optimization cancelled by user callback.\n");
return 0;
}
}
}
while( ++it < maxit && /*nw+*/nm+nf > 0 );

Expand Down
8 changes: 8 additions & 0 deletions src/mmgs/API_functions_s.c
Original file line number Diff line number Diff line change
Expand Up @@ -1728,3 +1728,11 @@ int MMGS_Free_names(const int starter,...)

return ier;
}

int MMGS_Set_progressCallback(MMG5_pMesh mesh,
MMG5_progressCallback callback,
void *user_data) {
mesh->info.progressCb = callback;
mesh->info.progressData = user_data;
return 1;
}
15 changes: 15 additions & 0 deletions src/mmgs/libmmgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -2576,6 +2576,21 @@ LIBMMGS_EXPORT void MMGS_Free_solutions(MMG5_pMesh mesh,MMG5_pSol sol);
*/
LIBMMGS_EXPORT void MMGS_Set_commonFunc(void);

/**
* \brief Set a progress callback for the remeshing process.
*
* \param mesh pointer to the mesh structure.
* \param callback progress callback function (NULL to disable).
* \param user_data opaque pointer forwarded to every callback invocation.
*
* \return 1 on success.
*
* \sa MMG5_progressCallback, MMG3D_Set_progressCallback.
*/
LIBMMGS_EXPORT int MMGS_Set_progressCallback(MMG5_pMesh mesh,
MMG5_progressCallback callback,
void *user_data);

#ifdef __cplusplus
}
#endif
Expand Down
Loading
Loading