75 const float imat[4][4],
76 float3 **vert_positions_pp,
78 int **corner_verts_pp,
79 int **corner_edges_pp,
80 int *all_face_offsets,
102 float3 *vert_positions = *vert_positions_pp;
104 int *corner_verts = *corner_verts_pp;
105 int *corner_edges = *corner_edges_pp;
107 if (mesh->verts_num) {
124 int *vgroup_index_map;
125 int vgroup_index_map_len;
127 ob_src, ob_dst, &vgroup_index_map_len);
129 dvert, mesh->verts_num, vgroup_index_map, vgroup_index_map_len);
130 if (vgroup_index_map !=
nullptr) {
136 if (ob_src != ob_dst) {
140 mul_m4_m4m4(cmat, imat, ob_src->object_to_world().ptr());
143 for (a = 0; a < mesh->verts_num; a++) {
164 float(*ocos)[3] =
static_cast<float(*)[3]
>(okb->
data);
165 for (a = 0; a < mesh->verts_num; a++,
cos++, ocos++) {
172 for (a = 0; a < mesh->verts_num; a++,
cos++) {
193 float(*ocos)[3] =
static_cast<float(*)[3]
>(okb->
data);
194 for (a = 0; a < mesh->verts_num; a++,
cos++, ocos++) {
200 for (a = 0; a < mesh->verts_num; a++,
cos++) {
209 if (mesh->edges_num) {
214 for (a = 0; a < mesh->edges_num; a++, edge++) {
219 if (mesh->corners_num) {
220 if (ob_src != ob_dst) {
235 for (a = 0; a < mesh->corners_num; a++) {
236 corner_verts[a] += *vertofs;
237 corner_edges[a] += *edgeofs;
241 if (mesh->faces_num) {
244 for (a = 1; a <= ob_src->
totcol; a++) {
247 for (
b = 0;
b < totcol;
b++) {
248 if (ma == matar[
b]) {
264 if (!material_indices && totcol > 1) {
268 if (material_indices) {
269 for (a = 0; a < mesh->faces_num; a++) {
270 material_indices[a + *polyofs] = matmap ? matmap[material_indices[a + *polyofs]] : 0;
274 const Span<int> src_face_offsets = mesh->face_offsets();
275 int *face_offsets = all_face_offsets + *polyofs;
277 face_offsets[i] = src_face_offsets[i] + *loopofs;
282 *vertofs += mesh->verts_num;
283 *vert_positions_pp += mesh->verts_num;
284 *edgeofs += mesh->edges_num;
285 *medge_pp += mesh->edges_num;
286 *loopofs += mesh->corners_num;
287 *corner_verts_pp += mesh->corners_num;
288 *corner_edges_pp += mesh->corners_num;
289 *polyofs += mesh->faces_num;
305 int max_face_set = 0;
306 for (
const int i : face_sets.
span.index_range()) {
309 if (face_sets.
span[i] <= *face_set_offset) {
310 face_sets.
span[i] += *face_set_offset;
312 max_face_set =
max_ii(max_face_set, face_sets.
span[i]);
314 *face_set_offset = max_face_set;
326 Key *key, *nkey =
nullptr;
328 int a,
b, totcol, totmat = 0, totedge = 0, totvert = 0;
329 int totloop = 0, faces_num = 0, vertofs, *matmap =
nullptr;
330 int i, haskey = 0, edgeofs, loopofs, polyofs;
331 bool ok =
false, join_parent =
false;
332 CustomData vert_data, edge_data, ldata, face_data;
349 if (ob_iter->type ==
OB_MESH) {
350 mesh =
static_cast<Mesh *
>(ob_iter->data);
353 totedge += mesh->edges_num;
354 totloop += mesh->corners_num;
355 faces_num += mesh->faces_num;
356 totmat += ob_iter->totcol;
362 if ((ob->
parent !=
nullptr) && (ob_iter == ob->
parent)) {
392 if (
ELEM(totvert, 0, mesh->verts_num)) {
400 "Joining results in %d vertices, limit is %ld",
409 matmap =
static_cast<int *
>(
MEM_callocN(
sizeof(*matmap) * totmat, __func__));
414 for (a = 0; a < ob->
totcol; a++) {
434 kb->data =
MEM_callocN(
sizeof(
float[3]) * totvert,
"join_shapekey");
435 kb->totelem = totvert;
447 int face_set_id_offset = 0;
453 if ((ob != ob_iter) && (ob_iter->type ==
OB_MESH)) {
454 mesh =
static_cast<Mesh *
>(ob_iter->data);
467 mesh->vertex_group_active_index == 0)
469 mesh->vertex_group_active_index = 1;
474 if (mesh->verts_num) {
478 for (a = 1; a <= ob_iter->totcol; a++) {
481 for (
b = 0;
b < totcol;
b++) {
482 if (ma == matar[
b]) {
501 if (mesh->key && key) {
503 int *index_map =
static_cast<int *
>(
504 MEM_mallocN(
sizeof(
int) * mesh->key->totkey, __func__));
517 index_map[i] = key->
totkey;
524 kbn->
data =
MEM_callocN(
sizeof(
float[3]) * totvert,
"joined_shapekey");
534 if (
LIKELY(kb->relative < mesh->key->totkey)) {
535 kb_map[i]->
relative = index_map[kb->relative];
561 int *face_offsets =
static_cast<int *
>(
MEM_malloc_arrayN(faces_num + 1,
sizeof(
int), __func__));
562 face_offsets[faces_num] = totloop;
612 if (ob_iter->type ==
OB_MESH) {
651 mesh =
static_cast<Mesh *
>(ob->
data);
656 mesh->face_offset_indices = face_offsets;
661 mesh->verts_num = totvert;
662 mesh->edges_num = totedge;
663 mesh->corners_num = totloop;
664 mesh->faces_num = faces_num;
666 mesh->vert_data = vert_data;
667 mesh->edge_data = edge_data;
668 mesh->corner_data = ldata;
669 mesh->face_data = face_data;
672 for (a = 1; a <= ob->
totcol; a++) {
678 for (a = 1; a <= mesh->totcol; a++) {
679 ma = mesh->mat[a - 1];
695 ob->
totcol = mesh->totcol = totcol;
738 Mesh *selme =
nullptr;
739 Mesh *me_deformed =
nullptr;
740 Key *key = mesh->key;
742 bool ok =
false, nonequal_verts =
false;
745 if (ob_iter == ob_active) {
749 if (ob_iter->type ==
OB_MESH) {
750 selme = (
Mesh *)ob_iter->data;
752 if (selme->
verts_num == mesh->verts_num) {
756 nonequal_verts =
true;
763 if (nonequal_verts) {
769 "No additional selected meshes with equal vertex count to join");
774 if (key ==
nullptr) {
785 if (ob_iter == ob_active) {
789 if (ob_iter->type ==
OB_MESH) {
790 selme = (
Mesh *)ob_iter->data;
792 if (selme->
verts_num == mesh->verts_num) {
827 Mesh **r_mesh_mirror,
830 Mesh *mesh_mirror =
nullptr;
834 if (mesh_eval !=
nullptr) {
835 mesh_mirror = mesh_eval;
837 else if (
BMEditMesh *em = mesh->runtime->edit_mesh.get()) {
844 *r_mesh_mirror = mesh_mirror;
845 *r_em_mirror = em_mirror;
881 const Span<float3> positions = mesh_eval ? mesh_eval->vert_positions() : mesh->vert_positions();
885 vec[0] = -positions[index][0];
886 vec[1] = positions[index][1];
887 vec[2] = positions[index][2];
915 if ((isfinite(co[0]) ==
false) || (isfinite(co[1]) ==
false) || (isfinite(co[2]) ==
false)) {
957 return (
BMVert *)(poinval);
977 if (
BMEditMesh *em = mesh->runtime->edit_mesh.get()) {
992static float *editmesh_get_mirror_uv(
993 BMEditMesh *em,
int axis,
float *uv,
float *mirrCent,
float *face_cent)
1000 if (isnan(uv[0]) || !isfinite(uv[0]) || isnan(uv[1]) || !isfinite(uv[1])) {
1006 vec[1] = -((uv[1]) - mirrCent[1]) + mirrCent[1];
1008 cent_vec[0] = face_cent[0];
1009 cent_vec[1] = -((face_cent[1]) - mirrCent[1]) + mirrCent[1];
1012 vec[0] = -((uv[0]) - mirrCent[0]) + mirrCent[0];
1015 cent_vec[0] = -((face_cent[0]) - mirrCent[0]) + mirrCent[0];
1016 cent_vec[1] = face_cent[1];
1027 if ((
fabsf(cent[0] - cent_vec[0]) < 0.001f) && (
fabsf(cent[1] - cent_vec[1]) < 0.001f)) {
1033 if ((
fabsf(luv[0] - vec[0]) < 0.001f) && (
fabsf(luv[1] - vec[1]) < 0.001f)) {
1052 v0 = std::min({mf->
v1, mf->
v2, mf->
v3, mf->
v4});
1053 v1 = std::max({mf->
v1, mf->
v2, mf->
v3, mf->
v4});
1056 v0 = std::min({mf->
v1, mf->
v2, mf->
v3});
1057 v1 = std::min({mf->
v1, mf->
v2, mf->
v3});
1060 return ((v0 * 39) ^ (v1 * 31));
1066 if (a->v1 ==
b->v1 && a->v2 ==
b->v2 && a->v3 ==
b->v3 && a->v4 ==
b->v4) {
1069 if (a->v4 ==
b->v1 && a->v1 ==
b->v2 && a->v2 ==
b->v3 && a->v3 ==
b->v4) {
1072 if (a->v3 ==
b->v1 && a->v4 ==
b->v2 && a->v1 ==
b->v3 && a->v2 ==
b->v4) {
1075 if (a->v2 ==
b->v1 && a->v3 ==
b->v2 && a->v4 ==
b->v3 && a->v1 ==
b->v4) {
1080 if (a->v1 ==
b->v1 && a->v2 ==
b->v2 && a->v3 ==
b->v3) {
1083 if (a->v3 ==
b->v1 && a->v1 ==
b->v2 && a->v2 ==
b->v3) {
1086 if (a->v2 ==
b->v1 && a->v3 ==
b->v2 && a->v1 ==
b->v3) {
1103 const MFace *mf, *hashmf;
1105 int *mirrorverts, *mirrorfaces;
1110 const int totvert = mesh_eval ? mesh_eval->
verts_num : mesh->verts_num;
1111 const int totface = mesh_eval ? mesh_eval->
totface_legacy : mesh->totface_legacy;
1114 mirrorverts =
static_cast<int *
>(
MEM_callocN(
sizeof(
int) * totvert,
"MirrorVerts"));
1115 mirrorfaces =
static_cast<int *
>(
MEM_callocN(
sizeof(
int[2]) * totface,
"MirrorFaces"));
1117 const Span<float3> vert_positions = mesh_eval ? mesh_eval->vert_positions() :
1118 mesh->vert_positions();
1120 &(mesh_eval ? mesh_eval :
mesh)->fdata_legacy,
CD_MFACE);
1124 for (
const int i : vert_positions.
index_range()) {
1132 for (a = 0, mf = mface; a < totface; a++, mf++) {
1136 for (a = 0, mf = mface; a < totface; a++, mf++) {
1137 mirrormf.
v1 = mirrorverts[mf->
v3];
1138 mirrormf.
v2 = mirrorverts[mf->
v2];
1139 mirrormf.
v3 = mirrorverts[mf->
v1];
1140 mirrormf.
v4 = (mf->
v4) ? mirrorverts[mf->
v4] : 0;
1143 if (mf->
v4 && mirrormf.
v4 == 0) {
1144 std::swap(mirrormf.
v1, mirrormf.
v3);
1145 std::swap(mirrormf.
v2, mirrormf.
v4);
1150 mirrorfaces[a * 2] = hashmf - mface;
1154 mirrorfaces[a * 2] = -1;
1172 if (!mesh || mesh->faces_num == 0) {
1191 if ((*r_index) == 0 || (*r_index) >
uint(mesh->faces_num)) {
1203 const float mval[2],
1207 const int *corner_verts,
1212 for (
int j = face.size(); j--;) {
1214 const int v_idx = corner_verts[face[j]];
1219 if (len_test < *r_len_best) {
1220 *r_len_best = len_test;
1221 *r_v_idx_best = v_idx;
1246 const float mval_f[2] = {
float(mval[0]),
float(mval[1])};
1249 const Span<float3> vert_positions = mesh_eval->vert_positions();
1251 const Span<int> corner_verts = mesh_eval->corner_verts();
1257 if (index_mp_to_orig) {
1258 for (
const int i : faces.index_range()) {
1259 if (index_mp_to_orig[i] == face_index) {
1264 corner_verts.
data(),
1271 if (face_index < faces.size()) {
1276 corner_verts.
data(),
1286 if (index_mv_to_orig) {
1287 v_idx_best = index_mv_to_orig[v_idx_best];
1291 if ((v_idx_best !=
ORIGINDEX_NONE) && (v_idx_best < mesh->verts_num)) {
1292 *r_index = v_idx_best;
1322 if (!data->hide_vert.is_empty() && data->hide_vert[index]) {
1331 data->len_best =
len;
1332 data->v_idx_best = index;
1344 if (!mesh || mesh->verts_num == 0) {
1364 if ((*r_index) == 0 || (*r_index) >
uint(mesh->verts_num)) {
1377 const float mval_f[2] = {
float(mval[0]),
float(mval[1])};
1383 if (mesh_eval ==
nullptr) {
1390 data.region = region;
1391 data.mval_f = mval_f;
1393 data.v_idx_best = -1;
1394 data.hide_vert = *attributes.
lookup<
bool>(
".hide_vert", bke::AttrDomain::Point);
1398 if (data.v_idx_best == -1) {
1402 *r_index = data.v_idx_best;
1413 BMesh *
bm = mesh->runtime->edit_mesh->bm;
1416 if (cd_dvert_offset != -1) {
1442 if (index == -1 || mesh->deform_verts().is_empty()) {
1446 return &dverts[index];
1473 for (
Object *obedit : objects) {
1491 int elem_offset[4] = {0, 0, 0, 0};
1492 for (
Object *obedit : objects) {
#define CTX_DATA_BEGIN(C, Type, instance, member)
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset(const CustomData *data, eCustomDataType type)
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)
void * CustomData_add_layer_named(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem, blender::StringRef name)
void CustomData_reset(CustomData *data)
const CustomData_MeshMasks CD_MASK_BAREMESH
bool CustomData_merge_layout(const CustomData *source, CustomData *dest, eCustomDataMask mask, eCDAllocType alloctype, int totelem)
void CustomData_copy_data_named(const CustomData *source, CustomData *dest, int source_index, int dest_index, int count)
const CustomData_MeshMasks CD_MASK_MESH
void * CustomData_get_for_write(CustomData *data, int index, eCustomDataType type, int totelem)
BMEditMesh * BKE_editmesh_from_object(Object *ob)
Return the BMEditMesh for a given object.
Key * BKE_key_add(Main *bmain, ID *id)
KeyBlock * BKE_keyblock_add(Key *key, const char *name)
void BKE_keyblock_convert_from_mesh(const Mesh *mesh, const Key *key, KeyBlock *kb)
void BKE_keyblock_copy_settings(KeyBlock *kb_dst, const KeyBlock *kb_src)
copy shape-key attributes, but not key data or name/UID.
KeyBlock * BKE_keyblock_find_name(Key *key, const char name[])
void BKE_key_sort(Key *key)
ID * BKE_id_copy(Main *bmain, const ID *id)
void BKE_id_free_ex(Main *bmain, void *idv, int flag_orig, bool use_flag_from_idtag)
General operations, lookup, etc. for materials.
struct Material * BKE_object_material_get(struct Object *ob, short act)
void BKE_objects_materials_test_all(struct Main *bmain, struct ID *id)
int BKE_mesh_mselect_active_get(const Mesh *mesh, int type)
Mesh * BKE_mesh_from_object(Object *ob)
void BKE_mesh_clear_geometry(Mesh *mesh)
void BKE_mesh_foreach_mapped_vert(const Mesh *mesh, void(*func)(void *user_data, int index, const float co[3], const float no[3]), void *user_data, MeshForeachFlag flag)
void multiresModifier_prepare_join(Depsgraph *depsgraph, Scene *scene, Object *ob, Object *to_ob)
MultiresModifierData * get_multires_modifier(Scene *scene, Object *ob, bool use_first)
General operations, lookup, etc. for blender objects.
void BKE_object_apply_mat4_ex(Object *ob, const float mat[4][4], Object *parent, const float parentinv[4][4], bool use_compat)
Mesh * BKE_object_get_evaluated_mesh(const Object *object_eval)
void BKE_object_free_derived_caches(Object *ob)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
GHash * BLI_ghash_new_ex(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
void BLI_ghash_insert(GHash *gh, void *key, void *val)
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int max_ii(int a, int b)
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void mul_m4_v3(const float M[4][4], float r[3])
void invert_m4_m4_safe_ortho(float inverse[4][4], const float mat[4][4])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float len_manhattan_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
Object is a sort of wrapper for general info.
uint DRW_select_buffer_sample_point(Depsgraph *depsgraph, ARegion *region, View3D *v3d, const int center[2])
uint DRW_select_buffer_find_nearest_to_point(Depsgraph *depsgraph, ARegion *region, View3D *v3d, const int center[2], uint id_min, uint id_max, uint *dist)
int ED_mesh_mirror_spatial_table_lookup(Object *ob, BMEditMesh *em, Mesh *mesh_eval, const float co[3])
void ED_mesh_mirror_spatial_table_begin(Object *ob, BMEditMesh *em, Mesh *mesh_eval)
void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store)
void ED_mesh_mirror_spatial_table_end(Object *ob)
bool ED_mesh_mirrtopo_recalc_check(BMEditMesh *em, Mesh *mesh, MirrTopoStore_t *mesh_topo_store)
void ED_mesh_mirrtopo_init(BMEditMesh *em, Mesh *mesh, MirrTopoStore_t *mesh_topo_store, bool skip_em_vert_array_init)
eV3DProjStatus ED_view3d_project_float_object(const ARegion *region, const float co[3], float r_co[2], eV3DProjTest flag)
void ED_view3d_init_mats_rv3d(const Object *ob, RegionView3D *rv3d)
void ED_view3d_select_id_validate(const ViewContext *vc)
ViewContext ED_view3d_viewcontext_init(bContext *C, Depsgraph *depsgraph)
#define V3D_PROJ_TEST_CLIP_DEFAULT
Read Guarded memory(de)allocation.
#define BM_ELEM_CD_GET_FLOAT_P(ele, offset)
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
#define BM_elem_index_get(ele)
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
ATTR_WARN_UNUSED_RESULT BMesh * bm
BMVert * BM_mesh_active_vert_get(BMesh *bm)
void BM_mesh_elem_index_ensure_ex(BMesh *bm, const char htype, int elem_offset[4])
BLI_INLINE BMVert * BM_vert_at_index(BMesh *bm, const int index)
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
void BM_face_uv_calc_center_median(const BMFace *f, const int cd_loop_uv_offset, float r_cent[2])
constexpr const T * data() const
constexpr IndexRange index_range() const
GAttributeReader lookup(const StringRef attribute_id) const
local_group_size(16, 16) .push_constant(Type b
const Depsgraph * depsgraph
draw_view in_light_buf[] float
void *(* MEM_mallocN)(size_t len, const char *str)
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
ccl_device_inline float3 cos(float3 v)
void mesh_eval_to_meshkey(const Mesh *me_deformed, Mesh *mesh, KeyBlock *kb)
Mesh * mesh_get_eval_deform(Depsgraph *depsgraph, const Scene *scene, Object *ob, const CustomData_MeshMasks *dataMask)
bool iter_other(Main *bmain, Object *orig_ob, bool include_orig, bool(*callback)(Object *ob, void *callback_data), void *callback_data)
bool multires_update_totlevels(Object *ob, void *totlevel_v)
void base_free_and_unlink(Main *bmain, Scene *scene, Object *ob)
const ImplicitSharingInfo * info_for_mem_free(void *data)
ListBase vertex_group_names
blender::VArraySpan< bool > hide_vert
MutableVArraySpan< T > span
struct ReportList * reports
void WM_event_add_notifier(const bContext *C, uint type, void *reference)