Blender V4.5
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 threading::parallel_for(src.index_range(), 1024, [&](const IndexRange range) {
517 for (const int i : range) {
518 dst[i] = math::transform_point(transform, src[i]);
519 }
520 });
521}
522
524 const float4x4 &transform,
526{
527 const float scale = mat4_to_scale(transform.ptr());
528 threading::parallel_for(src.index_range(), 1024, [&](const IndexRange range) {
529 for (const int i : range) {
530 dst[i] = src[i] * scale;
531 }
532 });
533}
534
536{
537 switch (GS(xod_base.id->name)) {
538 case ID_ME: {
539 Mesh *mesh = (Mesh *)xod_base.id;
540
541 Key *key = mesh->key;
542 const int key_index = -1;
543
544 const auto &xod = reinterpret_cast<XFormObjectData_Mesh &>(xod_base);
545 if (xod.is_edit_mode) {
546 BMesh *bm = mesh->runtime->edit_mesh->bm;
548 /* Always operate on all keys for the moment. */
549 // key_index = bm->shapenr - 1;
550 }
551 else {
552 copy_transformed_positions(xod.positions, transform, mesh->vert_positions_for_write());
553 mesh->tag_positions_changed();
554 }
555
556 if (key != nullptr) {
557 BKE_keyblock_data_set_with_mat4(key, key_index, xod.key_data, transform);
558 }
559
560 break;
561 }
562 case ID_LT: {
563 const auto &xod = reinterpret_cast<XFormObjectData_Lattice &>(xod_base);
564 Lattice *lt_orig = (Lattice *)xod_base.id;
565 Lattice *lt = xod.is_edit_mode ? lt_orig->editlatt->latt : lt_orig;
566
567 Key *key = lt->key;
568 const int key_index = -1;
569
571 if (xod.is_edit_mode) {
572 /* Always operate on all keys for the moment. */
573 // key_index = lt_orig->editlatt->shapenr - 1;
574 }
575
576 if ((key != nullptr) && !xod.key_data.is_empty()) {
577 BKE_keyblock_data_set_with_mat4(key, key_index, xod.key_data, transform);
578 }
579
580 break;
581 }
582 case ID_CU_LEGACY: {
583 const auto &xod = reinterpret_cast<XFormObjectData_Curve &>(xod_base);
584 BLI_assert(xod.is_edit_mode == false); /* Not used currently. */
585 Curve *cu = (Curve *)xod_base.id;
586
587 Key *key = cu->key;
588 const int key_index = -1;
589 ListBase *nurb = nullptr;
590
591 if (xod.is_edit_mode) {
592 EditNurb *editnurb = cu->editnurb;
593 nurb = &editnurb->nurbs;
595 &editnurb->nurbs, xod.positions, transform, CU_IS_2D(cu));
596 /* Always operate on all keys for the moment. */
597 // key_index = editnurb->shapenr - 1;
598 }
599 else {
600 nurb = &cu->nurb;
602 &cu->nurb, xod.positions, transform, CU_IS_2D(cu));
603 }
604
605 if ((key != nullptr) && !xod.key_data.is_empty()) {
607 key, nurb, key_index, xod.key_data.data(), transform);
608 }
609
610 break;
611 }
612 case ID_AR: {
613 const auto &xod = reinterpret_cast<XFormObjectData_Armature &>(xod_base);
614 BLI_assert(xod.is_edit_mode == false); /* Not used currently. */
615 bArmature *arm = (bArmature *)xod_base.id;
616 if (xod.is_edit_mode) {
618 }
619 else {
621 }
622 break;
623 }
624 case ID_MB: {
625 /* Meta-balls are a special case, edit-mode and object mode data is shared. */
626 MetaBall *mb = (MetaBall *)xod_base.id;
627 const auto &xod = reinterpret_cast<XFormObjectData_MetaBall &>(xod_base);
629 break;
630 }
631 case ID_GP: {
632 GreasePencil *grease_pencil = (GreasePencil *)xod_base.id;
633 const auto &xod = reinterpret_cast<XFormObjectData_GreasePencil &>(xod_base);
635 *grease_pencil, xod.positions, xod.radii, transform);
636 break;
637 }
638 case ID_CV: {
639 Curves *curves_id = reinterpret_cast<Curves *>(xod_base.id);
640 bke::CurvesGeometry &curves = curves_id->geometry.wrap();
641 const auto &xod = reinterpret_cast<const XFormObjectData_Curves &>(xod_base);
642 if (!curves.has_curve_with_type(CURVE_TYPE_BEZIER)) {
643 copy_transformed_positions(xod.positions, transform, curves.positions_for_write());
644 }
645 else {
646 Array<float3> transformed_positions(xod.positions.size());
647 copy_transformed_positions(xod.positions, transform, transformed_positions);
649 curves, curves.curves_range(), transformed_positions);
650 }
651 copy_transformed_radii(xod.radii, transform, curves.radius_for_write());
652 break;
653 }
654 case ID_PT: {
655 PointCloud *pointcloud = reinterpret_cast<PointCloud *>(xod_base.id);
656 const auto &xod = reinterpret_cast<const XFormObjectData_PointCloud &>(xod_base);
657 copy_transformed_positions(xod.positions, transform, pointcloud->positions_for_write());
658 copy_transformed_radii(xod.radii, transform, pointcloud->radius_for_write());
659 break;
660 }
661 default: {
662 break;
663 }
664 }
665}
666
668{
669 switch (GS(xod_base.id->name)) {
670 case ID_ME: {
671 Mesh *mesh = (Mesh *)xod_base.id;
672
673 Key *key = mesh->key;
674 const int key_index = -1;
675
676 const auto &xod = reinterpret_cast<XFormObjectData_Mesh &>(xod_base);
677 if (xod.is_edit_mode) {
678 BMesh *bm = mesh->runtime->edit_mesh->bm;
679 BM_mesh_vert_coords_apply(bm, xod.positions);
680 /* Always operate on all keys for the moment. */
681 // key_index = bm->shapenr - 1;
682 }
683 else {
684 mesh->vert_positions_for_write().copy_from(xod.positions);
685 mesh->tag_positions_changed();
686 }
687
688 if ((key != nullptr) && !xod.key_data.is_empty()) {
689 BKE_keyblock_data_set(key, key_index, xod.key_data.data());
690 }
691
692 break;
693 }
694 case ID_LT: {
695 const auto &xod = reinterpret_cast<XFormObjectData_Lattice &>(xod_base);
696 Lattice *lt_orig = (Lattice *)xod_base.id;
697 Lattice *lt = xod.is_edit_mode ? lt_orig->editlatt->latt : lt_orig;
698
699 Key *key = lt->key;
700 const int key_index = -1;
701
702 BKE_lattice_vert_coords_apply(lt, xod.positions);
703 if (xod.is_edit_mode) {
704 /* Always operate on all keys for the moment. */
705 // key_index = lt_orig->editlatt->shapenr - 1;
706 }
707
708 if ((key != nullptr) && !xod.key_data.is_empty()) {
709 BKE_keyblock_data_set(key, key_index, xod.key_data.data());
710 }
711
712 break;
713 }
714 case ID_CU_LEGACY: {
715 Curve *cu = (Curve *)xod_base.id;
716
717 Key *key = cu->key;
718 const int key_index = -1;
719
720 const auto &xod = reinterpret_cast<XFormObjectData_Curve &>(xod_base);
721 if (xod.is_edit_mode) {
722 EditNurb *editnurb = cu->editnurb;
723 BKE_curve_nurbs_vert_coords_apply(&editnurb->nurbs, xod.positions, CU_IS_2D(cu));
724 /* Always operate on all keys for the moment. */
725 // key_index = editnurb->shapenr - 1;
726 }
727 else {
728 BKE_curve_nurbs_vert_coords_apply(&cu->nurb, xod.positions, CU_IS_2D(cu));
729 }
730
731 if ((key != nullptr) && !xod.key_data.is_empty()) {
732 BKE_keyblock_data_set(key, key_index, xod.key_data.data());
733 }
734
735 break;
736 }
737 case ID_AR: {
738 bArmature *arm = (bArmature *)xod_base.id;
739 const auto &xod = reinterpret_cast<XFormObjectData_Armature &>(xod_base);
740 if (xod.is_edit_mode) {
742 }
743 else {
744 armature_coords_and_quats_apply(arm, xod.elems);
745 }
746 break;
747 }
748 case ID_MB: {
749 /* Meta-balls are a special case, edit-mode and object mode data is shared. */
750 MetaBall *mb = (MetaBall *)xod_base.id;
751 const auto &xod = reinterpret_cast<XFormObjectData_MetaBall &>(xod_base);
753 break;
754 }
755 case ID_GP: {
756 GreasePencil *grease_pencil = (GreasePencil *)xod_base.id;
757 const auto &xod = reinterpret_cast<XFormObjectData_GreasePencil &>(xod_base);
758 BKE_grease_pencil_point_coords_apply(*grease_pencil, xod.positions, xod.radii);
759 break;
760 }
761 case ID_CV: {
762 Curves *curves_id = reinterpret_cast<Curves *>(xod_base.id);
763 bke::CurvesGeometry &curves = curves_id->geometry.wrap();
764 const auto &xod = reinterpret_cast<const XFormObjectData_Curves &>(xod_base);
765 if (!curves.has_curve_with_type(CURVE_TYPE_BEZIER)) {
766 curves.positions_for_write().copy_from(xod.positions);
767 }
768 else {
769 bke::curves::bezier::write_all_positions(curves, curves.curves_range(), xod.positions);
770 }
771 curves.radius_for_write().copy_from(xod.radii);
772 break;
773 }
774 case ID_PT: {
775 PointCloud *pointcloud = reinterpret_cast<PointCloud *>(xod_base.id);
776 const auto &xod = reinterpret_cast<const XFormObjectData_PointCloud &>(xod_base);
777 pointcloud->positions_for_write().copy_from(xod.positions);
778 pointcloud->radius_for_write().copy_from(xod.radii);
779 break;
780 }
781 default: {
782 break;
783 }
784 }
785}
786
788{
789 switch (GS(xod_base.id->name)) {
790 case ID_ME: {
791 Mesh *mesh = (Mesh *)xod_base.id;
792 const auto &xod = reinterpret_cast<XFormObjectData_Mesh &>(xod_base);
793 if (xod.is_edit_mode) {
795 params.calc_looptris = true;
796 params.calc_normals = true;
797 params.is_destructive = false;
799 }
801 break;
802 }
803 case ID_LT: {
804 /* Generic update. */
805 Lattice *lt = (Lattice *)xod_base.id;
807 break;
808 }
809 case ID_CU_LEGACY: {
810 /* Generic update. */
811 Curve *cu = (Curve *)xod_base.id;
813 break;
814 }
815 case ID_AR: {
816 /* Generic update. */
817 bArmature *arm = (bArmature *)xod_base.id;
818 /* XXX, zero is needed, no other flags properly update this. */
819 DEG_id_tag_update(&arm->id, 0);
820 break;
821 }
822 case ID_MB: {
823 /* Generic update. */
824 MetaBall *mb = (MetaBall *)xod_base.id;
826 break;
827 }
828 case ID_GD_LEGACY: {
829 /* Generic update. */
830 bGPdata *gpd = (bGPdata *)xod_base.id;
832 break;
833 }
834 case ID_GP: {
835 /* Generic update. */
836 GreasePencil *grease_pencil = (GreasePencil *)xod_base.id;
838 break;
839 }
840 case ID_CV: {
841 Curves *curves_id = reinterpret_cast<Curves *>(xod_base.id);
842 bke::CurvesGeometry &curves = curves_id->geometry.wrap();
843 curves.tag_positions_changed();
844 curves.tag_radii_changed();
846 break;
847 }
848 case ID_PT: {
849 PointCloud *pointcloud = reinterpret_cast<PointCloud *>(xod_base.id);
850 pointcloud->tag_positions_changed();
851 pointcloud->tag_radii_changed();
853 break;
854 }
855 default: {
856 break;
857 }
858 }
859}
860
862
863} // namespace blender::ed::object
int BKE_armature_bonelist_count(const ListBase *lb)
Definition armature.cc:554
void BKE_armature_transform(bArmature *arm, const float mat[4][4], bool do_props)
Definition armature.cc:776
blender::Array< blender::float3 > BKE_curve_nurbs_vert_coords_alloc(const ListBase *lb)
Definition curve.cc:4559
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:1734
void BKE_keyblock_data_set(Key *key, int shape_index, const void *data)
Definition key.cc:1752
size_t BKE_keyblock_element_calc_size_from_shape(const Key *key, int shape_index)
Definition key.cc:1668
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:493
void BKE_mball_transform(MetaBall *mb, const float mat[4][4], bool do_props)
Definition mball.cc:530
#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:1026
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:982
@ ID_AR
@ ID_CV
@ ID_CU_LEGACY
@ ID_GD_LEGACY
@ ID_ME
@ ID_MB
@ ID_LT
@ ID_GP
@ ID_PT
@ CURVE_TYPE_BEZIER
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(a)
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 copy_transformed_positions(const Span< float3 > src, const float4x4 &transform, MutableSpan< float3 > dst)
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 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:404
char name[66]
Definition DNA_ID.h:415
struct Key * key
struct EditLatt * editlatt
void * first
ListBase elems
struct MetaElem * next
ListBase * edbo