13#include <lagrange/Mesh.h>
14#include <lagrange/attributes/attribute_utils.h>
15#include <lagrange/create_mesh.h>
16#include <lagrange/legacy/inline.h>
17#include <lagrange/primitive/generation_utils.h>
18#include <lagrange/subdivision/mesh_subdivision.h>
25template <
typename MeshType>
26std::unique_ptr<MeshType> generate_subdivided_sphere(
27 const MeshType& base_shape,
28 const typename MeshType::Scalar radius,
29 const Eigen::Matrix<typename MeshType::Scalar, 3, 1>& center = {0, 0, 0},
30 const typename MeshType::Index num_subdivisions = 0)
32 static_assert(MeshTrait<MeshType>::is_mesh(),
"Input type is not Mesh");
34 using VertexArray =
typename MeshType::VertexArray;
35 using VertexType =
typename MeshType::VertexType;
36 using UVArray =
typename MeshType::UVArray;
37 using Scalar =
typename MeshType::Scalar;
41 num_subdivisions >= 0,
42 "Invalid number of subdivisions: " + std::to_string(num_subdivisions));
44 auto mesh =
create_mesh(base_shape.get_vertices(), base_shape.get_facets());
46 if (num_subdivisions == 0) {
48 if (base_shape.is_uv_initialized()) {
49 mesh->initialize_uv(base_shape.get_uv(), base_shape.get_uv_indices());
51 lagrange::set_uniform_semantic_label(*mesh, PrimitiveSemanticLabel::SIDE);
55 subdivision::SubdivisionScheme scheme_type;
60 scheme_type = subdivision::SubdivisionScheme::SCHEME_LOOP;
64 scheme_type = subdivision::SubdivisionScheme::SCHEME_CATMARK;
66 default: scheme_type = subdivision::SubdivisionScheme::SCHEME_CATMARK;
69 auto subdivided_mesh =
70 subdivision::subdivide_mesh<MeshType, MeshType>(*mesh, scheme_type, num_subdivisions);
72 VertexArray subdiv_vertices;
73 subdivided_mesh->export_vertices(subdiv_vertices);
75 const VertexType base_center =
76 0.5 * (subdiv_vertices.colwise().minCoeff() + subdiv_vertices.colwise().maxCoeff());
78 constexpr Scalar comparison_tol = 1e-5;
79 const VertexArray centered_vertices = subdiv_vertices.rowwise() - base_center;
81 if (centered_vertices.norm() > comparison_tol) {
83 (centered_vertices.rowwise().normalized() * radius).rowwise() + center.transpose();
85 subdiv_vertices = centered_vertices.rowwise() + center.transpose();
87 subdivided_mesh->import_vertices(subdiv_vertices);
89 UVArray uvs = compute_spherical_uv_mapping<MeshType>(*subdivided_mesh, center);
90 subdivided_mesh->add_corner_attribute(
"uv");
91 subdivided_mesh->set_corner_attribute(
"uv", uvs);
92 map_corner_attribute_to_indexed_attribute(*subdivided_mesh,
"uv");
93 subdivided_mesh->remove_corner_attribute(
"uv");
94 assert(subdivided_mesh->is_uv_initialized());
97 lagrange::set_uniform_semantic_label(*subdivided_mesh, PrimitiveSemanticLabel::SIDE);
99 return subdivided_mesh;
Index get_vertex_per_facet() const
Retrieves the number of vertex per facet in a regular mesh.
Definition SurfaceMesh.cpp:2336
@ Scalar
Mesh attribute must have exactly 1 channel.
Definition AttributeFwd.h:56
#define la_runtime_assert(...)
Runtime assertion check.
Definition assert.h:174
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