Blender V5.0
geometry_component_mesh.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_math_vector.hh"
6
8#include "BKE_geometry_set.hh"
9#include "BKE_lib_id.hh"
10#include "BKE_mesh.hh"
11
13
14namespace blender::bke {
15
16/* -------------------------------------------------------------------- */
19
21
23 : GeometryComponent(Type::Mesh), mesh_(mesh), ownership_(ownership)
24{
25}
26
31
33{
34 MeshComponent *new_component = new MeshComponent();
35 if (mesh_ != nullptr) {
36 new_component->mesh_ = BKE_mesh_copy_for_eval(*mesh_);
37 new_component->ownership_ = GeometryOwnershipType::Owned;
38 }
39 return GeometryComponentPtr(new_component);
40}
41
43{
44 BLI_assert(this->is_mutable() || this->is_expired());
45 if (mesh_ != nullptr) {
46 if (ownership_ == GeometryOwnershipType::Owned) {
47 BKE_id_free(nullptr, mesh_);
48 }
49 mesh_ = nullptr;
50 }
51}
52
54{
55 return mesh_ != nullptr;
56}
57
59{
60 BLI_assert(this->is_mutable());
61 this->clear();
62 mesh_ = mesh;
63 ownership_ = ownership;
64}
65
67{
68 BLI_assert(this->is_mutable());
69 Mesh *mesh = mesh_;
70 mesh_ = nullptr;
71 return mesh;
72}
73
75{
76 return mesh_;
77}
78
80{
81 BLI_assert(this->is_mutable());
82 if (ownership_ == GeometryOwnershipType::ReadOnly) {
83 mesh_ = BKE_mesh_copy_for_eval(*mesh_);
85 }
86 return mesh_;
87}
88
90{
91 return mesh_ == nullptr;
92}
93
95{
96 return ownership_ == GeometryOwnershipType::Owned;
97}
98
100{
101 BLI_assert(this->is_mutable());
102 if (ownership_ != GeometryOwnershipType::Owned) {
103 if (mesh_) {
104 mesh_ = BKE_mesh_copy_for_eval(*mesh_);
105 }
106 ownership_ = GeometryOwnershipType::Owned;
107 }
108}
109
111{
112 if (mesh_) {
113 mesh_->count_memory(memory);
114 }
115}
116
118
119/* -------------------------------------------------------------------- */
122
124 const IndexMask &mask,
125 const AttrDomain domain,
126 const bool no_corner_normals,
127 const bool true_normals)
128{
129 switch (domain) {
130 case AttrDomain::Face: {
131 return VArray<float3>::from_span(true_normals ? mesh.face_normals_true() :
132 mesh.face_normals());
133 }
134 case AttrDomain::Point: {
135 return VArray<float3>::from_span(true_normals ? mesh.vert_normals_true() :
136 mesh.vert_normals());
137 }
138 case AttrDomain::Edge: {
139 /* In this case, start with vertex normals and convert to the edge domain, since the
140 * conversion from edges to vertices is very simple. Use "manual" domain interpolation
141 * instead of the GeometryComponent API to avoid calculating unnecessary values and to
142 * allow normalizing the result more simply. */
143 Span<float3> vert_normals = true_normals ? mesh.vert_normals_true() : mesh.vert_normals();
144 const Span<int2> edges = mesh.edges();
145 Array<float3> edge_normals(mask.min_array_size());
146 mask.foreach_index([&](const int i) {
147 const int2 &edge = edges[i];
148 edge_normals[i] = math::normalize(
149 math::interpolate(vert_normals[edge[0]], vert_normals[edge[1]], 0.5f));
150 });
151
152 return VArray<float3>::from_container(std::move(edge_normals));
153 }
154 case AttrDomain::Corner: {
155 if (no_corner_normals || true_normals) {
156 return mesh.attributes().adapt_domain(
157 VArray<float3>::from_span(true_normals ? mesh.face_normals_true() :
158 mesh.face_normals()),
161 }
162 return VArray<float3>::from_span(mesh.corner_normals());
163 }
164 default:
165 return {};
166 }
167}
168
170
171} // namespace blender::bke
172
173namespace blender::bke {
174
175/* -------------------------------------------------------------------- */
178
179std::optional<AttributeAccessor> MeshComponent::attributes() const
180{
182}
183
184std::optional<MutableAttributeAccessor> MeshComponent::attributes_for_write()
185{
186 Mesh *mesh = this->get_for_write();
188}
189
191
192} // namespace blender::bke
void BKE_id_free(Main *bmain, void *idv)
Mesh * BKE_mesh_copy_for_eval(const Mesh &source)
#define BLI_assert(a)
Definition BLI_assert.h:46
static VArray from_span(Span< T > values)
static VArray from_container(ContainerT container)
void replace(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
GeometryComponentPtr copy() const override
void count_memory(MemoryCounter &memory) const override
std::optional< AttributeAccessor > attributes() const final
std::optional< MutableAttributeAccessor > attributes_for_write() final
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
ImplicitSharingPtr< GeometryComponent > GeometryComponentPtr
const AttributeAccessorFunctions & mesh_attribute_accessor_functions()
VArray< float3 > mesh_normals_varray(const Mesh &mesh, const IndexMask &mask, AttrDomain domain, bool no_corner_normals=false, bool true_normals=false)
T interpolate(const T &a, const T &b, const FactorT &t)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
VecBase< int32_t, 2 > int2
i
Definition text_draw.cc:230