Blender V5.0
object_data_transform.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
14
15#include <cstdlib>
16#include <cstring>
17
18#include "DNA_armature_types.h"
20#include "DNA_lattice_types.h"
21#include "DNA_mesh_types.h"
22#include "DNA_meta_types.h"
23#include "DNA_object_types.h"
25
26#include "BLI_listbase.h"
27#include "BLI_math_matrix.h"
28#include "BLI_math_rotation.h"
29#include "BLI_math_vector.h"
30#include "BLI_task.hh"
31
32#include "BKE_armature.hh"
33#include "BKE_curve.hh"
34#include "BKE_curves_utils.hh"
35#include "BKE_editmesh.hh"
36#include "BKE_grease_pencil.hh"
37#include "BKE_key.hh"
38#include "BKE_lattice.hh"
39#include "BKE_mball.hh"
40#include "BKE_mesh_types.hh"
41
42#include "bmesh.hh"
43
44#include "DEG_depsgraph.hh"
45
46#include "ED_armature.hh"
47#include "ED_curves.hh"
48#include "ED_mesh.hh"
49#include "ED_object.hh"
50
51namespace blender::ed::object {
52
53/* -------------------------------------------------------------------- */
60
61/* Armature */
62
64 float tail[3];
65 float head[3];
66 float roll;
67 float arm_tail[3];
68 float arm_head[3];
69 float arm_roll;
70 float rad_tail;
71 float rad_head;
72 float dist;
73 float xwidth;
74 float zwidth;
75};
76
78 ElemData_Armature *elem_array)
79{
80 ElemData_Armature *elem = elem_array;
81 LISTBASE_FOREACH (const Bone *, bone, bone_base) {
82
83#define COPY_PTR(member) memcpy(elem->member, bone->member, sizeof(bone->member))
84#define COPY_VAL(member) memcpy(&elem->member, &bone->member, sizeof(bone->member))
85 COPY_PTR(head);
86 COPY_PTR(tail);
87 COPY_VAL(roll);
88 COPY_PTR(arm_head);
89 COPY_PTR(arm_tail);
90 COPY_VAL(arm_roll);
91 COPY_VAL(rad_tail);
92 COPY_VAL(rad_head);
93 COPY_VAL(dist);
94 COPY_VAL(xwidth);
95 COPY_VAL(zwidth);
96#undef COPY_PTR
97#undef COPY_VAL
98
99 elem = armature_coords_and_quats_get_recurse(&bone->childbase, elem + 1);
100 }
101 return elem;
102}
103
106{
108}
109
111 ListBase *bone_base, const ElemData_Armature *elem_array, const float4x4 &transform)
112{
113 const ElemData_Armature *elem = elem_array;
114 LISTBASE_FOREACH (Bone *, bone, bone_base) {
115
116#define COPY_PTR(member) memcpy(bone->member, elem->member, sizeof(bone->member))
117#define COPY_VAL(member) memcpy(&bone->member, &elem->member, sizeof(bone->member))
118 COPY_PTR(head);
119 COPY_PTR(tail);
120 COPY_VAL(roll);
121 COPY_PTR(arm_head);
122 COPY_PTR(arm_tail);
123 COPY_VAL(arm_roll);
124 COPY_VAL(rad_tail);
125 COPY_VAL(rad_head);
126 COPY_VAL(dist);
127 COPY_VAL(xwidth);
128 COPY_VAL(zwidth);
129#undef COPY_PTR
130#undef COPY_VAL
131
133 &bone->childbase, elem + 1, transform);
134 }
135 return elem;
136}
137
145
147 const Span<ElemData_Armature> elem_array)
148{
149 /* Avoid code duplication by using a unit matrix. */
151}
152
153/* Edit Armature */
156{
157 ElemData_Armature *elem = elem_array.data();
158 for (EditBone *ebone = static_cast<EditBone *>(arm->edbo->first); ebone;
159 ebone = ebone->next, elem++)
160 {
161
162#define COPY_PTR(member) memcpy(elem->member, ebone->member, sizeof(ebone->member))
163#define COPY_VAL(member) memcpy(&elem->member, &ebone->member, sizeof(ebone->member))
164 /* Unused for edit bones: arm_head, arm_tail, arm_roll */
165 COPY_PTR(head);
166 COPY_PTR(tail);
167 COPY_VAL(roll);
168 COPY_VAL(rad_tail);
169 COPY_VAL(rad_head);
170 COPY_VAL(dist);
171 COPY_VAL(xwidth);
172 COPY_VAL(zwidth);
173#undef COPY_PTR
174#undef COPY_VAL
175 }
176}
177
179 bArmature *arm, const Span<ElemData_Armature> elem_array, const float4x4 &transform)
180{
181 const ElemData_Armature *elem = elem_array.data();
182 for (EditBone *ebone = static_cast<EditBone *>(arm->edbo->first); ebone;
183 ebone = ebone->next, elem++)
184 {
185
186#define COPY_PTR(member) memcpy(ebone->member, elem->member, sizeof(ebone->member))
187#define COPY_VAL(member) memcpy(&ebone->member, &elem->member, sizeof(ebone->member))
188 /* Unused for edit bones: arm_head, arm_tail, arm_roll */
189 COPY_PTR(head);
190 COPY_PTR(tail);
191 COPY_VAL(roll);
192 COPY_VAL(rad_tail);
193 COPY_VAL(rad_head);
194 COPY_VAL(dist);
195 COPY_VAL(xwidth);
196 COPY_VAL(zwidth);
197#undef COPY_PTR
198#undef COPY_VAL
199 }
200 ED_armature_edit_transform(arm, transform.ptr(), true);
201}
202
204 const Span<ElemData_Armature> elem_array)
205{
206 /* Avoid code duplication by using a unit matrix. */
208}
209
210/* MetaBall */
211
213 float co[3];
214 float quat[4];
215 float exp[3];
216 float rad;
217};
218
221{
222 ElemData_MetaBall *elem = elem_array.data();
223 for (const MetaElem *ml = static_cast<const MetaElem *>(mb->elems.first); ml;
224 ml = ml->next, elem++)
225 {
226 copy_v3_v3(elem->co, &ml->x);
227 copy_qt_qt(elem->quat, ml->quat);
228 copy_v3_v3(elem->exp, &ml->expx);
229 elem->rad = ml->rad;
230 }
231}
232
234 const Span<ElemData_MetaBall> elem_array,
235 const float4x4 &transform)
236{
237 const ElemData_MetaBall *elem = elem_array.data();
238 for (MetaElem *ml = static_cast<MetaElem *>(mb->elems.first); ml; ml = ml->next, elem++) {
239 copy_v3_v3(&ml->x, elem->co);
240 copy_qt_qt(ml->quat, elem->quat);
241 copy_v3_v3(&ml->expx, elem->exp);
242 ml->rad = elem->rad;
243 }
244 BKE_mball_transform(mb, transform.ptr(), true);
245}
246
248{
249 /* Avoid code duplication by using a unit matrix. */
251}
252
254
255/* -------------------------------------------------------------------- */
262
264 /* Optional data for shape keys. */
267 bool is_edit_mode = false;
268 virtual ~XFormObjectData_Mesh() = default;
269};
270
272 /* Optional data for shape keys. */
275 bool is_edit_mode = false;
276 virtual ~XFormObjectData_Lattice() = default;
277};
278
280 /* Optional data for shape keys. */
283 bool is_edit_mode = false;
284 virtual ~XFormObjectData_Curve() = default;
285};
286
292
298
304
310
316
317static std::unique_ptr<XFormObjectData> data_xform_create_ex(ID *id, bool is_edit_mode)
318{
319 if (id == nullptr) {
320 return {};
321 }
322
323 switch (GS(id->name)) {
324 case ID_ME: {
325 Mesh *mesh = (Mesh *)id;
326 Key *key = mesh->key;
327 const int key_index = -1;
328
329 if (is_edit_mode) {
330 BMesh *bm = mesh->runtime->edit_mesh->bm;
331 /* Always operate on all keys for the moment. */
332 // key_index = bm->shapenr - 1;
333 auto xod = std::make_unique<XFormObjectData_Mesh>();
334 xod->id = id;
335 xod->is_edit_mode = is_edit_mode;
336 xod->positions.reinitialize(bm->totvert);
337
338 BM_mesh_vert_coords_get(bm, xod->positions.as_mutable_span());
339
340 if (key != nullptr) {
341 const size_t key_size = BKE_keyblock_element_calc_size_from_shape(key, key_index);
342 if (key_size) {
343 xod->key_data.reinitialize(key_size);
344 BKE_keyblock_data_get_from_shape(key, xod->key_data, key_index);
345 }
346 }
347 return xod;
348 }
349
350 auto xod = std::make_unique<XFormObjectData_Mesh>();
351 xod->id = id;
352 xod->is_edit_mode = is_edit_mode;
353 xod->positions = mesh->vert_positions();
354
355 if (key != nullptr) {
356 const size_t key_size = BKE_keyblock_element_calc_size_from_shape(key, key_index);
357 if (key_size) {
358 xod->key_data.reinitialize(key_size);
359 BKE_keyblock_data_get_from_shape(key, xod->key_data, key_index);
360 }
361 }
362 return xod;
363 }
364 case ID_LT: {
365 Lattice *lt_orig = (Lattice *)id;
366 Lattice *lt = is_edit_mode ? lt_orig->editlatt->latt : lt_orig;
367 Key *key = lt->key;
368 const int key_index = -1;
369
370 if (is_edit_mode) {
371 /* Always operate on all keys for the moment. */
372 // key_index = lt_orig->editlatt->shapenr - 1;
373 }
374
375 auto xod = std::make_unique<XFormObjectData_Lattice>();
376 xod->id = id;
377 xod->is_edit_mode = is_edit_mode;
378 xod->positions = BKE_lattice_vert_coords_alloc(lt);
379
380 if (key != nullptr) {
381 const size_t key_size = BKE_keyblock_element_calc_size_from_shape(key, key_index);
382 if (key_size) {
383 xod->key_data.reinitialize(key_size);
384 BKE_keyblock_data_get_from_shape(key, xod->key_data, key_index);
385 }
386 }
387
388 return xod;
389 }
390 case ID_CU_LEGACY: {
391 Curve *cu = (Curve *)id;
392 Key *key = cu->key;
393
394 if (cu->ob_type == OB_FONT) {
395 /* We could support translation. */
396 break;
397 }
398
399 const int key_index = -1;
400 ListBase *nurbs;
401 if (is_edit_mode) {
402 EditNurb *editnurb = cu->editnurb;
403 nurbs = &editnurb->nurbs;
404 /* Always operate on all keys for the moment. */
405 // key_index = editnurb->shapenr - 1;
406 }
407 else {
408 nurbs = &cu->nurb;
409 }
410
411 auto xod = std::make_unique<XFormObjectData_Curve>();
412 xod->id = id;
413 xod->is_edit_mode = is_edit_mode;
414 xod->positions = BKE_curve_nurbs_vert_coords_alloc(nurbs);
415
416 if (key != nullptr) {
417 const size_t key_size = BKE_keyblock_element_calc_size_from_shape(key, key_index);
418 if (key_size) {
419 xod->key_data.reinitialize(key_size);
420 BKE_keyblock_data_get_from_shape(key, xod->key_data, key_index);
421 }
422 }
423
424 return xod;
425 }
426 case ID_AR: {
427 bArmature *arm = (bArmature *)id;
428 if (is_edit_mode) {
429 auto xod = std::make_unique<XFormObjectData_Armature>();
430 xod->id = id;
431 xod->is_edit_mode = is_edit_mode;
432 xod->elems.reinitialize(BLI_listbase_count(arm->edbo));
433 edit_armature_coords_and_quats_get(arm, xod->elems);
434 return xod;
435 }
436 auto xod = std::make_unique<XFormObjectData_Armature>();
437 xod->id = id;
438 xod->is_edit_mode = is_edit_mode;
439 xod->elems.reinitialize(BKE_armature_bonelist_count(&arm->bonebase));
440 armature_coords_and_quats_get(arm, xod->elems);
441 return xod;
442 }
443 case ID_MB: {
444 /* Edit mode and object mode are shared. */
445 MetaBall *mb = (MetaBall *)id;
446 auto xod = std::make_unique<XFormObjectData_MetaBall>();
447 xod->id = id;
448 xod->is_edit_mode = is_edit_mode;
449 xod->elems.reinitialize(BLI_listbase_count(&mb->elems));
451 return xod;
452 }
453 case ID_GP: {
454 GreasePencil *grease_pencil = (GreasePencil *)id;
455 const int elem_array_len = BKE_grease_pencil_stroke_point_count(*grease_pencil);
456 auto xod = std::make_unique<XFormObjectData_GreasePencil>();
457 xod->id = id;
459 xod->positions.reinitialize(elem_array_len);
460 }
461 else {
462 xod->positions.reinitialize(elem_array_len * 3);
463 }
464 xod->radii.reinitialize(elem_array_len);
465 BKE_grease_pencil_point_coords_get(*grease_pencil, xod->positions, xod->radii);
466 return xod;
467 }
468 case ID_CV: {
469 Curves *curves_id = reinterpret_cast<Curves *>(id);
470 const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
471 auto xod = std::make_unique<XFormObjectData_Curves>();
472 xod->id = id;
473
474 if (!curves.has_curve_with_type(CURVE_TYPE_BEZIER)) {
475 xod->positions = curves.positions();
476 }
477 else {
479 curves.curves_range());
480 }
481
482 xod->radii.reinitialize(curves.points_num());
483 curves.radius().materialize(xod->radii);
484 return xod;
485 }
486 case ID_PT: {
487 PointCloud *pointcloud = reinterpret_cast<PointCloud *>(id);
488 auto xod = std::make_unique<XFormObjectData_PointCloud>();
489 xod->id = id;
490 xod->positions = pointcloud->positions();
491 xod->radii.reinitialize(pointcloud->totpoint);
492 pointcloud->radius().materialize(xod->radii);
493 return xod;
494 }
495 default: {
496 return {};
497 }
498 }
499 return {};
500}
501
502std::unique_ptr<XFormObjectData> data_xform_create(ID *id)
503{
504 return data_xform_create_ex(id, false);
505}
506
507std::unique_ptr<XFormObjectData> data_xform_create_from_edit_mode(ID *id)
508{
509 return data_xform_create_ex(id, true);
510}
511
513 const float4x4 &transform,
515{
516 const float scale = mat4_to_scale(transform.ptr());
517 threading::parallel_for(src.index_range(), 1024, [&](const IndexRange range) {
518 for (const int i : range) {
519 dst[i] = src[i] * scale;
520 }
521 });
522}
523
525{
526 switch (GS(xod_base.id->name)) {
527 case ID_ME: {
528 Mesh *mesh = (Mesh *)xod_base.id;
529
530 Key *key = mesh->key;
531 const int key_index = -1;
532
533 const auto &xod = reinterpret_cast<XFormObjectData_Mesh &>(xod_base);
534 if (xod.is_edit_mode) {
535 BMesh *bm = mesh->runtime->edit_mesh->bm;
537 /* Always operate on all keys for the moment. */
538 // key_index = bm->shapenr - 1;
539 }
540 else {
541 math::transform_points(xod.positions, transform, mesh->vert_positions_for_write());
542 mesh->tag_positions_changed();
543 }
544
545 if (key != nullptr) {
546 BKE_keyblock_data_set_with_mat4(key, key_index, xod.key_data, transform);
547 }
548
549 break;
550 }
551 case ID_LT: {
552 const auto &xod = reinterpret_cast<XFormObjectData_Lattice &>(xod_base);
553 Lattice *lt_orig = (Lattice *)xod_base.id;
554 Lattice *lt = xod.is_edit_mode ? lt_orig->editlatt->latt : lt_orig;
555
556 Key *key = lt->key;
557 const int key_index = -1;
558
560 if (xod.is_edit_mode) {
561 /* Always operate on all keys for the moment. */
562 // key_index = lt_orig->editlatt->shapenr - 1;
563 }
564
565 if ((key != nullptr) && !xod.key_data.is_empty()) {
566 BKE_keyblock_data_set_with_mat4(key, key_index, xod.key_data, transform);
567 }
568
569 break;
570 }
571 case ID_CU_LEGACY: {
572 const auto &xod = reinterpret_cast<XFormObjectData_Curve &>(xod_base);
573 BLI_assert(xod.is_edit_mode == false); /* Not used currently. */
574 Curve *cu = (Curve *)xod_base.id;
575
576 Key *key = cu->key;
577 const int key_index = -1;
578 ListBase *nurb = nullptr;
579
580 if (xod.is_edit_mode) {
581 EditNurb *editnurb = cu->editnurb;
582 nurb = &editnurb->nurbs;
584 &editnurb->nurbs, xod.positions, transform, CU_IS_2D(cu));
585 /* Always operate on all keys for the moment. */
586 // key_index = editnurb->shapenr - 1;
587 }
588 else {
589 nurb = &cu->nurb;
591 &cu->nurb, xod.positions, transform, CU_IS_2D(cu));
592 }
593
594 if ((key != nullptr) && !xod.key_data.is_empty()) {
596 key, nurb, key_index, xod.key_data.data(), transform);
597 }
598
599 break;
600 }
601 case ID_AR: {
602 const auto &xod = reinterpret_cast<XFormObjectData_Armature &>(xod_base);
603 BLI_assert(xod.is_edit_mode == false); /* Not used currently. */
604 bArmature *arm = (bArmature *)xod_base.id;
605 if (xod.is_edit_mode) {
607 }
608 else {
610 }
611 break;
612 }
613 case ID_MB: {
614 /* Meta-balls are a special case, edit-mode and object mode data is shared. */
615 MetaBall *mb = (MetaBall *)xod_base.id;
616 const auto &xod = reinterpret_cast<XFormObjectData_MetaBall &>(xod_base);
618 break;
619 }
620 case ID_GP: {
621 GreasePencil *grease_pencil = (GreasePencil *)xod_base.id;
622 const auto &xod = reinterpret_cast<XFormObjectData_GreasePencil &>(xod_base);
624 *grease_pencil, xod.positions, xod.radii, transform);
625 break;
626 }
627 case ID_CV: {
628 Curves *curves_id = reinterpret_cast<Curves *>(xod_base.id);
629 bke::CurvesGeometry &curves = curves_id->geometry.wrap();
630 const auto &xod = reinterpret_cast<const XFormObjectData_Curves &>(xod_base);
631 if (!curves.has_curve_with_type(CURVE_TYPE_BEZIER)) {
632 math::transform_points(xod.positions, transform, curves.positions_for_write());
633 }
634 else {
635 Array<float3> transformed_positions(xod.positions.size());
636 math::transform_points(xod.positions, transform, transformed_positions);
638 curves, curves.curves_range(), transformed_positions);
639 }
640 copy_transformed_radii(xod.radii, transform, curves.radius_for_write());
641 break;
642 }
643 case ID_PT: {
644 PointCloud *pointcloud = reinterpret_cast<PointCloud *>(xod_base.id);
645 const auto &xod = reinterpret_cast<const XFormObjectData_PointCloud &>(xod_base);
646 math::transform_points(xod.positions, transform, pointcloud->positions_for_write());
647 copy_transformed_radii(xod.radii, transform, pointcloud->radius_for_write());
648 break;
649 }
650 default: {
651 break;
652 }
653 }
654}
655
657{
658 switch (GS(xod_base.id->name)) {
659 case ID_ME: {
660 Mesh *mesh = (Mesh *)xod_base.id;
661
662 Key *key = mesh->key;
663 const int key_index = -1;
664
665 const auto &xod = reinterpret_cast<XFormObjectData_Mesh &>(xod_base);
666 if (xod.is_edit_mode) {
667 BMesh *bm = mesh->runtime->edit_mesh->bm;
668 BM_mesh_vert_coords_apply(bm, xod.positions);
669 /* Always operate on all keys for the moment. */
670 // key_index = bm->shapenr - 1;
671 }
672 else {
673 mesh->vert_positions_for_write().copy_from(xod.positions);
674 mesh->tag_positions_changed();
675 }
676
677 if ((key != nullptr) && !xod.key_data.is_empty()) {
678 BKE_keyblock_data_set(key, key_index, xod.key_data.data());
679 }
680
681 break;
682 }
683 case ID_LT: {
684 const auto &xod = reinterpret_cast<XFormObjectData_Lattice &>(xod_base);
685 Lattice *lt_orig = (Lattice *)xod_base.id;
686 Lattice *lt = xod.is_edit_mode ? lt_orig->editlatt->latt : lt_orig;
687
688 Key *key = lt->key;
689 const int key_index = -1;
690
691 BKE_lattice_vert_coords_apply(lt, xod.positions);
692 if (xod.is_edit_mode) {
693 /* Always operate on all keys for the moment. */
694 // key_index = lt_orig->editlatt->shapenr - 1;
695 }
696
697 if ((key != nullptr) && !xod.key_data.is_empty()) {
698 BKE_keyblock_data_set(key, key_index, xod.key_data.data());
699 }
700
701 break;
702 }
703 case ID_CU_LEGACY: {
704 Curve *cu = (Curve *)xod_base.id;
705
706 Key *key = cu->key;
707 const int key_index = -1;
708
709 const auto &xod = reinterpret_cast<XFormObjectData_Curve &>(xod_base);
710 if (xod.is_edit_mode) {
711 EditNurb *editnurb = cu->editnurb;
712 BKE_curve_nurbs_vert_coords_apply(&editnurb->nurbs, xod.positions, CU_IS_2D(cu));
713 /* Always operate on all keys for the moment. */
714 // key_index = editnurb->shapenr - 1;
715 }
716 else {
717 BKE_curve_nurbs_vert_coords_apply(&cu->nurb, xod.positions, CU_IS_2D(cu));
718 }
719
720 if ((key != nullptr) && !xod.key_data.is_empty()) {
721 BKE_keyblock_data_set(key, key_index, xod.key_data.data());
722 }
723
724 break;
725 }
726 case ID_AR: {
727 bArmature *arm = (bArmature *)xod_base.id;
728 const auto &xod = reinterpret_cast<XFormObjectData_Armature &>(xod_base);
729 if (xod.is_edit_mode) {
731 }
732 else {
733 armature_coords_and_quats_apply(arm, xod.elems);
734 }
735 break;
736 }
737 case ID_MB: {
738 /* Meta-balls are a special case, edit-mode and object mode data is shared. */
739 MetaBall *mb = (MetaBall *)xod_base.id;
740 const auto &xod = reinterpret_cast<XFormObjectData_MetaBall &>(xod_base);
742 break;
743 }
744 case ID_GP: {
745 GreasePencil *grease_pencil = (GreasePencil *)xod_base.id;
746 const auto &xod = reinterpret_cast<XFormObjectData_GreasePencil &>(xod_base);
747 BKE_grease_pencil_point_coords_apply(*grease_pencil, xod.positions, xod.radii);
748 break;
749 }
750 case ID_CV: {
751 Curves *curves_id = reinterpret_cast<Curves *>(xod_base.id);
752 bke::CurvesGeometry &curves = curves_id->geometry.wrap();
753 const auto &xod = reinterpret_cast<const XFormObjectData_Curves &>(xod_base);
754 if (!curves.has_curve_with_type(CURVE_TYPE_BEZIER)) {
755 curves.positions_for_write().copy_from(xod.positions);
756 }
757 else {
758 bke::curves::bezier::write_all_positions(curves, curves.curves_range(), xod.positions);
759 }
760 curves.radius_for_write().copy_from(xod.radii);
761 break;
762 }
763 case ID_PT: {
764 PointCloud *pointcloud = reinterpret_cast<PointCloud *>(xod_base.id);
765 const auto &xod = reinterpret_cast<const XFormObjectData_PointCloud &>(xod_base);
766 pointcloud->positions_for_write().copy_from(xod.positions);
767 pointcloud->radius_for_write().copy_from(xod.radii);
768 break;
769 }
770 default: {
771 break;
772 }
773 }
774}
775
777{
778 switch (GS(xod_base.id->name)) {
779 case ID_ME: {
780 Mesh *mesh = (Mesh *)xod_base.id;
781 const auto &xod = reinterpret_cast<XFormObjectData_Mesh &>(xod_base);
782 if (xod.is_edit_mode) {
784 params.calc_looptris = true;
785 params.calc_normals = true;
786 params.is_destructive = false;
788 }
790 break;
791 }
792 case ID_LT: {
793 /* Generic update. */
794 Lattice *lt = (Lattice *)xod_base.id;
796 break;
797 }
798 case ID_CU_LEGACY: {
799 /* Generic update. */
800 Curve *cu = (Curve *)xod_base.id;
802 break;
803 }
804 case ID_AR: {
805 /* Generic update. */
806 bArmature *arm = (bArmature *)xod_base.id;
807 /* XXX, zero is needed, no other flags properly update this. */
808 DEG_id_tag_update(&arm->id, 0);
809 break;
810 }
811 case ID_MB: {
812 /* Generic update. */
813 MetaBall *mb = (MetaBall *)xod_base.id;
815 break;
816 }
817 case ID_GD_LEGACY: {
818 /* Generic update. */
819 bGPdata *gpd = (bGPdata *)xod_base.id;
821 break;
822 }
823 case ID_GP: {
824 /* Generic update. */
825 GreasePencil *grease_pencil = (GreasePencil *)xod_base.id;
827 break;
828 }
829 case ID_CV: {
830 Curves *curves_id = reinterpret_cast<Curves *>(xod_base.id);
831 bke::CurvesGeometry &curves = curves_id->geometry.wrap();
832 curves.tag_positions_changed();
833 curves.tag_radii_changed();
835 break;
836 }
837 case ID_PT: {
838 PointCloud *pointcloud = reinterpret_cast<PointCloud *>(xod_base.id);
839 pointcloud->tag_positions_changed();
840 pointcloud->tag_radii_changed();
842 break;
843 }
844 default: {
845 break;
846 }
847 }
848}
849
851
852} // namespace blender::ed::object
int BKE_armature_bonelist_count(const ListBase *lb)
void BKE_armature_transform(bArmature *arm, const float mat[4][4], bool do_props)
blender::Array< blender::float3 > BKE_curve_nurbs_vert_coords_alloc(const ListBase *lb)
Definition curve.cc:4555
void BKE_curve_nurbs_vert_coords_apply_with_mat4(ListBase *lb, const blender::Span< blender::float3 >, const blender::float4x4 &transform, bool constrain_2d)
#define CU_IS_2D(cu)
Definition BKE_curve.hh:89
void BKE_curve_nurbs_vert_coords_apply(ListBase *lb, const blender::Span< blender::float3 > vert_coords, bool constrain_2d)
Low-level operations for curves.
Low-level operations for grease pencil.
void BKE_grease_pencil_point_coords_apply(GreasePencil &grease_pencil, blender::Span< blender::float3 > all_positions, blender::Span< float > all_radii)
void BKE_grease_pencil_point_coords_apply_with_mat4(GreasePencil &grease_pencil, blender::Span< blender::float3 > all_positions, blender::Span< float > all_radii, const blender::float4x4 &mat)
void BKE_grease_pencil_point_coords_get(const GreasePencil &grease_pencil, blender::MutableSpan< blender::float3 > all_positions, blender::MutableSpan< float > all_radii)
bool BKE_grease_pencil_has_curve_with_type(const GreasePencil &grease_pencil, CurveType type)
int BKE_grease_pencil_stroke_point_count(const GreasePencil &grease_pencil)
void BKE_keyblock_data_set_with_mat4(Key *key, int shape_index, blender::Span< blender::float3 > coords, const blender::float4x4 &transform)
void BKE_keyblock_data_get_from_shape(const Key *key, blender::MutableSpan< blender::float3 > arr, int shape_index)
void BKE_keyblock_curve_data_set_with_mat4(Key *key, const ListBase *nurb, int shape_index, const void *data, const blender::float4x4 &transform)
Definition key.cc:1701
void BKE_keyblock_data_set(Key *key, int shape_index, const void *data)
Definition key.cc:1719
size_t BKE_keyblock_element_calc_size_from_shape(const Key *key, int shape_index)
Definition key.cc:1635
void BKE_lattice_vert_coords_apply(Lattice *lt, blender::Span< blender::float3 > vert_coordss)
void BKE_lattice_vert_coords_apply_with_mat4(Lattice *lt, blender::Span< blender::float3 > vert_coordss, const blender::float4x4 &transform)
blender::Array< blender::float3 > BKE_lattice_vert_coords_alloc(const Lattice *lt)
Definition lattice.cc:488
void BKE_mball_transform(MetaBall *mb, const float mat[4][4], bool do_props)
Definition mball.cc:525
#define BLI_assert(a)
Definition BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:524
float mat4_to_scale(const float mat[4][4])
void copy_qt_qt(float q[4], const float a[4])
MINLINE void copy_v3_v3(float r[3], const float a[3])
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1118
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1074
@ ID_AR
@ ID_CV
@ ID_CU_LEGACY
@ ID_GD_LEGACY
@ ID_ME
@ ID_MB
@ ID_LT
@ ID_GP
@ ID_PT
Object is a sort of wrapper for general info.
@ OB_FONT
void EDBM_update(Mesh *mesh, const EDBMUpdate_Params *params)
void ED_armature_edit_transform(bArmature *arm, const float mat[4][4], const bool do_props)
BMesh * bm
void BM_mesh_vert_coords_apply(BMesh *bm, const Span< float3 > vert_coords)
void BM_mesh_vert_coords_get(BMesh *bm, MutableSpan< float3 > positions)
void BM_mesh_vert_coords_apply_with_mat4(BMesh *bm, const Span< float3 > vert_coords, const float4x4 &transform)
constexpr T * data() const
Definition BLI_span.hh:539
constexpr const T * data() const
Definition BLI_span.hh:215
constexpr IndexRange index_range() const
Definition BLI_span.hh:401
#define GS(x)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
Array< float3 > retrieve_all_positions(const bke::CurvesGeometry &curves, const IndexMask &curves_selection)
void write_all_positions(bke::CurvesGeometry &curves, const IndexMask &curves_selection, Span< float3 > all_positions)
static void edit_armature_coords_and_quats_apply_with_mat4(bArmature *arm, const Span< ElemData_Armature > elem_array, const float4x4 &transform)
static const ElemData_Armature * armature_coords_and_quats_apply_with_mat4_recurse(ListBase *bone_base, const ElemData_Armature *elem_array, const float4x4 &transform)
static void metaball_coords_and_quats_apply_with_mat4(MetaBall *mb, const Span< ElemData_MetaBall > elem_array, const float4x4 &transform)
static void edit_armature_coords_and_quats_get(const bArmature *arm, MutableSpan< ElemData_Armature > elem_array)
static void copy_transformed_radii(const Span< float > src, const float4x4 &transform, MutableSpan< float > dst)
static void armature_coords_and_quats_apply(bArmature *arm, const Span< ElemData_Armature > elem_array)
static void metaball_coords_and_quats_apply(MetaBall *mb, const Span< ElemData_MetaBall > elem_array)
void data_xform_by_mat4(XFormObjectData &xod, const float4x4 &transform)
std::unique_ptr< XFormObjectData > data_xform_create(ID *id)
void data_xform_restore(XFormObjectData &xod)
std::unique_ptr< XFormObjectData > data_xform_create_from_edit_mode(ID *id)
static ElemData_Armature * armature_coords_and_quats_get_recurse(const ListBase *bone_base, ElemData_Armature *elem_array)
static void metaball_coords_and_quats_get(const MetaBall *mb, MutableSpan< ElemData_MetaBall > elem_array)
void data_xform_tag_update(XFormObjectData &xod)
static std::unique_ptr< XFormObjectData > data_xform_create_ex(ID *id, bool is_edit_mode)
static void armature_coords_and_quats_get(const bArmature *arm, MutableSpan< ElemData_Armature > elem_array)
static void armature_coords_and_quats_apply_with_mat4(bArmature *arm, const Span< ElemData_Armature > elem_array, const float4x4 &transform)
static void edit_armature_coords_and_quats_apply(bArmature *arm, const Span< ElemData_Armature > elem_array)
void transform_points(const float4x4 &transform, MutableSpan< float3 > points, bool use_threading=true)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Definition BLI_task.hh:93
MatBase< float, 4, 4 > float4x4
#define COPY_PTR(member)
#define COPY_VAL(member)
struct Key * key
EditNurb * editnurb
ListBase nurb
short ob_type
CurvesGeometry geometry
EditBone * next
struct Lattice * latt
ListBase nurbs
Definition DNA_ID.h:414
char name[258]
Definition DNA_ID.h:432
struct Key * key
struct EditLatt * editlatt
void * first
ListBase elems
struct MetaElem * next
ListBase * edbo