14#include <lagrange/Mesh.h>
15#include <lagrange/MeshTrait.h>
16#include <lagrange/create_mesh.h>
17#include <lagrange/legacy/inline.h>
20#include <lagrange/utils/warnoff.h>
21#include <igl/adjacency_list.h>
22#include <igl/barycenter.h>
23#include <igl/triangle_triangle_adjacency.h>
24#include <lagrange/utils/warnon.h>
28namespace subdivision {
44template <
typename DerivedVI,
typename DerivedFI,
typename DerivedVO,
typename DerivedFO>
46 const Eigen::MatrixBase<DerivedVI>& VI,
47 const Eigen::MatrixBase<DerivedFI>& FI,
48 Eigen::PlainObjectBase<DerivedVO>& VO,
49 Eigen::PlainObjectBase<DerivedFO>& FO)
51 using Scalar =
typename DerivedVI::Scalar;
52 using Index =
typename DerivedFI::Scalar;
53 using MatrixXs = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
54 using MatrixXi = Eigen::Matrix<Index, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
55 using RowVector3s = Eigen::Matrix<Scalar, 1, 3>;
59 igl::barycenter(VI, FI, BC);
62 VO.resize(VI.rows() + FI.rows(), VI.cols());
63 VO.topRows(VI.rows()) = VI;
64 VO.bottomRows(BC.rows()) = BC;
65 std::vector<std::vector<Index>> VV;
66 igl::adjacency_list(FI, VV);
67 for (Index i = 0; i < (Index)VI.rows(); ++i) {
68 Scalar n =
static_cast<Scalar
>(VV[i].size());
69 Scalar an =
static_cast<Scalar
>((4.0 - 2.0 * std::cos(2.0 * M_PI / n)) / 9.0);
70 RowVector3s sum_vi = RowVector3s::Zero();
71 for (
auto j : VV[i]) {
74 VO.row(i) = (1 - an) * VI.row(i) + an / n * sum_vi;
78 FO.resize(3 * FI.rows(), FI.cols());
79 for (Index f = 0; f < (Index)FI.rows(); ++f) {
80 FO.row(3 * f + 0) << VI.rows() + f, FI(f, 0), FI(f, 1);
81 FO.row(3 * f + 1) << VI.rows() + f, FI(f, 1), FI(f, 2);
82 FO.row(3 * f + 2) << VI.rows() + f, FI(f, 2), FI(f, 0);
85 igl::triangle_triangle_adjacency(FI, TT, TTi);
86 for (Index f = 0; f < (Index)FI.rows(); ++f) {
87 for (Index i = 0; i < (Index)FI.cols(); ++i) {
88 if (TT(f, i) !=
static_cast<Index
>(-1) && TT(f, i) > f) {
91 FO(3 * f + i, 2) = VI.rows() + g;
92 FO(3 * g + j, 2) = VI.rows() + f;
115 std::enable_if_t<lagrange::MeshTraitHelper::is_mesh<MeshType>::value>* =
nullptr>
118 static_assert(MeshTrait<MeshType>::is_mesh(),
"Input type is not Mesh");
120 using VertexArray =
typename MeshType::VertexArray;
121 using FacetArray =
typename MeshType::FacetArray;
SurfaceMesh< Scalar, Index > sqrt_subdivision(const SurfaceMesh< Scalar, Index > &mesh)
Performs one step of sqrt(3)-subdivision.
Definition: sqrt_subdivision.cpp:101
Main namespace for Lagrange.
Definition: AABBIGL.h:30
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