// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2025 Alec Jacobson // // This Source Code Form is subject to the terms of the Mozilla Public License // v. 2.0. If a copy of the MPL was not distributed with this file, You can // obtain one at http://mozilla.org/MPL/2.0/. #include "lipschitz_octree_prune.h" #include "unique_sparse_voxel_corners.h" #include "find.h" #include "matlab_format.h" #include "parallel_for.h" #include #include template < bool batched, typename Derivedorigin, typename Func, typename Derivedijk, typename Derivedijk_maybe > IGL_INLINE void igl::lipschitz_octree_prune( const Eigen::MatrixBase & origin, const typename Derivedorigin::Scalar h0, const int depth, const Func & udf, const Eigen::MatrixBase & ijk, Eigen::PlainObjectBase & ijk_maybe) { // static assert to ensure that Derivedorigin is a vector and the // non-singleton dimension is 3 or Eigen::Dynamic static_assert( (Derivedorigin::RowsAtCompileTime == 1 && ( Derivedorigin::ColsAtCompileTime == 3 || Derivedorigin::ColsAtCompileTime == Eigen::Dynamic)) || (Derivedorigin::ColsAtCompileTime == 1 && ( Derivedorigin::RowsAtCompileTime == 3 || Derivedorigin::RowsAtCompileTime == Eigen::Dynamic)), "Derivedorigin must be a vector with 3 or Eigen::Dynamic dimensions"); // dynamic assert that the origin is a 3D vector assert((origin.rows() == 3 || origin.cols() == 3) && origin.size() == 3 && "origin must be a 3D vector"); using Scalar = typename Derivedorigin::Scalar; using RowVectorS3 = Eigen::Matrix; using MatrixSX8R = Eigen::Matrix; using MatrixSX3R = Eigen::Matrix; using MatrixiX3R = Eigen::Matrix; // h0 is already the h at this depth. const Scalar h = h0 / (1 << depth); Eigen::Matrix J; MatrixiX3R unique_ijk; MatrixSX3R unique_corner_positions; igl::unique_sparse_voxel_corners(origin,h0,depth,ijk,unique_ijk,J,unique_corner_positions); // Effectively a batched call to udf Eigen::Array big(unique_corner_positions.rows()); // Requires C++17 if constexpr (batched) { Eigen::Matrix u = udf(unique_corner_positions); for(int i = 0;i= 0 && "udf must be non-negative for lipschitz_octree_prune"); big(i) = (u(i) > h * std::sqrt(3)); } }else { //for(int u = 0;u= 0 && "udf must be non-negative for lipschitz_octree_prune"); big(i) = (u > h * std::sqrt(3)); }, 1000); } ijk_maybe.resize(ijk.rows(),3); int k = 0; for(int c = 0;c, std::function const&)>, Eigen::Matrix, Eigen::Matrix>(Eigen::MatrixBase> const&, Eigen::Matrix::Scalar, int, std::function const&)> const&, Eigen::MatrixBase> const&, Eigen::PlainObjectBase>&); template void igl::lipschitz_octree_prune, std::function (Eigen::Matrix const&)>, Eigen::Matrix, Eigen::Matrix>(Eigen::MatrixBase> const&, Eigen::Matrix::Scalar, int, std::function (Eigen::Matrix const&)> const&, Eigen::MatrixBase> const&, Eigen::PlainObjectBase>&); #endif