@@ -284,11 +284,11 @@ namespace inclusion_ccd
284284 const Vector3d &a1e,
285285 const Vector3d &b0e,
286286 const Vector3d &b1e,
287- const std::array<Scalar, 3 > &err ,
288- const Scalar ms ,
287+ const std::array<Scalar, 3 > &err_in ,
288+ const Scalar ms_in ,
289289 Scalar &toi,
290- Scalar tolerance ,
291- Scalar t_max ,
290+ const Scalar tolerance_in ,
291+ const Scalar t_max_in ,
292292 const int max_itr,
293293 Scalar &output_tolerance,
294294 const int CCD_TYPE,
@@ -297,60 +297,63 @@ namespace inclusion_ccd
297297 const int MAX_NO_ZERO_TOI_ITER = std::numeric_limits<int >::max ();
298298 // unsigned so can be larger than MAX_NO_ZERO_TOI_ITER
299299 unsigned int no_zero_toi_iter = 0 ;
300+
300301 bool is_impacting, tmp_is_impacting;
301- Scalar tolerance_in = tolerance;
302- Scalar ms_in = ms;
303- do
304- {
305- Vector3d tol = compute_edge_edge_tolerance_new (
306- a0s, a1s, b0s, b1s, a0e, a1e, b0e, b1e, tolerance_in);
307-
308- // this should be the error of the whole mesh
309- std::array<Scalar, 3 > err1;
310- if (err[0 ] < 0 )
311- { // if error[0]<0, means we need to calculate error here
312- std::vector<Vector3d> vlist;
313- vlist.emplace_back (a0s);
314- vlist.emplace_back (a1s);
315- vlist.emplace_back (b0s);
316- vlist.emplace_back (b1s);
317-
318- vlist.emplace_back (a0e);
319- vlist.emplace_back (a1e);
320- vlist.emplace_back (b0e);
321- vlist.emplace_back (b1e);
322- bool use_ms = ms > 0 ;
323- err1 = get_numerical_error (vlist, false , use_ms);
324- // std::cout << "err is " << err1[0] << " " << err1[1] << " "
325- // << err1[2] << " " << std::endl;
326- }
327- else
328- {
329- err1 = err;
330- }
331302
332- // ////////////////////////////////////////////////////////
303+ // Mutable copies for no_zero_toi
304+ Scalar t_max = t_max_in;
305+ Scalar tolerance = tolerance_in;
306+ Scalar ms = ms_in;
307+
308+ Vector3d tol = compute_edge_edge_tolerance_new (
309+ a0s, a1s, b0s, b1s, a0e, a1e, b0e, b1e, tolerance_in);
333310
311+ // ////////////////////////////////////////////////////////
312+ // this should be the error of the whole mesh
313+ std::array<Scalar, 3 > err;
314+ if (err_in[0 ] < 0 )
315+ { // if error[0]<0, means we need to calculate error here
316+ std::vector<Vector3d> vlist;
317+ vlist.emplace_back (a0s);
318+ vlist.emplace_back (a1s);
319+ vlist.emplace_back (b0s);
320+ vlist.emplace_back (b1s);
321+
322+ vlist.emplace_back (a0e);
323+ vlist.emplace_back (a1e);
324+ vlist.emplace_back (b0e);
325+ vlist.emplace_back (b1e);
326+ bool use_ms = ms > 0 ;
327+ err = get_numerical_error (vlist, false , use_ms);
328+ }
329+ else
330+ {
331+ err = err_in;
332+ }
333+ // ////////////////////////////////////////////////////////
334+
335+ do
336+ {
334337 // 0 is normal ccd, and
335338 // 1 is ccd with input time interval upper bound, using real tolerance, max_itr and horizontal tree.
336339 if (CCD_TYPE == 0 )
337340 {
338- tmp_is_impacting = interval_root_finder_double_normalCCD (
339- tol, toi, false , err1, ms_in, a0s, a1s, b0s, b1s, a0e, a1e,
340- b0e, b1e);
341- return tmp_is_impacting ;
341+ // no handling for zero toi
342+ return interval_root_finder_double_normalCCD (
343+ tol, toi, false , err, ms, a0s, a1s, b0s, b1s, a0e, a1e, b0e,
344+ b1e) ;
342345 }
343346 else
344347 {
345348 assert (CCD_TYPE == 1 );
346349 assert (t_max >= 0 && t_max <= 1 );
347350 tmp_is_impacting = interval_root_finder_double_horizontal_tree (
348- tol, tolerance_in , toi, false , err1, ms_in , a0s, a1s, b0s, b1s,
351+ tol, tolerance , toi, false , err, ms , a0s, a1s, b0s, b1s,
349352 a0e, a1e, b0e, b1e, t_max, max_itr, output_tolerance);
350353 }
351354 assert (!tmp_is_impacting || toi >= 0 );
352355
353- if (no_zero_toi_iter == 0 )
356+ if (t_max == t_max_in )
354357 {
355358 // This will be the final output because we might need to
356359 // perform CCD again if the toi is zero. In which case we will
@@ -362,33 +365,34 @@ namespace inclusion_ccd
362365 toi = tmp_is_impacting ? toi : t_max;
363366 }
364367
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-
386-
387- no_zero_toi_iter++;
368+ // This modification is for CCD-filtered line-search (e.g., IPC)
369+ // strategies for dealing with toi = 0:
370+ // 1. shrink t_max (when reaches max_itr),
371+ // 2. shrink tolerance (when not reach max_itr and tolerance is big) or
372+ // ms (when tolerance is too small comparing with ms)
373+ if (tmp_is_impacting && toi == 0 && no_zero_toi)
374+ {
375+ if (output_tolerance > tolerance)
376+ {
377+ // reaches max_itr, so shrink t_max to return a more accurate result to reach target tolerance.
378+ t_max *= 0.9 ;
379+ }
380+ else if (10 * tolerance < ms)
381+ {
382+ ms *= 0.5 ; // ms is too large, shrink it
383+ }
384+ else
385+ {
386+ tolerance *= 0.5 ; // tolerance is too large, shrink it
387+
388+ tol = compute_edge_edge_tolerance_new (
389+ a0s, a1s, b0s, b1s, a0e, a1e, b0e, b1e, tolerance);
390+ }
391+ }
388392
389393 // Only perform a second iteration if toi == 0.
390394 // WARNING: This option assumes the initial distance is not zero.
391- } while (no_zero_toi && no_zero_toi_iter < MAX_NO_ZERO_TOI_ITER
395+ } while (no_zero_toi && ++ no_zero_toi_iter < MAX_NO_ZERO_TOI_ITER
392396 && tmp_is_impacting && toi == 0 );
393397 assert (!no_zero_toi || !is_impacting || toi != 0 );
394398
@@ -404,11 +408,11 @@ namespace inclusion_ccd
404408 const Vector3d &face_vertex0_end,
405409 const Vector3d &face_vertex1_end,
406410 const Vector3d &face_vertex2_end,
407- const std::array<Scalar, 3 > &err ,
408- const Scalar ms ,
411+ const std::array<Scalar, 3 > &err_in ,
412+ const Scalar ms_in ,
409413 Scalar &toi,
410- Scalar tolerance ,
411- Scalar t_max ,
414+ const Scalar tolerance_in ,
415+ const Scalar t_max_in ,
412416 const int max_itr,
413417 Scalar &output_tolerance,
414418 const int CCD_TYPE,
@@ -417,63 +421,68 @@ namespace inclusion_ccd
417421 const int MAX_NO_ZERO_TOI_ITER = std::numeric_limits<int >::max ();
418422 // unsigned so can be larger than MAX_NO_ZERO_TOI_ITER
419423 unsigned int no_zero_toi_iter = 0 ;
424+
420425 bool is_impacting, tmp_is_impacting;
421- Scalar tolerance_in = tolerance;
422- Scalar ms_in = ms;
423- do
426+
427+ // Mutable copies for no_zero_toi
428+ Scalar t_max = t_max_in;
429+ Scalar tolerance = tolerance_in;
430+ Scalar ms = ms_in;
431+
432+ Vector3d tol = compute_face_vertex_tolerance_3d_new (
433+ vertex_start, face_vertex0_start, face_vertex1_start,
434+ face_vertex2_start, vertex_end, face_vertex0_end, face_vertex1_end,
435+ face_vertex2_end, tolerance);
436+
437+ // ////////////////////////////////////////////////////////
438+ // this is the error of the whole mesh
439+ std::array<Scalar, 3 > err;
440+ if (err_in[0 ] < 0 )
441+ { // if error[0]<0, means we need to calculate error here
442+ std::vector<Vector3d> vlist;
443+ vlist.emplace_back (vertex_start);
444+ vlist.emplace_back (face_vertex0_start);
445+ vlist.emplace_back (face_vertex1_start);
446+ vlist.emplace_back (face_vertex2_start);
447+
448+ vlist.emplace_back (vertex_end);
449+ vlist.emplace_back (face_vertex0_end);
450+ vlist.emplace_back (face_vertex1_end);
451+ vlist.emplace_back (face_vertex2_end);
452+ bool use_ms = ms > 0 ;
453+ err = get_numerical_error (vlist, true , use_ms);
454+ }
455+ else
424456 {
425- Vector3d tol = compute_face_vertex_tolerance_3d_new (
426- vertex_start, face_vertex0_start, face_vertex1_start,
427- face_vertex2_start, vertex_end, face_vertex0_end,
428- face_vertex1_end, face_vertex2_end, tolerance_in);
429-
430- // ////////////////////////////////////////////////////////
431- // this is the error of the whole mesh
432- std::array<Scalar, 3 > err1;
433- if (err[0 ] < 0 )
434- { // if error[0]<0, means we need to calculate error here
435- std::vector<Vector3d> vlist;
436- vlist.emplace_back (vertex_start);
437- vlist.emplace_back (face_vertex0_start);
438- vlist.emplace_back (face_vertex1_start);
439- vlist.emplace_back (face_vertex2_start);
440-
441- vlist.emplace_back (vertex_end);
442- vlist.emplace_back (face_vertex0_end);
443- vlist.emplace_back (face_vertex1_end);
444- vlist.emplace_back (face_vertex2_end);
445- bool use_ms = ms > 0 ;
446- err1 = get_numerical_error (vlist, true , use_ms);
447- }
448- else
449- {
450- err1 = err;
451- }
452- // ////////////////////////////////////////////////////////
457+ err = err_in;
458+ }
459+ // ////////////////////////////////////////////////////////
453460
461+ do
462+ {
454463 // 0 is normal ccd, and
455464 // 1 is ccd with input time interval upper bound, using real tolerance, max_itr and horizontal tree.
456465 if (CCD_TYPE == 0 )
457466 {
458- tmp_is_impacting = interval_root_finder_double_normalCCD (
459- tol, toi, true , err1, ms_in, vertex_start, face_vertex0_start,
467+ // no handling for zero toi
468+ return interval_root_finder_double_normalCCD (
469+ tol, toi, true , err, ms, vertex_start, face_vertex0_start,
460470 face_vertex1_start, face_vertex2_start, vertex_end,
461471 face_vertex0_end, face_vertex1_end, face_vertex2_end);
462- return tmp_is_impacting;
463472 }
464473 else
465474 {
466475 assert (CCD_TYPE == 1 );
467476 assert (t_max >= 0 && t_max <= 1 );
468477 tmp_is_impacting = interval_root_finder_double_horizontal_tree (
469- tol, tolerance_in , toi, true , err1, ms_in , vertex_start,
478+ tol, tolerance , toi, true , err, ms , vertex_start,
470479 face_vertex0_start, face_vertex1_start, face_vertex2_start,
471480 vertex_end, face_vertex0_end, face_vertex1_end,
472481 face_vertex2_end, t_max, max_itr, output_tolerance);
473482 }
474483 assert (!tmp_is_impacting || toi >= 0 );
475484
476- if (no_zero_toi_iter == 0 )
485+ if (t_max == t_max_in )
477486 {
478487 // This will be the final output because we might need to
479488 // perform CCD again if the toi is zero. In which case we will
@@ -485,32 +494,37 @@ namespace inclusion_ccd
485494 toi = tmp_is_impacting ? toi : t_max;
486495 }
487496
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- }
508-
509- no_zero_toi_iter++;
497+ // This modification is for CCD-filtered line-search (e.g., IPC)
498+ // strategies for dealing with toi = 0:
499+ // 1. shrink t_max (when reaches max_itr),
500+ // 2. shrink tolerance (when not reach max_itr and tolerance is big) or
501+ // ms (when tolerance is too small comparing with ms)
502+ if (tmp_is_impacting && toi == 0 && no_zero_toi)
503+ {
504+ if (output_tolerance > tolerance)
505+ {
506+ // reaches max_itr, so shrink t_max to return a more accurate result to reach target tolerance.
507+ t_max *= 0.9 ;
508+ }
509+ else if (10 * tolerance < ms)
510+ {
511+ ms *= 0.5 ; // ms is too large, shrink it
512+ }
513+ else
514+ {
515+ tolerance *= 0.5 ; // tolerance is too large, shrink it
516+
517+ // recompute this
518+ tol = compute_face_vertex_tolerance_3d_new (
519+ vertex_start, face_vertex0_start, face_vertex1_start,
520+ face_vertex2_start, vertex_end, face_vertex0_end,
521+ face_vertex1_end, face_vertex2_end, tolerance);
522+ }
523+ }
510524
511525 // Only perform a second iteration if toi == 0.
512526 // WARNING: This option assumes the initial distance is not zero.
513- } while (no_zero_toi && no_zero_toi_iter < MAX_NO_ZERO_TOI_ITER
527+ } while (no_zero_toi && ++ no_zero_toi_iter < MAX_NO_ZERO_TOI_ITER
514528 && tmp_is_impacting && toi == 0 );
515529 assert (!no_zero_toi || !is_impacting || toi != 0 );
516530
0 commit comments