Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-11-21 13:03:03 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-11-21 14:45:15 +0300
commit20620afc33cacd11429045f94ce27a8bc297c456 (patch)
tree48ad86362e5817c1d4fce540c01af08fb059edc0 /source/blender/editors/object/object_data_transform.c
parentd98d4fce93f4b7ae2f4c48d70a3e5f4b324ac1ba (diff)
Object: edit-mode data support for object vertex coordinate access
Allows to access/transform/restore edit-mode coordinates in a generic way.
Diffstat (limited to 'source/blender/editors/object/object_data_transform.c')
-rw-r--r--source/blender/editors/object/object_data_transform.c280
1 files changed, 262 insertions, 18 deletions
diff --git a/source/blender/editors/object/object_data_transform.c b/source/blender/editors/object/object_data_transform.c
index ee86c79ead5..51d8fb8fd72 100644
--- a/source/blender/editors/object/object_data_transform.c
+++ b/source/blender/editors/object/object_data_transform.c
@@ -44,16 +44,21 @@
#include "BLI_utildefines.h"
#include "BKE_curve.h"
+#include "BKE_editmesh.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
#include "BKE_armature.h"
#include "BKE_lattice.h"
+#include "bmesh.h"
+
#include "DEG_depsgraph.h"
#include "WM_types.h"
#include "ED_object.h"
+#include "ED_mesh.h"
+#include "ED_armature.h"
#include "MEM_guardedalloc.h"
@@ -149,6 +154,70 @@ static void armature_coords_and_quats_apply_with_mat4(bArmature *arm,
BKE_armature_transform(arm, mat, true);
}
+static void armature_coords_and_quats_apply(bArmature *arm,
+ const struct ElemData_Armature *elem_array)
+{
+ /* Avoid code duplication by using a unit matrix. */
+ float mat[4][4];
+ unit_m4(mat);
+ armature_coords_and_quats_apply_with_mat4(arm, elem_array, mat);
+}
+
+/* Edit Armature */
+static void edit_armature_coords_and_quats_get(const bArmature *arm,
+ struct ElemData_Armature *elem_array)
+{
+ struct ElemData_Armature *elem = elem_array;
+ for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next, elem++) {
+
+#define COPY_PTR(member) memcpy(elem->member, ebone->member, sizeof(ebone->member))
+#define COPY_VAL(member) memcpy(&elem->member, &ebone->member, sizeof(ebone->member))
+ /* Unused for edit bones: arm_head, arm_tail, arm_roll */
+ COPY_PTR(head);
+ COPY_PTR(tail);
+ COPY_VAL(roll);
+ COPY_VAL(rad_tail);
+ COPY_VAL(rad_head);
+ COPY_VAL(dist);
+ COPY_VAL(xwidth);
+ COPY_VAL(zwidth);
+#undef COPY_PTR
+#undef COPY_VAL
+ }
+}
+
+static void edit_armature_coords_and_quats_apply_with_mat4(
+ bArmature *arm, const struct ElemData_Armature *elem_array, const float mat[4][4])
+{
+ const struct ElemData_Armature *elem = elem_array;
+ for (EditBone *ebone = arm->edbo->first; ebone; ebone = ebone->next, elem++) {
+
+#define COPY_PTR(member) memcpy(ebone->member, elem->member, sizeof(ebone->member))
+#define COPY_VAL(member) memcpy(&ebone->member, &elem->member, sizeof(ebone->member))
+ /* Unused for edit bones: arm_head, arm_tail, arm_roll */
+ COPY_PTR(head);
+ COPY_PTR(tail);
+ COPY_VAL(roll);
+ COPY_VAL(rad_tail);
+ COPY_VAL(rad_head);
+ COPY_VAL(dist);
+ COPY_VAL(xwidth);
+ COPY_VAL(zwidth);
+#undef COPY_PTR
+#undef COPY_VAL
+ }
+ ED_armature_edit_transform(arm, mat, true);
+}
+
+static void edit_armature_coords_and_quats_apply(bArmature *arm,
+ const struct ElemData_Armature *elem_array)
+{
+ /* Avoid code duplication by using a unit matrix. */
+ float mat[4][4];
+ unit_m4(mat);
+ edit_armature_coords_and_quats_apply_with_mat4(arm, elem_array, mat);
+}
+
/* MetaBall */
struct ElemData_MetaBall {
@@ -183,6 +252,15 @@ static void metaball_coords_and_quats_apply_with_mat4(MetaBall *mb,
BKE_mball_transform(mb, mat, true);
}
+static void metaball_coords_and_quats_apply(MetaBall *mb,
+ const struct ElemData_MetaBall *elem_array)
+{
+ /* Avoid code duplication by using a unit matrix. */
+ float mat[4][4];
+ unit_m4(mat);
+ metaball_coords_and_quats_apply_with_mat4(mb, elem_array, mat);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -195,6 +273,7 @@ static void metaball_coords_and_quats_apply_with_mat4(MetaBall *mb,
struct XFormObjectData {
ID *id;
+ bool is_edit_mode;
};
struct XFormObjectData_Mesh {
@@ -222,21 +301,32 @@ struct XFormObjectData_MetaBall {
struct ElemData_MetaBall elem_array[0];
};
-struct XFormObjectData *ED_object_data_xform_create(ID *id)
+struct XFormObjectData *ED_object_data_xform_create_ex(ID *id, bool is_edit_mode)
{
struct XFormObjectData *xod_base = NULL;
switch (GS(id->name)) {
case ID_ME: {
Mesh *me = (Mesh *)id;
- const int elem_array_len = me->totvert;
- struct XFormObjectData_Mesh *xod = MEM_mallocN(
- sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
- BKE_mesh_vert_coords_get(me, xod->elem_array);
- xod_base = &xod->base;
+ if (is_edit_mode) {
+ BMesh *bm = me->edit_mesh->bm;
+ const int elem_array_len = bm->totvert;
+ struct XFormObjectData_Mesh *xod = MEM_mallocN(
+ sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
+ BM_mesh_vert_coords_get(bm, xod->elem_array);
+ xod_base = &xod->base;
+ }
+ else {
+ const int elem_array_len = me->totvert;
+ struct XFormObjectData_Mesh *xod = MEM_mallocN(
+ sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
+ BKE_mesh_vert_coords_get(me, xod->elem_array);
+ xod_base = &xod->base;
+ }
break;
}
case ID_LT: {
- Lattice *lt = (Lattice *)id;
+ Lattice *lt_orig = (Lattice *)id;
+ Lattice *lt = is_edit_mode ? lt_orig->editlatt->latt : lt_orig;
const int elem_array_len = lt->pntsu * lt->pntsv * lt->pntsw;
struct XFormObjectData_Lattice *xod = MEM_mallocN(
sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
@@ -251,23 +341,43 @@ struct XFormObjectData *ED_object_data_xform_create(ID *id)
/* We could support translation. */
break;
}
- const int elem_array_len = BKE_nurbList_verts_count(&cu->nurb);
+
+ ListBase *nurbs;
+ if (is_edit_mode) {
+ EditNurb *editnurb = cu->editnurb;
+ nurbs = &editnurb->nurbs;
+ }
+ else {
+ nurbs = &cu->nurb;
+ }
+
+ const int elem_array_len = BKE_nurbList_verts_count(nurbs);
struct XFormObjectData_Curve *xod = MEM_mallocN(
sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
- BKE_curve_nurbs_vert_coords_get(&cu->nurb, xod->elem_array, elem_array_len);
+ BKE_curve_nurbs_vert_coords_get(nurbs, xod->elem_array, elem_array_len);
xod_base = &xod->base;
break;
}
case ID_AR: {
bArmature *arm = (bArmature *)id;
- const int elem_array_len = BKE_armature_bonelist_count(&arm->bonebase);
- struct XFormObjectData_Armature *xod = MEM_mallocN(
- sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
- armature_coords_and_quats_get(arm, xod->elem_array);
- xod_base = &xod->base;
+ if (is_edit_mode) {
+ const int elem_array_len = BLI_listbase_count(arm->edbo);
+ struct XFormObjectData_Armature *xod = MEM_mallocN(
+ sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
+ edit_armature_coords_and_quats_get(arm, xod->elem_array);
+ xod_base = &xod->base;
+ }
+ else {
+ const int elem_array_len = BKE_armature_bonelist_count(&arm->bonebase);
+ struct XFormObjectData_Armature *xod = MEM_mallocN(
+ sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__);
+ armature_coords_and_quats_get(arm, xod->elem_array);
+ xod_base = &xod->base;
+ }
break;
}
case ID_MB: {
+ /* Edit mode and object mode are shared. */
MetaBall *mb = (MetaBall *)id;
const int elem_array_len = BLI_listbase_count(&mb->elems);
struct XFormObjectData_MetaBall *xod = MEM_mallocN(
@@ -282,10 +392,21 @@ struct XFormObjectData *ED_object_data_xform_create(ID *id)
}
if (xod_base) {
xod_base->id = id;
+ xod_base->is_edit_mode = is_edit_mode;
}
return xod_base;
}
+struct XFormObjectData *ED_object_data_xform_create(ID *id)
+{
+ return ED_object_data_xform_create_ex(id, false);
+}
+
+struct XFormObjectData *ED_object_data_xform_create_from_edit_mode(ID *id)
+{
+ return ED_object_data_xform_create_ex(id, true);
+}
+
void ED_object_data_xform_destroy(struct XFormObjectData *xod)
{
MEM_freeN(xod);
@@ -297,28 +418,49 @@ void ED_object_data_xform_by_mat4(struct XFormObjectData *xod_base, const float
case ID_ME: {
Mesh *me = (Mesh *)xod_base->id;
struct XFormObjectData_Mesh *xod = (struct XFormObjectData_Mesh *)xod_base;
- BKE_mesh_vert_coords_apply_with_mat4(me, xod->elem_array, mat);
+ if (xod_base->is_edit_mode) {
+ BMesh *bm = me->edit_mesh->bm;
+ BM_mesh_vert_coords_apply_with_mat4(bm, xod->elem_array, mat);
+ }
+ else {
+ BKE_mesh_vert_coords_apply_with_mat4(me, xod->elem_array, mat);
+ }
break;
}
case ID_LT: {
- Lattice *lt = (Lattice *)xod_base->id;
+ Lattice *lt_orig = (Lattice *)xod_base->id;
+ Lattice *lt = xod_base->is_edit_mode ? lt_orig->editlatt->latt : lt_orig;
struct XFormObjectData_Lattice *xod = (struct XFormObjectData_Lattice *)xod_base;
BKE_lattice_vert_coords_apply_with_mat4(lt, xod->elem_array, mat);
break;
}
case ID_CU: {
+ BLI_assert(xod_base->is_edit_mode == false); /* Not used currently. */
Curve *cu = (Curve *)xod_base->id;
struct XFormObjectData_Curve *xod = (struct XFormObjectData_Curve *)xod_base;
- BKE_curve_nurbs_vert_coords_apply_with_mat4(&cu->nurb, xod->elem_array, mat, true);
+ if (xod_base->is_edit_mode) {
+ EditNurb *editnurb = cu->editnurb;
+ BKE_curve_nurbs_vert_coords_apply_with_mat4(&editnurb->nurbs, xod->elem_array, mat, true);
+ }
+ else {
+ BKE_curve_nurbs_vert_coords_apply_with_mat4(&cu->nurb, xod->elem_array, mat, true);
+ }
break;
}
case ID_AR: {
+ BLI_assert(xod_base->is_edit_mode == false); /* Not used currently. */
bArmature *arm = (bArmature *)xod_base->id;
struct XFormObjectData_Armature *xod = (struct XFormObjectData_Armature *)xod_base;
- armature_coords_and_quats_apply_with_mat4(arm, xod->elem_array, mat);
+ if (xod_base->is_edit_mode) {
+ edit_armature_coords_and_quats_apply_with_mat4(arm, xod->elem_array, mat);
+ }
+ else {
+ armature_coords_and_quats_apply_with_mat4(arm, xod->elem_array, mat);
+ }
break;
}
case ID_MB: {
+ /* Metaballs are a special case, edit-mode and object mode data is shared. */
MetaBall *mb = (MetaBall *)xod_base->id;
struct XFormObjectData_MetaBall *xod = (struct XFormObjectData_MetaBall *)xod_base;
metaball_coords_and_quats_apply_with_mat4(mb, xod->elem_array, mat);
@@ -330,4 +472,106 @@ void ED_object_data_xform_by_mat4(struct XFormObjectData *xod_base, const float
}
}
+void ED_object_data_xform_restore(struct XFormObjectData *xod_base)
+{
+ switch (GS(xod_base->id->name)) {
+ case ID_ME: {
+ Mesh *me = (Mesh *)xod_base->id;
+ struct XFormObjectData_Mesh *xod = (struct XFormObjectData_Mesh *)xod_base;
+ if (xod_base->is_edit_mode) {
+ BMesh *bm = me->edit_mesh->bm;
+ BM_mesh_vert_coords_apply(bm, xod->elem_array);
+ }
+ else {
+ BKE_mesh_vert_coords_apply(me, xod->elem_array);
+ }
+ break;
+ }
+ case ID_LT: {
+ Lattice *lt_orig = (Lattice *)xod_base->id;
+ Lattice *lt = xod_base->is_edit_mode ? lt_orig->editlatt->latt : lt_orig;
+ struct XFormObjectData_Lattice *xod = (struct XFormObjectData_Lattice *)xod_base;
+ BKE_lattice_vert_coords_apply(lt, xod->elem_array);
+ break;
+ }
+ case ID_CU: {
+ Curve *cu = (Curve *)xod_base->id;
+ struct XFormObjectData_Curve *xod = (struct XFormObjectData_Curve *)xod_base;
+ if (xod_base->is_edit_mode) {
+ EditNurb *editnurb = cu->editnurb;
+ BKE_curve_nurbs_vert_coords_apply(&editnurb->nurbs, xod->elem_array, true);
+ }
+ else {
+ BKE_curve_nurbs_vert_coords_apply(&cu->nurb, xod->elem_array, true);
+ }
+ break;
+ }
+ case ID_AR: {
+ bArmature *arm = (bArmature *)xod_base->id;
+ struct XFormObjectData_Armature *xod = (struct XFormObjectData_Armature *)xod_base;
+ if (xod_base->is_edit_mode) {
+ edit_armature_coords_and_quats_apply(arm, xod->elem_array);
+ }
+ else {
+ armature_coords_and_quats_apply(arm, xod->elem_array);
+ }
+ break;
+ }
+ case ID_MB: {
+ /* Metaballs are a special case, edit-mode and object mode data is shared. */
+ MetaBall *mb = (MetaBall *)xod_base->id;
+ struct XFormObjectData_MetaBall *xod = (struct XFormObjectData_MetaBall *)xod_base;
+ metaball_coords_and_quats_apply(mb, xod->elem_array);
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+}
+
+void ED_object_data_xform_tag_update(struct XFormObjectData *xod_base)
+{
+ switch (GS(xod_base->id->name)) {
+ case ID_ME: {
+ Mesh *me = (Mesh *)xod_base->id;
+ if (xod_base->is_edit_mode) {
+ EDBM_update_generic(me->edit_mesh, true, false);
+ EDBM_mesh_normals_update(me->edit_mesh);
+ }
+ DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY);
+ break;
+ }
+ case ID_LT: {
+ /* Generic update. */
+ Lattice *lt = (Lattice *)xod_base->id;
+ DEG_id_tag_update(&lt->id, ID_RECALC_GEOMETRY);
+ break;
+ }
+ case ID_CU: {
+ /* Generic update. */
+ Curve *cu = (Curve *)xod_base->id;
+ DEG_id_tag_update(&cu->id, ID_RECALC_GEOMETRY);
+ break;
+ }
+ case ID_AR: {
+ /* Generic update. */
+ bArmature *arm = (bArmature *)xod_base->id;
+ /* XXX, zero is needed, no other flags properly update this. */
+ DEG_id_tag_update(&arm->id, 0);
+ break;
+ }
+ case ID_MB: {
+ /* Generic update. */
+ MetaBall *mb = (MetaBall *)xod_base->id;
+ DEG_id_tag_update(&mb->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
+ break;
+ }
+
+ default: {
+ break;
+ }
+ }
+}
+
/** \} */