@@ -298,11 +298,12 @@ namespace inclusion_ccd
298298 // unsigned so can be larger than MAX_NO_ZERO_TOI_ITER
299299 unsigned int no_zero_toi_iter = 0 ;
300300 bool is_impacting, tmp_is_impacting;
301-
301+ Scalar tolerance_in = tolerance;
302+ Scalar ms_in = ms;
302303 do
303304 {
304305 Vector3d tol = compute_edge_edge_tolerance_new (
305- a0s, a1s, b0s, b1s, a0e, a1e, b0e, b1e, tolerance );
306+ a0s, a1s, b0s, b1s, a0e, a1e, b0e, b1e, tolerance_in );
306307
307308 // this should be the error of the whole mesh
308309 std::array<Scalar, 3 > err1;
@@ -335,15 +336,16 @@ namespace inclusion_ccd
335336 if (CCD_TYPE == 0 )
336337 {
337338 tmp_is_impacting = interval_root_finder_double_normalCCD (
338- tol, toi, false , err1, ms , a0s, a1s, b0s, b1s, a0e, a1e,
339+ tol, toi, false , err1, ms_in , a0s, a1s, b0s, b1s, a0e, a1e,
339340 b0e, b1e);
341+ return tmp_is_impacting;
340342 }
341343 else
342344 {
343345 assert (CCD_TYPE == 1 );
344346 assert (t_max >= 0 && t_max <= 1 );
345347 tmp_is_impacting = interval_root_finder_double_horizontal_tree (
346- tol, tolerance , toi, false , err1, ms , a0s, a1s, b0s, b1s,
348+ tol, tolerance_in , toi, false , err1, ms_in , a0s, a1s, b0s, b1s,
347349 a0e, a1e, b0e, b1e, t_max, max_itr, output_tolerance);
348350 }
349351 assert (!tmp_is_impacting || toi >= 0 );
@@ -360,26 +362,34 @@ namespace inclusion_ccd
360362 toi = tmp_is_impacting ? toi : t_max;
361363 }
362364
363- if (tmp_is_impacting && toi == 0 )
364- {
365- // This modification is for CCD-filtered line-search (e.g., IPC)
366- // we rebuild the time interval since tol is conservative:
367- // this is the new time range
368- t_max = std::min (tol[0 ] * 10 , Scalar (0.1 ));
369-
370- // if early terminated, use tolerance; otherwise, use smaller tolerance
371- // althouth time resolution and tolerance is not the same thing, but decrease
372- // tolerance will be helpful
373- tolerance =
374- output_tolerance > tolerance ? tolerance : 0.1 * tolerance;
375- }
365+ // This modification is for CCD-filtered line-search (e.g., IPC)
366+ // strategies for dealing with toi = 0:
367+ // 1. shrink t_max (when reaches max_itr),
368+ // 2. shrink tolerance (when not reach max_itr and tolerance is big) or
369+ // ms (when tolerance is too small comparing with ms)
370+ if (tmp_is_impacting && toi == 0 && no_zero_toi) {
371+
372+ // meaning reaches max_itr, need to shrink the t_max to return a more accurate result to reach target tolerance.
373+ if (output_tolerance > tolerance_in) {
374+ t_max *= 0.9 ;
375+ }
376+ else {// meaning the given tolerance or ms is too large. need to shrink them,
377+ if (10 * tolerance_in < ms_in) {// ms is too large, shrink it
378+ ms_in *= 0.5 ;
379+ }
380+ else {// tolerance is too large, shrink it
381+ tolerance_in *= 0.5 ;
382+ }
383+ }
384+ }
385+
376386
377387 no_zero_toi_iter++;
378388
379389 // Only perform a second iteration if toi == 0.
380390 // WARNING: This option assumes the initial distance is not zero.
381391 } while (no_zero_toi && no_zero_toi_iter < MAX_NO_ZERO_TOI_ITER
382- && tmp_is_impacting && toi == 0 && CCD_TYPE == 1 );
392+ && tmp_is_impacting && toi == 0 );
383393 assert (!no_zero_toi || !is_impacting || toi != 0 );
384394
385395 return is_impacting;
@@ -408,13 +418,14 @@ namespace inclusion_ccd
408418 // unsigned so can be larger than MAX_NO_ZERO_TOI_ITER
409419 unsigned int no_zero_toi_iter = 0 ;
410420 bool is_impacting, tmp_is_impacting;
411-
421+ Scalar tolerance_in = tolerance;
422+ Scalar ms_in = ms;
412423 do
413424 {
414425 Vector3d tol = compute_face_vertex_tolerance_3d_new (
415426 vertex_start, face_vertex0_start, face_vertex1_start,
416427 face_vertex2_start, vertex_end, face_vertex0_end,
417- face_vertex1_end, face_vertex2_end, tolerance );
428+ face_vertex1_end, face_vertex2_end, tolerance_in );
418429
419430 // ////////////////////////////////////////////////////////
420431 // this is the error of the whole mesh
@@ -445,16 +456,17 @@ namespace inclusion_ccd
445456 if (CCD_TYPE == 0 )
446457 {
447458 tmp_is_impacting = interval_root_finder_double_normalCCD (
448- tol, toi, true , err1, ms , vertex_start, face_vertex0_start,
459+ tol, toi, true , err1, ms_in , vertex_start, face_vertex0_start,
449460 face_vertex1_start, face_vertex2_start, vertex_end,
450461 face_vertex0_end, face_vertex1_end, face_vertex2_end);
462+ return tmp_is_impacting;
451463 }
452464 else
453465 {
454466 assert (CCD_TYPE == 1 );
455467 assert (t_max >= 0 && t_max <= 1 );
456468 tmp_is_impacting = interval_root_finder_double_horizontal_tree (
457- tol, tolerance , toi, true , err1, ms , vertex_start,
469+ tol, tolerance_in , toi, true , err1, ms_in , vertex_start,
458470 face_vertex0_start, face_vertex1_start, face_vertex2_start,
459471 vertex_end, face_vertex0_end, face_vertex1_end,
460472 face_vertex2_end, t_max, max_itr, output_tolerance);
@@ -473,26 +485,33 @@ namespace inclusion_ccd
473485 toi = tmp_is_impacting ? toi : t_max;
474486 }
475487
476- if (tmp_is_impacting && toi == 0 )
477- {
478- // This modification is for CCD-filtered line-search (e.g., IPC)
479- // we rebuild the time interval since tol is conservative:
480- // this is the new time range
481- t_max = std::min (tol[0 ] * 10 , Scalar (0.1 ));
482-
483- // if early terminated, use tolerance; otherwise, use smaller tolerance
484- // althouth time resolution and tolerance is not the same thing, but decrease
485- // tolerance will be helpful
486- tolerance =
487- output_tolerance > tolerance ? tolerance : 0.1 * tolerance;
488- }
488+ // This modification is for CCD-filtered line-search (e.g., IPC)
489+ // strategies for dealing with toi = 0:
490+ // 1. shrink t_max (when reaches max_itr),
491+ // 2. shrink tolerance (when not reach max_itr and tolerance is big) or
492+ // ms (when tolerance is too small comparing with ms)
493+ if (tmp_is_impacting && toi == 0 && no_zero_toi) {
494+
495+ // meaning reaches max_itr, need to shrink the t_max to return a more accurate result to reach target tolerance.
496+ if (output_tolerance > tolerance_in) {
497+ t_max *= 0.9 ;
498+ }
499+ else {// meaning the given tolerance or ms is too large. need to shrink them,
500+ if (10 * tolerance_in < ms_in) {// ms is too large, shrink it
501+ ms_in *= 0.5 ;
502+ }
503+ else {// tolerance is too large, shrink it
504+ tolerance_in *= 0.5 ;
505+ }
506+ }
507+ }
489508
490509 no_zero_toi_iter++;
491510
492511 // Only perform a second iteration if toi == 0.
493512 // WARNING: This option assumes the initial distance is not zero.
494513 } while (no_zero_toi && no_zero_toi_iter < MAX_NO_ZERO_TOI_ITER
495- && tmp_is_impacting && toi == 0 && CCD_TYPE == 1 );
514+ && tmp_is_impacting && toi == 0 );
496515 assert (!no_zero_toi || !is_impacting || toi != 0 );
497516
498517 return is_impacting;
0 commit comments