Blender V5.0
mesh_data_update.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2005 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "DNA_cloth_types.h"
11#include "DNA_key_types.h"
12#include "DNA_mesh_types.h"
13#include "DNA_meshdata_types.h"
14#include "DNA_object_types.h"
15#include "DNA_scene_types.h"
16
17#include "BLI_linklist.h"
18#include "BLI_math_geom.h"
19#include "BLI_math_matrix.h"
21#include "BLI_span.hh"
22#include "BLI_string.h"
23#include "BLI_task.hh"
24#include "BLI_utildefines.h"
25#include "BLI_vector.hh"
26
27#include "BKE_editmesh.hh"
28#include "BKE_editmesh_cache.hh"
29#include "BKE_geometry_set.hh"
30#include "BKE_key.hh"
31#include "BKE_layer.hh"
32#include "BKE_lib_id.hh"
33#include "BKE_material.hh"
34#include "BKE_mesh.hh"
35#include "BKE_mesh_iterators.hh"
36#include "BKE_mesh_runtime.hh"
37#include "BKE_mesh_wrapper.hh"
38#include "BKE_modifier.hh"
39#include "BKE_multires.hh"
40#include "BKE_object.hh"
41#include "BKE_object_types.hh"
42#include "BKE_paint.hh"
43
44#include "BKE_shrinkwrap.hh"
45#include "DEG_depsgraph.hh"
47
48namespace blender::bke {
49
57// #define USE_MODIFIER_VALIDATE
58
59#ifdef USE_MODIFIER_VALIDATE
60# define ASSERT_IS_VALID_MESH_INPUT(mesh) (BLI_assert(BKE_mesh_is_valid(mesh) == true))
61# define ASSERT_IS_VALID_MESH_OUTPUT(mesh) \
62 (BLI_assert((mesh == nullptr) || (BKE_mesh_is_valid(mesh) == true)))
63#else
64# define ASSERT_IS_VALID_MESH_INPUT(mesh) \
65 { \
66 (void)mesh; \
67 };
68# define ASSERT_IS_VALID_MESH_OUTPUT(mesh) \
69 { \
70 (void)mesh; \
71 };
72
73#endif
74
75static void mesh_init_origspace(Mesh &mesh);
76
78{
79 CustomData_set_only_copy(&mesh->vert_data, mask->vmask);
80 CustomData_set_only_copy(&mesh->edge_data, mask->emask);
81 CustomData_set_only_copy(&mesh->fdata_legacy, mask->fmask);
82 /* this wasn't in 2.63 and is disabled for 2.64 because it gives problems with
83 * weight paint mode when there are modifiers applied, needs further investigation,
84 * see replies to r50969, Campbell */
85#if 0
86 CustomData_set_only_copy(&mesh->ldata, mask->lmask);
87 CustomData_set_only_copy(&mesh->pdata, mask->pmask);
88#endif
89}
90
91/* orco custom data layer */
93 const BMEditMesh *em,
94 eCustomDataType layer_type,
95 Array<float3> &storage)
96{
97 if (layer_type == CD_ORCO) {
98
99 if (em) {
100 storage = BM_mesh_vert_coords_alloc(em->bm);
101 return storage;
102 }
103 storage = BKE_mesh_orco_verts_get(&ob);
104 return storage;
105 }
106 if (layer_type == CD_CLOTH_ORCO) {
107 /* apply shape key for cloth, this should really be solved
108 * by a more flexible customdata system, but not simple */
109 if (!em) {
112 if (clmd && clmd->sim_parms->shapekey_rest) {
114 BKE_key_from_object(const_cast<Object *>(&ob)), clmd->sim_parms->shapekey_rest);
115
116 if (kb && kb->data) {
117 return {static_cast<const float3 *>(kb->data), kb->totelem};
118 }
119 }
120 }
121
122 return {};
123 }
124
125 return {};
126}
127
128static Mesh *create_orco_mesh(const Object &ob,
129 const Mesh &mesh,
130 const BMEditMesh *em,
131 eCustomDataType layer)
132{
133 Mesh *orco_mesh;
134 if (em) {
135 orco_mesh = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, nullptr, &mesh);
137 }
138 else {
139 orco_mesh = BKE_mesh_copy_for_eval(mesh);
140 }
141
142 Array<float3> storage;
143 const Span<float3> orco = get_orco_coords(ob, em, layer, storage);
144
145 if (!orco.is_empty()) {
146 orco_mesh->vert_positions_for_write().copy_from(orco);
147 orco_mesh->tag_positions_changed();
148 }
149
150 return orco_mesh;
151}
152
154{
155 void *data = CustomData_get_layer_for_write(&mesh.vert_data, layer, mesh.verts_num);
156 if (!data) {
157 data = CustomData_add_layer(&mesh.vert_data, layer, CD_CONSTRUCT, mesh.verts_num);
158 }
159 return MutableSpan(reinterpret_cast<float3 *>(data), mesh.verts_num);
160}
161
162static void add_orco_mesh(Object &ob,
163 const BMEditMesh *em,
164 Mesh &mesh,
165 const Mesh *mesh_orco,
166 const eCustomDataType layer)
167{
168 const int totvert = mesh.verts_num;
169
170 MutableSpan<float3> layer_orco;
171 if (mesh_orco) {
172 layer_orco = orco_coord_layer_ensure(mesh, layer);
173
174 if (mesh_orco->verts_num == totvert) {
175 layer_orco.copy_from(mesh_orco->vert_positions());
176 }
177 else {
178 layer_orco.copy_from(mesh.vert_positions());
179 }
180 }
181 else {
182 /* TODO(@sybren): `totvert` should potentially change here, as `ob->data`
183 * or `em` may have a different number of vertices than the evaluated `mesh`. */
184 Array<float3> storage;
185 const Span<float3> orco = get_orco_coords(ob, em, layer, storage);
186 if (!orco.is_empty()) {
187 layer_orco = orco_coord_layer_ensure(mesh, layer);
188 layer_orco.copy_from(orco);
189 }
190 }
191
192 if (!layer_orco.is_empty()) {
193 if (layer == CD_ORCO) {
194 BKE_mesh_orco_verts_transform((Mesh *)ob.data, layer_orco, false);
195 }
196 }
197}
198
205static void mesh_calc_finalize(const Mesh &mesh_input, Mesh &mesh_eval)
206{
207 /* Make sure the name is the same. This is because mesh allocation from template does not
208 * take care of naming. */
209 STRNCPY(mesh_eval.id.name, mesh_input.id.name);
210}
211
221 const ModifierEvalContext &mectx,
222 Mesh *input_mesh,
223 GeometrySet &geometry_set)
224{
225 Mesh *mesh_output = nullptr;
227 if (mti->modify_geometry_set == nullptr) {
228 mesh_output = BKE_modifier_modify_mesh(md, &mectx, input_mesh);
229 }
230 else {
231 /* For performance reasons, this should be called by the modifier and/or nodes themselves at
232 * some point. */
234
235 /* Replace only the mesh rather than the whole component, because the entire #MeshComponent
236 * might have been replaced by data from a different object in the node tree, which means the
237 * component contains vertex group name data for that object that should not be removed. */
238 geometry_set.replace_mesh(input_mesh, GeometryOwnershipType::Editable);
239
240 /* Let the modifier change the geometry set. */
241 mti->modify_geometry_set(md, &mectx, &geometry_set);
242
243 /* Release the mesh from the geometry set again. */
244 if (geometry_set.has<MeshComponent>()) {
245 MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
246 if (mesh_component.get() != input_mesh) {
247 /* Make sure the mesh component actually owns the mesh before taking over ownership. */
248 mesh_component.ensure_owns_direct_data();
249 }
250 mesh_output = mesh_component.release();
251 }
252 /* Need to ensure that non-mesh data is also owned by the geometry set. Otherwise it might be
253 * freed while there is still a reference to it in the geometry. */
254 geometry_set.ensure_owns_direct_data();
255
256 /* Return an empty mesh instead of null. */
257 if (mesh_output == nullptr) {
258 mesh_output = BKE_mesh_new_nomain(0, 0, 0, 0);
259 BKE_mesh_copy_parameters_for_eval(mesh_output, input_mesh);
260 }
261 }
262
263 return mesh_output;
264}
265
267{
268 MutableAttributeAccessor attributes = mesh.attributes_for_write();
269 const AttributeReader positions = attributes.lookup<float3>("position");
270 attributes.remove("rest_position");
271 if (positions) {
272 if (positions.sharing_info && positions.varray.is_span()) {
273 attributes.add<float3>("rest_position",
275 AttributeInitShared(positions.varray.get_internal_span().data(),
276 *positions.sharing_info));
277 }
278 else {
279 attributes.add<float3>(
280 "rest_position", AttrDomain::Point, AttributeInitVArray(positions.varray));
281 }
282 }
283}
284
285static void mesh_calc_modifiers(Depsgraph &depsgraph,
286 const Scene &scene,
287 Object &ob,
288 const bool use_deform,
289 const bool need_mapping,
290 const CustomData_MeshMasks &dataMask,
291 const bool use_cache,
292 const bool allow_shared_mesh,
293 /* return args */
294 Mesh **r_deform,
295 Mesh **r_final,
296 GeometrySet **r_geometry_set)
297{
298 /* Input mesh shouldn't be modified. */
299 Mesh &mesh_input = *static_cast<Mesh *>(ob.data);
300 /* The final mesh is the result of calculating all enabled modifiers. */
301 Mesh *mesh = nullptr;
302 /* The result of calculating all leading deform modifiers. */
303 Mesh *mesh_deform = nullptr;
304 /* This geometry set contains the non-mesh data that might be generated by modifiers. */
305 GeometrySet geometry_set_final;
306
308
309 /* Mesh with constructive modifiers but no deformation applied. Tracked
310 * along with final mesh if undeformed / orco coordinates are requested
311 * for texturing. */
312 Mesh *mesh_orco = nullptr;
313 Mesh *mesh_orco_cloth = nullptr;
314
315 /* Modifier evaluation modes. */
316 const bool use_render = (DEG_get_mode(&depsgraph) == DAG_EVAL_RENDER);
317 const int required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime;
318
319 /* Sculpt can skip certain modifiers. */
320 const bool has_multires = BKE_sculpt_multires_active(&scene, &ob) != nullptr;
321 bool multires_applied = false;
322 const bool sculpt_mode = ob.mode & OB_MODE_SCULPT && ob.sculpt && !use_render;
323 const bool sculpt_dyntopo = (sculpt_mode && ob.sculpt->bm) && !use_render;
324
325 /* Modifier evaluation contexts for different types of modifiers. */
326 ModifierApplyFlag apply_render = use_render ? MOD_APPLY_RENDER : ModifierApplyFlag(0);
327 ModifierApplyFlag apply_cache = use_cache ? MOD_APPLY_USECACHE : ModifierApplyFlag(0);
328 const ModifierEvalContext mectx = {&depsgraph, &ob, apply_render | apply_cache};
329 const ModifierEvalContext mectx_orco = {&depsgraph, &ob, apply_render | MOD_APPLY_ORCO};
330
331 /* Get effective list of modifiers to execute. Some effects like shape keys
332 * are added as virtual modifiers before the user created modifiers. */
333 VirtualModifierData virtual_modifier_data;
334 ModifierData *firstmd = BKE_modifiers_get_virtual_modifierlist(&ob, &virtual_modifier_data);
335 ModifierData *md = firstmd;
336
337 /* Compute accumulated datamasks needed by each modifier. It helps to do
338 * this fine grained so that for example vertex groups are preserved up to
339 * an armature modifier, but not through a following subsurf modifier where
340 * subdividing them is expensive. */
341 CustomData_MeshMasks final_datamask = dataMask;
342 CDMaskLink *datamasks = BKE_modifier_calc_data_masks(&scene, md, &final_datamask, required_mode);
343 CDMaskLink *md_datamask = datamasks;
344 /* XXX Always copying POLYINDEX, else tessellated data are no more valid! */
346
347 /* Clear errors before evaluation. */
349
351 if (mesh == nullptr) {
352 ASSERT_IS_VALID_MESH_INPUT(&mesh_input);
353 mesh = BKE_mesh_copy_for_eval(mesh_input);
355 }
357 }
358
359 /* Apply all leading deform modifiers. */
360 if (use_deform) {
361 for (; md; md = md->next, md_datamask = md_datamask->next) {
363
364 if (!BKE_modifier_is_enabled(&scene, md, required_mode)) {
365 continue;
366 }
367
368 if (mti->type == ModifierTypeType::OnlyDeform && !sculpt_dyntopo) {
369 ScopedModifierTimer modifier_timer{*md};
370 if (!mesh) {
371 ASSERT_IS_VALID_MESH_INPUT(&mesh_input);
372 mesh = BKE_mesh_copy_for_eval(mesh_input);
374 }
375
376 if (mti->required_data_mask) {
378 mti->required_data_mask(md, &mask);
379 if (mask.vmask & CD_MASK_ORCO) {
380 add_orco_mesh(ob, nullptr, *mesh, nullptr, CD_ORCO);
381 }
382 }
383
384 BKE_modifier_deform_verts(md, &mectx, mesh, mesh->vert_positions_for_write());
385 }
386 else {
387 break;
388 }
389 }
390
391 /* Result of all leading deforming modifiers is cached for
392 * places that wish to use the original mesh but with deformed
393 * coordinates (like vertex paint). */
394 if (r_deform) {
395 mesh_deform = BKE_mesh_copy_for_eval(mesh ? *mesh : mesh_input);
396 }
397 }
398
399 /* Apply all remaining constructive and deforming modifiers. */
400 bool have_non_onlydeform_modifiers_applied = false;
401 for (; md; md = md->next, md_datamask = md_datamask->next) {
403
404 if (!BKE_modifier_is_enabled(&scene, md, required_mode)) {
405 continue;
406 }
407
408 if (mti->type == ModifierTypeType::OnlyDeform && !use_deform) {
409 continue;
410 }
411
413 have_non_onlydeform_modifiers_applied)
414 {
415 BKE_modifier_set_error(&ob, md, "Modifier requires original data, bad stack position");
416 continue;
417 }
418
419 if (sculpt_mode && (!has_multires || multires_applied || sculpt_dyntopo)) {
420 bool unsupported = false;
421
422 if (md->type == eModifierType_Multires && ((MultiresModifierData *)md)->sculptlvl == 0) {
423 /* If multires is on level 0 skip it silently without warning message. */
424 if (!sculpt_dyntopo) {
425 continue;
426 }
427 }
428
429 if (sculpt_dyntopo) {
430 unsupported = true;
431 }
432
434 unsupported |= (mti->type != ModifierTypeType::OnlyDeform);
435 }
436
437 unsupported |= multires_applied;
438
439 if (unsupported) {
440 if (sculpt_dyntopo) {
441 BKE_modifier_set_error(&ob, md, "Not supported in dyntopo");
442 }
443 else {
444 BKE_modifier_set_error(&ob, md, "Not supported in sculpt mode");
445 }
446 continue;
447 }
448 }
449
450 if (need_mapping && !BKE_modifier_supports_mapping(md)) {
451 continue;
452 }
453
454 ScopedModifierTimer modifier_timer{*md};
455
456 /* Add orco mesh as layer if needed by this modifier. */
457 if (mesh && mesh_orco && mti->required_data_mask) {
459 mti->required_data_mask(md, &mask);
460 if (mask.vmask & CD_MASK_ORCO) {
461 add_orco_mesh(ob, nullptr, *mesh, mesh_orco, CD_ORCO);
462 }
463 }
464
466 if (!mesh) {
467 ASSERT_IS_VALID_MESH_INPUT(&mesh_input);
468 mesh = BKE_mesh_copy_for_eval(mesh_input);
470 }
471 BKE_modifier_deform_verts(md, &mectx, mesh, mesh->vert_positions_for_write());
472 }
473 else {
474 bool check_for_needs_mapping = false;
475 if (mesh != nullptr) {
476 if (have_non_onlydeform_modifiers_applied == false) {
477 /* If we only deformed, we won't have initialized #CD_ORIGINDEX.
478 * as this is the only part of the function that initializes mapping. */
479 check_for_needs_mapping = true;
480 }
481 }
482 else {
483 ASSERT_IS_VALID_MESH_INPUT(&mesh_input);
484 mesh = BKE_mesh_copy_for_eval(mesh_input);
486 check_for_needs_mapping = true;
487 }
488
489 have_non_onlydeform_modifiers_applied = true;
490
491 /* determine which data layers are needed by following modifiers */
492 CustomData_MeshMasks nextmask = md_datamask->next ? md_datamask->next->mask : final_datamask;
493
494 if (check_for_needs_mapping) {
495 /* Initialize original indices the first time we evaluate a
496 * constructive modifier. Modifiers will then do mapping mostly
497 * automatic by copying them through CustomData_copy_data along
498 * with other data.
499 *
500 * These are created when either requested by evaluation, or if
501 * following modifiers requested them. */
502 if (need_mapping ||
503 ((nextmask.vmask | nextmask.emask | nextmask.pmask) & CD_MASK_ORIGINDEX))
504 {
505 /* calc */
506 CustomData_add_layer(&mesh->vert_data, CD_ORIGINDEX, CD_CONSTRUCT, mesh->verts_num);
507 CustomData_add_layer(&mesh->edge_data, CD_ORIGINDEX, CD_CONSTRUCT, mesh->edges_num);
508 CustomData_add_layer(&mesh->face_data, CD_ORIGINDEX, CD_CONSTRUCT, mesh->faces_num);
509
510 /* Not worth parallelizing this,
511 * gives less than 0.1% overall speedup in best of best cases... */
513 &mesh->vert_data, CD_ORIGINDEX, mesh->verts_num),
514 mesh->verts_num,
515 0);
517 &mesh->edge_data, CD_ORIGINDEX, mesh->edges_num),
518 mesh->edges_num,
519 0);
521 &mesh->face_data, CD_ORIGINDEX, mesh->faces_num),
522 mesh->faces_num,
523 0);
524 }
525 }
526
527 /* set the Mesh to only copy needed data */
528 CustomData_MeshMasks mask = md_datamask->mask;
529 /* needMapping check here fixes bug #28112, otherwise it's
530 * possible that it won't be copied */
531 CustomData_MeshMasks_update(&mask, &append_mask);
532 if (need_mapping) {
533 mask.vmask |= CD_MASK_ORIGINDEX;
534 mask.emask |= CD_MASK_ORIGINDEX;
535 mask.pmask |= CD_MASK_ORIGINDEX;
536 }
538
539 /* add cloth rest shape key if needed */
540 if (mask.vmask & CD_MASK_CLOTH_ORCO) {
541 add_orco_mesh(ob, nullptr, *mesh, mesh_orco, CD_CLOTH_ORCO);
542 }
543
544 /* add an origspace layer if needed */
545 if ((md_datamask->mask.lmask) & CD_MASK_ORIGSPACE_MLOOP) {
546 if (!CustomData_has_layer(&mesh->corner_data, CD_ORIGSPACE_MLOOP)) {
548 &mesh->corner_data, CD_ORIGSPACE_MLOOP, CD_SET_DEFAULT, mesh->corners_num);
550 }
551 }
552
554 Mesh *mesh_next = modifier_modify_mesh_and_geometry_set(md, mectx, mesh, geometry_set_final);
556
557 if (mesh_next) {
558 /* if the modifier returned a new mesh, release the old one */
559 if (mesh != mesh_next) {
560 BLI_assert(mesh != &mesh_input);
561 BKE_id_free(nullptr, mesh);
562 }
563 mesh = mesh_next;
564 }
565
566 /* create an orco mesh in parallel */
567 if (nextmask.vmask & CD_MASK_ORCO) {
568 if (!mesh_orco) {
569 mesh_orco = create_orco_mesh(ob, mesh_input, nullptr, CD_ORCO);
570 }
571
572 nextmask.vmask &= ~CD_MASK_ORCO;
573 CustomData_MeshMasks temp_cddata_masks = {0};
574 temp_cddata_masks.vmask = CD_MASK_ORIGINDEX;
575 temp_cddata_masks.emask = CD_MASK_ORIGINDEX;
576 temp_cddata_masks.fmask = CD_MASK_ORIGINDEX;
577 temp_cddata_masks.pmask = CD_MASK_ORIGINDEX;
578
579 if (mti->required_data_mask != nullptr) {
580 mti->required_data_mask(md, &temp_cddata_masks);
581 }
582 CustomData_MeshMasks_update(&temp_cddata_masks, &nextmask);
583 mesh_set_only_copy(mesh_orco, &temp_cddata_masks);
584
586 mesh_next = BKE_modifier_modify_mesh(md, &mectx_orco, mesh_orco);
588
589 if (mesh_next) {
590 /* if the modifier returned a new mesh, release the old one */
591 if (mesh_orco != mesh_next) {
592 BLI_assert(mesh_orco != &mesh_input);
593 BKE_id_free(nullptr, mesh_orco);
594 }
595
596 mesh_orco = mesh_next;
597 }
598 }
599
600 /* create cloth orco mesh in parallel */
601 if (nextmask.vmask & CD_MASK_CLOTH_ORCO) {
602 if (!mesh_orco_cloth) {
603 mesh_orco_cloth = create_orco_mesh(ob, mesh_input, nullptr, CD_CLOTH_ORCO);
604 }
605
606 nextmask.vmask &= ~CD_MASK_CLOTH_ORCO;
607 nextmask.vmask |= CD_MASK_ORIGINDEX;
608 nextmask.emask |= CD_MASK_ORIGINDEX;
609 nextmask.pmask |= CD_MASK_ORIGINDEX;
610 mesh_set_only_copy(mesh_orco_cloth, &nextmask);
611
612 ASSERT_IS_VALID_MESH_INPUT(mesh_orco_cloth);
613 mesh_next = BKE_modifier_modify_mesh(md, &mectx_orco, mesh_orco_cloth);
615
616 if (mesh_next) {
617 /* if the modifier returned a new mesh, release the old one */
618 if (mesh_orco_cloth != mesh_next) {
619 BLI_assert(mesh_orco != &mesh_input);
620 BKE_id_free(nullptr, mesh_orco_cloth);
621 }
622
623 mesh_orco_cloth = mesh_next;
624 }
625 }
626
627 mesh->runtime->deformed_only = false;
628 }
629
630 if (sculpt_mode && md->type == eModifierType_Multires) {
631 multires_applied = true;
632 }
633 }
634
635 BLI_linklist_free((LinkNode *)datamasks, nullptr);
636
637 for (md = firstmd; md; md = md->next) {
639 }
640
641 if (mesh == nullptr) {
642 if (allow_shared_mesh) {
643 mesh = &mesh_input;
644 }
645 else {
646 mesh = BKE_mesh_copy_for_eval(mesh_input);
647 }
648 }
649
650 /* Denotes whether the object which the modifier stack came from owns the mesh or whether the
651 * mesh is shared across multiple objects since there are no effective modifiers. */
652 const bool is_own_mesh = (mesh != &mesh_input);
653
654 /* Add orco coordinates to final and deformed mesh if requested. */
655 if (final_datamask.vmask & CD_MASK_ORCO) {
656 /* No need in ORCO layer if the mesh was not deformed or modified: undeformed mesh in this case
657 * matches input mesh. */
658 if (is_own_mesh) {
659 add_orco_mesh(ob, nullptr, *mesh, mesh_orco, CD_ORCO);
660 }
661
662 if (mesh_deform) {
663 add_orco_mesh(ob, nullptr, *mesh_deform, nullptr, CD_ORCO);
664 }
665 }
666
667 if (mesh_orco) {
668 BKE_id_free(nullptr, mesh_orco);
669 }
670 if (mesh_orco_cloth) {
671 BKE_id_free(nullptr, mesh_orco_cloth);
672 }
673
674 /* Remove temporary data layer only needed for modifier evaluation.
675 * Save some memory, and ensure GPU subdivision does not need to deal with this. */
677
678 /* Compute normals. */
679 if (is_own_mesh) {
680 mesh_calc_finalize(mesh_input, *mesh);
681 }
682 else {
683 MeshRuntime *runtime = mesh_input.runtime;
684 if (runtime->mesh_eval == nullptr) {
685 std::lock_guard lock{mesh_input.runtime->eval_mutex};
686 if (runtime->mesh_eval == nullptr) {
687 /* Not yet finalized by any instance, do it now
688 * Isolate since computing normals is multithreaded and we are holding a lock. */
690 mesh = BKE_mesh_copy_for_eval(mesh_input);
691 mesh_calc_finalize(mesh_input, *mesh);
692 runtime->mesh_eval = mesh;
693 });
694 }
695 else {
696 /* Already finalized by another instance, reuse. */
697 mesh = runtime->mesh_eval;
698 }
699 }
700 else {
701 /* Already finalized by another instance, reuse. */
702 mesh = runtime->mesh_eval;
703 }
704 }
705
706 /* Return final mesh */
707 *r_final = mesh;
708 if (r_deform) {
709 *r_deform = mesh_deform;
710 }
711 if (r_geometry_set) {
712 *r_geometry_set = new GeometrySet(std::move(geometry_set_final));
713 }
714}
715
717 const Object *ob,
718 ModifierData *md,
719 bool has_prev_mesh)
720{
722 const int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
723
724 if (!BKE_modifier_is_enabled(scene, md, required_mode)) {
725 return false;
726 }
727
728 if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && has_prev_mesh) {
729 BKE_modifier_set_error(ob, md, "Modifier requires original data, bad stack position");
730 return false;
731 }
732
733 return true;
734}
735
737{
738 switch (mesh->runtime->wrapper_type) {
740 if (mesh->runtime->edit_data->vert_positions.is_empty()) {
741 mesh->runtime->edit_data->vert_positions = BM_mesh_vert_coords_alloc(
742 mesh->runtime->edit_mesh->bm);
743 }
744 return mesh->runtime->edit_data->vert_positions;
747 return mesh->vert_positions_for_write();
748 }
750 return {};
751}
752
753static void editbmesh_calc_modifiers(Depsgraph &depsgraph,
754 const Scene &scene,
755 Object &ob,
756 const CustomData_MeshMasks &dataMask,
757 /* return args */
758 Mesh **r_cage,
759 Mesh **r_final,
760 GeometrySet **r_geometry_set)
761{
762 Mesh &mesh_input = *static_cast<Mesh *>(ob.data);
763 BMEditMesh &em_input = *mesh_input.runtime->edit_mesh;
764
765 Mesh *mesh_cage = nullptr;
766 /* This geometry set contains the non-mesh data that might be generated by modifiers. */
767 GeometrySet geometry_set_final;
768
769 /* Mesh with constructive modifiers but no deformation applied. Tracked
770 * along with final mesh if undeformed / orco coordinates are requested
771 * for texturing. */
772 Mesh *mesh_orco = nullptr;
773
774 /* Modifier evaluation modes. */
775 const int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
776
777 const bool use_render = (DEG_get_mode(&depsgraph) == DAG_EVAL_RENDER);
778 /* Modifier evaluation contexts for different types of modifiers. */
779 ModifierApplyFlag apply_render = use_render ? MOD_APPLY_RENDER : ModifierApplyFlag(0);
780 const ModifierEvalContext mectx = {&depsgraph, &ob, MOD_APPLY_USECACHE | apply_render};
781 const ModifierEvalContext mectx_orco = {&depsgraph, &ob, MOD_APPLY_ORCO};
782
783 /* Get effective list of modifiers to execute. Some effects like shape keys
784 * are added as virtual modifiers before the user created modifiers. */
785 VirtualModifierData virtual_modifier_data;
786 ModifierData *md = BKE_modifiers_get_virtual_modifierlist(&ob, &virtual_modifier_data);
787
788 /* Compute accumulated datamasks needed by each modifier. It helps to do
789 * this fine grained so that for example vertex groups are preserved up to
790 * an armature modifier, but not through a following subsurf modifier where
791 * subdividing them is expensive. */
792 CustomData_MeshMasks final_datamask = dataMask;
793 CDMaskLink *datamasks = BKE_modifier_calc_data_masks(&scene, md, &final_datamask, required_mode);
794 CDMaskLink *md_datamask = datamasks;
796
798 mesh_input.runtime->edit_mesh, &final_datamask, &mesh_input);
799
800 int cageIndex = BKE_modifiers_get_cage_index(&scene, &ob, nullptr, true);
801 if (r_cage && cageIndex == -1) {
802 mesh_cage = mesh;
803 }
804
805 /* The mesh from edit mode should not have any original index layers already, since those
806 * are added during evaluation when necessary and are redundant on an original mesh. */
807 BLI_assert(CustomData_get_layer(&em_input.bm->pdata, CD_ORIGINDEX) == nullptr &&
808 CustomData_get_layer(&em_input.bm->edata, CD_ORIGINDEX) == nullptr &&
809 CustomData_get_layer(&em_input.bm->pdata, CD_ORIGINDEX) == nullptr);
810
811 /* Clear errors before evaluation. */
813
817 }
818
819 bool non_deform_modifier_applied = false;
820 for (int i = 0; md; i++, md = md->next, md_datamask = md_datamask->next) {
822 if (!editbmesh_modifier_is_enabled(&scene, &ob, md, non_deform_modifier_applied)) {
823 continue;
824 }
825
826 ScopedModifierTimer modifier_timer{*md};
827
828 /* Add an orco mesh as layer if needed by this modifier. */
829 if (mesh_orco && mti->required_data_mask) {
831 mti->required_data_mask(md, &mask);
832 if (mask.vmask & CD_MASK_ORCO) {
833 add_orco_mesh(ob, &em_input, *mesh, mesh_orco, CD_ORCO);
834 }
835 }
836
837 if (mesh == mesh_cage) {
838 /* If the cage mesh has already been assigned, we have passed the cage index in the modifier
839 * list. If the cage and final meshes are still the same, duplicate the final mesh so the
840 * cage mesh isn't modified anymore. */
842 if (mesh_cage->runtime->edit_mesh) {
843 mesh->runtime->is_original_bmesh = true;
844 mesh->runtime->deformed_only = mesh_cage->runtime->deformed_only;
845 if (mesh_cage->runtime->edit_data) {
846 mesh->runtime->edit_data = std::make_unique<EditMeshData>(
847 *mesh_cage->runtime->edit_data);
848 }
849 }
850 }
851
853 if (mti->deform_verts_EM) {
855 md, &mectx, &em_input, mesh, mesh_wrapper_vert_coords_ensure_for_write(mesh));
857 }
858 else {
860 BKE_modifier_deform_verts(md, &mectx, mesh, mesh->vert_positions_for_write());
861 mesh->tag_positions_changed();
862 }
863 }
864 else {
865 non_deform_modifier_applied = true;
866
867 /* create an orco derivedmesh in parallel */
868 CustomData_MeshMasks mask = md_datamask->mask;
869 if (mask.vmask & CD_MASK_ORCO) {
870 if (!mesh_orco) {
871 mesh_orco = create_orco_mesh(ob, mesh_input, &em_input, CD_ORCO);
872 }
873
874 mask.vmask &= ~CD_MASK_ORCO;
875 mask.vmask |= CD_MASK_ORIGINDEX;
876 mask.emask |= CD_MASK_ORIGINDEX;
877 mask.pmask |= CD_MASK_ORIGINDEX;
878 mesh_set_only_copy(mesh_orco, &mask);
879
881 Mesh *mesh_next = BKE_modifier_modify_mesh(md, &mectx_orco, mesh_orco);
883
884 if (mesh_next) {
885 /* if the modifier returned a new dm, release the old one */
886 if (mesh_orco && mesh_orco != mesh_next) {
887 BKE_id_free(nullptr, mesh_orco);
888 }
889 mesh_orco = mesh_next;
890 }
891 }
892
893 /* set the DerivedMesh to only copy needed data */
894 CustomData_MeshMasks_update(&mask, &append_mask);
895 /* XXX WHAT? overwrites mask ??? */
896 /* CD_MASK_ORCO may have been cleared above */
897 mask = md_datamask->mask;
898 mask.vmask |= CD_MASK_ORIGINDEX;
899 mask.emask |= CD_MASK_ORIGINDEX;
900 mask.pmask |= CD_MASK_ORIGINDEX;
901
903
904 if (mask.lmask & CD_MASK_ORIGSPACE_MLOOP) {
905 if (!CustomData_has_layer(&mesh->corner_data, CD_ORIGSPACE_MLOOP)) {
907 &mesh->corner_data, CD_ORIGSPACE_MLOOP, CD_SET_DEFAULT, mesh->corners_num);
909 }
910 }
911
913 Mesh *mesh_next = modifier_modify_mesh_and_geometry_set(md, mectx, mesh, geometry_set_final);
915
916 if (mesh_next) {
917 if (mesh != mesh_next) {
918 BKE_id_free(nullptr, mesh);
919 }
920 mesh = mesh_next;
921 }
922 mesh->runtime->deformed_only = false;
923 }
924
925 if (r_cage && i == cageIndex) {
926 mesh_cage = mesh;
927 }
928 }
929
930 BLI_linklist_free((LinkNode *)datamasks, nullptr);
931
932 /* Add orco coordinates to final and deformed mesh if requested. */
933 if (final_datamask.vmask & CD_MASK_ORCO) {
934 /* FIXME(@ideasman42): avoid the need to convert to mesh data just to add an orco layer. */
936
937 add_orco_mesh(ob, &em_input, *mesh, mesh_orco, CD_ORCO);
938 }
939
940 if (mesh_orco) {
941 BKE_id_free(nullptr, mesh_orco);
942 }
943
944 /* Return final mesh. */
945 *r_final = mesh;
946 if (r_cage) {
947 *r_cage = mesh_cage;
948 }
949 if (r_geometry_set) {
950 *r_geometry_set = new GeometrySet(std::move(geometry_set_final));
951 }
952}
953
954static void mesh_build_extra_data(const Depsgraph &depsgraph,
955 const Object &ob,
956 const Mesh &mesh_eval)
957{
958 uint32_t eval_flags = DEG_get_eval_flags_for_id(&depsgraph, &ob.id);
959
960 if (eval_flags & DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY) {
962 }
963}
964
965static void mesh_build_data(Depsgraph &depsgraph,
966 const Scene &scene,
967 Object &ob,
968 const CustomData_MeshMasks &dataMask,
969 const bool need_mapping)
970{
971#if 0 /* XXX This is already taken care of in #mesh_calc_modifiers... */
972 if (need_mapping) {
973 /* Also add the flag so that it is recorded in lastDataMask. */
974 dataMask->vmask |= CD_MASK_ORIGINDEX;
975 dataMask->emask |= CD_MASK_ORIGINDEX;
976 dataMask->pmask |= CD_MASK_ORIGINDEX;
977 }
978#endif
979
980 Mesh *mesh_eval = nullptr, *mesh_deform_eval = nullptr;
981 GeometrySet *geometry_set_eval = nullptr;
983 scene,
984 ob,
985 true,
986 need_mapping,
987 dataMask,
988 true,
989 true,
990 &mesh_deform_eval,
991 &mesh_eval,
992 &geometry_set_eval);
993
994 /* The modifier stack evaluation is storing result in mesh->runtime.mesh_eval, but this result
995 * is not guaranteed to be owned by object.
996 *
997 * Check ownership now, since later on we can not go to a mesh owned by someone else via
998 * object's runtime: this could cause access freed data on depsgraph destruction (mesh who owns
999 * the final result might be freed prior to object). */
1000 Mesh *mesh = (Mesh *)ob.data;
1001 const bool is_mesh_eval_owned = (mesh_eval != mesh->runtime->mesh_eval);
1002 BKE_object_eval_assign_data(&ob, &mesh_eval->id, is_mesh_eval_owned);
1003
1004 /* Add the final mesh as a non-owning component to the geometry set. */
1005 MeshComponent &mesh_component = geometry_set_eval->get_component_for_write<MeshComponent>();
1006 mesh_component.replace(mesh_eval, GeometryOwnershipType::Editable);
1007 ob.runtime->geometry_set_eval = geometry_set_eval;
1008
1009 ob.runtime->mesh_deform_eval = mesh_deform_eval;
1010 ob.runtime->last_data_mask = dataMask;
1011 ob.runtime->last_need_mapping = need_mapping;
1012
1013 /* Make sure that drivers can target shapekey properties.
1014 * Note that this causes a potential inconsistency, as the shapekey may have a
1015 * different topology than the evaluated mesh. */
1016 BLI_assert(mesh->key == nullptr || DEG_is_evaluated(mesh->key));
1017 mesh_eval->key = mesh->key;
1018
1019 if ((ob.mode & OB_MODE_ALL_SCULPT) && ob.sculpt) {
1020 if (DEG_is_active(&depsgraph)) {
1022 }
1023 }
1024
1025 mesh_build_extra_data(depsgraph, ob, *mesh_eval);
1026}
1027
1028static void editbmesh_build_data(Depsgraph &depsgraph,
1029 const Scene &scene,
1030 Object &obedit,
1031 CustomData_MeshMasks &dataMask)
1032{
1033 Mesh *mesh = static_cast<Mesh *>(obedit.data);
1034 Mesh *me_cage;
1035 Mesh *me_final;
1036 GeometrySet *geometry_set_eval;
1037
1039 depsgraph, scene, obedit, dataMask, &me_cage, &me_final, &geometry_set_eval);
1040
1041 const bool is_mesh_eval_owned = (me_final != mesh->runtime->mesh_eval);
1042 BKE_object_eval_assign_data(&obedit, &me_final->id, is_mesh_eval_owned);
1043
1044 /* Add the final mesh as a non-owning component to the geometry set. */
1045 MeshComponent &mesh_component = geometry_set_eval->get_component_for_write<MeshComponent>();
1046 mesh_component.replace(me_final, GeometryOwnershipType::Editable);
1047 obedit.runtime->geometry_set_eval = geometry_set_eval;
1048
1049 /* Make sure that drivers can target shapekey properties.
1050 * Note that this causes a potential inconsistency, as the shapekey may have a
1051 * different topology than the evaluated mesh. */
1052 BLI_assert(mesh->key == nullptr || DEG_is_evaluated(mesh->key));
1053 me_final->key = mesh->key;
1054
1055 obedit.runtime->editmesh_eval_cage = me_cage;
1056
1057 obedit.runtime->last_data_mask = dataMask;
1058}
1059
1060static void object_get_datamask(const Depsgraph &depsgraph,
1061 Object &ob,
1062 CustomData_MeshMasks &r_mask,
1063 bool *r_need_mapping)
1064{
1067
1069
1070 if (r_need_mapping) {
1071 *r_need_mapping = false;
1072 }
1073
1074 /* Must never access original objects when dependency graph is not active: it might be already
1075 * freed. */
1076 if (!DEG_is_active(&depsgraph)) {
1077 return;
1078 }
1079
1080 BKE_view_layer_synced_ensure(scene, view_layer);
1081 Object *actob = BKE_view_layer_active_object_get(view_layer);
1082 if (actob) {
1083 actob = DEG_get_original(actob);
1084 }
1085 if (DEG_get_original(&ob) == actob) {
1086 bool editing = BKE_paint_select_face_test(actob);
1087
1088 /* weight paint and face select need original indices because of selection buffer drawing */
1089 if (r_need_mapping) {
1090 *r_need_mapping = (editing || (ob.mode & (OB_MODE_WEIGHT_PAINT | OB_MODE_VERTEX_PAINT)));
1091 }
1092
1093 /* Check if we need #MTFace & loop-color due to face select or texture paint. */
1094 if ((ob.mode & OB_MODE_TEXTURE_PAINT) || editing) {
1096 r_mask.fmask |= CD_MASK_MTFACE;
1097 }
1098
1099 /* Check if we need loop-color due to vertex paint or weight-paint. */
1100 if (ob.mode & OB_MODE_VERTEX_PAINT) {
1102 }
1103
1104 if (ob.mode & OB_MODE_WEIGHT_PAINT) {
1105 r_mask.vmask |= CD_MASK_MDEFORMVERT;
1106 }
1107 }
1108
1109 /* Multiple objects can be in edit-mode at once. */
1110 if (actob && (actob->mode & OB_MODE_EDIT)) {
1111 if (ob.mode & OB_MODE_EDIT) {
1112 r_mask.vmask |= CD_MASK_MVERT_SKIN;
1113 }
1114 }
1115}
1116
1118 const Scene &scene,
1119 Object &ob,
1120 const CustomData_MeshMasks &dataMask)
1121{
1122 BLI_assert(ob.type == OB_MESH);
1123
1124 /* Evaluated meshes aren't supposed to be created on original instances. If you do,
1125 * they aren't cleaned up properly on mode switch, causing crashes, e.g #58150. */
1127
1129 if (DEG_is_active(&depsgraph)) {
1131 }
1132
1133 /* NOTE: Access the `edit_mesh` after freeing the derived caches, so that `ob.data` is restored
1134 * to the pre-evaluated state. This is because the evaluated state is not necessarily sharing the
1135 * `edit_mesh` pointer with the input. For example, if the object is first evaluated in the
1136 * object mode, and then user in another scene moves object to edit mode. */
1137 Mesh *mesh = static_cast<Mesh *>(ob.data);
1138
1139 bool need_mapping;
1140 CustomData_MeshMasks cddata_masks = dataMask;
1141 object_get_datamask(depsgraph, ob, cddata_masks, &need_mapping);
1142
1143 if (mesh->runtime->edit_mesh) {
1144 editbmesh_build_data(depsgraph, scene, ob, cddata_masks);
1145 }
1146 else {
1147 mesh_build_data(depsgraph, scene, ob, cddata_masks, need_mapping);
1148 }
1149}
1150
1152 const Scene *scene,
1153 Object *ob,
1154 const CustomData_MeshMasks *dataMask)
1155{
1156 BMEditMesh *em = ((Mesh *)ob->data)->runtime->edit_mesh.get();
1157 if (em != nullptr) {
1158 /* There is no such a concept as deformed mesh in edit mode.
1159 * Explicitly disallow this request so that the evaluated result is not modified with evaluated
1160 * result from the wrong mode. */
1161 BLI_assert_msg(0, "Request of deformed mesh of object which is in edit mode");
1162 return nullptr;
1163 }
1164
1165 /* This function isn't thread-safe and can't be used during evaluation. */
1167
1168 /* Evaluated meshes aren't supposed to be created on original instances. If you do,
1169 * they aren't cleaned up properly on mode switch, causing crashes, e.g #58150. */
1171
1172 /* If there's no evaluated mesh or the last data mask used doesn't include
1173 * the data we need, rebuild the evaluated mesh. */
1174 bool need_mapping;
1175
1176 CustomData_MeshMasks cddata_masks = *dataMask;
1177 object_get_datamask(*depsgraph, *ob, cddata_masks, &need_mapping);
1178
1179 if (!ob->runtime->mesh_deform_eval ||
1180 !CustomData_MeshMasks_are_matching(&(ob->runtime->last_data_mask), &cddata_masks) ||
1181 (need_mapping && !ob->runtime->last_need_mapping))
1182 {
1183 /* FIXME: this block may leak memory (& assert) because it runs #BKE_object_eval_assign_data
1184 * intended only to run during depsgraph-evaluation that overwrites the evaluated mesh
1185 * without freeing beforehand, see: !128228. */
1186 CustomData_MeshMasks_update(&cddata_masks, &ob->runtime->last_data_mask);
1188 *depsgraph, *scene, *ob, cddata_masks, need_mapping || ob->runtime->last_need_mapping);
1189 }
1190
1191 return ob->runtime->mesh_deform_eval;
1192}
1193
1195 const Scene *scene,
1196 Object *ob,
1197 const CustomData_MeshMasks *dataMask)
1198{
1199 Mesh *result;
1201 *depsgraph, *scene, *ob, true, false, *dataMask, false, false, nullptr, &result, nullptr);
1202 return result;
1203}
1204
1206 const Scene *scene,
1207 Object *ob,
1208 const CustomData_MeshMasks *dataMask)
1209{
1210 Mesh *result;
1212 *depsgraph, *scene, *ob, false, false, *dataMask, false, false, nullptr, &result, nullptr);
1213 return result;
1214}
1215
1217 const Scene *scene,
1218 Object *ob,
1219 const CustomData_MeshMasks *dataMask)
1220{
1221 Mesh *result;
1223 *depsgraph, *scene, *ob, false, false, *dataMask, false, false, nullptr, &result, nullptr);
1224 return result;
1225}
1226
1228 const Scene *scene,
1229 Object *obedit,
1230 BMEditMesh * /*em*/,
1231 const CustomData_MeshMasks *dataMask)
1232{
1233 CustomData_MeshMasks cddata_masks = *dataMask;
1234
1235 /* If there's no evaluated mesh or the last data mask used doesn't include
1236 * the data we need, rebuild the evaluated mesh. */
1237 object_get_datamask(*depsgraph, *obedit, cddata_masks, nullptr);
1238
1239 if (!obedit->runtime->editmesh_eval_cage ||
1240 !CustomData_MeshMasks_are_matching(&(obedit->runtime->last_data_mask), &cddata_masks))
1241 {
1242 /* FIXME: this block may leak memory (& assert) because it runs #BKE_object_eval_assign_data
1243 * intended only to run during depsgraph-evaluation that overwrites the evaluated mesh
1244 * without freeing beforehand, see: !128228. */
1245 editbmesh_build_data(*depsgraph, *scene, *obedit, cddata_masks);
1246 }
1247
1248 return obedit->runtime->editmesh_eval_cage;
1249}
1250
1252 const Scene *scene,
1253 Object *obedit,
1254 const CustomData_MeshMasks *dataMask)
1255{
1256 BLI_assert((obedit->id.tag & ID_TAG_COPIED_ON_EVAL) == 0);
1257 const Scene *scene_eval = DEG_get_evaluated(depsgraph, scene);
1258 Object *obedit_eval = DEG_get_evaluated(depsgraph, obedit);
1259 BMEditMesh *em_eval = BKE_editmesh_from_object(obedit_eval);
1260 return editbmesh_get_eval_cage(depsgraph, scene_eval, obedit_eval, em_eval, dataMask);
1261}
1262
1267
1268static void make_vertexcos__mapFunc(void *user_data,
1269 int index,
1270 const float co[3],
1271 const float /*no*/[3])
1272{
1273 MappedUserData *mappedData = (MappedUserData *)user_data;
1274
1275 if (!mappedData->vertex_visit[index]) {
1276 mappedData->vertexcos[index] = float3(co);
1277 mappedData->vertex_visit[index].set();
1278 }
1279}
1280
1282{
1283 if (mesh_eval->runtime->deformed_only == false) {
1284 MappedUserData user_data;
1285 r_cos.fill(float3(0));
1286 user_data.vertexcos = r_cos;
1287 user_data.vertex_visit.resize(r_cos.size());
1289 }
1290 else {
1291 r_cos.copy_from(BKE_mesh_wrapper_vert_coords(mesh_eval));
1292 }
1293}
1294
1296{
1297 const float default_osf[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
1298
1300 &mesh.corner_data, CD_ORIGSPACE_MLOOP, mesh.corners_num);
1301 const Span<float3> positions = mesh.vert_positions();
1302 const OffsetIndices faces = mesh.faces();
1303 const Span<int> corner_verts = mesh.corner_verts();
1304
1305 int j, k;
1306
1307 Vector<float2, 64> vcos_2d;
1308
1309 for (const int i : faces.index_range()) {
1310 const IndexRange face = faces[i];
1311 OrigSpaceLoop *lof = lof_array + face.start();
1312
1313 if (ELEM(face.size(), 3, 4)) {
1314 for (j = 0; j < face.size(); j++, lof++) {
1315 copy_v2_v2(lof->uv, default_osf[j]);
1316 }
1317 }
1318 else {
1319 float co[3];
1320 float mat[3][3];
1321
1322 float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX};
1323 float translate[2], scale[2];
1324
1325 const float3 p_nor = mesh::face_normal_calc(positions, corner_verts.slice(face));
1326
1327 axis_dominant_v3_to_m3(mat, p_nor);
1328
1329 vcos_2d.resize(face.size());
1330 for (j = 0; j < face.size(); j++) {
1331 mul_v3_m3v3(co, mat, positions[corner_verts[face[j]]]);
1332 copy_v2_v2(vcos_2d[j], co);
1333
1334 for (k = 0; k < 2; k++) {
1335 if (co[k] > max[k]) {
1336 max[k] = co[k];
1337 }
1338 else if (co[k] < min[k]) {
1339 min[k] = co[k];
1340 }
1341 }
1342 }
1343
1344 /* Brings min to (0, 0). */
1345 negate_v2_v2(translate, min);
1346
1347 /* Scale will bring max to (1, 1). */
1348 sub_v2_v2v2(scale, max, min);
1349 if (scale[0] == 0.0f) {
1350 scale[0] = 1e-9f;
1351 }
1352 if (scale[1] == 0.0f) {
1353 scale[1] = 1e-9f;
1354 }
1355 invert_v2(scale);
1356
1357 /* Finally, transform all vcos_2d into ((0, 0), (1, 1))
1358 * square and assign them as origspace. */
1359 for (j = 0; j < face.size(); j++, lof++) {
1360 add_v2_v2v2(lof->uv, vcos_2d[j], translate);
1361 mul_v2_v2(lof->uv, scale);
1362 }
1363 }
1364 }
1365
1367}
1368
1369} // namespace blender::bke
void CustomData_set_only_copy(const CustomData *data, eCustomDataMask mask)
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX
@ CD_SET_DEFAULT
@ CD_CONSTRUCT
void CustomData_MeshMasks_update(CustomData_MeshMasks *mask_dst, const CustomData_MeshMasks *mask_src)
Definition customdata.cc:96
bool CustomData_MeshMasks_are_matching(const CustomData_MeshMasks *mask_ref, const CustomData_MeshMasks *mask_required)
const CustomData_MeshMasks CD_MASK_BAREMESH
void CustomData_free_layers(CustomData *data, eCustomDataType type)
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)
BMEditMesh * BKE_editmesh_from_object(Object *ob)
Return the BMEditMesh for a given object.
Definition editmesh.cc:61
KeyBlock * BKE_keyblock_find_by_index(Key *key, int index)
Definition key.cc:1907
Key * BKE_key_from_object(Object *ob)
Definition key.cc:1791
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_id_free(Main *bmain, void *idv)
General operations, lookup, etc. for materials.
void BKE_mesh_copy_parameters_for_eval(Mesh *me_dst, const Mesh *me_src)
void BKE_mesh_tessface_clear(Mesh *mesh)
blender::Array< blender::float3 > BKE_mesh_orco_verts_get(const Object *ob)
void BKE_mesh_orco_verts_transform(Mesh *mesh, blender::MutableSpan< blender::float3 > orco, bool invert)
Mesh * BKE_mesh_new_nomain(int verts_num, int edges_num, int faces_num, int corners_num)
Mesh * BKE_mesh_copy_for_eval(const Mesh &source)
Mesh * BKE_mesh_from_bmesh_for_eval_nomain(BMesh *bm, const CustomData_MeshMasks *cd_mask_extra, const Mesh *me_settings)
void BKE_mesh_ensure_default_orig_index_customdata(Mesh *mesh)
@ MESH_FOREACH_NOP
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)
@ ME_WRAPPER_TYPE_MDATA
@ ME_WRAPPER_TYPE_SUBD
@ ME_WRAPPER_TYPE_BMESH
blender::Span< blender::float3 > BKE_mesh_wrapper_vert_coords(const Mesh *mesh)
Mesh * BKE_mesh_wrapper_from_editmesh(std::shared_ptr< BMEditMesh > em, const CustomData_MeshMasks *cd_mask_extra, const Mesh *me_settings)
void BKE_mesh_wrapper_ensure_mdata(Mesh *mesh)
void BKE_mesh_wrapper_tag_positions_changed(Mesh *mesh)
void BKE_modifiers_clear_errors(Object *ob)
bool BKE_modifier_is_enabled(const Scene *scene, ModifierData *md, int required_mode)
int BKE_modifiers_get_cage_index(const Scene *scene, Object *ob, int *r_lastPossibleCageIndex, bool is_virtual)
ModifierData * BKE_modifiers_findby_type(const Object *ob, ModifierType type)
const ModifierTypeInfo * BKE_modifier_get_info(ModifierType type)
CDMaskLink * BKE_modifier_calc_data_masks(const Scene *scene, ModifierData *md, CustomData_MeshMasks *final_datamask, int required_mode)
@ eModifierTypeFlag_RequiresOriginalData
bool BKE_modifier_supports_mapping(ModifierData *md)
void BKE_modifier_free_temporary_data(ModifierData *md)
Mesh * BKE_modifier_modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
void BKE_modifier_set_error(const Object *ob, ModifierData *md, const char *format,...) ATTR_PRINTF_FORMAT(3
bool BKE_modifier_deform_verts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, blender::MutableSpan< blender::float3 > positions)
void BKE_modifier_deform_vertsEM(ModifierData *md, const ModifierEvalContext *ctx, const BMEditMesh *em, Mesh *mesh, blender::MutableSpan< blender::float3 > positions)
ModifierData * BKE_modifiers_get_virtual_modifierlist(const Object *ob, VirtualModifierData *data)
ModifierApplyFlag
@ MOD_APPLY_USECACHE
@ MOD_APPLY_RENDER
@ MOD_APPLY_ORCO
General operations, lookup, etc. for blender objects.
void BKE_object_eval_assign_data(Object *object, ID *data, bool is_owned)
void BKE_object_free_derived_caches(Object *ob)
void BKE_sculpt_update_object_after_eval(Depsgraph *depsgraph, Object *ob_eval)
Definition paint.cc:2764
void BKE_sculpt_update_object_before_eval(Object *ob_eval)
Definition paint.cc:2705
MultiresModifierData * BKE_sculpt_multires_active(const Scene *scene, Object *ob)
Definition paint.cc:2513
bool BKE_paint_select_face_test(const Object *ob)
Definition paint.cc:1640
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3])
Normal to x,y matrix.
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
MINLINE void mul_v2_v2(float r[2], const float a[2])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void negate_v2_v2(float r[2], const float a[2])
void range_vn_i(int *array_tar, int size, int start)
MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void invert_v2(float r[2])
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:693
#define ELEM(...)
bool DEG_is_evaluating(const Depsgraph *depsgraph)
Definition depsgraph.cc:317
@ DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY
@ DAG_EVAL_RENDER
bool DEG_is_active(const Depsgraph *depsgraph)
Definition depsgraph.cc:323
uint32_t DEG_get_eval_flags_for_id(const Depsgraph *graph, const ID *id)
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
bool DEG_is_evaluated(const T *id)
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
ViewLayer * DEG_get_evaluated_view_layer(const Depsgraph *graph)
T * DEG_get_original(T *id)
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
void DEG_get_customdata_mask_for_object(const Depsgraph *graph, Object *object, CustomData_MeshMasks *r_mask)
@ ID_TAG_COPIED_ON_EVAL
Definition DNA_ID.h:997
@ ID_TAG_COPIED_ON_EVAL_FINAL_RESULT
Definition DNA_ID.h:1007
#define CD_MASK_PROP_BYTE_COLOR
#define CD_MASK_ORIGINDEX
#define CD_MASK_ORCO
#define CD_MASK_MDEFORMVERT
#define CD_MASK_MVERT_SKIN
#define CD_MASK_PROP_FLOAT2
#define CD_MASK_MTFACE
#define CD_MASK_ORIGSPACE_MLOOP
@ CD_ORIGSPACE_MLOOP
@ CD_CLOTH_ORCO
#define CD_MASK_CLOTH_ORCO
@ eModifierMode_Render
@ eModifierMode_Editmode
@ eModifierMode_Realtime
@ eModifierType_Cloth
@ eModifierType_Multires
@ OB_MODE_EDIT
@ OB_MODE_WEIGHT_PAINT
@ OB_MODE_SCULPT
@ OB_MODE_TEXTURE_PAINT
@ OB_MODE_VERTEX_PAINT
#define OB_MODE_ALL_SCULPT
Object is a sort of wrapper for general info.
@ OB_MODIFIER_FLAG_ADD_REST_POSITION
@ OB_MESH
@ SCULPT_ONLY_DEFORM
volatile int lock
BMesh const char void * data
Array< float3 > BM_mesh_vert_coords_alloc(BMesh *bm)
BPy_StructRNA * depsgraph
constexpr int64_t size() const
constexpr int64_t start() const
constexpr int64_t size() const
Definition BLI_span.hh:493
constexpr bool is_empty() const
Definition BLI_span.hh:509
constexpr void fill(const T &value) const
Definition BLI_span.hh:517
constexpr void copy_from(Span< T > values) const
Definition BLI_span.hh:739
constexpr Span slice(int64_t start, int64_t size) const
Definition BLI_span.hh:137
constexpr bool is_empty() const
Definition BLI_span.hh:260
void resize(const int64_t new_size)
void resize(const int64_t new_size_in_bits, const bool value=false)
GAttributeReader lookup(const StringRef attribute_id) const
void replace(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
bool add(const StringRef attribute_id, const AttrDomain domain, const AttrType data_type, const AttributeInit &initializer)
bool remove(const StringRef attribute_id)
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
static char faces[256]
#define ASSERT_IS_VALID_MESH_INPUT(mesh)
#define ASSERT_IS_VALID_MESH_OUTPUT(mesh)
float3 face_normal_calc(Span< float3 > vert_positions, Span< int > face_verts)
const ShrinkwrapBoundaryData & boundary_cache_ensure(const Mesh &mesh)
static void add_orco_mesh(Object &ob, const BMEditMesh *em, Mesh &mesh, const Mesh *mesh_orco, const eCustomDataType layer)
static Mesh * create_orco_mesh(const Object &ob, const Mesh &mesh, const BMEditMesh *em, eCustomDataType layer)
Mesh * editbmesh_get_eval_cage(Depsgraph *depsgraph, const Scene *scene, Object *obedit, BMEditMesh *em, const CustomData_MeshMasks *dataMask)
static void mesh_build_data(Depsgraph &depsgraph, const Scene &scene, Object &ob, const CustomData_MeshMasks &dataMask, const bool need_mapping)
static void object_get_datamask(const Depsgraph &depsgraph, Object &ob, CustomData_MeshMasks &r_mask, bool *r_need_mapping)
Mesh * mesh_create_eval_no_deform_render(Depsgraph *depsgraph, const Scene *scene, Object *ob, const CustomData_MeshMasks *dataMask)
static void editbmesh_calc_modifiers(Depsgraph &depsgraph, const Scene &scene, Object &ob, const CustomData_MeshMasks &dataMask, Mesh **r_cage, Mesh **r_final, GeometrySet **r_geometry_set)
static void mesh_init_origspace(Mesh &mesh)
Mesh * mesh_create_eval_no_deform(Depsgraph *depsgraph, const Scene *scene, Object *ob, const CustomData_MeshMasks *dataMask)
static Span< float3 > get_orco_coords(const Object &ob, const BMEditMesh *em, eCustomDataType layer_type, Array< float3 > &storage)
static Mesh * modifier_modify_mesh_and_geometry_set(ModifierData *md, const ModifierEvalContext &mectx, Mesh *input_mesh, GeometrySet &geometry_set)
static void mesh_calc_finalize(const Mesh &mesh_input, Mesh &mesh_eval)
static void make_vertexcos__mapFunc(void *user_data, int index, const float co[3], const float[3])
bool editbmesh_modifier_is_enabled(const Scene *scene, const Object *ob, ModifierData *md, bool has_prev_mesh)
static void mesh_build_extra_data(const Depsgraph &depsgraph, const Object &ob, const Mesh &mesh_eval)
static void mesh_set_only_copy(Mesh *mesh, const CustomData_MeshMasks *mask)
static MutableSpan< float3 > orco_coord_layer_ensure(Mesh &mesh, const eCustomDataType layer)
Mesh * editbmesh_get_eval_cage_from_orig(Depsgraph *depsgraph, const Scene *scene, Object *obedit, const CustomData_MeshMasks *dataMask)
Mesh * mesh_get_eval_deform(Depsgraph *depsgraph, const Scene *scene, Object *ob, const CustomData_MeshMasks *dataMask)
static void editbmesh_build_data(Depsgraph &depsgraph, const Scene &scene, Object &obedit, CustomData_MeshMasks &dataMask)
void mesh_data_update(Depsgraph &depsgraph, const Scene &scene, Object &ob, const CustomData_MeshMasks &dataMask)
static void mesh_calc_modifiers(Depsgraph &depsgraph, const Scene &scene, Object &ob, const bool use_deform, const bool need_mapping, const CustomData_MeshMasks &dataMask, const bool use_cache, const bool allow_shared_mesh, Mesh **r_deform, Mesh **r_final, GeometrySet **r_geometry_set)
void mesh_get_mapped_verts_coords(Mesh *mesh_eval, MutableSpan< float3 > r_cos)
static MutableSpan< float3 > mesh_wrapper_vert_coords_ensure_for_write(Mesh *mesh)
Mesh * mesh_create_eval_final(Depsgraph *depsgraph, const Scene *scene, Object *ob, const CustomData_MeshMasks *dataMask)
static void set_rest_position(Mesh &mesh)
void isolate_task(const Function &function)
Definition BLI_task.hh:248
VecBase< float, 3 > float3
#define min(a, b)
Definition sort.cc:36
#define FLT_MAX
Definition stdcycles.h:14
CustomData edata
CustomData pdata
struct ClothSimSettings * sim_parms
int tag
Definition DNA_ID.h:442
char name[258]
Definition DNA_ID.h:432
void * data
MeshRuntimeHandle * runtime
struct Key * key
int verts_num
struct ModifierData * next
void(* modify_geometry_set)(ModifierData *md, const ModifierEvalContext *ctx, blender::bke::GeometrySet *geometry_set)
void(* required_data_mask)(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
ModifierTypeFlag flags
ModifierTypeType type
void(* deform_verts_EM)(ModifierData *md, const ModifierEvalContext *ctx, const BMEditMesh *em, Mesh *mesh, blender::MutableSpan< blender::float3 > positions)
ObjectRuntimeHandle * runtime
uint8_t modifier_flag
struct SculptSession * sculpt
struct ToolSettings * toolsettings
const ImplicitSharingInfo * sharing_info
GeometryComponent & get_component_for_write(GeometryComponent::Type component_type)
bool has(const GeometryComponent::Type component_type) const
void replace_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
MutableSpan< float3 > vertexcos
i
Definition text_draw.cc:230
max
Definition text_draw.cc:251