14#include <lagrange/Mesh.h>
15#include <lagrange/MeshTrait.h>
16#include <lagrange/create_mesh.h>
17#include <lagrange/internal/constants.h>
18#include <lagrange/legacy/inline.h>
21#include <lagrange/utils/warnoff.h>
22#include <igl/adjacency_list.h>
23#include <igl/barycenter.h>
24#include <igl/triangle_triangle_adjacency.h>
25#include <lagrange/utils/warnon.h>
45template <
typename DerivedVI,
typename DerivedFI,
typename DerivedVO,
typename DerivedFO>
47 const Eigen::MatrixBase<DerivedVI>& VI,
48 const Eigen::MatrixBase<DerivedFI>& FI,
49 Eigen::PlainObjectBase<DerivedVO>& VO,
50 Eigen::PlainObjectBase<DerivedFO>& FO)
52 using Scalar =
typename DerivedVI::Scalar;
53 using Index =
typename DerivedFI::Scalar;
54 using MatrixXs = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
55 using MatrixXi = Eigen::Matrix<Index, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
56 using RowVector3s = Eigen::Matrix<Scalar, 1, 3>;
60 igl::barycenter(VI, FI, BC);
63 VO.resize(VI.rows() + FI.rows(), VI.cols());
64 VO.topRows(VI.rows()) = VI;
65 VO.bottomRows(BC.rows()) = BC;
66 std::vector<std::vector<Index>> VV;
67 igl::adjacency_list(FI, VV);
68 for (Index i = 0; i < (Index)VI.rows(); ++i) {
71 static_cast<Scalar>((4.0 - 2.0 * std::cos(2.0 * lagrange::internal::pi / n)) / 9.0);
72 RowVector3s sum_vi = RowVector3s::Zero();
73 for (
auto j : VV[i]) {
76 VO.row(i) = (1 - an) * VI.row(i) + an / n * sum_vi;
80 FO.resize(3 * FI.rows(), FI.cols());
81 for (Index f = 0; f < (Index)FI.rows(); ++f) {
82 FO.row(3 * f + 0) << VI.rows() + f, FI(f, 0), FI(f, 1);
83 FO.row(3 * f + 1) << VI.rows() + f, FI(f, 1), FI(f, 2);
84 FO.row(3 * f + 2) << VI.rows() + f, FI(f, 2), FI(f, 0);
87 igl::triangle_triangle_adjacency(FI, TT, TTi);
88 for (Index f = 0; f < (Index)FI.rows(); ++f) {
89 for (Index i = 0; i < (Index)FI.cols(); ++i) {
90 if (TT(f, i) !=
static_cast<Index
>(-1) && TT(f, i) > f) {
93 FO(3 * f + i, 2) = VI.rows() + g;
94 FO(3 * g + j, 2) = VI.rows() + f;
117 std::enable_if_t<lagrange::MeshTraitHelper::is_mesh<MeshType>::value>* =
nullptr>
118std::unique_ptr<MeshType> sqrt_subdivision(
const MeshType& mesh)
120 static_assert(MeshTrait<MeshType>::is_mesh(),
"Input type is not Mesh");
122 using VertexArray =
typename MeshType::VertexArray;
123 using FacetArray =
typename MeshType::FacetArray;
127 sqrt_subdivision(mesh.get_vertices(), mesh.get_facets(), V, F);
@ Scalar
Mesh attribute must have exactly 1 channel.
Definition AttributeFwd.h:56
Subdivision surfaces.
Definition mesh_subdivision.h:32
Main namespace for Lagrange.
auto create_mesh(const Eigen::MatrixBase< DerivedV > &vertices, const Eigen::MatrixBase< DerivedF > &facets)
This function create a new mesh given the vertex and facet arrays by copying data into the Mesh objec...
Definition create_mesh.h:39