box_cubic.cpp 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2026 Alec Jacobson <[email protected]>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "box_cubic.h"
  9. #include "../cubic.h"
  10. #include "../parallel_for.h"
  11. #include <cyPolynomial.h>
  12. template <
  13. typename DerivedC,
  14. typename DerivedB>
  15. IGL_INLINE void igl::cycodebase::box_cubic(
  16. const Eigen::MatrixBase<DerivedC>& C,
  17. Eigen::PlainObjectBase<DerivedB>& B1,
  18. Eigen::PlainObjectBase<DerivedB>& B2)
  19. {
  20. using Scalar = typename DerivedC::Scalar;
  21. typedef Eigen::Matrix<Scalar,3,1> VectorS3;
  22. typedef Eigen::Matrix<Scalar,DerivedC::RowsAtCompileTime,1> VectorSC;
  23. // Using the control points is a simple (but not tight) bound
  24. B1 = C({0,3},Eigen::all).colwise().minCoeff();
  25. B2 = C({0,3},Eigen::all).colwise().maxCoeff();
  26. // Better to find each of the t values where dC/dt = 0 and evaluate C there
  27. for(int d = 0;d<C.cols();d++)
  28. {
  29. // [3*C1 - 3*C0, 6*C0 - 12*C1 + 6*C2, 9*C1 - 3*C0 - 9*C2 + 3*C3]
  30. VectorS3 coef(
  31. Scalar(3) * (C(1,d) - C(0,d)),
  32. Scalar(6) * (C(0,d) - Scalar(2) * C(1,d) + C(2,d)),
  33. Scalar(3) * (C(3,d) - C(0,d) + Scalar(3) * (C(1,d) - C(2,d)))
  34. );
  35. VectorS3 r;
  36. int nr = cy::PolynomialRoots<2>(r.data(), coef.data(),0.0,1.0);
  37. for(int i = 0;i<nr;i++)
  38. {
  39. const Scalar t = r[i];
  40. // Evaluate cubic at t
  41. Eigen::Matrix<Scalar,1,1> Cdt;
  42. igl::cubic(C.col(d),t,Cdt);
  43. B1(d) = std::min(B1(d),Cdt(0));
  44. B2(d) = std::max(B2(d),Cdt(0));
  45. }
  46. }
  47. }
  48. template <
  49. typename DerivedP,
  50. typename DerivedC,
  51. typename DerivedB>
  52. IGL_INLINE void igl::cycodebase::box_cubic(
  53. const Eigen::MatrixBase<DerivedP>& P,
  54. const Eigen::MatrixBase<DerivedC>& C,
  55. Eigen::PlainObjectBase<DerivedB>& B1,
  56. Eigen::PlainObjectBase<DerivedB>& B2)
  57. {
  58. B1.resize(C.rows(),P.cols());
  59. B2.resize(C.rows(),P.cols());
  60. typedef Eigen::Matrix<typename DerivedP::Scalar,1,DerivedP::ColsAtCompileTime> RowVectorP;
  61. igl::parallel_for(C.rows(),[&](const int c)
  62. {
  63. RowVectorP B1_c, B2_c;
  64. // Eval copies, but is it really good to make a template for the non copy?
  65. box_cubic(P(C.row(c),Eigen::all).eval(),B1_c,B2_c);
  66. B1.row(c) = B1_c;
  67. B2.row(c) = B2_c;
  68. },1000);
  69. }
  70. #ifdef IGL_STATIC_LIBRARY
  71. // Explicit template instantiation
  72. // generated by autoexplicit.sh
  73. template void igl::cycodebase::box_cubic<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 1, -1, -1>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1>>&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 1, -1, -1>>&);
  74. template void igl::cycodebase::box_cubic<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 1, -1, 1, 1, -1>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, -1, 1, 1, -1>>&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, -1, 1, 1, -1>>&);
  75. template void igl::cycodebase::box_cubic<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>>(Eigen::MatrixBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>> const&, Eigen::MatrixBase<Eigen::Matrix<int, -1, -1, 0, -1, -1>> const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>>&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1>>&);
  76. #endif