[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [28338] trunk/blender/source/blender: Fix [#22078] Cannot apply modifier in python (context error)

Matt Ebb matt at mke3.net
Thu Apr 22 03:55:21 CEST 2010


Revision: 28338
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=28338
Author:   broken
Date:     2010-04-22 03:55:10 +0200 (Thu, 22 Apr 2010)

Log Message:
-----------
Fix [#22078] Cannot apply modifier in python (context error)

Previously all modifier operators relied on the buttons layout data context pointer to 
decide which modifier to work on. This meant that these operators would only work 
from from the properties panel, and not from scripting/macros or for operator redo.

This commit makes all modifier operators take the modifier name as an operator 
property, so the operators can be re-done or executed outside of the modifier panel. 
When invoking the operators from the modifier panel, they automatically fill in the 
operator property from context.

This isn't a perfect API design, but it does bring these operators in line with the design 
of being able to access all UI functionality via other means like scripts.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_modifier.h
    trunk/blender/source/blender/blenkernel/intern/modifier.c
    trunk/blender/source/blender/editors/interface/interface_templates.c
    trunk/blender/source/blender/editors/object/object_modifier.c

Modified: trunk/blender/source/blender/blenkernel/BKE_modifier.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_modifier.h	2010-04-22 01:06:59 UTC (rev 28337)
+++ trunk/blender/source/blender/blenkernel/BKE_modifier.h	2010-04-22 01:55:10 UTC (rev 28338)
@@ -292,6 +292,7 @@
 									  IDWalkFunc walk,
 									  void *userData);
 struct ModifierData  *modifiers_findByType(struct Object *ob, ModifierType type);
+struct ModifierData  *modifiers_findByName(struct Object *ob, const char *name);
 void          modifiers_clearErrors(struct Object *ob);
 int           modifiers_getCageIndex(struct Scene *scene, struct Object *ob,
 									 int *lastPossibleCageIndex_r, int virtual_);

Modified: trunk/blender/source/blender/blenkernel/intern/modifier.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/modifier.c	2010-04-22 01:06:59 UTC (rev 28337)
+++ trunk/blender/source/blender/blenkernel/intern/modifier.c	2010-04-22 01:55:10 UTC (rev 28338)
@@ -176,6 +176,17 @@
 	return md;
 }
 
+ModifierData *modifiers_findByName(Object *ob, const char *name)
+{
+	ModifierData *md = ob->modifiers.first;
+	
+	for (; md; md=md->next)
+		if (strcmp(md->name, name)==0)
+			break;
+	
+	return md;
+}
+
 void modifiers_clearErrors(Object *ob)
 {
 	ModifierData *md = ob->modifiers.first;

Modified: trunk/blender/source/blender/editors/interface/interface_templates.c
===================================================================
--- trunk/blender/source/blender/editors/interface/interface_templates.c	2010-04-22 01:06:59 UTC (rev 28337)
+++ trunk/blender/source/blender/editors/interface/interface_templates.c	2010-04-22 01:55:10 UTC (rev 28338)
@@ -815,6 +815,7 @@
 				}
 			}
 			else {
+				uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT);
 				uiItemEnumO(row, "OBJECT_OT_modifier_apply", "Apply", 0, "apply_as", MODIFIER_APPLY_DATA);
 				
 				if (modifier_sameTopology(md))

Modified: trunk/blender/source/blender/editors/object/object_modifier.c
===================================================================
--- trunk/blender/source/blender/editors/object/object_modifier.c	2010-04-22 01:06:59 UTC (rev 28337)
+++ trunk/blender/source/blender/editors/object/object_modifier.c	2010-04-22 01:55:10 UTC (rev 28338)
@@ -573,16 +573,69 @@
 	ot->prop= prop;
 }
 
