124#define NO_ACTIVE_LAYER bke::AttrDomain::Auto
291 Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
297 return std::any_of(indices.begin(), indices.end(), [&](
const int i) { return data[i]; });
330 const int kb_act_idx = ob.
shapenr - 1;
338 for (
int i = 0; i < mesh.verts_num; i++) {
339 sub_v3_v3v3(offsets[i], new_positions[i], offsets[i]);
345 if ((currkey != kb) && (*dependent)[currkey_i]) {
355 &ob, kb,
reinterpret_cast<const float(*)[3]
>(new_positions.
data()));
360 const Span<std::unique_ptr<Node>> unodes,
363 Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
375 MutableSpan orig_positions = mesh.vert_positions_for_write();
378 for (const int node_i : range) {
379 Node &unode = *unodes[node_i];
380 const Span<int> verts = unode.vert_indices.as_span().take_front(unode.unique_verts_num);
381 for (const int i : verts.index_range()) {
382 std::swap(unode.position[i], eval_mut[verts[i]]);
385 modified_verts.fill_indices(verts, true);
393 for (const int node_i : range) {
394 Node &unode = *unodes[node_i];
395 const Span<int> verts = unode.vert_indices.as_span().take_front(unode.unique_verts_num);
396 for (const int i : verts.index_range()) {
397 std::swap(unode.orig_position[i], key_positions[verts[i]]);
405 mesh.vert_positions_for_write().copy_from(key_positions);
412 for (const int node_i : range) {
413 Node &unode = *unodes[node_i];
414 const Span<int> verts = unode.vert_indices.as_span().take_front(unode.unique_verts_num);
415 for (const int i : verts.index_range()) {
416 std::swap(unode.position[i], eval_mut[verts[i]]);
419 modified_verts.fill_indices(verts, true);
423 if (orig_positions.data() != eval_mut.data()) {
425 for (const int node_i : range) {
426 Node &unode = *unodes[node_i];
427 const Span<int> verts = unode.vert_indices.as_span().take_front(
428 unode.unique_verts_num);
429 for (const int i : verts.index_range()) {
430 std::swap(unode.orig_position[i], orig_positions[verts[i]]);
438 PositionDeformData position_data(
depsgraph,
object);
439 threading::EnumerableThreadSpecific<Vector<float3>> all_tls;
440 threading::parallel_for(unodes.index_range(), 1, [&](
const IndexRange range) {
441 Vector<float3> &translations = all_tls.local();
442 for (const int i : range) {
443 Node &unode = *unodes[i];
444 const Span<int> verts = unode.vert_indices.as_span().take_front(unode.unique_verts_num);
445 translations.resize(verts.size());
446 translations_from_new_positions(
447 unode.position.as_span().take_front(unode.unique_verts_num),
452 gather_data_mesh(position_data.eval,
454 unode.position.as_mutable_span().take_front(unode.unique_verts_num));
456 position_data.deform(translations, verts);
458 modified_verts.fill_indices(verts, true);
475 for (
const int offset : data.index_range()) {
476 std::swap(data[offset], undo_data[offset]);
487 Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
490 ".hide_vert", bke::AttrDomain::Point);
495 hide_vert.
span[vert] = !hide_vert.
span[vert];
496 modified_vertices[vert] =
true;
517 for (
const int j : a.index_range()) {
518 const bool value_a = a[j];
519 const bool value_b =
b[j];
530 Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
533 ".hide_poly", bke::AttrDomain::Face);
537 for (
const int i : face_indices.index_range()) {
538 const int face = face_indices[i];
541 hide_poly.
span[face] = !hide_poly.
span[face];
542 modified_faces[face] =
true;
550 Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
553 for (std::unique_ptr<Node> &unode : step_data.
nodes) {
554 if (color_attribute.
domain == bke::AttrDomain::Point && !unode->col.is_empty()) {
555 color::swap_gathered_colors(
556 unode->vert_indices.as_span().take_front(unode->unique_verts_num),
557 color_attribute.
span,
560 else if (color_attribute.
domain == bke::AttrDomain::Corner && !unode->loop_col.is_empty()) {
561 color::swap_gathered_colors(unode->corner_indices, color_attribute.
span, unode->loop_col);
564 modified_vertices.
fill_indices(unode->vert_indices.as_span(),
true);
576 ".sculpt_mask", bke::AttrDomain::Point);
580 for (
const int i : index.index_range()) {
581 const int vert = index[i];
582 if (mask.span[vert] != unode.
mask[i]) {
583 std::swap(mask.span[vert], unode.
mask[i]);
584 modified_vertices[vert] =
true;
605 for (
const int offset : data.index_range()) {
606 std::swap(data[offset], undo_data[offset]);
620 *
static_cast<Mesh *
>(
object.data));
621 bool modified =
false;
623 const int face = face_indices[i];
628 modified_face_set_faces[face] =
true;
646 if (step_data.
type == Type::Mask) {
649 const IndexMask node_mask = bke::pbvh::all_leaf_nodes(pbvh, memory);
663 Mesh *mesh =
static_cast<Mesh *
>(
object.data);
687 dyntopo::disable(C, &step_data);
712 dyntopo::disable(C,
nullptr);
719 const Mesh *mesh =
static_cast<const Mesh *
>(
object.data);
722 geometry->is_initialized =
true;
729 &mesh->corner_data, &geometry->corner_data,
CD_MASK_MESH.
lmask, mesh->corners_num);
732 implicit_sharing::copy_shared_pointer(mesh->face_offset_indices,
733 mesh->runtime->face_offsets_sharing_info,
734 &geometry->face_offset_indices,
735 &geometry->face_offsets_sharing_info);
737 geometry->totvert = mesh->verts_num;
738 geometry->totedge = mesh->edges_num;
739 geometry->totloop = mesh->corners_num;
740 geometry->faces_num = mesh->faces_num;
749 mesh->verts_num = geometry->totvert;
750 mesh->edges_num = geometry->totedge;
751 mesh->corners_num = geometry->totloop;
752 mesh->faces_num = geometry->faces_num;
753 mesh->totface_legacy = 0;
760 &geometry->corner_data, &mesh->corner_data,
CD_MASK_MESH.
lmask, geometry->totloop);
762 &geometry->face_data, &mesh->face_data,
CD_MASK_MESH.
pmask, geometry->faces_num);
763 implicit_sharing::copy_shared_pointer(geometry->face_offset_indices,
764 geometry->face_offsets_sharing_info,
765 &mesh->face_offset_indices,
766 &mesh->runtime->face_offsets_sharing_info);
775 implicit_sharing::free_shared_data(&geometry->face_offset_indices,
776 &geometry->face_offsets_sharing_info);
786 Mesh *mesh =
static_cast<Mesh *
>(
object.data);
805 switch (step_data.
type) {
806 case Type::DyntopoBegin:
811 case Type::DyntopoEnd:
858 bke::subdiv::eval_refine_from_mesh(
859 subdiv,
static_cast<const Mesh *
>(
object.data), deformed_verts);
885 if (step_data.
type == Type::None && step_data.
nodes.is_empty()) {
893 switch (step_data.
type) {
898 case Type::Position: {
900 const IndexMask node_mask = bke::pbvh::all_leaf_nodes(pbvh, memory);
912 Array<bool> modified_grids(subdiv_ccg.grids_num,
false);
913 for (std::unique_ptr<Node> &unode : step_data.
nodes) {
916 const IndexMask changed_nodes = IndexMask::from_predicate(
917 node_mask,
GrainSize(1), memory, [&](
const int i) {
928 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
932 const IndexMask changed_nodes = IndexMask::from_predicate(
933 node_mask,
GrainSize(1), memory, [&](
const int i) {
940 Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
941 mesh.tag_positions_changed();
945 Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
949 mesh.
runtime->corner_normals_cache.tag_dirty();
951 bke::pbvh::update_bounds(*
depsgraph,
object, pbvh);
952 bke::pbvh::store_bounds_orig(pbvh);
955 case Type::HideVert: {
957 const IndexMask node_mask = bke::pbvh::all_leaf_nodes(pbvh, memory);
967 Array<bool> modified_grids(subdiv_ccg.grids_num,
false);
968 for (std::unique_ptr<Node> &unode : step_data.
nodes) {
971 const IndexMask changed_nodes = IndexMask::from_predicate(
972 node_mask,
GrainSize(1), memory, [&](
const int i) {
979 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
981 for (std::unique_ptr<Node> &unode : step_data.
nodes) {
984 const IndexMask changed_nodes = IndexMask::from_predicate(
985 node_mask,
GrainSize(1), memory, [&](
const int i) {
992 bke::pbvh::update_visibility(
object, pbvh);
998 case Type::HideFace: {
1000 const IndexMask node_mask = bke::pbvh::all_leaf_nodes(pbvh, memory);
1007 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
1008 Array<bool> modified_faces(mesh.faces_num,
false);
1009 for (std::unique_ptr<Node> &unode : step_data.
nodes) {
1016 const IndexMask changed_nodes = IndexMask::from_predicate(
1017 node_mask,
GrainSize(1), memory, [&](
const int i) {
1019 const Span<int> faces = bke::pbvh::node_face_indices_calc_grids(
1020 subdiv_ccg, nodes[i], faces_vector);
1027 const IndexMask changed_nodes = IndexMask::from_predicate(
1028 node_mask,
GrainSize(1), memory, [&](
const int i) {
1034 hide::sync_all_from_faces(
object);
1035 bke::pbvh::update_visibility(
object, pbvh);
1040 const IndexMask node_mask = bke::pbvh::all_leaf_nodes(pbvh, memory);
1050 for (std::unique_ptr<Node> &unode : step_data.
nodes) {
1053 const IndexMask changed_nodes = IndexMask::from_predicate(
1054 node_mask,
GrainSize(1), memory, [&](
const int i) {
1057 bke::pbvh::update_mask_grids(*ss.
subdiv_ccg, changed_nodes, pbvh);
1062 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
1063 Array<bool> modified_verts(mesh.verts_num,
false);
1064 for (std::unique_ptr<Node> &unode : step_data.
nodes) {
1067 const IndexMask changed_nodes = IndexMask::from_predicate(
1068 node_mask,
GrainSize(1), memory, [&](
const int i) {
1071 bke::pbvh::update_mask_mesh(mesh, changed_nodes, pbvh);
1076 case Type::FaceSet: {
1078 const IndexMask node_mask = bke::pbvh::all_leaf_nodes(pbvh, memory);
1085 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
1086 Array<bool> modified_faces(mesh.faces_num,
false);
1087 for (std::unique_ptr<Node> &unode : step_data.
nodes) {
1093 const IndexMask changed_nodes = IndexMask::from_predicate(
1094 node_mask,
GrainSize(1), memory, [&](
const int i) {
1096 const Span<int> faces = bke::pbvh::node_face_indices_calc_grids(
1097 subdiv_ccg, nodes[i], faces_vector);
1104 const IndexMask changed_nodes = IndexMask::from_predicate(
1105 node_mask,
GrainSize(1), memory, [&](
const int i) {
1114 const IndexMask node_mask = bke::pbvh::all_leaf_nodes(pbvh, memory);
1123 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
1124 Array<bool> modified_verts(mesh.verts_num,
false);
1126 const IndexMask changed_nodes = IndexMask::from_predicate(
1127 node_mask,
GrainSize(1), memory, [&](
const int i) {
1133 case Type::Geometry: {
1143 case Type::DyntopoBegin:
1144 case Type::DyntopoEnd:
1164 step_data.~StepData();
1179 if (step_data->
type != type) {
1189 return node_ptr->get();
1201 const Span<int> grid_indices = node.grids();
1204 unode.
grid_hidden[i].copy_from(grid_hidden[grid_indices[i]]);
1216 unode.
normal.as_mutable_span());
1219 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
1223 mesh.vert_positions();
1235 subdiv_ccg, subdiv_ccg.
normals.as_span(), unode.
grids, unode.
normal.as_mutable_span());
1242 bke::AttrDomain::Point);
1248 for (
const int i :
verts.index_range()) {
1256 const VArraySpan<bool> hide_poly = *attributes.lookup<
bool>(
".hide_poly", bke::AttrDomain::Face);
1262 for (
const int i : faces.index_range()) {
1270 const VArraySpan mask = *attributes.lookup<
float>(
".sculpt_mask", bke::AttrDomain::Point);
1271 if (mask.is_empty()) {
1293 const Span<int> corner_verts = mesh.corner_verts();
1301 unode.
col.reinitialize(
verts.size());
1302 color::gather_colors_vert(
1303 faces, corner_verts, vert_to_face_map, colors, color_attribute.
domain,
verts, unode.
col);
1305 if (color_attribute.
domain == bke::AttrDomain::Corner) {
1306 for (
const int face : node.faces()) {
1307 for (
const int corner : faces[face]) {
1331 step_data->
type = Type::Geometry;
1343 const VArraySpan face_sets = *attributes.lookup<
int>(
".sculpt_face_set", bke::AttrDomain::Face);
1359 const Mesh &mesh = *
static_cast<Mesh *
>(
object.data);
1366 const bool need_faces =
ELEM(type, Type::FaceSet, Type::HideFace);
1375 case Type::Position: {
1376 unode.
position.reinitialize(verts_num);
1378 unode.
normal.reinitialize(verts_num);
1385 case Type::HideVert: {
1390 case Type::HideFace: {
1404 case Type::DyntopoBegin:
1405 case Type::DyntopoEnd:
1409 case Type::Geometry:
1413 case Type::FaceSet: {
1427 const Mesh &base_mesh = *
static_cast<const Mesh *
>(
object.data);
1430 unode.
grids = node.grids();
1433 const int verts_num = unode.
grids.
size() * grid_area;
1435 const bool need_faces =
ELEM(type, Type::FaceSet, Type::HideFace);
1437 bke::pbvh::node_face_indices_calc_grids(subdiv_ccg, node, unode.
face_indices);
1444 case Type::Position: {
1445 unode.
position.reinitialize(verts_num);
1447 unode.
normal.reinitialize(verts_num);
1451 case Type::HideVert: {
1455 case Type::HideFace: {
1469 case Type::DyntopoBegin:
1470 case Type::DyntopoEnd:
1474 case Type::Geometry:
1478 case Type::FaceSet: {
1499 Node *unode = step_data->
nodes.is_empty() ? nullptr : step_data->
nodes.first().get();
1501 if (unode ==
nullptr) {
1502 step_data->
nodes.append(std::make_unique<Node>());
1503 unode = step_data->
nodes.last().get();
1505 step_data->
type = type;
1508 if (type == Type::DyntopoEnd) {
1512 else if (type == Type::DyntopoBegin) {
1540 case Type::Position:
1552 case Type::HideFace:
1553 case Type::HideVert: {
1567 case Type::DyntopoBegin:
1568 case Type::DyntopoEnd:
1569 case Type::Geometry:
1586 std::unique_ptr<Node> unode = std::make_unique<Node>();
1600 if (ss.
bm ||
ELEM(type, Type::DyntopoBegin, Type::DyntopoEnd)) {
1607 step_data->
type = type;
1618 switch (pbvh.
type()) {
1619 case bke::pbvh::Type::Mesh:
1623 case bke::pbvh::Type::Grids:
1626 case bke::pbvh::Type::BMesh:
1642 if (ss.
bm ||
ELEM(type, Type::DyntopoBegin, Type::DyntopoEnd)) {
1650 step_data->
type = type;
1652 switch (pbvh.
type()) {
1653 case bke::pbvh::Type::Mesh: {
1660 nodes_to_fill.append({&nodes[i], unode});
1663 threading::parallel_for(nodes_to_fill.index_range(), 1, [&](
const IndexRange range) {
1664 for (const auto &[node, unode] : nodes_to_fill.as_span().slice(range)) {
1665 fill_node_data_mesh(depsgraph, object, *node, type, *unode);
1670 case bke::pbvh::Type::Grids: {
1677 nodes_to_fill.append({&nodes[i], unode});
1680 threading::parallel_for(nodes_to_fill.index_range(), 1, [&](
const IndexRange range) {
1681 for (const auto &[node, unode] : nodes_to_fill.as_span().slice(range)) {
1682 fill_node_data_grids(object, *node, type, *unode);
1687 case bke::pbvh::Type::BMesh: {
1703 const char *name = mesh->active_color_attribute;
1705 const std::optional<bke::AttributeMetaData> meta_data = attributes.
lookup_meta_data(name);
1714 attr->
domain = meta_data->domain;
1716 attr->
type = meta_data->data_type;
1750 switch (pbvh.
type()) {
1751 case bke::pbvh::Type::Mesh: {
1752 const Mesh &mesh = *
static_cast<const Mesh *
>(ob.
data);
1757 case bke::pbvh::Type::Grids: {
1762 case bke::pbvh::Type::BMesh: {
1783 size_t size =
sizeof(
Node);
1784 size += node.position.as_span().size_in_bytes();
1785 size += node.orig_position.as_span().size_in_bytes();
1786 size += node.normal.as_span().size_in_bytes();
1787 size += node.col.as_span().size_in_bytes();
1788 size += node.mask.as_span().size_in_bytes();
1789 size += node.loop_col.as_span().size_in_bytes();
1790 size += node.vert_indices.as_span().size_in_bytes();
1791 size += node.corner_indices.as_span().size_in_bytes();
1792 size += node.vert_hidden.size() / 8;
1793 size += node.face_hidden.size() / 8;
1794 size += node.grids.as_span().size_in_bytes();
1795 size += node.grid_hidden.all_bits().size() / 8;
1796 size += node.face_sets.as_span().size_in_bytes();
1797 size += node.face_indices.as_span().size_in_bytes();
1808 step_data->
nodes.append(std::move(node));
1813 for (std::unique_ptr<Node> &unode : step_data->
nodes) {
1817 step_data->
undo_size = threading::parallel_reduce(
1818 step_data->
nodes.index_range(),
1822 for (const int i : range) {
1823 size += node_size_in_bytes(*step_data->nodes[i]);
1827 std::plus<size_t>());
1831 if (wm->op_undo_depth == 0 || use_nested_undo) {
1834 if (wm->op_undo_depth == 0) {
1844 save_active_attribute(ob, &us->active_color_end);
1858 if (attr->
domain == bke::AttrDomain::Auto) {
1893 mesh->attributes_for_write().add(
1918 if (unode && us->
data.
type == Type::DyntopoEnd) {
1949 const bool is_final)
1961 while ((us_iter != us) || (!is_final && us_iter == us)) {
1967 if (us_iter == us) {
1991 if (us_iter == us) {
2018 object::mode_generic_exit(bmain,
depsgraph, scene, ob);
2028 mesh->
flag &= ~ME_SCULPT_DYNAMIC_TOPOLOGY;
2078 ut->
name =
"Sculpt";
2137 if (pbvh ==
nullptr) {
2142 const IndexMask node_mask = bke::pbvh::all_leaf_nodes(*pbvh, memory);
2190 return std::nullopt;
2200 return std::nullopt;
2203 result->normals.
take_front(node.verts().size())};
2211 return std::nullopt;
2226 if (!positions.is_empty()) {
2229 if (!normals.is_empty()) {
2241 return std::nullopt;
2243 return unode->
col.as_span();
2251 return std::nullopt;
2261 return std::nullopt;
2271 return std::nullopt;
2281 return std::nullopt;
struct CustomDataLayer * BKE_attribute_search_for_write(AttributeOwner &owner, const char *name, eCustomDataMask type, AttrDomainMask domain_mask)
void BKE_id_attributes_active_color_set(struct ID *id, const char *name)
struct CustomDataLayer * BKE_attribute_find(const AttributeOwner &owner, const char *name, eCustomDataType type, blender::bke::AttrDomain domain)
#define ATTR_DOMAIN_MASK_COLOR
#define ATTR_DOMAIN_AS_MASK(domain)
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
RegionView3D * CTX_wm_region_view3d(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
void CustomData_init_from(const CustomData *source, CustomData *dest, eCustomDataMask mask, int totelem)
void CustomData_free(CustomData *data, int totelem)
#define CD_TYPE_AS_MASK(_type)
const CustomData_MeshMasks CD_MASK_MESH
KeyBlock * BKE_keyblock_from_object(Object *ob)
void BKE_keyblock_update_from_offset(const Object *ob, KeyBlock *kb, const float(*ofs)[3])
KeyBlock * BKE_keyblock_find_name(Key *key, const char name[])
std::optional< blender::Array< bool > > BKE_keyblock_get_dependent_keys(const Key *key, int index)
void BKE_keyblock_update_from_vertcos(const Object *ob, KeyBlock *kb, const float(*vertCos)[3])
Key * BKE_key_from_object(Object *ob)
float(* BKE_keyblock_convert_to_vertcos(const Object *ob, const KeyBlock *kb))[3]
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
void BKE_mesh_clear_geometry(Mesh *mesh)
blender::Array< blender::float3 > BKE_multires_create_deformed_base_mesh_vert_coords(Depsgraph *depsgraph, Object *object, MultiresModifierData *mmd)
void multires_mark_as_modified(Depsgraph *depsgraph, Object *object, MultiresModifiedFlags flags)
General operations, lookup, etc. for blender objects.
Mesh * BKE_object_get_original_mesh(const Object *object)
bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const RegionView3D *rv3d)
void BKE_sculptsession_free_deformMats(SculptSession *ss)
MultiresModifierData * BKE_sculpt_multires_active(const Scene *scene, Object *ob)
void BKE_sculpt_update_object_for_edit(Depsgraph *depsgraph, Object *ob_orig, bool is_paint_tool)
void BKE_sculptsession_free_pbvh(Object &object)
PaintMode BKE_paintmode_get_active_from_context(const bContext *C)
const blender::Set< BMFace *, 0 > & BKE_pbvh_bmesh_node_faces(blender::bke::pbvh::BMeshNode *node)
const blender::Set< BMVert *, 0 > & BKE_pbvh_bmesh_node_unique_verts(blender::bke::pbvh::BMeshNode *node)
const blender::Set< BMVert *, 0 > & BKE_pbvh_bmesh_node_other_verts(blender::bke::pbvh::BMeshNode *node)
void BKE_pbvh_sync_visibility_from_verts(Object &object)
void BKE_scene_graph_evaluated_ensure(Depsgraph *depsgraph, Main *bmain)
CCGKey BKE_subdiv_ccg_key_top_level(const SubdivCCG &subdiv_ccg)
blender::BitGroupVector & BKE_subdiv_ccg_grid_hidden_ensure(SubdivCCG &subdiv_ccg)
void BKE_subdiv_ccg_grid_hidden_free(SubdivCCG &subdiv_ccg)
@ MULTIRES_HIDDEN_MODIFIED
@ MULTIRES_COORDS_MODIFIED
@ UNDOTYPE_FLAG_DECODE_ACTIVE_STEP
const UndoType * BKE_UNDOSYS_TYPE_SCULPT
eUndoPushReturn BKE_undosys_step_push(UndoStack *ustack, bContext *C, const char *name)
UndoStep * BKE_undosys_step_push_init_with_type(UndoStack *ustack, bContext *C, const char *name, const UndoType *ut)
#define BKE_undosys_stack_limit_steps_and_memory_defaults(ustack)
UndoStep * BKE_undosys_stack_init_or_active_with_type(UndoStack *ustack, const UndoType *ut)
#define BLI_assert_unreachable()
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
#define STRNCPY(dst, src)
void DEG_id_tag_update(ID *id, unsigned int flags)
#define ID_REAL_USERS(id)
#define MAX_CUSTOMDATA_LAYER_NAME
#define CD_MASK_COLOR_ALL
@ ME_SCULPT_DYNAMIC_TOPOLOGY
Object is a sort of wrapper for general info.
void ED_undo_push(bContext *C, const char *str)
UndoStack * ED_undo_stack_get()
void ED_undosys_stack_memfile_id_changed_tag(UndoStack *ustack, ID *id)
Read Guarded memory(de)allocation.
void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *name)
void BM_log_all_added(BMesh *bm, BMLog *log)
void BM_log_original_vert_data(BMLog *log, BMVert *v, const float **r_co, const float **r_no)
void BM_log_face_modified(BMLog *log, BMFace *f)
void BM_log_redo(BMesh *bm, BMLog *log)
void BM_log_vert_before_modified(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
void BM_log_entry_drop(BMLogEntry *entry)
BMLog * BM_log_from_existing_entries_create(BMesh *bm, BMLogEntry *entry)
void BM_log_undo(BMesh *bm, BMLog *log)
void BM_log_before_all_removed(BMesh *bm, BMLog *log)
BMLogEntry * BM_log_entry_add(BMLog *log)
const BMAllocTemplate bm_mesh_allocsize_default
BMesh * BM_mesh_create(const BMAllocTemplate *allocsize, const BMeshCreateParams *params)
BMesh Make Mesh.
void BM_mesh_normals_update(BMesh *bm)
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static AttributeOwner from_id(ID *id)
Span< T > as_span() const
MutableSpan< T > as_mutable_span()
IndexRange index_range() const
void fill(const T &value) const
void reinitialize(const int64_t new_size)
constexpr IndexRange take_front(int64_t n) const
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr void fill_indices(Span< IndexT > indices, const T &value) const
constexpr const T * data() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr Span take_front(int64_t n) const
constexpr bool is_empty() const
void append(const T &value)
Span< T > as_span() const
int64_t group_size() const
std::optional< AttributeMetaData > lookup_meta_data(const StringRef attribute_id) const
void tag_attribute_changed(const IndexMask &node_mask, StringRef attribute_name)
void tag_positions_changed(const IndexMask &node_mask)
Span< NodeT > nodes() const
void tag_face_sets_changed(const IndexMask &node_mask)
void tag_masks_changed(const IndexMask &node_mask)
void tag_visibility_changed(const IndexMask &node_mask)
void foreach_index(Fn &&fn) const
local_group_size(16, 16) .push_constant(Type b
const Depsgraph * depsgraph
draw_view in_light_buf[] float
bool ED_geometry_attribute_convert(Mesh *mesh, const char *name, const eCustomDataType dst_type, const blender::bke::AttrDomain dst_domain, ReportList *reports)
void MEM_freeN(void *vmemh)
MutableSpan< float3 > vert_positions_eval_for_write(const Depsgraph &depsgraph, Object &object_orig)
static void save_active_attribute(Object &object, SculptAttrRef *attr)
void push_end(Object &ob)
void push_nodes(const Depsgraph &depsgraph, Object &object, const IndexMask &node_mask, const Type type)
static void store_vert_visibility_grids(const SubdivCCG &subdiv_ccg, const bke::pbvh::GridsNode &node, Node &unode)
static bool use_multires_mesh(bContext *C)
static void geometry_push(const Object &object)
static void store_positions_grids(const SubdivCCG &subdiv_ccg, Node &unode)
static BLI_NOINLINE void bmesh_push(const Object &object, const bke::pbvh::BMeshNode *node, Type type)
static void free_step_data(StepData &step_data)
void push_multires_mesh_begin(bContext *C, const char *str)
void push_multires_mesh_end(bContext *C, const char *str)
static void fill_node_data_mesh(const Depsgraph &depsgraph, const Object &object, const bke::pbvh::MeshNode &node, const Type type, Node &unode)
static size_t node_size_in_bytes(const Node &node)
static bool topology_matches(const StepData &step_data, const Object &object)
static SculptUndoStep * get_active_step()
static void store_face_visibility(const Mesh &mesh, Node &unode)
static void step_encode_init(bContext *, UndoStep *us_p)
static void restore_mask_grids(Object &object, Node &unode, MutableSpan< bool > modified_grids)
void push_node(const Depsgraph &depsgraph, const Object &object, const bke::pbvh::Node *node, Type type)
static bool use_multires_undo(const StepData &step_data, const SculptSession &ss)
void push_begin_ex(const Scene &, Object &ob, const char *name)
static void step_decode_redo_impl(bContext *C, Depsgraph *depsgraph, SculptUndoStep *us)
static void restore_geometry_data(const NodeGeometry *geometry, Mesh *mesh)
static void restore_vert_visibility_grids(SubdivCCG &subdiv_ccg, Node &unode, MutableSpan< bool > modified_grids)
static StepData * get_step_data()
static void store_vert_visibility_mesh(const Mesh &mesh, const bke::pbvh::Node &node, Node &unode)
static void restore_mask_mesh(Object &object, Node &unode, MutableSpan< bool > modified_vertices)
static void store_mask_grids(const SubdivCCG &subdiv_ccg, Node &unode)
static NodeGeometry * geometry_get(StepData &step_data)
static void store_positions_mesh(const Depsgraph &depsgraph, const Object &object, Node &unode)
static void fill_node_data_grids(const Object &object, const bke::pbvh::GridsNode &node, const Type type, Node &unode)
static void geometry_free_data(NodeGeometry *geometry)
static void step_decode_undo(bContext *C, Depsgraph *depsgraph, SculptUndoStep *us, const bool is_final)
void geometry_begin_ex(const Scene &scene, Object &ob, const char *name)
static void step_free(UndoStep *us_p)
void register_type(UndoType *ut)
static int bmesh_restore(bContext *C, Depsgraph &depsgraph, StepData &step_data, Object &object, SculptSession &ss)
static const Node * get_node(const bke::pbvh::Node *node, const Type type)
static bool step_encode(bContext *, Main *bmain, UndoStep *us_p)
static bool indices_contain_true(const Span< bool > data, const Span< int > indices)
static Node * ensure_node(StepData &step_data, const bke::pbvh::Node &node, bool &r_new)
void geometry_begin(const Scene &scene, Object &ob, const wmOperator *op)
static void restore_position_grids(MutableSpan< float3 > positions, const CCGKey &key, Node &unode, MutableSpan< bool > modified_grids)
static void step_decode_undo_impl(bContext *C, Depsgraph *depsgraph, SculptUndoStep *us)
static void restore_list(bContext *C, Depsgraph *depsgraph, StepData &step_data)
void geometry_end(Object &ob)
static void restore_hidden_face(Object &object, Node &unode, MutableSpan< bool > modified_faces)
static void step_decode_redo(bContext *C, Depsgraph *depsgraph, SculptUndoStep *us)
static void store_geometry_data(NodeGeometry *geometry, const Object &object)
static void store_mask_mesh(const Mesh &mesh, Node &unode)
static void bmesh_restore_generic(StepData &step_data, Object &object, SculptSession &ss)
static void restore_position_mesh(const Depsgraph &depsgraph, Object &object, const Span< std::unique_ptr< Node > > unodes, MutableSpan< bool > modified_verts)
static bool restore_active_shape_key(bContext &C, Depsgraph &depsgraph, const StepData &step_data, Object &object)
static void refine_subdiv(Depsgraph *depsgraph, SculptSession &ss, Object &object, bke::subdiv::Subdiv *subdiv)
static void store_color(const Mesh &mesh, const bke::pbvh::MeshNode &node, Node &unode)
static void update_shapekeys(const Object &ob, KeyBlock *kb, const Span< float3 > new_positions)
static void restore_vert_visibility_mesh(Object &object, Node &unode, MutableSpan< bool > modified_vertices)
void push_begin(const Scene &scene, Object &ob, const wmOperator *op)
static void bmesh_enable(Object &object, StepData &step_data)
static void bmesh_restore_end(bContext *C, StepData &step_data, Object &object, SculptSession &ss)
void restore_from_bmesh_enter_geometry(const StepData &step_data, Mesh &mesh)
static void store_face_sets(const Mesh &mesh, Node &unode)
static void step_decode(bContext *C, Main *bmain, UndoStep *us_p, const eUndoStepDir dir, bool is_final)
static void restore_color(Object &object, StepData &step_data, MutableSpan< bool > modified_vertices)
BMLogEntry * get_bmesh_log_entry()
static bool restore_face_sets(Object &object, Node &unode, MutableSpan< bool > modified_face_set_faces)
static void push_all_grids(const Depsgraph &depsgraph, Object *object)
void push_end_ex(Object &ob, const bool use_nested_undo)
static void restore_geometry(StepData &step_data, Object &object)
static void bmesh_restore_begin(bContext *C, StepData &step_data, Object &object, SculptSession &ss)
static void set_active_layer(bContext *C, SculptAttrRef *attr)
void object_sculpt_mode_enter(Main &bmain, Depsgraph &depsgraph, Scene &scene, Object &ob, bool force_dyntopo, ReportList *reports)
std::optional< Span< float > > orig_mask_data_lookup_grids(const Object &object, const bke::pbvh::GridsNode &node)
std::optional< Span< int > > orig_face_set_data_lookup_mesh(const Object &object, const bke::pbvh::MeshNode &node)
void gather_data_grids(const SubdivCCG &subdiv_ccg, Span< T > src, Span< int > grids, MutableSpan< T > node_data)
std::optional< OrigPositionData > orig_position_data_lookup_grids(const Object &object, const bke::pbvh::GridsNode &node)
void orig_position_data_gather_bmesh(const BMLog &bm_log, const Set< BMVert *, 0 > &verts, MutableSpan< float3 > positions, MutableSpan< float3 > normals)
std::optional< Span< float4 > > orig_color_data_lookup_mesh(const Object &object, const bke::pbvh::MeshNode &node)
void gather_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
std::optional< Span< float > > orig_mask_data_lookup_mesh(const Object &object, const bke::pbvh::MeshNode &node)
std::optional< OrigPositionData > orig_position_data_lookup_mesh_all_verts(const Object &object, const bke::pbvh::MeshNode &node)
std::optional< OrigPositionData > orig_position_data_lookup_mesh(const Object &object, const bke::pbvh::MeshNode &node)
std::optional< Span< int > > orig_face_set_data_lookup_grids(const Object &object, const bke::pbvh::GridsNode &node)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
bool is_memfile_undo_flush_needed
MeshRuntimeHandle * runtime
struct SculptSession * sculpt
KeyBlock * shapekey_active
blender::float4 pivot_rot
blender::float3 pivot_pos
struct SculptSession::@48 multires
MultiresModifierData * modifier
bool deform_modifiers_active
blender::Array< blender::float3 > normals
blender::BitGroupVector grid_hidden
blender::Array< float > masks
blender::Array< blender::float3 > positions
void(* step_encode_init)(bContext *C, UndoStep *us)
void(* step_free)(UndoStep *us)
bool(* poll)(struct bContext *C)
void(* step_decode)(bContext *C, Main *bmain, UndoStep *us, eUndoStepDir dir, bool is_final)
bool(* step_encode)(bContext *C, Main *bmain, UndoStep *us)
MutableVArraySpan< T > span
int * face_offset_indices
const ImplicitSharingInfo * face_offsets_sharing_info
Array< float3, 0 > orig_position
Vector< int > face_indices
BitGroupVector< 0 > grid_hidden
Array< float3, 0 > normal
BitVector< 0 > face_hidden
Array< int, 0 > vert_indices
Array< float4, 0 > loop_col
Array< int, 0 > face_sets
BitVector< 0 > vert_hidden
Array< float3, 0 > position
Vector< int, 0 > corner_indices
char name[MAX_CUSTOMDATA_LAYER_NAME]
SculptAttrRef active_color_start
SculptAttrRef active_color_end
Vector< std::unique_ptr< Node > > nodes
NodeGeometry geometry_original
std::string active_shape_key_name
NodeGeometry geometry_bmesh_enter
Map< const bke::pbvh::Node *, std::unique_ptr< Node > > undo_nodes_by_pbvh_node
NodeGeometry geometry_modified
struct wmOperatorType * type
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
void WM_file_tag_modified()