14#define DNA_DEPRECATED_ALLOW
79#define STACK_FIXED_DEPTH 100
94 Mesh *mesh =
reinterpret_cast<Mesh *
>(id);
113 std::optional<Library *> owner_library,
118 Mesh *mesh_dst =
reinterpret_cast<Mesh *
>(id_dst);
119 const Mesh *mesh_src =
reinterpret_cast<const Mesh *
>(id_src);
122 mesh_dst->
runtime->deformed_only = mesh_src->
runtime->deformed_only;
126 mesh_src->
runtime->wrapper_type;
127 mesh_dst->
runtime->subsurf_runtime_data = mesh_src->
runtime->subsurf_runtime_data;
128 mesh_dst->
runtime->cd_mask_extra = mesh_src->
runtime->cd_mask_extra;
132 mesh_dst->
runtime->subsurf_face_dot_tags = mesh_src->
runtime->subsurf_face_dot_tags;
133 mesh_dst->
runtime->subsurf_optimal_display_edges =
134 mesh_src->
runtime->subsurf_optimal_display_edges;
137 mesh_dst->
runtime->deformed_only =
true;
148 mesh_dst->
runtime->is_original_bmesh =
false;
153 mesh_dst->
runtime->bounds_cache = mesh_src->
runtime->bounds_cache;
154 mesh_dst->
runtime->vert_normals_cache = mesh_src->
runtime->vert_normals_cache;
155 mesh_dst->
runtime->vert_normals_true_cache = mesh_src->
runtime->vert_normals_true_cache;
156 mesh_dst->
runtime->face_normals_cache = mesh_src->
runtime->face_normals_cache;
157 mesh_dst->
runtime->face_normals_true_cache = mesh_src->
runtime->face_normals_true_cache;
158 mesh_dst->
runtime->corner_normals_cache = mesh_src->
runtime->corner_normals_cache;
159 mesh_dst->
runtime->loose_verts_cache = mesh_src->
runtime->loose_verts_cache;
160 mesh_dst->
runtime->verts_no_face_cache = mesh_src->
runtime->verts_no_face_cache;
161 mesh_dst->
runtime->loose_edges_cache = mesh_src->
runtime->loose_edges_cache;
162 mesh_dst->
runtime->corner_tris_cache = mesh_src->
runtime->corner_tris_cache;
163 mesh_dst->
runtime->corner_tri_faces_cache = mesh_src->
runtime->corner_tri_faces_cache;
164 mesh_dst->
runtime->vert_to_face_offset_cache = mesh_src->
runtime->vert_to_face_offset_cache;
165 mesh_dst->
runtime->vert_to_face_map_cache = mesh_src->
runtime->vert_to_face_map_cache;
166 mesh_dst->
runtime->vert_to_corner_map_cache = mesh_src->
runtime->vert_to_corner_map_cache;
167 mesh_dst->
runtime->corner_to_face_map_cache = mesh_src->
runtime->corner_to_face_map_cache;
168 mesh_dst->
runtime->bvh_cache_verts = mesh_src->
runtime->bvh_cache_verts;
169 mesh_dst->
runtime->bvh_cache_edges = mesh_src->
runtime->bvh_cache_edges;
170 mesh_dst->
runtime->bvh_cache_faces = mesh_src->
runtime->bvh_cache_faces;
171 mesh_dst->
runtime->bvh_cache_corner_tris = mesh_src->
runtime->bvh_cache_corner_tris;
172 mesh_dst->
runtime->bvh_cache_corner_tris_no_hidden =
173 mesh_src->
runtime->bvh_cache_corner_tris_no_hidden;
174 mesh_dst->
runtime->bvh_cache_loose_verts = mesh_src->
runtime->bvh_cache_loose_verts;
175 mesh_dst->
runtime->bvh_cache_loose_verts_no_hidden =
176 mesh_src->
runtime->bvh_cache_loose_verts_no_hidden;
177 mesh_dst->
runtime->bvh_cache_loose_edges = mesh_src->
runtime->bvh_cache_loose_edges;
178 mesh_dst->
runtime->bvh_cache_loose_edges_no_hidden =
179 mesh_src->
runtime->bvh_cache_loose_edges_no_hidden;
180 mesh_dst->
runtime->max_material_index = mesh_src->
runtime->max_material_index;
181 if (mesh_src->
runtime->bake_materials) {
182 mesh_dst->
runtime->bake_materials = std::make_unique<blender::bke::bake::BakeMaterialsList>(
183 *mesh_src->
runtime->bake_materials);
199 mesh_dst->
runtime->edit_data = std::make_unique<blender::bke::EditMeshData>(*edit_data);
226 mesh_src->
runtime->face_offsets_sharing_info,
228 &mesh_dst->
runtime->face_offsets_sharing_info);
244 reinterpret_cast<ID **
>(&mesh_dst->
key),
251 Mesh *mesh =
reinterpret_cast<Mesh *
>(id);
266 &mesh->
runtime->face_offsets_sharing_info);
275 Mesh *mesh =
reinterpret_cast<Mesh *
>(id);
286 Mesh *mesh =
reinterpret_cast<Mesh *
>(id);
296 Mesh *mesh =
reinterpret_cast<Mesh *
>(id);
301 auto convert_domain = [&fn](
CustomData *customdata,
size_t size) {
335 mesh->mface =
nullptr;
336 mesh->totface_legacy = 0;
342 mesh->active_uv_map_attribute =
const_cast<char *
>(
346 mesh->active_uv_map_attribute =
nullptr;
349 mesh->default_uv_map_attribute =
const_cast<char *
>(
353 mesh->default_uv_map_attribute =
nullptr;
364 mesh->corners_num = 0;
369 mesh->face_offset_indices =
nullptr;
383 attribute_data,
mesh->edge_data,
mesh->face_data, edge_layers, face_layers);
386 mesh->attribute_storage.dna_attributes =
nullptr;
387 mesh->attribute_storage.dna_attributes_num = 0;
390 mesh->attribute_storage.dna_attributes = attribute_data.
attributes.data();
391 mesh->attribute_storage.dna_attributes_num = attribute_data.
attributes.size();
396 mesh->runtime =
nullptr;
424 mesh->attribute_storage.wrap().blend_write(*writer, attribute_data);
426 if (
mesh->face_offset_indices) {
429 mesh->face_offset_indices,
430 sizeof(
int) *
mesh->faces_num,
432 [&]() { BLO_write_int32_array(writer, mesh->faces_num + 1, mesh->face_offset_indices); });
464 mesh->attribute_storage.wrap().blend_read(*reader);
465 if (
mesh->deform_verts().is_empty()) {
482 if (
mesh->face_offset_indices) {
484 reader, &
mesh->face_offset_indices, [&]() {
485 BLO_read_int32_array(reader, mesh->faces_num + 1, &mesh->face_offset_indices);
486 return blender::implicit_sharing::info_for_mem_free(mesh->face_offset_indices);
490 if (
mesh->mselect ==
nullptr) {
532 return ELEM(
name,
"position",
".corner_vert",
".corner_edge",
".edge_verts");
537 BMesh *
bm =
mesh->runtime->edit_mesh ?
mesh->runtime->edit_mesh->bm :
nullptr;
570 if (
mesh->runtime->edit_mesh) {
575 return mesh->attributes().contains(
"custom_normal");
593 if (
mesh.default_color_attribute) {
613 const eCustomDataMask
types)
651 return {
float3(std::numeric_limits<float>::max()),
float3(std::numeric_limits<float>::lowest())};
670 int target_group_size)
674 groups[node_index].children_offset = 0;
676 std::copy(face_indices.
begin(), face_indices.
end(), groups[node_index].faces.
begin());
681 const int children_start = groups.
size();
682 groups[node_index].children_offset = children_start;
685 groups[children_start].parent = node_index;
686 groups[children_start + 1].parent = node_index;
691 if (bounds_precalc) {
700 for (
const int face : face_indices.
slice(range)) {
741 if (groups[
i].children_offset == 0 && !groups[
i].
faces.is_empty()) {
750 for (const int i : range) {
751 const int group_idx = leaf_indices[i];
752 NonContiguousGroup &group = groups[group_idx];
754 int corners_count = 0;
756 for (const int face_index : group.faces) {
757 const IndexRange face = faces[face_index];
758 verts.add_multiple(corner_verts.slice(face));
759 corners_count += face.size();
762 new (&verts_per_leaf[i]) Array<int>(verts.size());
763 std::copy(verts.begin(), verts.end(), verts_per_leaf[i].begin());
764 std::sort(verts_per_leaf[i].begin(), verts_per_leaf[i].end());
765 group.corner_count = corners_count;
773 for (
const int i : leaf_indices.index_range()) {
774 const int group_idx = leaf_indices[
i];
777 shared_verts.
clear();
779 for (
const int vert : verts_per_leaf[
i]) {
780 if (vert_used[vert]) {
781 shared_verts.
append(vert);
784 vert_used[vert].set();
807 if (
faces.is_empty()) {
818 for (
const int face : range) {
820 vert_positions, corner_verts.
slice(
faces[face]));
821 face_centers[face] =
bounds.center();
833 groups[0].parent = -1;
834 groups[0].children_offset = 0;
840 face_centers, prim_face_indices, groups, 0, 0,
bounds, material_index, 2500);
860 group_unique_offsets.
reserve(local_groups.
size() + 1);
861 group_unique_offsets.
append(0);
864 group_face_offsets.
reserve(local_groups.
size() + 1);
865 group_face_offsets.
append(0);
867 for (
const int group_index : local_groups.
index_range()) {
871 if (!added_verts[vert_idx]) {
872 new_vert_order.
append(vert_idx);
873 added_verts[vert_idx].set();
876 group_unique_offsets.
append(new_vert_order.
size());
879 if (!added_verts[vert_idx]) {
880 new_vert_order.
append(vert_idx);
881 added_verts[vert_idx].set();
885 for (
const int face_idx : local_group.
faces) {
886 new_face_order.
append(face_idx);
888 group_face_offsets.
append(new_face_order.
size());
892 if (!added_verts[vert]) {
893 new_vert_order.
append(vert);
894 added_verts[vert].set();
900 vert_reverse_map[new_vert_order[
i]] =
i;
904 for (
int2 &edge : edges) {
905 edge.x = vert_reverse_map[edge.x];
906 edge.y = vert_reverse_map[edge.y];
913 int new_corner_idx = 0;
914 for (
const int old_face_idx : new_face_order) {
915 const IndexRange face = old_faces[old_face_idx];
916 for (
const int corner : face) {
917 new_corner_verts[new_corner_idx] = vert_reverse_map[corner_verts[corner]];
921 corner_verts.
copy_from(new_corner_verts);
925 gather_group_sizes(old_faces, new_face_order, face_sizes);
953 int new_corner_idx = 0;
954 for (
const int old_face_idx : new_face_order) {
955 const IndexRange face = old_faces[old_face_idx];
956 for (
const int old_corner_idx : face) {
957 type.
copy_construct(attribute_data[old_corner_idx], new_values[new_corner_idx]);
967 for (
int &vert_idx : local_group.unique_verts) {
968 vert_idx = vert_reverse_map[vert_idx];
970 for (
int &vert_idx : local_group.shared_verts) {
971 vert_idx = vert_reverse_map[vert_idx];
977 for (
const int node_idx : local_groups.
index_range()) {
987 int unique_start = (node_idx == 0) ? 0 : group_unique_offsets[node_idx];
988 int unique_end = group_unique_offsets[node_idx + 1];
991 int face_start = (node_idx == 0) ? 0 : group_face_offsets[node_idx];
992 int face_end = group_face_offsets[node_idx + 1];
1004 mesh.tag_positions_changed();
1005 mesh.tag_topology_changed();
1006 mesh.runtime->spatial_groups = std::make_unique<Array<MeshGroup>>(std::move(
nodes));
1031 if (
mesh.face_offset_indices) {
1033 &
mesh.runtime->face_offsets_sharing_info);
1039 mesh.totface_legacy = 0;
1040 mesh.corners_num = 0;
1068 if (free_customdata) {
1075 mesh->totface_legacy = 0;
1087 if (
mesh->faces_num == 0) {
1092 mesh->face_offset_indices);
1096 mesh->face_offsets_for_write().fill(-1);
1099 mesh->face_offset_indices[0] = 0;
1100 mesh->face_offset_indices[
mesh->faces_num] =
mesh->corners_num;
1105 return {
static_cast<const float3 *
>(
1118 return {
static_cast<const int2 *
>(
1152 return {
static_cast<const int *
>(
1165 return {
static_cast<const int *
>(
1200 this->face_offsets().size_in_bytes());
1214 return blender::bke::MutableAttributeAccessor(
this,
1219 const int edges_num,
1220 const int faces_num,
1221 const int corners_num)
1227 mesh->verts_num = verts_num;
1228 mesh->edges_num = edges_num;
1229 mesh->faces_num = faces_num;
1230 mesh->corners_num = corners_num;
1241 const int edges_num,
1242 const int faces_num,
1243 const int corners_num)
1246 mesh->verts_num = verts_num;
1247 mesh->edges_num = edges_num;
1248 mesh->corners_num = corners_num;
1305 if (me_dst->
mat !=
nullptr) {
1315 const int verts_num,
1316 const int edges_num,
1317 const int tessface_num,
1318 const int faces_num,
1319 const int corners_num,
1323 const bool do_tessface = (tessface_num ||
1366 const int verts_num,
1367 const int edges_num,
1368 const int faces_num,
1369 const int corners_num)
1377 return reinterpret_cast<Mesh *
>(
1394 const int active_shapekey,
1395 const bool add_key_index,
1409 const Mesh *me_settings)
1420 const Mesh *me_settings)
1457 float texspace_location[3], texspace_size[3];
1460 texspace_size[0] = (
bounds.max[0] -
bounds.min[0]) / 2.0f;
1461 texspace_size[1] = (
bounds.max[1] -
bounds.min[1]) / 2.0f;
1462 texspace_size[2] = (
bounds.max[2] -
bounds.min[2]) / 2.0f;
1464 for (
int a = 0; a < 3; a++) {
1465 if (texspace_size[a] == 0.0f) {
1466 texspace_size[a] = 1.0f;
1468 else if (texspace_size[a] > 0.0f && texspace_size[a] < 0.00001f) {
1469 texspace_size[a] = 0.00001f;
1471 else if (texspace_size[a] < 0.0f && texspace_size[a] > -0.00001f) {
1472 texspace_size[a] = -0.00001f;
1496 if (r_texspace_location) {
1499 if (r_texspace_size) {
1505 char **r_texspace_flag,
1506 float **r_texspace_location,
1507 float **r_texspace_size)
1511 if (r_texspace_flag !=
nullptr) {
1512 *r_texspace_flag = &
mesh->texspace_flag;
1514 if (r_texspace_location !=
nullptr) {
1515 *r_texspace_location =
mesh->texspace_location;
1517 if (r_texspace_size !=
nullptr) {
1518 *r_texspace_size =
mesh->texspace_size;
1529 result.as_mutable_span().take_front(positions.
size()).copy_from(positions);
1537 float texspace_location[3], texspace_size[3];
1540 mesh->texcomesh ?
mesh->texcomesh :
mesh, texspace_location, texspace_size);
1551 co[0] = (co[0] - texspace_location[0]) / texspace_size[0];
1552 co[1] = (co[1] - texspace_location[1]) / texspace_size[1];
1553 co[2] = (co[2] - texspace_location[2]) / texspace_size[2];
1579 if (ob ==
nullptr) {
1583 return static_cast<Mesh *
>(ob->
data);
1591 Mesh *old =
nullptr;
1593 if (ob ==
nullptr) {
1600 old =
static_cast<Mesh *
>(ob->
data);
1619 if (!material_indices) {
1628 if (indices_span[
i] > 0 && indices_span[
i] >= index) {
1632 indices_span.
save();
1633 material_indices.
finish();
1649 return indices_span.
contains(index);
1657 attributes.
remove(
"material_index");
1666 const short remap_len_short = short(remap_len);
1668#define MAT_NR_REMAP(n) \
1669 if (n < remap_len_short) { \
1670 BLI_assert(n >= 0 && remap[n] < remap_len_short); \
1687 if (!material_indices) {
1690 for (
const int i : material_indices.
span.index_range()) {
1693 material_indices.
span.save();
1694 material_indices.
finish();
1705 if (!keep_sharp_edges) {
1706 attributes.
remove(
"sharp_edge");
1708 attributes.
remove(
"sharp_face");
1710 attributes.
add<
bool>(
"sharp_face",
1723 if (
angle == 0.0f) {
1727 if (!keep_sharp_edges) {
1728 attributes.
remove(
"sharp_edge");
1734 mesh.corner_verts(),
1735 mesh.corner_edges(),
1736 mesh.face_normals(),
1737 mesh.corner_to_face_map(),
1746std::optional<blender::Bounds<blender::float3>> Mesh::bounds_min_max()
const
1751 return std::nullopt;
1753 this->
runtime->bounds_cache.ensure([&](Bounds<float3> &r_bounds) {
1754 switch (this->
runtime->wrapper_type) {
1757 *this->runtime->edit_data);
1761 r_bounds = *bounds::min_max(this->vert_positions());
1765 return this->
runtime->bounds_cache.data();
1770 this->
runtime->bounds_cache.ensure([&](blender::Bounds<float3> &r_data) { r_data =
bounds; });
1776 mesh.runtime->edit_mesh->bm;
1779std::optional<int> Mesh::material_index_max()
const
1781 this->
runtime->max_material_index.ensure([&](std::optional<int> &value) {
1785 value = std::nullopt;
1788 int max_material_index = 0;
1792 max_material_index = std::max<int>(max_material_index, efa->
mat_nr);
1794 value = max_material_index;
1798 value = std::nullopt;
1805 if (value.has_value()) {
1806 value = std::clamp(*value, 0,
MAXMAT);
1809 return this->
runtime->max_material_index.data();
1814 using namespace blender;
1815 this->
runtime->used_material_indices.ensure([&](VectorSet<int> &r_data) {
1816 const std::optional<int> max_material_index_opt = this->material_index_max();
1818 if (!max_material_index_opt.has_value()) {
1821 const int max_material_index = *max_material_index_opt;
1822 const auto clamp_material_index = [&](
const int index) {
1823 return std::clamp<int>(
index, 0, max_material_index);
1827 Array<bool> used_indices(max_material_index + 1,
false);
1833 used_indices[clamp_material_index(efa->
mat_nr)] =
true;
1836 else if (
const VArray<int> material_indices =
1838 .lookup_or_default<int>(
"material_index", bke::AttrDomain::Face, 0)
1841 if (
const std::optional<int> single_material_index = material_indices.get_if_single()) {
1842 used_indices[clamp_material_index(*single_material_index)] =
true;
1845 VArraySpan<int> material_indices_span = material_indices;
1846 threading::parallel_for(
1847 material_indices_span.
index_range(), 1024, [&](
const IndexRange range) {
1848 for (const int i : range) {
1849 used_indices[clamp_material_index(material_indices_span[i])] = true;
1854 for (
const int i : used_indices.index_range()) {
1855 if (used_indices[i]) {
1860 return this->runtime->used_material_indices.data();
1868 for (float3 &position : positions.slice(range)) {
1869 position += translation;
1880 std::optional<Bounds<float3>>
bounds;
1881 if (
mesh.runtime->bounds_cache.is_cached()) {
1887 if (do_shape_keys &&
mesh.key) {
1893 mesh.tag_positions_changed_uniformly();
1896 bounds->min += translation;
1897 bounds->max += translation;
1906 if (do_shape_keys &&
mesh.key) {
1914 mesh.tag_positions_changed();
1930 mesh->totselect = 0;
1937 MSelect *mselect_src, *mselect_dst;
1940 if (
mesh->totselect == 0) {
1944 mselect_src =
mesh->mselect;
1955 for (i_src = 0, i_dst = 0; i_src <
mesh->totselect; i_src++) {
1956 int index = mselect_src[i_src].
index;
1957 switch (mselect_src[i_src].type) {
1959 if (select_vert[index]) {
1960 mselect_dst[i_dst] = mselect_src[i_src];
1966 if (select_edge[index]) {
1967 mselect_dst[i_dst] = mselect_src[i_src];
1973 if (select_poly[index]) {
1974 mselect_dst[i_dst] = mselect_src[i_src];
1990 mselect_dst =
nullptr;
1992 else if (i_dst !=
mesh->totselect) {
1996 mesh->totselect = i_dst;
1997 mesh->mselect = mselect_dst;
2004 for (
int i = 0;
i <
mesh->totselect;
i++) {
2005 if ((
mesh->mselect[
i].index == index) && (
mesh->mselect[
i].type == type)) {
2017 if (
mesh->totselect) {
2018 if (
mesh->mselect[
mesh->totselect - 1].type == type) {
2019 return mesh->mselect[
mesh->totselect - 1].index;
2029 if (msel_index == -1) {
2033 mesh->mselect[
mesh->totselect].index = index;
2034 mesh->mselect[
mesh->totselect].type = type;
2037 else if (msel_index !=
mesh->totselect - 1) {
2039 std::swap(
mesh->mselect[msel_index],
mesh->mselect[
mesh->totselect - 1]);
2043 (
mesh->mselect[
mesh->totselect - 1].type == type));
2048 r_count[0] = r_count[1] = r_count[2] = 0;
2049 if (
mesh->runtime->edit_mesh) {
2051 r_count[0] =
bm->totvertsel;
2052 r_count[1] =
bm->totedgesel;
2053 r_count[2] =
bm->totfacesel;
2067 if (
mesh->runtime->mesh_eval !=
nullptr) {
2069 mesh->runtime->mesh_eval =
nullptr;
#define ATTR_DOMAIN_MASK_COLOR
#define ATTR_DOMAIN_AS_MASK(domain)
bool BKE_bpath_foreach_path_fixed_process(BPathForeachPathData *bpath_data, char *path, size_t path_maxncpy)
void CustomData_blend_write_prepare(CustomData &data, blender::bke::AttrDomain domain, int domain_size, blender::Vector< CustomDataLayer, 16 > &layers_to_write, blender::bke::AttributeStorage::BlendWriteData &write_data)
void CustomData_count_memory(const CustomData &data, int totelem, blender::MemoryCounter &memory)
const CustomData_MeshMasks CD_MASK_EVERYTHING
void * CustomData_get_layer_named_for_write(CustomData *data, eCustomDataType type, blender::StringRef name, int totelem)
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
eCustomDataMask CD_TYPE_AS_MASK(eCustomDataType type)
const void * CustomData_get_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
void CustomData_MeshMasks_update(CustomData_MeshMasks *mask_dst, const CustomData_MeshMasks *mask_src)
void CustomData_reset(CustomData *data)
bool CustomData_has_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
void * CustomData_bmesh_get(const CustomData *data, void *block, eCustomDataType type)
void CustomData_blend_write(BlendWriter *writer, CustomData *data, blender::Span< CustomDataLayer > layers_to_write, int count, eCustomDataMask cddata_mask, ID *id)
void CustomData_free(CustomData *data)
void CustomData_init_from(const CustomData *source, CustomData *dest, eCustomDataMask mask, int totelem)
void CustomData_blend_read(BlendDataReader *reader, CustomData *data, int count)
const char * CustomData_get_render_layer_name(const CustomData *data, eCustomDataType type)
void CustomData_init_layout_from(const CustomData *source, CustomData *dest, eCustomDataMask mask, eCDAllocType alloctype, int totelem)
void * CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
void * CustomData_add_layer(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem)
const CustomData_MeshMasks CD_MASK_DERIVEDMESH
const char * CustomData_get_active_layer_name(const CustomData *data, eCustomDataType type)
bool CustomData_free_layer_named(CustomData *data, blender::StringRef name)
const CustomData_MeshMasks CD_MASK_MESH
std::optional< blender::Bounds< blender::float3 > > BKE_editmesh_cache_calc_minmax(const BMEditMesh &em, const blender::bke::EditMeshData &emd)
@ IDTYPE_FLAGS_APPEND_IS_REUSABLE
const char * BKE_idtype_idcode_to_name(short idcode)
struct ID * BKE_id_copy_in_lib(Main *bmain, std::optional< Library * > owner_library, const ID *id, std::optional< const ID * > new_owner_id, ID **new_id_p, int flag)
void * BKE_libblock_alloc(Main *bmain, short type, const char *name, int flag) ATTR_WARN_UNUSED_RESULT
void BKE_id_free(Main *bmain, void *idv)
void BKE_libblock_init_empty(ID *id) ATTR_NONNULL(1)
ID * BKE_id_copy_ex(Main *bmain, const ID *id, ID **new_id_p, int flag)
void * BKE_id_new(Main *bmain, short type, const char *name)
void * BKE_id_new_nomain(short type, const char *name)
void BKE_id_blend_write(BlendWriter *writer, ID *id)
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(data_, id_super_, cb_flag_)
General operations, lookup, etc. for materials.
void BKE_object_materials_sync_length(Main *bmain, Object *ob, ID *id)
Mesh * BKE_mesh_new_nomain(int verts_num, int edges_num, int faces_num, int corners_num)
void BKE_mesh_runtime_clear_cache(Mesh *mesh)
int BKE_mesh_wrapper_vert_len(const Mesh *mesh)
void BKE_modifiers_test_object(Object *ob)
void multires_force_sculpt_rebuild(Object *object)
General operations, lookup, etc. for blender objects.
A BVH for high poly meshes.
#define BLI_assert_unreachable()
BLI_INLINE unsigned int BLI_hash_int(unsigned int k)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
MINLINE void madd_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
void range_vn_i(int *array_tar, int size, int start)
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
char * BLI_strdupn(const char *str, size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Platform independent time functions.
long int BLI_time_now_seconds_i(void)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define BLO_write_id_struct(writer, struct_name, id_address, id)
void BLO_read_string(BlendDataReader *reader, char **ptr_p)
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
#define BLO_write_struct_array(writer, struct_name, array_size, data_ptr)
void BLO_write_shared_tag(BlendWriter *writer, const void *data)
#define BLO_read_struct_list(reader, struct_name, list)
#define BLO_read_struct_array(reader, struct_name, array_size, ptr_p)
void BLO_write_pointer_array(BlendWriter *writer, int64_t num, const void *data_ptr)
void BLO_read_pointer_array(BlendDataReader *reader, int64_t array_size, void **ptr_p)
bool BLO_write_is_undo(BlendWriter *writer)
void BLO_write_shared(BlendWriter *writer, const void *data, size_t approximate_size_in_bytes, const blender::ImplicitSharingInfo *sharing_info, blender::FunctionRef< void()> write_fn)
const blender::ImplicitSharingInfo * BLO_read_shared(BlendDataReader *reader, T **data_ptr, blender::FunctionRef< const blender::ImplicitSharingInfo *()> read_fn)
#define BLT_I18NCONTEXT_ID_MESH
bool DEG_is_active(const Depsgraph *depsgraph)
void DEG_debug_print_eval(Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address)
T * DEG_get_original(T *id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
#define CD_MASK_COLOR_ALL
#define DNA_struct_default_get(struct_name)
@ ME_TEXSPACE_FLAG_AUTO_EVALUATED
struct MDeformVert MDeformVert
Object is a sort of wrapper for general info.
static void split(const char *text, const char *seps, char ***str, int *count)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
void BKE_mesh_mselect_clear(Mesh *mesh)
void BKE_mesh_copy_parameters_for_eval(Mesh *me_dst, const Mesh *me_src)
void BKE_mesh_orco_verts_transform(Mesh *mesh, MutableSpan< float3 > orco, const bool invert)
void BKE_mesh_tessface_clear(Mesh *mesh)
BMesh * BKE_mesh_to_bmesh(Mesh *mesh, const int active_shapekey, const bool add_key_index, const BMeshCreateParams *params)
void BKE_mesh_ensure_skin_customdata(Mesh *mesh)
Mesh * BKE_mesh_new_nomain(const int verts_num, const int edges_num, const int faces_num, const int corners_num)
Mesh * BKE_mesh_from_bmesh_nomain(BMesh *bm, const BMeshToMeshParams *params, const Mesh *me_settings)
void BKE_mesh_clear_geometry_and_metadata(Mesh *mesh)
int BKE_mesh_mselect_active_get(const Mesh *mesh, int type)
static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address)
void BKE_mesh_orco_ensure(Object *ob, Mesh *mesh)
bool BKE_mesh_attribute_required(const StringRef name)
static void mesh_foreach_path(ID *id, BPathForeachPathData *bpath_data)
void BKE_mesh_count_selected_items(const Mesh *mesh, int r_count[3])
Mesh * BKE_mesh_new_nomain_from_template(const Mesh *me_src, const int verts_num, const int edges_num, const int faces_num, const int corners_num)
bool BKE_mesh_has_custom_loop_normals(Mesh *mesh)
void BKE_mesh_texspace_ensure(Mesh *mesh)
void BKE_mesh_mselect_active_set(Mesh *mesh, int index, int type)
static void mesh_foreach_working_space_color(ID *id, const IDTypeForeachColorFunctionCallback &fn)
Mesh * BKE_mesh_add(Main *bmain, const char *name)
void BKE_mesh_assign_object(Main *bmain, Object *ob, Mesh *mesh)
bool BKE_mesh_material_index_used(Mesh *mesh, short index)
void BKE_mesh_copy_parameters(Mesh *me_dst, const Mesh *me_src)
static void copy_attribute_names(const Mesh &mesh_src, Mesh &mesh_dst)
Mesh * BKE_mesh_copy_for_eval(const Mesh &source)
static void mesh_clear_geometry(Mesh &mesh)
void BKE_mesh_mselect_validate(Mesh *mesh)
static void mesh_free_data(ID *id)
static void clear_attribute_names(Mesh &mesh)
Mesh * BKE_mesh_from_bmesh_for_eval_nomain(BMesh *bm, const CustomData_MeshMasks *cd_mask_extra, const Mesh *me_settings)
static void ensure_orig_index_layer(CustomData &data, const int size)
static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
Mesh * BKE_mesh_from_object(Object *ob)
int BKE_mesh_mselect_find(const Mesh *mesh, int index, int type)
static void mesh_init_data(ID *id)
static void mesh_foreach_id(ID *id, LibraryForeachIDData *data)
void BKE_mesh_texspace_get(Mesh *mesh, float r_texspace_location[3], float r_texspace_size[3])
blender::Array< float3 > BKE_mesh_orco_verts_get(const Object *ob)
static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata)
void BKE_mesh_material_index_clear(Mesh *mesh)
static bool use_bmesh_material_indices(const Mesh &mesh)
void BKE_mesh_material_index_remove(Mesh *mesh, short index)
void BKE_mesh_texspace_get_reference(Mesh *mesh, char **r_texspace_flag, float **r_texspace_location, float **r_texspace_size)
void BKE_mesh_eval_geometry(Depsgraph *depsgraph, Mesh *mesh)
static void mesh_copy_data(Main *bmain, std::optional< Library * > owner_library, ID *id_dst, const ID *id_src, const int flag)
void BKE_mesh_clear_geometry(Mesh *mesh)
#define STACK_FIXED_DEPTH
void BKE_mesh_face_offsets_ensure_alloc(Mesh *mesh)
BMesh * BKE_mesh_to_bmesh_ex(const Mesh *mesh, const BMeshCreateParams *create_params, const BMeshFromMeshParams *convert_params)
void BKE_mesh_material_remap(Mesh *mesh, const uint *remap, uint remap_len)
Mesh * BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src, const int verts_num, const int edges_num, const int tessface_num, const int faces_num, const int corners_num, const CustomData_MeshMasks mask)
void BKE_mesh_ensure_default_orig_index_customdata(Mesh *mesh)
void BKE_mesh_ensure_default_orig_index_customdata_no_check(Mesh *mesh)
void BKE_mesh_texspace_calc(Mesh *mesh)
void BM_data_layer_add(BMesh *bm, CustomData *data, int type)
#define BM_ITER_MESH(ele, iter, bm, itype)
BMesh const char void * data
BMesh * BM_mesh_create(const BMAllocTemplate *allocsize, const BMeshCreateParams *params)
BMesh Make Mesh.
#define BMALLOC_TEMPLATE_FROM_ME(...)
void BM_mesh_bm_from_me(BMesh *bm, const Mesh *mesh, const BMeshFromMeshParams *params)
void BM_mesh_bm_to_me_for_eval(BMesh &bm, Mesh &mesh, const CustomData_MeshMasks *cd_mask_extra)
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *mesh, const BMeshToMeshParams *params)
ATTR_WARN_UNUSED_RESULT const BMVert * v
BPy_StructRNA * depsgraph
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
IndexRange index_range() const
LinearAllocator & allocator()
void copy_construct(const void *src, void *dst) const
GMutableSpan as_mutable_span()
void copy_from(GSpan values)
const CPPType & type() const
constexpr int64_t size() const
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr MutableSpan drop_front(const int64_t n) const
constexpr T * end() const
constexpr T * begin() const
constexpr IndexRange index_range() const
constexpr void copy_from(Span< T > values) const
constexpr MutableSpan take_front(const int64_t n) const
constexpr Span slice(int64_t start, int64_t size) const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool contains(const T &value) const
T get_internal_single() const
static VArray from_single(T value, const int64_t size)
void append(const T &value)
IndexRange index_range() const
void resize(const int64_t new_size)
void reserve(const int64_t min_capacity)
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, AttrType data_type, const void *default_value=nullptr) const
void foreach_attribute(const FunctionRef< void(const AttributeIter &)> fn) const
GAttributeReader lookup(const StringRef attribute_id) const
std::optional< AttributeMetaData > lookup_meta_data(StringRef attribute_id) const
GAttributeWriter lookup_for_write(StringRef attribute_id)
bool add(const StringRef attribute_id, const AttrDomain domain, const AttrType data_type, const AttributeInit &initializer)
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, AttrType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
bool remove(const StringRef attribute_id)
GSpanAttributeWriter lookup_for_write_span(StringRef attribute_id)
void add_shared(const ImplicitSharingInfo *sharing_info, const FunctionRef< void(MemoryCounter &shared_memory)> count_fn)
CCL_NAMESPACE_BEGIN ccl_device float invert(const float color, const float factor)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void fill_index_range(MutableSpan< T > span, const T start=0)
void gather(GSpan src, Span< int > map, GMutableSpan dst)
void edges_sharp_from_angle_set(OffsetIndices< int > faces, Span< int > corner_verts, Span< int > corner_edges, Span< float3 > face_normals, Span< int > corner_to_face, Span< bool > sharp_faces, const float split_angle, MutableSpan< bool > sharp_edges)
Bounds< float3 > calc_face_bounds(const Span< float3 > vert_positions, const Span< int > face_verts)
int partition_along_axis(const Span< float3 > face_centers, MutableSpan< int > faces, const int axis, const float middle)
bool leaf_needs_material_split(const Span< int > faces, const Span< int > material_indices)
int partition_material_indices(const Span< int > material_indices, MutableSpan< int > faces)
std::optional< eCustomDataType > attr_type_to_custom_data_type(AttrType attr_type)
static Bounds< float3 > merge_bounds(const Bounds< float3 > &a, const Bounds< float3 > &b)
bool attribute_name_is_anonymous(const StringRef name)
static void translate_positions(MutableSpan< float3 > positions, const float3 &translation)
void mesh_sharp_edges_set_from_angle(Mesh &mesh, float angle, bool keep_sharp_edges=false)
static Vector< NonContiguousGroup > compute_local_mesh_groups(Mesh &mesh)
const AttributeAccessorFunctions & mesh_attribute_accessor_functions()
void mesh_freestyle_marks_to_legacy(AttributeStorage::BlendWriteData &attr_write_data, CustomData &edge_data, CustomData &face_data, Vector< CustomDataLayer, 16 > &edge_layers, Vector< CustomDataLayer, 16 > &face_layers)
void attribute_storage_blend_write_prepare(AttributeStorage &data, AttributeStorage::BlendWriteData &write_data)
static Bounds< float3 > negative_bounds()
static void build_vertex_groups_for_leaves(const int verts_num, const OffsetIndices< int > faces, const Span< int > corner_verts, Vector< NonContiguousGroup > &groups)
void mesh_remove_invalid_attribute_strings(Mesh &mesh)
static bool meta_data_matches(const std::optional< bke::AttributeMetaData > meta_data, const AttrDomainMask domains, const eCustomDataMask types)
static void partition_faces_recursively(const Span< float3 > face_centers, MutableSpan< int > face_indices, Vector< NonContiguousGroup > &groups, int node_index, int depth, const std::optional< Bounds< float3 > > &bounds_precalc, const Span< int > material_indices, int target_group_size)
void mesh_convert_storage_to_customdata(Mesh &mesh)
void mesh_smooth_set(Mesh &mesh, bool use_smooth, bool keep_sharp_edges=false)
void mesh_apply_spatial_organization(Mesh &mesh)
Mesh * mesh_new_no_attributes(int verts_num, int edges_num, int faces_num, int corners_num)
void mesh_transform(Mesh &mesh, const float4x4 &transform, bool do_shape_keys)
void transform_custom_normal_attribute(const float4x4 &transform, MutableAttributeAccessor &attributes)
void mesh_ensure_required_data_layers(Mesh &mesh)
void mesh_ensure_default_color_attribute_on_add(Mesh &mesh, StringRef id, AttrDomain domain, bke::AttrType data_type)
void mesh_translate(Mesh &mesh, const float3 &translation, bool do_shape_keys)
Bounds< T > merge(const Bounds< T > &a, const Bounds< T > &b)
std::optional< T > max(const VArray< T > &values)
void copy_shared_pointer(T *src_ptr, const ImplicitSharingInfo *src_sharing_info, T **r_dst_ptr, const ImplicitSharingInfo **r_dst_sharing_info)
const ImplicitSharingInfo * info_for_mem_free(void *data)
void free_shared_data(T **data, const ImplicitSharingInfo **sharing_info)
void make_trivial_data_mutable(T **data, const ImplicitSharingInfo **sharing_info, const int64_t size)
T midpoint(const T &a, const T &b)
void min_max(const T &value, T &min, T &max)
int dominant_axis(const VecBase< T, 3 > &a)
void transform_points(const float4x4 &transform, MutableSpan< float3 > points, bool use_threading=true)
OffsetIndices< int > accumulate_counts_to_offsets(MutableSpan< int > counts_to_offsets, int start_offset=0)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Value parallel_reduce(IndexRange range, int64_t grain_size, const Value &identity, const Function &function, const Reduction &reduction)
MatBase< float, 4, 4 > float4x4
VecBase< int32_t, 2 > int2
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
VecBase< float, 3 > float3
static void init(bNodeTree *, bNode *node)
const ImplicitSharingInfoHandle * sharing_info
CustomDataExternal * external
const blender::FunctionRef< void(blender::ImplicitSharingPtr<> &sharing_info, blender::ColorGeometry4f *&data, size_t size)> implicit_sharing_array
float remesh_voxel_adaptivity
struct AttributeStorage attribute_storage
MeshRuntimeHandle * runtime
char * active_uv_map_attribute
char * default_color_attribute
ListBase vertex_group_names
int * face_offset_indices
int attributes_active_index
int vertex_group_active_index
int face_sets_color_default
char * default_uv_map_attribute
float texspace_location[3]
char * active_color_attribute
Vector<::Attribute, 16 > & attributes
VMutableArray< T > varray
Array< int > shared_verts
const ImplicitSharingInfo * face_offsets_sharing_info
Array< int > shared_verts
Array< int > unique_verts
MutableVArraySpan< T > span