[Bf-blender-cvs] [35fea3a] mesh-transfer-data: Transfer operators: do not run several times on same mesh, nor on linked ones.
Bastien Montagne
noreply at git.blender.org
Wed Nov 19 16:34:26 CET 2014
Commit: 35fea3a7c397d09d10c17ba837a9dfab8e97232d
Author: Bastien Montagne
Date: Wed Nov 19 15:33:23 2014 +0100
Branches: mesh-transfer-data
https://developer.blender.org/rB35fea3a7c397d09d10c17ba837a9dfab8e97232d
Transfer operators: do not run several times on same mesh, nor on linked ones.
===================================================================
M source/blender/editors/object/object_data_transfer.c
===================================================================
diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c
index 1ec692f..b52f6cc 100644
--- a/source/blender/editors/object/object_data_transfer.c
+++ b/source/blender/editors/object/object_data_transfer.c
@@ -31,6 +31,7 @@
#include "MEM_guardedalloc.h"
+#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -45,6 +46,7 @@
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_remap.h"
#include "BKE_object.h"
+#include "BKE_report.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -259,11 +261,63 @@ static bool data_transfer_check(bContext *UNUSED(C), wmOperator *op)
return false;
}
+/* Helper, used by both data_transfer_exec and datalayout_transfer_exec. */
+static void data_transfer_exec_preprocess_objects(bContext *C, wmOperator *op, Object *ob_src, ListBase *ctx_objects)
+{
+ CollectionPointerLink *ctx_ob;
+ CTX_data_selected_editable_objects(C, ctx_objects);
+
+ for (ctx_ob = ctx_objects->first; ctx_ob; ctx_ob = ctx_ob->next) {
+ Object *ob = ctx_ob->ptr.data;
+ Mesh *me;
+ if ((ob == ob_src) || (ob->type != OB_MESH)) {
+ continue;
+ }
+
+ me = ob->data;
+ if (me->id.lib) {
+ /* Do not transfer to linked data, not supported. */
+ BKE_reportf(op->reports, RPT_WARNING, "Skipping object '%s', linked data '%s' cannot be modified",
+ ob->id.name + 2, me->id.name + 2);
+ me->id.flag &= ~LIB_DOIT;
+ continue;
+ }
+
+ me->id.flag |= LIB_DOIT;
+ }
+}
+
+/* Helper, used by both data_transfer_exec and datalayout_transfer_exec. */
+static bool data_transfer_exec_is_object_valid(wmOperator *op, Object *ob_src, Object *ob_dst)
+{
+ Mesh *me;
+ if ((ob_dst == ob_src) || (ob_dst->type != OB_MESH)) {
+ return false;
+ }
+
+ me = ob_dst->data;
+ if (me->id.flag & LIB_DOIT) {
+ me->id.flag &= ~LIB_DOIT;
+ return true;
+ }
+ else if (me->id.lib == NULL) {
+ /* Do not transfer apply operation more than once. */
+ /* XXX This is not nice regarding vgroups, which are half-Object data... :/ */
+ BKE_reportf(op->reports, RPT_WARNING,
+ "Skipping object '%s', data '%s' has already been processed with a previous object",
+ ob_dst->id.name + 2, me->id.name + 2);
+ }
+ return false;
+}
+
static int data_transfer_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Object *ob_src = CTX_data_active_object(C);
+ ListBase ctx_objects;
+ CollectionPointerLink *ctx_ob_dst;
+
bool changed = false;
const int data_type = RNA_enum_get(op->ptr, "data_type");
@@ -296,25 +350,27 @@ static int data_transfer_exec(bContext *C, wmOperator *op)
layers_select_dst[fromto_idx] = layers_dst;
}
- CTX_DATA_BEGIN (C, Object *, ob_dst, selected_editable_objects)
- {
- if ((ob_dst == ob_src) || (ob_dst->type != OB_MESH)) {
- continue;
- }
+ data_transfer_exec_preprocess_objects(C, op, ob_src, &ctx_objects);
- if (space_transform) {
- BLI_SPACE_TRANSFORM_SETUP(space_transform, ob_dst, ob_src);
- }
+ for (ctx_ob_dst = ctx_objects.first; ctx_ob_dst; ctx_ob_dst = ctx_ob_dst->next) {
+ Object *ob_dst = ctx_ob_dst->ptr.data;
+ if (data_transfer_exec_is_object_valid(op, ob_src, ob_dst)) {
+ if (space_transform) {
+ BLI_SPACE_TRANSFORM_SETUP(space_transform, ob_dst, ob_src);
+ }
- if (BKE_object_data_transfer_mesh(scene, ob_src, ob_dst, data_type, use_create,
- map_vert_mode, map_edge_mode, map_loop_mode, map_poly_mode,
- space_transform, max_distance, ray_radius, layers_select_src, layers_select_dst,
- mix_mode, mix_factor, NULL, false, op->reports))
- {
- changed = true;
+ if (BKE_object_data_transfer_mesh(
+ scene, ob_src, ob_dst, data_type, use_create,
+ map_vert_mode, map_edge_mode, map_loop_mode, map_poly_mode,
+ space_transform, max_distance, ray_radius, layers_select_src, layers_select_dst,
+ mix_mode, mix_factor, NULL, false, op->reports))
+ {
+ changed = true;
+ }
}
}
- CTX_DATA_END;
+
+ BLI_freelistN(&ctx_objects);
#if 0 /* TODO */
/* Note: issue with that is that if canceled, operator cannot be redone... Nasty in our case. */
@@ -494,7 +550,9 @@ static int datalayout_transfer_exec(bContext *C, wmOperator *op)
}
else {
Object *ob_src = ob_act;
- Object *ob_dst;
+
+ ListBase ctx_objects;
+ CollectionPointerLink *ctx_ob_dst;
const int data_type = RNA_enum_get(op->ptr, "data_type");
const bool use_delete = RNA_boolean_get(op->ptr, "use_delete");
@@ -510,16 +568,17 @@ static int datalayout_transfer_exec(bContext *C, wmOperator *op)
layers_select_dst[fromto_idx] = layers_dst;
}
- CTX_DATA_BEGIN (C, Object *, ob_dst, selected_editable_objects)
- {
- if ((ob_dst == ob_src) || (ob_dst->type != OB_MESH)) {
- continue;
- }
+ data_transfer_exec_preprocess_objects(C, op, ob_src, &ctx_objects);
- BKE_object_data_transfer_layout(scene, ob_src, ob_dst, data_type, use_delete,
- layers_select_src, layers_select_dst);
+ for (ctx_ob_dst = ctx_objects.first; ctx_ob_dst; ctx_ob_dst = ctx_ob_dst->next) {
+ Object *ob_dst = ctx_ob_dst->ptr.data;
+ if (data_transfer_exec_is_object_valid(op, ob_src, ob_dst)) {
+ BKE_object_data_transfer_layout(scene, ob_src, ob_dst, data_type, use_delete,
+ layers_select_src, layers_select_dst);
+ }
}
- CTX_DATA_END;
+
+ BLI_freelistN(&ctx_objects);
}
return OPERATOR_FINISHED;
More information about the Bf-blender-cvs
mailing list