From 4a432d7e27796cfa2e38b9b891032fcc50c56ce4 Mon Sep 17 00:00:00 2001 From: Zachary Ferguson Date: Tue, 26 May 2026 11:34:30 -0400 Subject: [PATCH] Fix MSVC duplicate symbol errors for PrimitiveDistance explicit specializations Add explicit specialization declarations in primitive_distance.hpp for the seven methods that have optimized definitions in primitive_distance.cpp (compute_closest_direction_hessian for Edge3/Edge3, Point2/Point2, Point3/Point3; compute_mollifier_gradient and compute_mollifier_hessian for Edge3/Edge3 and Face/Point3). Without these declarations, MSVC instantiates the inline primary template body in every including translation unit, producing duplicate symbol linker errors. GCC/Clang handle this via COMDAT merging; MSVC does not. Co-Authored-By: Claude Sonnet 4.6 --- .../distance/primitive_distance.hpp | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/src/ipc/smooth_contact/distance/primitive_distance.hpp b/src/ipc/smooth_contact/distance/primitive_distance.hpp index 9debba70d..c34e0875d 100644 --- a/src/ipc/smooth_contact/distance/primitive_distance.hpp +++ b/src/ipc/smooth_contact/distance/primitive_distance.hpp @@ -212,6 +212,92 @@ template class PrimitiveDistance { } }; +// Explicit specialization declarations — prevent implicit instantiation of the +// inline primary template body in other translation units (MSVC requires this). +#ifndef IPC_TOOLKIT_DEBUG_AUTODIFF +template <> +std::tuple< + Eigen::Vector::DIM>, + Eigen::Matrix< + double, + PrimitiveDistance::DIM, + PrimitiveDistance::N_CORE_DOFS>, + std::array< + Eigen::Matrix< + double, + PrimitiveDistance::N_CORE_DOFS, + PrimitiveDistance::N_CORE_DOFS>, + PrimitiveDistance::DIM>> +PrimitiveDistance::compute_closest_direction_hessian( + const Eigen::Vector::N_CORE_DOFS>& + x, + EdgeEdgeDistanceType dtype); + +template <> +std::tuple< + Eigen::Vector::DIM>, + Eigen::Matrix< + double, + PrimitiveDistance::DIM, + PrimitiveDistance::N_CORE_DOFS>, + std::array< + Eigen::Matrix< + double, + PrimitiveDistance::N_CORE_DOFS, + PrimitiveDistance::N_CORE_DOFS>, + PrimitiveDistance::DIM>> +PrimitiveDistance::compute_closest_direction_hessian( + const Eigen::Vector::N_CORE_DOFS>& + x, + PointPointDistanceType dtype); + +template <> +std::tuple< + Eigen::Vector::DIM>, + Eigen::Matrix< + double, + PrimitiveDistance::DIM, + PrimitiveDistance::N_CORE_DOFS>, + std::array< + Eigen::Matrix< + double, + PrimitiveDistance::N_CORE_DOFS, + PrimitiveDistance::N_CORE_DOFS>, + PrimitiveDistance::DIM>> +PrimitiveDistance::compute_closest_direction_hessian( + const Eigen::Vector::N_CORE_DOFS>& + x, + PointPointDistanceType dtype); + +template <> +GradientType::N_CORE_DOFS + 1> +PrimitiveDistance::compute_mollifier_gradient( + const Eigen::Vector::N_CORE_DOFS>& + x, + double dist_sqr); + +template <> +GradientType::N_CORE_DOFS + 1> +PrimitiveDistance::compute_mollifier_gradient( + const Eigen::Vector::N_CORE_DOFS>& + x, + double dist_sqr); + +template <> +HessianType::N_CORE_DOFS + 1> +PrimitiveDistance::compute_mollifier_hessian( + const Eigen::Vector::N_CORE_DOFS>& + x, + double dist_sqr); + +template <> +HessianType::N_CORE_DOFS + 1> +PrimitiveDistance::compute_mollifier_hessian( + const Eigen::Vector::N_CORE_DOFS>& + x, + double dist_sqr); +#endif + } // namespace ipc #include "primitive_distance.tpp"