Blender V4.3
bake_items.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 "BKE_bake_items.hh"
7#include "BKE_curves.hh"
9#include "BKE_instances.hh"
10#include "BKE_mesh.hh"
11#include "BKE_pointcloud.hh"
12#include "BKE_volume.hh"
13#include "BKE_volume_grid.hh"
14
16#include "BLI_memory_counter.hh"
17
18#include "DNA_material_types.h"
19#include "DNA_volume_types.h"
20
21namespace blender::bke::bake {
22
23using namespace io::serialize;
24using DictionaryValuePtr = std::shared_ptr<DictionaryValue>;
25
26GeometryBakeItem::GeometryBakeItem(GeometrySet geometry) : geometry(std::move(geometry)) {}
27
29{
30 this->geometry.count_memory(memory);
31}
32
33static std::unique_ptr<BakeMaterialsList> materials_to_weak_references(
34 Material ***materials, short *materials_num, BakeDataBlockMap *data_block_map)
35{
36 if (*materials_num == 0) {
37 return {};
38 }
39 auto materials_list = std::make_unique<BakeMaterialsList>();
40 materials_list->resize(*materials_num);
41 for (const int i : materials_list->index_range()) {
42 Material *material = (*materials)[i];
43 if (material) {
44 (*materials_list)[i] = BakeDataBlockID(material->id);
45 if (data_block_map) {
46 data_block_map->try_add(material->id);
47 }
48 }
49 }
50
51 MEM_SAFE_FREE(*materials);
52 *materials_num = 0;
53
54 return materials_list;
55}
56
58 BakeDataBlockMap *data_block_map)
59{
60 main_geometry.ensure_owns_all_data();
61 main_geometry.modify_geometry_sets([&](GeometrySet &geometry) {
62 if (Mesh *mesh = geometry.get_mesh_for_write()) {
63 mesh->attributes_for_write().remove_anonymous();
64 mesh->runtime->bake_materials = materials_to_weak_references(
65 &mesh->mat, &mesh->totcol, data_block_map);
66 }
67 if (Curves *curves = geometry.get_curves_for_write()) {
68 curves->geometry.wrap().attributes_for_write().remove_anonymous();
69 curves->geometry.runtime->bake_materials = materials_to_weak_references(
70 &curves->mat, &curves->totcol, data_block_map);
71 }
72 if (GreasePencil *grease_pencil = geometry.get_grease_pencil_for_write()) {
73 for (GreasePencilDrawingBase *base : grease_pencil->drawings()) {
74 if (base->type != GP_DRAWING) {
75 continue;
76 }
77 greasepencil::Drawing &drawing = reinterpret_cast<GreasePencilDrawing *>(base)->wrap();
78 drawing.strokes_for_write().attributes_for_write().remove_anonymous();
79 }
80 grease_pencil->attributes_for_write().remove_anonymous();
81 grease_pencil->runtime->bake_materials = materials_to_weak_references(
82 &grease_pencil->material_array, &grease_pencil->material_array_num, data_block_map);
83 }
84 if (PointCloud *pointcloud = geometry.get_pointcloud_for_write()) {
85 pointcloud->attributes_for_write().remove_anonymous();
86 pointcloud->runtime->bake_materials = materials_to_weak_references(
87 &pointcloud->mat, &pointcloud->totcol, data_block_map);
88 }
89 if (Volume *volume = geometry.get_volume_for_write()) {
90 volume->runtime->bake_materials = materials_to_weak_references(
91 &volume->mat, &volume->totcol, data_block_map);
92 }
93 if (bke::Instances *instances = geometry.get_instances_for_write()) {
94 instances->attributes_for_write().remove_anonymous();
95 }
96 geometry.keep_only_during_modify({GeometryComponent::Type::Mesh,
102 });
103}
104
105static void restore_materials(Material ***materials,
106 short *materials_num,
107 std::unique_ptr<BakeMaterialsList> materials_list,
108 BakeDataBlockMap *data_block_map)
109{
110 if (!materials_list) {
111 return;
112 }
113 BLI_assert(*materials == nullptr);
114 *materials_num = materials_list->size();
115 *materials = MEM_cnew_array<Material *>(materials_list->size(), __func__);
116 if (!data_block_map) {
117 return;
118 }
119
120 for (const int i : materials_list->index_range()) {
121 const std::optional<BakeDataBlockID> &data_block_id = (*materials_list)[i];
122 if (data_block_id) {
123 (*materials)[i] = reinterpret_cast<Material *>(
124 data_block_map->lookup_or_remember_missing(*data_block_id));
125 }
126 }
127}
128
129void GeometryBakeItem::try_restore_data_blocks(GeometrySet &main_geometry,
130 BakeDataBlockMap *data_block_map)
131{
132 main_geometry.modify_geometry_sets([&](GeometrySet &geometry) {
133 if (Mesh *mesh = geometry.get_mesh_for_write()) {
134 restore_materials(
135 &mesh->mat, &mesh->totcol, std::move(mesh->runtime->bake_materials), data_block_map);
136 }
137 if (Curves *curves = geometry.get_curves_for_write()) {
138 restore_materials(&curves->mat,
139 &curves->totcol,
140 std::move(curves->geometry.runtime->bake_materials),
141 data_block_map);
142 }
143 if (GreasePencil *grease_pencil = geometry.get_grease_pencil_for_write()) {
144 restore_materials(&grease_pencil->material_array,
145 &grease_pencil->material_array_num,
146 std::move(grease_pencil->runtime->bake_materials),
147 data_block_map);
148 }
149 if (PointCloud *pointcloud = geometry.get_pointcloud_for_write()) {
150 restore_materials(&pointcloud->mat,
151 &pointcloud->totcol,
152 std::move(pointcloud->runtime->bake_materials),
153 data_block_map);
154 }
155 if (Volume *volume = geometry.get_volume_for_write()) {
156 restore_materials(&volume->mat,
157 &volume->totcol,
158 std::move(volume->runtime->bake_materials),
159 data_block_map);
160 }
161 });
162}
163
164#ifdef WITH_OPENVDB
165VolumeGridBakeItem::VolumeGridBakeItem(std::unique_ptr<GVolumeGrid> grid) : grid(std::move(grid))
166{
167}
168
169VolumeGridBakeItem::~VolumeGridBakeItem() = default;
170
171void VolumeGridBakeItem::count_memory(MemoryCounter &memory) const
172{
173 if (grid && *grid) {
174 grid->get().count_memory(memory);
175 }
176}
177
178#endif
179
180PrimitiveBakeItem::PrimitiveBakeItem(const CPPType &type, const void *value) : type_(type)
181{
182 value_ = MEM_mallocN_aligned(type.size(), type.alignment(), __func__);
183 type.copy_construct(value, value_);
184}
185
187{
188 type_.destruct(value_);
189 MEM_freeN(value_);
190}
191
192StringBakeItem::StringBakeItem(std::string value) : value_(std::move(value)) {}
193
195{
196 memory.add(value_.size());
197}
198
200{
201 this->items_by_id.reserve(bake_state.items_by_id.size());
202 for (auto item : bake_state.items_by_id.items()) {
203 this->items_by_id.add_new(item.key, item.value.get());
204 }
205}
206
208{
209 for (const std::unique_ptr<BakeItem> &item : items_by_id.values()) {
210 if (item) {
211 item->count_memory(memory);
212 }
213 }
214}
215
216void BakeItem::count_memory(MemoryCounter & /*memory*/) const {}
217
218} // namespace blender::bke::bake
Low-level operations for curves.
Low-level operations for grease pencil.
General operations for point clouds.
Volume data-block.
#define BLI_assert(a)
Definition BLI_assert.h:50
#define MEM_SAFE_FREE(v)
void destruct(void *ptr) const
virtual void count_memory(MemoryCounter &memory) const
static void prepare_geometry_for_bake(GeometrySet &geometry, BakeDataBlockMap *data_block_map)
Definition bake_items.cc:57
GeometryBakeItem(GeometrySet geometry)
Definition bake_items.cc:26
void count_memory(MemoryCounter &memory) const override
Definition bake_items.cc:28
PrimitiveBakeItem(const CPPType &type, const void *value)
void count_memory(MemoryCounter &memory) const override
void * MEM_mallocN_aligned(size_t len, size_t alignment, const char *str)
Definition mallocn.cc:110
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
std::shared_ptr< DictionaryValue > DictionaryValuePtr
Definition bake_items.cc:24
static std::unique_ptr< BakeMaterialsList > materials_to_weak_references(Material ***materials, short *materials_num, BakeDataBlockMap *data_block_map)
Definition bake_items.cc:33
static void restore_materials(Material ***materials, short *materials_num, std::unique_ptr< BakeMaterialsList > materials_list, BakeDataBlockMap *data_block_map)
void modify_geometry_sets(ForeachSubGeometryCallback callback)
virtual void try_add(ID &id)=0
virtual ID * lookup_or_remember_missing(const BakeDataBlockID &key)=0
Map< int, const BakeItem * > items_by_id
Map< int, std::unique_ptr< BakeItem > > items_by_id
void count_memory(MemoryCounter &memory) const