+/************************ poll function for operators using mod names and data context *********************/
+
+static int edit_modifier_poll_generic(bContext *C, StructRNA *rna_type)
+{
+	PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", rna_type);
+	Object *ob= (ptr.id.data)?ptr.id.data:ED_object_active_context(C);
+	
+	if (!ob || ob->id.lib) return 0;
+	if (ptr.data && ((ID*)ptr.id.data)->lib) return 0;
+	
+	return 1;
+}
+
+static int edit_modifier_poll(bContext *C)
+{
+	return edit_modifier_poll_generic(C, &RNA_Modifier);
+}
+
+static void edit_modifier_properties(wmOperatorType *ot)
+{
+	RNA_def_string(ot->srna, "modifier", "", 32, "Modifier", "Name of the modifier to apply");
+}
+
+static int edit_modifier_invoke_properties(bContext *C, wmOperator *op)
+{
+	PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
+	ModifierData *md;
+	
+	if (RNA_property_is_set(op->ptr, "modifier"))
+		return 1;
+	
+	if (ptr.data) {
+		md = ptr.data;
+		RNA_string_set(op->ptr, "modifier", md->name);
+		return 1;
+	}
+	
+	return 0;
+}
+
+static ModifierData *edit_modifier_property_get(bContext *C, wmOperator *op, Object *ob, int type)
+{
+	char modifier_name[32];
+	ModifierData *md;
+	RNA_string_get(op->ptr, "modifier", modifier_name);
+	
+	md = modifiers_findByName(ob, modifier_name);
+	
+	if (md && type != 0 && md->type != type)
+		md = NULL;
+
+	return md;
+}
+
 /************************ remove modifier operator *********************/
 
 static int modifier_remove_exec(bContext *C, wmOperator *op)
 {
 	Scene *scene= CTX_data_scene(C);
-	PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
-	Object *ob= ptr.id.data;
-	ModifierData *md= ptr.data;
-
-	if(!ED_object_modifier_remove(op->reports, scene, ob, md))
+	Object *ob = ED_object_active_context(C);
+	ModifierData *md = edit_modifier_property_get(C, op, ob, 0);
+	
+	if(!ob || !md || !ED_object_modifier_remove(op->reports, scene, ob, md))
 		return OPERATOR_CANCELLED;
 
 	WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
@@ -590,28 +643,37 @@
 	return OPERATOR_FINISHED;
 }
 
+static int modifier_remove_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+	if (edit_modifier_invoke_properties(C, op))
+		return modifier_remove_exec(C, op);
+	else
+		return OPERATOR_CANCELLED;
+}
+
 void OBJECT_OT_modifier_remove(wmOperatorType *ot)
 {
 	ot->name= "Remove Modifier";
 	ot->description= "Remove a modifier from the active object";
 	ot->idname= "OBJECT_OT_modifier_remove";
 
+	ot->invoke= modifier_remove_invoke;
 	ot->exec= modifier_remove_exec;
-	ot->poll= modifier_poll;
+	ot->poll= edit_modifier_poll;
 	
 	/* flags */
 	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+	edit_modifier_properties(ot);
 }
 
 /************************ move up modifier operator *********************/
 
 static int modifier_move_up_exec(bContext *C, wmOperator *op)
 {
-	PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
-	Object *ob= ptr.id.data;
-	ModifierData *md= ptr.data;
+	Object *ob = ED_object_active_context(C);
+	ModifierData *md = edit_modifier_property_get(C, op, ob, 0);
 
-	if(!ED_object_modifier_move_up(op->reports, ob, md))
+	if(!ob || !md || !ED_object_modifier_move_up(op->reports, ob, md))
 		return OPERATOR_CANCELLED;
 
 	DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
@@ -620,26 +682,35 @@
 	return OPERATOR_FINISHED;
 }
 
+static int modifier_move_up_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+	if (edit_modifier_invoke_properties(C, op))
+		return modifier_move_up_exec(C, op);
+	else
+		return OPERATOR_CANCELLED;
+}
+
 void OBJECT_OT_modifier_move_up(wmOperatorType *ot)
 {
 	ot->name= "Move Up Modifier";
 	ot->description= "Move modifier up in the stack";
 	ot->idname= "OBJECT_OT_modifier_move_up";
 
+	ot->invoke= modifier_move_up_invoke;
 	ot->exec= modifier_move_up_exec;
-	ot->poll= modifier_poll;
+	ot->poll= edit_modifier_poll;
 	
 	/* flags */
 	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+	edit_modifier_properties(ot);
 }
 
 /************************ move down modifier operator *********************/
 
 static int modifier_move_down_exec(bContext *C, wmOperator *op)
 {
-	PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
-	Object *ob= ptr.id.data;
-	ModifierData *md= ptr.data;
+	Object *ob = ED_object_active_context(C);
+	ModifierData *md = edit_modifier_property_get(C, op, ob, 0);
 
 	if(!ob || !md || !ED_object_modifier_move_down(op->reports, ob, md))
 		return OPERATOR_CANCELLED;
@@ -650,17 +721,27 @@
 	return OPERATOR_FINISHED;
 }
 
