Blender V5.0
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
8
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"
19#include "BLI_span.hh"
20#include "BLI_utildefines.h"
21
22#include "BKE_crazyspace.hh"
23#include "BKE_curves.hh"
24#include "BKE_editmesh.hh"
25#include "BKE_geometry_set.hh"
26#include "BKE_grease_pencil.hh"
27#include "BKE_lib_id.hh"
28#include "BKE_mesh.hh"
29#include "BKE_mesh_runtime.hh"
30#include "BKE_mesh_wrapper.hh"
31#include "BKE_modifier.hh"
32#include "BKE_multires.hh"
33#include "BKE_object_types.hh"
34#include "BKE_report.hh"
35
37
38BLI_INLINE void tan_calc_quat_v3(float r_quat[4],
39 const float co_1[3],
40 const float co_2[3],
41 const float co_3[3])
42{
43 float vec_u[3], vec_v[3];
44 float nor[3];
45
46 sub_v3_v3v3(vec_u, co_1, co_2);
47 sub_v3_v3v3(vec_v, co_1, co_3);
48
49 cross_v3_v3v3(nor, vec_u, vec_v);
50
51 if (normalize_v3(nor) > FLT_EPSILON) {
52 const float zero_vec[3] = {0.0f};
53 tri_to_quat_ex(r_quat, zero_vec, vec_u, vec_v, nor);
54 }
55 else {
56 unit_qt(r_quat);
57 }
58}
59
60static void set_crazy_vertex_quat(float r_quat[4],
61 const float co_1[3],
62 const float co_2[3],
63 const float co_3[3],
64 const float vd_1[3],
65 const float vd_2[3],
66 const float vd_3[3])
67{
68 float q1[4], q2[4];
69
70 tan_calc_quat_v3(q1, co_1, co_2, co_3);
71 tan_calc_quat_v3(q2, vd_1, vd_2, vd_3);
72
73 sub_qt_qtqt(r_quat, q2, q1);
74}
75
76static bool modifiers_disable_subsurf_temporary(Object *ob, const int cageIndex)
77{
78 bool changed = false;
79
80 ModifierData *md = static_cast<ModifierData *>(ob->modifiers.first);
81 for (int i = 0; md && i <= cageIndex; i++, md = md->next) {
82 if (md->type == eModifierType_Subsurf) {
84 changed = true;
85 }
86 }
87
88 return changed;
89}
90
92 Object *obedit)
93{
95 Object *obedit_eval = DEG_get_evaluated(depsgraph, obedit);
96 const int cageIndex = BKE_modifiers_get_cage_index(scene_eval, obedit_eval, nullptr, true);
97
98 /* Disable subsurf temporal, get mapped cos, and enable it. */
99 if (modifiers_disable_subsurf_temporary(obedit_eval, cageIndex)) {
100 /* Need to make new cage.
101 * TODO: Avoid losing original evaluated geometry. */
102 blender::bke::mesh_data_update(*depsgraph, *scene_eval, *obedit_eval, CD_MASK_BAREMESH);
103 }
104
105 /* Now get the cage. */
106 BMEditMesh *em_eval = BKE_editmesh_from_object(obedit_eval);
108 depsgraph, scene_eval, obedit_eval, em_eval, &CD_MASK_BAREMESH);
109
110 const int nverts = em_eval->bm->totvert;
111 blender::Array<blender::float3> vertexcos(nverts);
112 blender::bke::mesh_get_mapped_verts_coords(mesh_eval_cage, vertexcos);
113
114 /* Set back the flag, and ensure new cage needs to be built. */
115 if (modifiers_disable_subsurf_temporary(obedit_eval, cageIndex)) {
117 }
118
119 return vertexcos;
120}
121
123 const blender::Span<blender::float3> origcos,
124 const blender::Span<blender::float3> mappedcos,
125 float (*quats)[4],
126 const bool use_select)
127{
128 using namespace blender;
129 BMFace *f;
130 BMIter iter;
131 int index;
132 const bool has_origcos = !origcos.is_empty();
133
134 {
135 BMVert *v;
136 BM_ITER_MESH_INDEX (v, &iter, em->bm, BM_VERTS_OF_MESH, index) {
138 BM_elem_index_set(v, index); /* set_inline */
139 }
141 }
142
143 BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
144 BMLoop *l_iter, *l_first;
145
146 l_iter = l_first = BM_FACE_FIRST_LOOP(f);
147 do {
148 if (BM_elem_flag_test(l_iter->v, BM_ELEM_HIDDEN) ||
149 BM_elem_flag_test(l_iter->v, BM_ELEM_TAG) ||
150 (use_select && !BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)))
151 {
152 continue;
153 }
154
155 if (!BM_elem_flag_test(l_iter->v, BM_ELEM_TAG)) {
156 const float *co_prev, *co_curr, *co_next; /* orig */
157
158 const int vert_prev = BM_elem_index_get(l_iter->prev->v);
159 const int vert = BM_elem_index_get(l_iter->v);
160 const int vert_next = BM_elem_index_get(l_iter->next->v);
161
162 /* Retrieve mapped coordinates. */
163 const float3 &vd_prev = mappedcos[vert_prev];
164 const float3 &vd_curr = mappedcos[vert];
165 const float3 &vd_next = mappedcos[vert_next];
166
167 if (has_origcos) {
168 co_prev = origcos[vert_prev];
169 co_curr = origcos[vert];
170 co_next = origcos[vert_next];
171 }
172 else {
173 co_prev = l_iter->prev->v->co;
174 co_curr = l_iter->v->co;
175 co_next = l_iter->next->v->co;
176 }
177
178 set_crazy_vertex_quat(quats[vert], co_curr, co_next, co_prev, vd_curr, vd_next, vd_prev);
179
181 }
182 } while ((l_iter = l_iter->next) != l_first);
183 }
184}
185
187 const blender::Span<blender::float3> origcos,
188 const blender::Span<blender::float3> mappedcos,
189 float (*quats)[4])
190{
191 using namespace blender;
192 using namespace blender::bke;
193 BitVector<> vert_tag(mesh->verts_num);
194
195 /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */
196 const Span<float3> positions = origcos.is_empty() ? mesh->vert_positions() : origcos;
197 const OffsetIndices<int> faces = mesh->faces();
198 const Span<int> corner_verts = mesh->corner_verts();
199
200 for (const int i : faces.index_range()) {
201 const IndexRange face = faces[i];
202
203 for (const int corner : face) {
204 const int vert = corner_verts[corner];
205 if (vert_tag[vert]) {
206 continue;
207 }
208 const int vert_prev = corner_verts[mesh::face_corner_prev(face, corner)];
209 const int vert_next = corner_verts[mesh::face_corner_next(face, corner)];
210
211 const float3 &vd_prev = mappedcos[vert_prev];
212 const float3 &vd_curr = mappedcos[vert];
213 const float3 &vd_next = mappedcos[vert_next];
214
215 const float3 &co_prev = positions[vert_prev];
216 const float3 &co_curr = positions[vert];
217 const float3 &co_next = positions[vert_next];
218
219 set_crazy_vertex_quat(quats[vert], co_curr, co_next, co_prev, vd_curr, vd_next, vd_prev);
220
221 vert_tag[vert].set();
222 }
223 }
224}
225
227 Depsgraph *depsgraph,
228 Scene *scene,
229 Object *ob,
230 BMEditMesh *em,
233{
234 ModifierData *md;
235 Mesh *me_input = static_cast<Mesh *>(ob->data);
236 Mesh *mesh = nullptr;
237 int i, modifiers_left_num = 0;
238 const int verts_num = em->bm->totvert;
239 int cageIndex = BKE_modifiers_get_cage_index(scene, ob, nullptr, true);
240 VirtualModifierData virtual_modifier_data;
242
244
245 md = BKE_modifiers_get_virtual_modifierlist(ob, &virtual_modifier_data);
246
247 /* compute the deformation matrices and coordinates for the first
248 * modifiers with on cage editing that are enabled and support computing
249 * deform matrices */
250 for (i = 0; md && i <= cageIndex; i++, md = md->next) {
251 const ModifierTypeInfo *mti = BKE_modifier_get_info(static_cast<ModifierType>(md->type));
252
253 if (!blender::bke::editbmesh_modifier_is_enabled(scene, ob, md, mesh != nullptr)) {
254 continue;
255 }
256
258 if (deformmats.is_empty()) {
259 const int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
262 scene, md, &cd_mask_extra, required_mode);
263 cd_mask_extra = datamasks->mask;
264 BLI_linklist_free((LinkNode *)datamasks, nullptr);
265
267 std::make_shared<BMEditMesh>(*em), &cd_mask_extra, me_input);
268 deformcos.reinitialize(verts_num);
270 deformmats.reinitialize(verts_num);
271 deformmats.fill(blender::float3x3::identity());
272 }
273 mti->deform_matrices_EM(md, &mectx, em, mesh, deformcos, deformmats);
274 }
275 else {
276 break;
277 }
278 }
279
280 for (; md && i <= cageIndex; md = md->next, i++) {
281 if (blender::bke::editbmesh_modifier_is_enabled(scene, ob, md, mesh != nullptr) &&
283 {
284 modifiers_left_num++;
285 }
286 }
287
288 if (mesh) {
289 BKE_id_free(nullptr, mesh);
290 }
291
292 return modifiers_left_num;
293}
294
303 Object *object,
304 Object *object_crazy)
305{
306 Object *object_eval = DEG_get_evaluated(depsgraph, object);
307 *object_crazy = blender::dna::shallow_copy(*object_eval);
308 object_crazy->runtime = MEM_new<blender::bke::ObjectRuntime>(__func__, *object_eval->runtime);
309 if (object_crazy->runtime->data_orig != nullptr) {
310 object_crazy->data = object_crazy->runtime->data_orig;
311 }
312}
313
315{
317 return true;
318 }
319 const ModifierTypeInfo *mti = BKE_modifier_get_info(static_cast<ModifierType>(md->type));
320 return (mti->type == ModifierTypeType::OnlyDeform);
321}
322
324{
325 const ModifierTypeInfo *mti = BKE_modifier_get_info(static_cast<ModifierType>(md->type));
326 return (mti->type == ModifierTypeType::OnlyDeform);
327}
328
330 Scene *scene,
331 Object *object,
334{
335 ModifierData *md;
336 Mesh *mesh_eval = nullptr;
337 int modifiers_left_num = 0;
338 VirtualModifierData virtual_modifier_data;
339 Object object_eval;
340 crazyspace_init_object_for_eval(depsgraph, object, &object_eval);
341 BLI_SCOPED_DEFER([&]() { MEM_delete(object_eval.runtime); });
342 MultiresModifierData *mmd = get_multires_modifier(scene, &object_eval, false);
343 const bool is_sculpt_mode = (object->mode & OB_MODE_SCULPT) != 0;
344 const bool has_multires = mmd != nullptr && mmd->sculptlvl > 0;
345 const ModifierEvalContext mectx = {depsgraph, &object_eval, ModifierApplyFlag(0)};
346
347 if (is_sculpt_mode && has_multires) {
348 deformcos = {};
349 deformmats = {};
350 return modifiers_left_num;
351 }
352
353 md = BKE_modifiers_get_virtual_modifierlist(&object_eval, &virtual_modifier_data);
354
355 for (; md; md = md->next) {
357 continue;
358 }
359
361 const ModifierTypeInfo *mti = BKE_modifier_get_info(static_cast<ModifierType>(md->type));
362 if (deformmats.is_empty()) {
363 /* NOTE: Evaluated object is re-set to its original un-deformed state. */
364 Mesh *mesh = static_cast<Mesh *>(object_eval.data);
365 mesh_eval = BKE_mesh_copy_for_eval(*mesh);
366 deformcos = mesh->vert_positions();
367 deformmats.reinitialize(mesh->verts_num);
368 deformmats.fill(blender::float3x3::identity());
369 }
370
371 if (mti->deform_matrices) {
372 mti->deform_matrices(md, &mectx, mesh_eval, deformcos, deformmats);
373 }
374 else {
375 /* More complex handling will continue in BKE_crazyspace_build_sculpt.
376 * Exiting the loop on a non-deform modifier causes issues - #71213. */
378 break;
379 }
380 }
381 }
382
383 for (; md; md = md->next) {
385 continue;
386 }
387
389 modifiers_left_num++;
390 }
391 }
392
393 if (mesh_eval != nullptr) {
394 BKE_id_free(nullptr, mesh_eval);
395 }
396
397 return modifiers_left_num;
398}
399
401 Scene *scene,
402 Object *object,
405{
407 depsgraph, scene, object, deformmats, deformcos);
408
409 if (totleft) {
410 /* There are deformation modifier which doesn't support deformation matrices calculation.
411 * Need additional crazy-space correction. */
412
413 Mesh *mesh = (Mesh *)object->data;
414 Mesh *mesh_eval = nullptr;
415
416 if (deformcos.is_empty()) {
417 deformcos = mesh->vert_positions();
418 deformmats.reinitialize(mesh->verts_num);
419 deformmats.fill(blender::float3x3::identity());
420 }
421
422 blender::Array<blender::float3, 0> origVerts = deformcos;
423 float (*quats)[4];
424 int i, deformed = 0;
425 VirtualModifierData virtual_modifier_data;
426 Object object_eval;
427 crazyspace_init_object_for_eval(depsgraph, object, &object_eval);
428 BLI_SCOPED_DEFER([&]() { MEM_delete(object_eval.runtime); });
430 &virtual_modifier_data);
431 const ModifierEvalContext mectx = {depsgraph, &object_eval, ModifierApplyFlag(0)};
432
433 for (; md; md = md->next) {
435 continue;
436 }
437
439 const ModifierTypeInfo *mti = BKE_modifier_get_info(static_cast<ModifierType>(md->type));
440
441 /* skip leading modifiers which have been already
442 * handled in sculpt_get_first_deform_matrices */
443 if (mti->deform_matrices && !deformed) {
444 continue;
445 }
446
447 if (mesh_eval == nullptr) {
448 mesh_eval = BKE_mesh_copy_for_eval(*mesh);
449 }
450
451 mti->deform_verts(md, &mectx, mesh_eval, deformcos);
452 deformed = 1;
453 }
454 }
455
456 quats = MEM_malloc_arrayN<float[4]>(size_t(mesh->verts_num), "crazy quats");
457
458 BKE_crazyspace_set_quats_mesh(mesh, origVerts, deformcos, quats);
459
460 for (i = 0; i < mesh->verts_num; i++) {
461 float qmat[3][3], tmat[3][3];
462
463 quat_to_mat3(qmat, quats[i]);
464 mul_m3_m3m3(tmat, qmat, deformmats[i].ptr());
465 copy_m3_m3(deformmats[i].ptr(), tmat);
466 }
467
468 MEM_freeN(quats);
469
470 if (mesh_eval != nullptr) {
471 BKE_id_free(nullptr, mesh_eval);
472 }
473 }
474
475 if (deformmats.is_empty()) {
476 Mesh *mesh = (Mesh *)object->data;
477
478 deformcos = mesh->vert_positions();
479 deformmats.reinitialize(mesh->verts_num);
480 deformmats.fill(blender::float3x3::identity());
481 }
482}
483
484/* -------------------------------------------------------------------- */
487
489 Scene *scene,
490 Object *object,
491 ReportList *reports)
492{
493 if (!object->runtime->crazyspace_deform_imats.is_empty() ||
494 !object->runtime->crazyspace_deform_cos.is_empty())
495 {
496 return;
497 }
498
499 if (object->type != OB_MESH) {
500 BKE_report(reports,
501 RPT_ERROR,
502 "Crazyspace transformation is only available for Mesh type of objects");
503 return;
504 }
505
507 scene,
508 object,
509 object->runtime->crazyspace_deform_imats,
510 object->runtime->crazyspace_deform_cos);
511}
512
514 ReportList *reports,
515 int vert,
516 const float displacement[3],
517 float r_displacement_deformed[3])
518{
519 if (vert < 0 || vert >= object->runtime->crazyspace_deform_imats.size()) {
520 BKE_reportf(reports,
521 RPT_ERROR,
522 "Invalid vertex index %d (expected to be within 0 to %d range)",
523 vert,
524 int(object->runtime->crazyspace_deform_imats.size()));
525 return;
526 }
527
529 r_displacement_deformed, object->runtime->crazyspace_deform_imats[vert].ptr(), displacement);
530}
531
533 ReportList *reports,
534 int vert,
535 const float displacement_deformed[3],
536 float r_displacement[3])
537{
538 if (vert < 0 || vert >= 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 vert,
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[vert].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
563
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(&depsgraph, &ob_orig);
624 return get_evaluated_curves_deformation(ob_eval, ob_orig);
625}
626
628 const GreasePencilEditHints *edit_hints, const bke::greasepencil::Drawing &drawing_orig)
629{
630 for (const GreasePencilDrawingEditHints &drawing_hint : *edit_hints->drawing_hints) {
631 if (drawing_hint.drawing_orig == &drawing_orig) {
632 return &drawing_hint;
633 }
634 }
635 return {};
636}
637
639 const Object *ob_eval, const Object &ob_orig, const bke::greasepencil::Drawing &drawing_orig)
640{
641 BLI_assert(ob_orig.type == OB_GREASE_PENCIL);
642 const GreasePencil &grease_pencil_orig = *static_cast<const GreasePencil *>(ob_orig.data);
643
644 GeometryDeformation deformation;
645 /* Use the undeformed positions by default. */
646 deformation.positions = drawing_orig.strokes().positions();
647
648 if (ob_eval == nullptr) {
649 return deformation;
650 }
651 const GeometrySet *geometry_eval = ob_eval->runtime->geometry_set_eval;
652 if (geometry_eval == nullptr) {
653 return deformation;
654 }
655
656 /* If there are edit hints, use the positions of those. */
657 if (geometry_eval->has<GeometryComponentEditData>()) {
658 const GeometryComponentEditData &edit_component_eval =
659 *geometry_eval->get_component<GeometryComponentEditData>();
660 const GreasePencilEditHints *edit_hints = edit_component_eval.grease_pencil_edit_hints_.get();
661 if (edit_hints != nullptr && &edit_hints->grease_pencil_id_orig == &grease_pencil_orig &&
662 edit_hints->drawing_hints.has_value())
663 {
664 if (const GreasePencilDrawingEditHints *drawing_hints =
665 get_drawing_edit_hint_for_original_drawing(edit_hints, drawing_orig))
666 {
667 if (drawing_hints->positions()) {
668 deformation.positions = *drawing_hints->positions();
669 }
670 if (drawing_hints->deform_mats.has_value()) {
671 deformation.deform_mats = *drawing_hints->deform_mats;
672 }
673 }
674 }
675 }
676
677 return deformation;
678}
679
681 const Depsgraph &depsgraph,
682 const Object &ob_orig,
683 const bke::greasepencil::Drawing &drawing_orig)
684{
685 const Object *ob_eval = DEG_get_evaluated(&depsgraph, &ob_orig);
686 return get_evaluated_grease_pencil_drawing_deformation(ob_eval, ob_orig, drawing_orig);
687}
688
689} // 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:61
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:178
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
@ RPT_ERROR
Definition BKE_report.hh:39
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:153
#define BLI_assert(a)
Definition BLI_assert.h:46
#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)
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1074
@ 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.
#define BM_FACE_FIRST_LOOP(p)
@ BM_ELEM_HIDDEN
@ BM_ELEM_SELECT
@ BM_ELEM_TAG
#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
#define BM_VERT
ATTR_WARN_UNUSED_RESULT const BMVert * v
BPy_StructRNA * depsgraph
void fill(const T &value) const
Definition BLI_array.hh:272
void reinitialize(const int64_t new_size)
Definition BLI_array.hh:419
bool is_empty() const
Definition BLI_array.hh:264
constexpr bool is_empty() const
Definition BLI_span.hh:260
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< Array< GreasePencilDrawingEditHints > > drawing_hints
const bke::CurvesGeometry & strokes() const
nullptr float
blender::Array< blender::float3 > BKE_crazyspace_get_mapped_editverts(Depsgraph *depsgraph, Object *obedit)
Definition crazyspace.cc:91
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:38
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:60
void BKE_crazyspace_api_eval(Depsgraph *depsgraph, Scene *scene, Object *object, ReportList *reports)
static bool crazyspace_modifier_supports_deform(ModifierData *md)
static bool modifiers_disable_subsurf_temporary(Object *ob, const int cageIndex)
Definition crazyspace.cc:76
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])
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)
void BKE_crazyspace_api_displacement_to_original(Object *object, ReportList *reports, int vert, const float displacement_deformed[3], float r_displacement[3])
void BKE_crazyspace_api_displacement_to_deformed(Object *object, ReportList *reports, int vert, const float displacement[3], float r_displacement_deformed[3])
uint nor
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
static char faces[256]
GeometryDeformation get_evaluated_grease_pencil_drawing_deformation(const Object *ob_eval, const Object &ob_orig, const bke::greasepencil::Drawing &drawing_orig)
GeometryDeformation get_evaluated_curves_deformation(const Object *ob_eval, const Object &ob_orig)
static const GreasePencilDrawingEditHints * get_drawing_edit_hint_for_original_drawing(const GreasePencilEditHints *edit_hints, const bke::greasepencil::Drawing &drawing_orig)
int face_corner_prev(const IndexRange face, const int corner)
Definition BKE_mesh.hh:306
int face_corner_next(const IndexRange face, const int corner)
Definition BKE_mesh.hh:315
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)
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
i
Definition text_draw.cc:230
PointerRNA * ptr
Definition wm_files.cc:4238