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