Blender V4.3
crazyspace.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
9#include "MEM_guardedalloc.h"
10
11#include "DNA_mesh_types.h"
12#include "DNA_modifier_types.h"
13#include "DNA_object_types.h"
14
15#include "BLI_linklist.h"
16#include "BLI_math_matrix.h"
17#include "BLI_math_rotation.h"
18#include "BLI_utildefines.h"
19
20#include "BKE_crazyspace.hh"
21#include "BKE_curves.hh"
22#include "BKE_editmesh.hh"
23#include "BKE_geometry_set.hh"
24#include "BKE_grease_pencil.hh"
25#include "BKE_lib_id.hh"
26#include "BKE_mesh.hh"
27#include "BKE_mesh_runtime.hh"
28#include "BKE_mesh_wrapper.hh"
29#include "BKE_modifier.hh"
30#include "BKE_multires.hh"
31#include "BKE_object_types.hh"
32#include "BKE_report.hh"
33
35
36BLI_INLINE void tan_calc_quat_v3(float r_quat[4],
37 const float co_1[3],
38 const float co_2[3],
39 const float co_3[3])
40{
41 float vec_u[3], vec_v[3];
42 float nor[3];
43
44 sub_v3_v3v3(vec_u, co_1, co_2);
45 sub_v3_v3v3(vec_v, co_1, co_3);
46
47 cross_v3_v3v3(nor, vec_u, vec_v);
48
49 if (normalize_v3(nor) > FLT_EPSILON) {
50 const float zero_vec[3] = {0.0f};
51 tri_to_quat_ex(r_quat, zero_vec, vec_u, vec_v, nor);
52 }
53 else {
54 unit_qt(r_quat);
55 }
56}
57
58static void set_crazy_vertex_quat(float r_quat[4],
59 const float co_1[3],
60 const float co_2[3],
61 const float co_3[3],
62 const float vd_1[3],
63 const float vd_2[3],
64 const float vd_3[3])
65{
66 float q1[4], q2[4];
67
68 tan_calc_quat_v3(q1, co_1, co_2, co_3);
69 tan_calc_quat_v3(q2, vd_1, vd_2, vd_3);
70
71 sub_qt_qtqt(r_quat, q2, q1);
72}
73
74static bool modifiers_disable_subsurf_temporary(Object *ob, const int cageIndex)
75{
76 bool changed = false;
77
78 ModifierData *md = static_cast<ModifierData *>(ob->modifiers.first);
79 for (int i = 0; md && i <= cageIndex; i++, md = md->next) {
80 if (md->type == eModifierType_Subsurf) {
82 changed = true;
83 }
84 }
85
86 return changed;
87}
88
90 Object *obedit)
91{
93 Object *obedit_eval = DEG_get_evaluated_object(depsgraph, obedit);
94 const int cageIndex = BKE_modifiers_get_cage_index(scene_eval, obedit_eval, nullptr, true);
95
96 /* Disable subsurf temporal, get mapped cos, and enable it. */
97 if (modifiers_disable_subsurf_temporary(obedit_eval, cageIndex)) {
98 /* Need to make new cage.
99 * TODO: Avoid losing original evaluated geometry. */
100 blender::bke::mesh_data_update(*depsgraph, *scene_eval, *obedit_eval, CD_MASK_BAREMESH);
101 }
102
103 /* Now get the cage. */
104 BMEditMesh *em_eval = BKE_editmesh_from_object(obedit_eval);
106 depsgraph, scene_eval, obedit_eval, em_eval, &CD_MASK_BAREMESH);
107
108 const int nverts = em_eval->bm->totvert;
109 blender::Array<blender::float3> vertexcos(nverts);
110 blender::bke::mesh_get_mapped_verts_coords(mesh_eval_cage, vertexcos);
111
112 /* Set back the flag, and ensure new cage needs to be built. */
113 if (modifiers_disable_subsurf_temporary(obedit_eval, cageIndex)) {
115 }
116
117 return vertexcos;
118}
119
121 const blender::Span<blender::float3> origcos,
122 const blender::Span<blender::float3> mappedcos,
123 float (*quats)[4],
124 const bool use_select)
125{
126 using namespace blender;
127 BMFace *f;
128 BMIter iter;
129 int index;
130 const bool has_origcos = !origcos.is_empty();
131
132 {
133 BMVert *v;
134 BM_ITER_MESH_INDEX (v, &iter, em->bm, BM_VERTS_OF_MESH, index) {
136 BM_elem_index_set(v, index); /* set_inline */
137 }
138 em->bm->elem_index_dirty &= ~BM_VERT;
139 }
140
141 BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
142 BMLoop *l_iter, *l_first;
143
144 l_iter = l_first = BM_FACE_FIRST_LOOP(f);
145 do {
146 if (BM_elem_flag_test(l_iter->v, BM_ELEM_HIDDEN) ||
147 BM_elem_flag_test(l_iter->v, BM_ELEM_TAG) ||
148 (use_select && !BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)))
149 {
150 continue;
151 }
152
153 if (!BM_elem_flag_test(l_iter->v, BM_ELEM_TAG)) {
154 const float *co_prev, *co_curr, *co_next; /* orig */
155
156 const int vert_prev = BM_elem_index_get(l_iter->prev->v);
157 const int vert = BM_elem_index_get(l_iter->v);
158 const int vert_next = BM_elem_index_get(l_iter->next->v);
159
160 /* Retrieve mapped coordinates. */
161 const float3 &vd_prev = mappedcos[vert_prev];
162 const float3 &vd_curr = mappedcos[vert];
163 const float3 &vd_next = mappedcos[vert_next];
164
165 if (has_origcos) {
166 co_prev = origcos[vert_prev];
167 co_curr = origcos[vert];
168 co_next = origcos[vert_next];
169 }
170 else {
171 co_prev = l_iter->prev->v->co;
172 co_curr = l_iter->v->co;
173 co_next = l_iter->next->v->co;
174 }
175
176 set_crazy_vertex_quat(quats[vert], co_curr, co_next, co_prev, vd_curr, vd_next, vd_prev);
177
179 }
180 } while ((l_iter = l_iter->next) != l_first);
181 }
182}
183
185 const blender::Span<blender::float3> origcos,
186 const blender::Span<blender::float3> mappedcos,
187 float (*quats)[4])
188{
189 using namespace blender;
190 using namespace blender::bke;
191 BitVector<> vert_tag(mesh->verts_num);
192
193 /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */
194 const Span<float3> positions = origcos.is_empty() ? mesh->vert_positions() : origcos;
195 const OffsetIndices<int> faces = mesh->faces();
196 const Span<int> corner_verts = mesh->corner_verts();
197
198 for (const int i : faces.index_range()) {
199 const IndexRange face = faces[i];
200
201 for (const int corner : face) {
202 const int vert = corner_verts[corner];
203 if (vert_tag[vert]) {
204 continue;
205 }
206 const int vert_prev = corner_verts[mesh::face_corner_prev(face, corner)];
207 const int vert_next = corner_verts[mesh::face_corner_next(face, corner)];
208
209 const float3 &vd_prev = mappedcos[vert_prev];
210 const float3 &vd_curr = mappedcos[vert];
211 const float3 &vd_next = mappedcos[vert_next];
212
213 const float3 &co_prev = positions[vert_prev];
214 const float3 &co_curr = positions[vert];
215 const float3 &co_next = positions[vert_next];
216
217 set_crazy_vertex_quat(quats[vert], co_curr, co_next, co_prev, vd_curr, vd_next, vd_prev);
218
219 vert_tag[vert].set();
220 }
221 }
222}
223
225 Depsgraph *depsgraph,
226 Scene *scene,
227 Object *ob,
228 BMEditMesh *em,
231{
232 ModifierData *md;
233 Mesh *me_input = static_cast<Mesh *>(ob->data);
234 Mesh *mesh = nullptr;
235 int i, modifiers_left_num = 0;
236 const int verts_num = em->bm->totvert;
237 int cageIndex = BKE_modifiers_get_cage_index(scene, ob, nullptr, true);
238 VirtualModifierData virtual_modifier_data;
240
242
243 md = BKE_modifiers_get_virtual_modifierlist(ob, &virtual_modifier_data);
244
245 /* compute the deformation matrices and coordinates for the first
246 * modifiers with on cage editing that are enabled and support computing
247 * deform matrices */
248 for (i = 0; md && i <= cageIndex; i++, md = md->next) {
249 const ModifierTypeInfo *mti = BKE_modifier_get_info(static_cast<ModifierType>(md->type));
250
251 if (!blender::bke::editbmesh_modifier_is_enabled(scene, ob, md, mesh != nullptr)) {
252 continue;
253 }
254
256 if (deformmats.is_empty()) {
257 const int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
260 scene, md, &cd_mask_extra, required_mode);
261 cd_mask_extra = datamasks->mask;
262 BLI_linklist_free((LinkNode *)datamasks, nullptr);
263
265 std::make_shared<BMEditMesh>(*em), &cd_mask_extra, me_input);
266 deformcos.reinitialize(verts_num);
267 BKE_mesh_wrapper_vert_coords_copy(mesh, deformcos);
268 deformmats.reinitialize(verts_num);
269 deformmats.fill(blender::float3x3::identity());
270 }
271 mti->deform_matrices_EM(md, &mectx, em, mesh, deformcos, deformmats);
272 }
273 else {
274 break;
275 }
276 }
277
278 for (; md && i <= cageIndex; md = md->next, i++) {
279 if (blender::bke::editbmesh_modifier_is_enabled(scene, ob, md, mesh != nullptr) &&
281 {
282 modifiers_left_num++;
283 }
284 }
285
286 if (mesh) {
287 BKE_id_free(nullptr, mesh);
288 }
289
290 return modifiers_left_num;
291}
292
301 Object *object,
302 Object *object_crazy)
303{
304 Object *object_eval = DEG_get_evaluated_object(depsgraph, object);
305 *object_crazy = blender::dna::shallow_copy(*object_eval);
306 object_crazy->runtime = MEM_new<blender::bke::ObjectRuntime>(__func__, *object_eval->runtime);
307 if (object_crazy->runtime->data_orig != nullptr) {
308 object_crazy->data = object_crazy->runtime->data_orig;
309 }
310}
311
313{
315 return true;
316 }
317 const ModifierTypeInfo *mti = BKE_modifier_get_info(static_cast<ModifierType>(md->type));
318 return (mti->type == ModifierTypeType::OnlyDeform);
319}
320
322{
323 const ModifierTypeInfo *mti = BKE_modifier_get_info(static_cast<ModifierType>(md->type));
324 return (mti->type == ModifierTypeType::OnlyDeform);
325}
326
328 Scene *scene,
329 Object *object,
332{
333 ModifierData *md;
334 Mesh *mesh_eval = nullptr;
335 int modifiers_left_num = 0;
336 VirtualModifierData virtual_modifier_data;
337 Object object_eval;
338 crazyspace_init_object_for_eval(depsgraph, object, &object_eval);
339 BLI_SCOPED_DEFER([&]() { MEM_delete(object_eval.runtime); });
340 MultiresModifierData *mmd = get_multires_modifier(scene, &object_eval, false);
341 const bool is_sculpt_mode = (object->mode & OB_MODE_SCULPT) != 0;
342 const bool has_multires = mmd != nullptr && mmd->sculptlvl > 0;
343 const ModifierEvalContext mectx = {depsgraph, &object_eval, ModifierApplyFlag(0)};
344
345 if (is_sculpt_mode && has_multires) {
346 deformcos = {};
347 deformmats = {};
348 return modifiers_left_num;
349 }
350
351 md = BKE_modifiers_get_virtual_modifierlist(&object_eval, &virtual_modifier_data);
352
353 for (; md; md = md->next) {
355 continue;
356 }
357
359 const ModifierTypeInfo *mti = BKE_modifier_get_info(static_cast<ModifierType>(md->type));
360 if (deformmats.is_empty()) {
361 /* NOTE: Evaluated object is re-set to its original un-deformed state. */
362 Mesh *mesh = static_cast<Mesh *>(object_eval.data);
363 mesh_eval = BKE_mesh_copy_for_eval(*mesh);
364 deformcos = mesh->vert_positions();
365 deformmats.reinitialize(mesh->verts_num);
366 deformmats.fill(blender::float3x3::identity());
367 }
368
369 if (mti->deform_matrices) {
370 mti->deform_matrices(md, &mectx, mesh_eval, deformcos, deformmats);
371 }
372 else {
373 /* More complex handling will continue in BKE_crazyspace_build_sculpt.
374 * Exiting the loop on a non-deform modifier causes issues - #71213. */
376 break;
377 }
378 }
379 }
380
381 for (; md; md = md->next) {
383 continue;
384 }
385
387 modifiers_left_num++;
388 }
389 }
390
391 if (mesh_eval != nullptr) {
392 BKE_id_free(nullptr, mesh_eval);
393 }
394
395 return modifiers_left_num;
396}
397
399 Scene *scene,
400 Object *object,
403{
405 depsgraph, scene, object, deformmats, deformcos);
406
407 if (totleft) {
408 /* There are deformation modifier which doesn't support deformation matrices calculation.
409 * Need additional crazy-space correction. */
410
411 Mesh *mesh = (Mesh *)object->data;
412 Mesh *mesh_eval = nullptr;
413
414 if (deformcos.is_empty()) {
415 deformcos = mesh->vert_positions();
416 deformmats.reinitialize(mesh->verts_num);
417 deformmats.fill(blender::float3x3::identity());
418 }
419
420 blender::Array<blender::float3, 0> deformedVerts = deformcos;
421 blender::Array<blender::float3, 0> origVerts = deformedVerts;
422 float(*quats)[4];
423 int i, deformed = 0;
424 VirtualModifierData virtual_modifier_data;
425 Object object_eval;
426 crazyspace_init_object_for_eval(depsgraph, object, &object_eval);
427 BLI_SCOPED_DEFER([&]() { MEM_delete(object_eval.runtime); });
429 &virtual_modifier_data);
430 const ModifierEvalContext mectx = {depsgraph, &object_eval, ModifierApplyFlag(0)};
431
432 for (; md; md = md->next) {
434 continue;
435 }
436
438 const ModifierTypeInfo *mti = BKE_modifier_get_info(static_cast<ModifierType>(md->type));
439
440 /* skip leading modifiers which have been already
441 * handled in sculpt_get_first_deform_matrices */
442 if (mti->deform_matrices && !deformed) {
443 continue;
444 }
445
446 if (mesh_eval == nullptr) {
447 mesh_eval = BKE_mesh_copy_for_eval(*mesh);
448 }
449
450 mti->deform_verts(md, &mectx, mesh_eval, deformedVerts);
451 deformed = 1;
452 }
453 }
454
455 quats = static_cast<float(*)[4]>(MEM_mallocN(mesh->verts_num * sizeof(*quats), "crazy quats"));
456
457 BKE_crazyspace_set_quats_mesh(mesh, origVerts, deformedVerts, quats);
458
459 for (i = 0; i < mesh->verts_num; i++) {
460 float qmat[3][3], tmat[3][3];
461
462 quat_to_mat3(qmat, quats[i]);
463 mul_m3_m3m3(tmat, qmat, deformmats[i].ptr());
464 copy_m3_m3(deformmats[i].ptr(), tmat);
465 }
466
467 MEM_freeN(quats);
468
469 if (mesh_eval != nullptr) {
470 BKE_id_free(nullptr, mesh_eval);
471 }
472 }
473
474 if (deformmats.is_empty()) {
475 Mesh *mesh = (Mesh *)object->data;
476
477 deformcos = mesh->vert_positions();
478 deformmats.reinitialize(mesh->verts_num);
479 deformmats.fill(blender::float3x3::identity());
480 }
481}
482
483/* -------------------------------------------------------------------- */
488 Scene *scene,
489 Object *object,
490 ReportList *reports)
491{
492 if (!object->runtime->crazyspace_deform_imats.is_empty() ||
493 !object->runtime->crazyspace_deform_cos.is_empty())
494 {
495 return;
496 }
497
498 if (object->type != OB_MESH) {
499 BKE_report(reports,
500 RPT_ERROR,
501 "Crazyspace transformation is only available for Mesh type of objects");
502 return;
503 }
504
506 scene,
507 object,
508 object->runtime->crazyspace_deform_imats,
509 object->runtime->crazyspace_deform_cos);
510}
511
513 ReportList *reports,
514 int vertex_index,
515 const float displacement[3],
516 float r_displacement_deformed[3])
517{
518 if (vertex_index < 0 || vertex_index >= object->runtime->crazyspace_deform_imats.size()) {
519 BKE_reportf(reports,
520 RPT_ERROR,
521 "Invalid vertex index %d (expected to be within 0 to %d range)",
522 vertex_index,
523 int(object->runtime->crazyspace_deform_imats.size()));
524 return;
525 }
526
527 mul_v3_m3v3(r_displacement_deformed,
528 object->runtime->crazyspace_deform_imats[vertex_index].ptr(),
529 displacement);
530}
531
533 ReportList *reports,
534 int vertex_index,
535 const float displacement_deformed[3],
536 float r_displacement[3])
537{
538 if (vertex_index < 0 || vertex_index >= object->runtime->crazyspace_deform_imats.size()) {
539 BKE_reportf(reports,
540 RPT_ERROR,
541 "Invalid vertex index %d (expected to be within 0 to %d range)",
542 vertex_index,
543 int(object->runtime->crazyspace_deform_imats.size()));
544 return;
545 }
546
547 float mat[3][3];
548 if (!invert_m3_m3(mat, object->runtime->crazyspace_deform_imats[vertex_index].ptr())) {
549 copy_v3_v3(r_displacement, displacement_deformed);
550 return;
551 }
552
553 mul_v3_m3v3(r_displacement, mat, displacement_deformed);
554}
555
557{
558 object->runtime->crazyspace_deform_imats = {};
559 object->runtime->crazyspace_deform_cos = {};
560}
561
564namespace blender::bke::crazyspace {
565
567{
568 BLI_assert(ob_orig.type == OB_CURVES);
569 const Curves &curves_id_orig = *static_cast<const Curves *>(ob_orig.data);
570 const CurvesGeometry &curves_orig = curves_id_orig.geometry.wrap();
571 const int points_num = curves_orig.points_num();
572
573 GeometryDeformation deformation;
574 /* Use the undeformed positions by default. */
575 deformation.positions = curves_orig.positions();
576
577 if (ob_eval == nullptr) {
578 return deformation;
579 }
580 const GeometrySet *geometry_eval = ob_eval->runtime->geometry_set_eval;
581 if (geometry_eval == nullptr) {
582 return deformation;
583 }
584
585 /* If available, use deformation information generated during evaluation. */
586 const GeometryComponentEditData *edit_component_eval =
588 bool uses_extra_positions = false;
589 if (edit_component_eval != nullptr) {
590 const CurvesEditHints *edit_hints = edit_component_eval->curves_edit_hints_.get();
591 if (edit_hints != nullptr && &edit_hints->curves_id_orig == &curves_id_orig) {
592 if (const std::optional<Span<float3>> positions = edit_hints->positions()) {
593 BLI_assert(positions->size() == points_num);
594 deformation.positions = *positions;
595 uses_extra_positions = true;
596 }
597 if (edit_hints->deform_mats.has_value()) {
598 BLI_assert(edit_hints->deform_mats->size() == points_num);
599 deformation.deform_mats = *edit_hints->deform_mats;
600 }
601 }
602 }
603
604 /* Use the positions of the evaluated curves directly, if the number of points matches. */
605 if (!uses_extra_positions) {
606 const CurveComponent *curves_component_eval = geometry_eval->get_component<CurveComponent>();
607 if (curves_component_eval != nullptr) {
608 const Curves *curves_id_eval = curves_component_eval->get();
609 if (curves_id_eval != nullptr) {
610 const CurvesGeometry &curves_eval = curves_id_eval->geometry.wrap();
611 if (curves_eval.points_num() == points_num) {
612 deformation.positions = curves_eval.positions();
613 }
614 }
615 }
616 }
617 return deformation;
618}
619
621 const Object &ob_orig)
622{
623 const Object *ob_eval = DEG_get_evaluated_object(&depsgraph, const_cast<Object *>(&ob_orig));
624 return get_evaluated_curves_deformation(ob_eval, ob_orig);
625}
626
628 const Object &ob_orig,
629 const int layer_index,
630 const int frame)
631{
632 BLI_assert(ob_orig.type == OB_GREASE_PENCIL);
633 const GreasePencil &grease_pencil_orig = *static_cast<const GreasePencil *>(ob_orig.data);
634
635 const Span<const bke::greasepencil::Layer *> layers_orig = grease_pencil_orig.layers();
636 const bke::greasepencil::Layer &layer_orig = grease_pencil_orig.layer(layer_index);
637 const bke::greasepencil::Drawing *drawing_orig = grease_pencil_orig.get_drawing_at(layer_orig,
638 frame);
639 if (drawing_orig == nullptr) {
640 return {};
641 }
642
643 GeometryDeformation deformation;
644 /* Use the undeformed positions by default. */
645 deformation.positions = drawing_orig->strokes().positions();
646
647 if (ob_eval == nullptr) {
648 return deformation;
649 }
650 const GeometrySet *geometry_eval = ob_eval->runtime->geometry_set_eval;
651 if (geometry_eval == nullptr) {
652 return deformation;
653 }
654
655 /* If there are edit hints, use the positions of those. */
656 if (geometry_eval->has<GeometryComponentEditData>()) {
657 const GeometryComponentEditData &edit_component_eval =
658 *geometry_eval->get_component<GeometryComponentEditData>();
659 const GreasePencilEditHints *edit_hints = edit_component_eval.grease_pencil_edit_hints_.get();
660 if (edit_hints != nullptr && &edit_hints->grease_pencil_id_orig == &grease_pencil_orig &&
661 edit_hints->drawing_hints.has_value())
662 {
663 BLI_assert(edit_hints->drawing_hints->size() == layers_orig.size());
664 const GreasePencilDrawingEditHints &drawing_hints =
665 edit_hints->drawing_hints.value()[layer_index];
666 if (const std::optional<Span<float3>> positions = drawing_hints.positions()) {
667 deformation.positions = *positions;
668 return deformation;
669 }
670 }
671 }
672
673 /* Otherwise use the positions of the evaluated drawing if the number of points match. */
674 if (const GreasePencilComponent *grease_pencil_component_eval =
675 geometry_eval->get_component<GreasePencilComponent>())
676 {
677 if (const GreasePencil *grease_pencil_eval = grease_pencil_component_eval->get()) {
678 Span<const bke::greasepencil::Layer *> layers_eval = grease_pencil_eval->layers();
679 if (layers_eval.size() == layers_orig.size()) {
680 const bke::greasepencil::Layer &layer_eval = *layers_eval[layer_index];
681 if (const bke::greasepencil::Drawing *drawing_eval = grease_pencil_eval->get_drawing_at(
682 layer_eval, frame))
683 if (drawing_eval->strokes().points_num() == drawing_orig->strokes().points_num()) {
684 deformation.positions = drawing_eval->strokes().positions();
685 return deformation;
686 }
687 }
688 }
689 }
690
691 return deformation;
692}
693
695 const Object &ob_orig,
696 const int layer_index,
697 const int frame)
698{
699 const Object *ob_eval = DEG_get_evaluated_object(&depsgraph, const_cast<Object *>(&ob_orig));
700 return get_evaluated_grease_pencil_drawing_deformation(ob_eval, ob_orig, layer_index, frame);
701}
702
703} // namespace blender::bke::crazyspace
Low-level operations for curves.
const CustomData_MeshMasks CD_MASK_BAREMESH
BMEditMesh * BKE_editmesh_from_object(Object *ob)
Return the BMEditMesh for a given object.
Definition editmesh.cc:63
Low-level operations for grease pencil.
void BKE_id_free(Main *bmain, void *idv)
Mesh * BKE_mesh_copy_for_eval(const Mesh &source)
void BKE_mesh_wrapper_vert_coords_copy(const Mesh *mesh, blender::MutableSpan< blender::float3 > positions)
Mesh * BKE_mesh_wrapper_from_editmesh(std::shared_ptr< BMEditMesh > em, const CustomData_MeshMasks *cd_mask_extra, const Mesh *me_settings)
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)
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)
bool BKE_modifier_is_correctable_deformed(ModifierData *md)
ModifierData * BKE_modifiers_get_virtual_modifierlist(const Object *ob, VirtualModifierData *data)
ModifierApplyFlag
MultiresModifierData * get_multires_modifier(Scene *scene, Object *ob, bool use_first)
Definition multires.cc:304
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:125
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_INLINE
void copy_m3_m3(float m1[3][3], const float m2[3][3])
bool invert_m3_m3(float inverse[3][3], const float mat[3][3])
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
void quat_to_mat3(float m[3][3], const float q[4])
void sub_qt_qtqt(float q[4], const float a[4], const float b[4])
void unit_qt(float q[4])
void tri_to_quat_ex(float quat[4], const float v1[3], const float v2[3], const float v3[3], const float no_orig[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float normalize_v3(float n[3])
#define BLI_SCOPED_DEFER(function_to_defer)
#define ELEM(...)
void DEG_id_tag_update(ID *id, unsigned int flags)
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1041
@ eModifierMode_Editmode
@ eModifierMode_DisableTemporary
@ eModifierMode_Realtime
@ eModifierType_Subsurf
@ eModifierType_Multires
@ OB_MODE_SCULPT
Object is a sort of wrapper for general info.
@ OB_GREASE_PENCIL
@ OB_MESH
@ OB_CURVES
Read Guarded memory(de)allocation.
@ BM_ELEM_HIDDEN
@ BM_ELEM_SELECT
@ BM_ELEM_TAG
#define BM_FACE_FIRST_LOOP(p)
#define BM_elem_index_get(ele)
#define BM_elem_flag_disable(ele, hflag)
#define BM_elem_index_set(ele, index)
#define BM_elem_flag_test(ele, hflag)
#define BM_elem_flag_enable(ele, hflag)
#define BM_ITER_MESH(ele, iter, bm, itype)
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar)
@ BM_VERTS_OF_MESH
@ BM_FACES_OF_MESH
ATTR_WARN_UNUSED_RESULT const BMVert * v
void fill(const T &value) const
Definition BLI_array.hh:261
void reinitialize(const int64_t new_size)
Definition BLI_array.hh:388
bool is_empty() const
Definition BLI_array.hh:253
constexpr int64_t size() const
Definition BLI_span.hh:253
constexpr bool is_empty() const
Definition BLI_span.hh:261
std::optional< Span< float3 > > positions() const
std::optional< Array< float3x3 > > deform_mats
Span< float3 > positions() const
std::unique_ptr< GreasePencilEditHints > grease_pencil_edit_hints_
std::unique_ptr< CurvesEditHints > curves_edit_hints_
std::optional< Span< float3 > > positions() const
const bke::CurvesGeometry & strokes() const
blender::Array< blender::float3 > BKE_crazyspace_get_mapped_editverts(Depsgraph *depsgraph, Object *obedit)
Definition crazyspace.cc:89
void BKE_crazyspace_build_sculpt(Depsgraph *depsgraph, Scene *scene, Object *object, blender::Array< blender::float3x3, 0 > &deformmats, blender::Array< blender::float3, 0 > &deformcos)
BLI_INLINE void tan_calc_quat_v3(float r_quat[4], const float co_1[3], const float co_2[3], const float co_3[3])
Definition crazyspace.cc:36
int BKE_crazyspace_get_first_deform_matrices_editbmesh(Depsgraph *depsgraph, Scene *scene, Object *ob, BMEditMesh *em, blender::Array< blender::float3x3, 0 > &deformmats, blender::Array< blender::float3, 0 > &deformcos)
static void set_crazy_vertex_quat(float r_quat[4], const float co_1[3], const float co_2[3], const float co_3[3], const float vd_1[3], const float vd_2[3], const float vd_3[3])
Definition crazyspace.cc:58
void BKE_crazyspace_api_eval(Depsgraph *depsgraph, Scene *scene, Object *object, ReportList *reports)
void BKE_crazyspace_api_displacement_to_original(Object *object, ReportList *reports, int vertex_index, const float displacement_deformed[3], float r_displacement[3])
static bool crazyspace_modifier_supports_deform(ModifierData *md)
static bool modifiers_disable_subsurf_temporary(Object *ob, const int cageIndex)
Definition crazyspace.cc:74
void BKE_crazyspace_set_quats_editmesh(BMEditMesh *em, const blender::Span< blender::float3 > origcos, const blender::Span< blender::float3 > mappedcos, float(*quats)[4], const bool use_select)
void BKE_crazyspace_api_eval_clear(Object *object)
static void crazyspace_init_object_for_eval(Depsgraph *depsgraph, Object *object, Object *object_crazy)
void BKE_crazyspace_set_quats_mesh(Mesh *mesh, const blender::Span< blender::float3 > origcos, const blender::Span< blender::float3 > mappedcos, float(*quats)[4])
void BKE_crazyspace_api_displacement_to_deformed(Object *object, ReportList *reports, int vertex_index, const float displacement[3], float r_displacement_deformed[3])
static bool crazyspace_modifier_supports_deform_matrices(ModifierData *md)
int BKE_sculpt_get_first_deform_matrices(Depsgraph *depsgraph, Scene *scene, Object *object, blender::Array< blender::float3x3, 0 > &deformmats, blender::Array< blender::float3, 0 > &deformcos)
const Depsgraph * depsgraph
draw_view in_light_buf[] float
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
GeometryDeformation get_evaluated_grease_pencil_drawing_deformation(const Object *ob_eval, const Object &ob_orig, int layer_index, int frame)
GeometryDeformation get_evaluated_curves_deformation(const Object *ob_eval, const Object &ob_orig)
Mesh * editbmesh_get_eval_cage(Depsgraph *depsgraph, const Scene *scene, Object *obedit, BMEditMesh *em, const CustomData_MeshMasks *dataMask)
bool editbmesh_modifier_is_enabled(const Scene *scene, const Object *ob, ModifierData *md, bool has_prev_mesh)
void mesh_data_update(Depsgraph &depsgraph, const Scene &scene, Object &ob, const CustomData_MeshMasks &dataMask)
void mesh_get_mapped_verts_coords(Mesh *mesh_eval, MutableSpan< float3 > r_cos)
Frequency::GEOMETRY nor[]
struct BMVert * v
struct BMLoop * prev
struct BMLoop * next
float co[3]
int totvert
char elem_index_dirty
CurvesGeometry geometry
void * first
struct ModifierData * next
void(* deform_verts)(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, blender::MutableSpan< blender::float3 > positions)
void(* deform_matrices_EM)(ModifierData *md, const ModifierEvalContext *ctx, const BMEditMesh *em, Mesh *mesh, blender::MutableSpan< blender::float3 > positions, blender::MutableSpan< blender::float3x3 > matrices)
ModifierTypeType type
void(* deform_matrices)(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, blender::MutableSpan< blender::float3 > positions, blender::MutableSpan< blender::float3x3 > matrices)
ObjectRuntimeHandle * runtime
ListBase modifiers
bool has(const GeometryComponent::Type component_type) const
const GeometryComponent * get_component(GeometryComponent::Type component_type) const
PointerRNA * ptr
Definition wm_files.cc:4126