+static int modifier_move_down_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+	if (edit_modifier_invoke_properties(C, op))
+		return modifier_move_down_exec(C, op);
+	else
+		return OPERATOR_CANCELLED;
+}
+
 void OBJECT_OT_modifier_move_down(wmOperatorType *ot)
 {
 	ot->name= "Move Down Modifier";
 	ot->description= "Move modifier down in the stack";
 	ot->idname= "OBJECT_OT_modifier_move_down";
 
+	ot->invoke= modifier_move_down_invoke;
 	ot->exec= modifier_move_down_exec;
-	ot->poll= modifier_poll;
+	ot->poll= edit_modifier_poll;
 	
 	/* flags */
 	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+	edit_modifier_properties(ot);
 }
 
 /************************ apply modifier operator *********************/
@@ -668,13 +749,13 @@
 static int modifier_apply_exec(bContext *C, wmOperator *op)
 {
 	Scene *scene= CTX_data_scene(C);
-	PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
-	Object *ob= ptr.id.data;
-	ModifierData *md= ptr.data;
+	Object *ob = ED_object_active_context(C);
+	ModifierData *md = edit_modifier_property_get(C, op, ob, 0);
 	int apply_as= RNA_enum_get(op->ptr, "apply_as");
-
-	if(!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as))
+	
+	if(!ob || !md || !ED_object_modifier_apply(op->reports, scene, ob, md, apply_as)) {
 		return OPERATOR_CANCELLED;
+	}
 
 	DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
 	WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
@@ -682,6 +763,14 @@
 	return OPERATOR_FINISHED;
 }
 
+static int modifier_apply_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+	if (edit_modifier_invoke_properties(C, op))
+		return modifier_apply_exec(C, op);
+	else
+		return OPERATOR_CANCELLED;
+}
+
 static EnumPropertyItem modifier_apply_as_items[] = {
 	{MODIFIER_APPLY_DATA, "DATA", 0, "Object Data", "Apply modifier to the object's data"},
 	{MODIFIER_APPLY_SHAPE, "SHAPE", 0, "New Shape", "Apply deform-only modifier to a new shape on this object"},
@@ -693,14 +782,15 @@
 	ot->description= "Apply modifier and remove from the stack";
 	ot->idname= "OBJECT_OT_modifier_apply";
 
-	//ot->invoke= WM_menu_invoke;
+	ot->invoke= modifier_apply_invoke;
 	ot->exec= modifier_apply_exec;
-	ot->poll= modifier_poll;
+	ot->poll= edit_modifier_poll;
 	
 	/* flags */
 	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 	
 	RNA_def_enum(ot->srna, "apply_as", modifier_apply_as_items, MODIFIER_APPLY_DATA, "Apply as", "How to apply the modifier to the geometry");
+	edit_modifier_properties(ot);
 }
 
 /************************ convert modifier operator *********************/
@@ -708,10 +798,9 @@
 static int modifier_convert_exec(bContext *C, wmOperator *op)
 {
 	Scene *scene= CTX_data_scene(C);
-	PointerRNA ptr= CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier);
-	Object *ob= ptr.id.data;
-	ModifierData *md= ptr.data;
-
+	Object *ob = ED_object_active_context(C);
+	ModifierData *md = edit_modifier_property_get(C, op, ob, 0);
+	
 	if(!ob || !md || !ED_object_modifier_convert(op->reports, scene, ob, md))
 		return OPERATOR_CANCELLED;
 
@@ -721,26 +810,35 @@
 	return OPERATOR_FINISHED;
 }
 
+static int modifier_convert_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+	if (edit_modifier_invoke_properties(C, op))
+		return modifier_convert_exec(C, op);
+	else
+		return OPERATOR_CANCELLED;
+}
+
 void OBJECT_OT_modifier_convert(wmOperatorType *ot)
 {
 	ot->name= "Convert Modifier";
 	ot->description= "Convert particles to a mesh object";
 	ot->idname= "OBJECT_OT_modifier_convert";
 
+	ot->invoke= modifier_convert_invoke;
 	ot->exec= modifier_convert_exec;
-	ot->poll= modifier_poll;

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list