Beispiel #1
0
/* Get unit conversion factor for given ID + F-Curve */
float ANIM_unit_mapping_get_factor(Scene *scene, ID *id, FCurve *fcu, short restore)
{
    /* sanity checks */
    if (id && fcu && fcu->rna_path) {
        PointerRNA ptr, id_ptr;
        PropertyRNA *prop;

        /* get RNA property that F-Curve affects */
        RNA_id_pointer_create(id, &id_ptr);
        if (RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop)) {
            /* rotations: radians <-> degrees? */
            if (RNA_SUBTYPE_UNIT(RNA_property_subtype(prop)) == PROP_UNIT_ROTATION) {
                /* if the radians flag is not set, default to using degrees which need conversions */
                if ((scene) && (scene->unit.system_rotation == USER_UNIT_ROT_RADIANS) == 0) {
                    if (restore)
                        return DEG2RADF(1.0f);  /* degrees to radians */
                    else
                        return RAD2DEGF(1.0f);  /* radians to degrees */
                }
            }

            /* TODO: other rotation types here as necessary */
        }
    }

    /* no mapping needs to occur... */
    return 1.0f;
}
int UI_pie_menu_invoke_from_rna_enum(
        struct bContext *C, const char *title, const char *path,
        const wmEvent *event)
{
	PointerRNA ctx_ptr;
	PointerRNA r_ptr;
	PropertyRNA *r_prop;
	uiPieMenu *pie;
	uiLayout *layout;

	RNA_pointer_create(NULL, &RNA_Context, C, &ctx_ptr);

	if (!RNA_path_resolve(&ctx_ptr, path, &r_ptr, &r_prop)) {
		return OPERATOR_CANCELLED;
	}

	/* invalid property, only accept enums */
	if (RNA_property_type(r_prop) != PROP_ENUM) {
		BLI_assert(0);
		return OPERATOR_CANCELLED;
	}

	pie = UI_pie_menu_begin(C, IFACE_(title), ICON_NONE, event);

	layout = UI_pie_menu_layout(pie);

	layout = uiLayoutRadial(layout);
	uiItemFullR(layout, &r_ptr, r_prop, RNA_NO_INDEX, 0, UI_ITEM_R_EXPAND, NULL, 0);

	UI_pie_menu_end(C, pie);

	return OPERATOR_INTERFACE;
}
static int copy_to_selected_button_exec(bContext *C, wmOperator *op)
{
	PointerRNA ptr, lptr, idptr;
	PropertyRNA *prop, *lprop;
	int success = 0;
	int index, all = RNA_boolean_get(op->ptr, "all");

	/* try to reset the nominated setting to its default value */
	uiContextActiveProperty(C, &ptr, &prop, &index);
	
	/* if there is a valid property that is editable... */
	if (ptr.data && prop) {
		char *path = NULL;
		int use_path;
		CollectionPointerLink *link;
		ListBase lb;

		if (!copy_to_selected_list(C, &ptr, &lb, &use_path))
			return success;

		if (!use_path || (path = RNA_path_from_ID_to_property(&ptr, prop))) {
			for (link = lb.first; link; link = link->next) {
				if (link->ptr.data != ptr.data) {
					if (use_path) {
						lprop = NULL;
						RNA_id_pointer_create(link->ptr.id.data, &idptr);
						RNA_path_resolve(&idptr, path, &lptr, &lprop);
					}
					else {
						lptr = link->ptr;
						lprop = prop;
					}

					if (lprop == prop) {
						if (RNA_property_editable(&lptr, lprop)) {
							if (RNA_property_copy(&lptr, &ptr, prop, (all) ? -1 : index)) {
								RNA_property_update(C, &lptr, prop);
								success = 1;
							}
						}
					}
				}
			}

			if (path)
				MEM_freeN(path);
		}

		BLI_freelistN(&lb);
	}
	
	return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
static int copy_to_selected_button_poll(bContext *C)
{
	PointerRNA ptr, lptr, idptr;
	PropertyRNA *prop, *lprop;
	int index, success = 0;

	uiContextActiveProperty(C, &ptr, &prop, &index);

	if (ptr.data && prop) {
		char *path = NULL;
		int use_path;
		CollectionPointerLink *link;
		ListBase lb;

		if (!copy_to_selected_list(C, &ptr, &lb, &use_path))
			return success;

		if (!use_path || (path = RNA_path_from_ID_to_property(&ptr, prop))) {
			for (link = lb.first; link; link = link->next) {
				if (link->ptr.data != ptr.data) {
					if (use_path) {
						lprop = NULL;
						RNA_id_pointer_create(link->ptr.id.data, &idptr);
						RNA_path_resolve(&idptr, path, &lptr, &lprop);
					}
					else {
						lptr = link->ptr;
						lprop = prop;
					}

					if (lprop == prop) {
						if (RNA_property_editable(&lptr, prop))
							success = 1;
					}
				}
			}

			if (path)
				MEM_freeN(path);
		}

		BLI_freelistN(&lb);
	}

	return success;
}
Beispiel #5
0
/* Main Driver Management API calls:
 * 	Add a new driver for the specified property on the given ID block or replace an existing one
 *	with the driver + driver-curve data from the buffer 
 */
short ANIM_paste_driver (ReportList *reports, ID *id, const char rna_path[], int array_index, short UNUSED(flag))
{	
	PointerRNA id_ptr, ptr;
	PropertyRNA *prop;
	FCurve *fcu;
	
	/* validate pointer first - exit if failure */
	RNA_id_pointer_create(id, &id_ptr);
	if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
		BKE_reportf(reports, RPT_ERROR,
			"Could not paste Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", 
			id->name, rna_path);
		return 0;
	}
	
	/* if the buffer is empty, cannot paste... */
	if (channeldriver_copypaste_buf == NULL) {
		BKE_report(reports, RPT_ERROR, "Paste Driver: No Driver to paste");
		return 0;
	}
	
	/* create Driver F-Curve, but without data which will be copied across... */
	fcu= verify_driver_fcurve(id, rna_path, array_index, -1);

	if (fcu) {
		/* copy across the curve data from the buffer curve 
		 * NOTE: this step needs care to not miss new settings
		 */
			/* keyframes/samples */
		fcu->bezt= MEM_dupallocN(channeldriver_copypaste_buf->bezt);
		fcu->fpt= MEM_dupallocN(channeldriver_copypaste_buf->fpt);
		fcu->totvert= channeldriver_copypaste_buf->totvert;
		
			/* modifiers */
		copy_fmodifiers(&fcu->modifiers, &channeldriver_copypaste_buf->modifiers);
		
			/* extrapolation mode */
		fcu->extend= channeldriver_copypaste_buf->extend;
			
			/* the 'juicy' stuff - the driver */
		fcu->driver= fcurve_copy_driver(channeldriver_copypaste_buf->driver);
	}
	
	/* done */
	return (fcu != NULL);
}
Beispiel #6
0
/* medium match strictness: path match only (i.e. ignore ID) */
static tAnimCopybufItem *pastebuf_match_path_property(FCurve *fcu, const short from_single, const short UNUSED(to_simple))
{
	tAnimCopybufItem *aci;

	for (aci= animcopybuf.first; aci; aci= aci->next) {
		/* check that paths exist */
		if (aci->rna_path && fcu->rna_path) {
			/* find the property of the fcurve and compare against the end of the tAnimCopybufItem
			 * more involved since it needs to to path lookups.
			 * This is not 100% reliable since the user could be editing the curves on a path that wont
			 * resolve, or a bone could be renamed after copying for eg. but in normal copy & paste
			 * this should work out ok. 
			 */
			if (BLI_findindex(which_libbase(G.main, aci->id_type), aci->id) == -1) {
				/* pedantic but the ID could have been removed, and beats crashing! */
				printf("paste_animedit_keys: error ID has been removed!\n");
			}
			else {
				PointerRNA id_ptr, rptr;
				PropertyRNA *prop;
				
				RNA_id_pointer_create(aci->id, &id_ptr);
				RNA_path_resolve(&id_ptr, aci->rna_path, &rptr, &prop);
				
				if (prop) {
					const char *identifier= RNA_property_identifier(prop);
					int len_id = strlen(identifier);
					int len_path = strlen(fcu->rna_path);
					if (len_id <= len_path) {
						/* note, paths which end with "] will fail with this test - Animated ID Props */
						if (strcmp(identifier, fcu->rna_path + (len_path-len_id))==0) {
							if ((from_single) || (aci->array_index == fcu->array_index))
								break;
						}
					}
				}
				else {
					printf("paste_animedit_keys: failed to resolve path id:%s, '%s'!\n", aci->id->name, aci->rna_path);
				}
			}
		}
	}

	return aci;
}
Beispiel #7
0
/* Main Driver Management API calls:
 * 	Make a copy of the driver for the specified property on the given ID block
 */
short ANIM_copy_driver (ReportList *reports, ID *id, const char rna_path[], int array_index, short UNUSED(flag))
{
	PointerRNA id_ptr, ptr;
	PropertyRNA *prop;
	FCurve *fcu;
	
	/* validate pointer first - exit if failure */
	RNA_id_pointer_create(id, &id_ptr);
	if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
		BKE_reportf(reports, RPT_ERROR,
			"Could not find Driver to copy, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", 
			id->name, rna_path);
		return 0;
	}
	
	/* try to get F-Curve with Driver */
	fcu= verify_driver_fcurve(id, rna_path, array_index, 0);
	
	/* clear copy/paste buffer first (for consistency with other copy/paste buffers) */
	free_anim_drivers_copybuf();
	
	/* copy this to the copy/paste buf if it exists */
	if (fcu && fcu->driver) {
		/* make copies of some info such as the rna_path, then clear this info from the F-Curve temporarily
		 * so that we don't end up wasting memory storing the path which won't get used ever...
		 */
		char *tmp_path = fcu->rna_path;
		fcu->rna_path= NULL;
		
		/* make a copy of the F-Curve with */
		channeldriver_copypaste_buf= copy_fcurve(fcu);
		
		/* restore the path */
		fcu->rna_path= tmp_path;
		
		/* copied... */
		return 1;
	}
	
	/* done */
	return 0;
}
Beispiel #8
0
/* tags the given anim list element for refreshes (if applicable)
 * due to Animation Editor editing
 */
void ANIM_list_elem_update(Scene *scene, bAnimListElem *ale)
{
    ID *id;
    FCurve *fcu;
    AnimData *adt;

    id= ale->id;
    if (!id)
        return;

    /* tag AnimData for refresh so that other views will update in realtime with these changes */
    adt= BKE_animdata_from_id(id);
    if (adt)
        adt->recalc |= ADT_RECALC_ANIM;

    /* update data */
    fcu= (ale->datatype == ALE_FCURVE)? ale->key_data: NULL;

    if (fcu && fcu->rna_path) {
        /* if we have an fcurve, call the update for the property we
           are editing, this is then expected to do the proper redraws
           and depsgraph updates  */
        PointerRNA id_ptr, ptr;
        PropertyRNA *prop;

        RNA_id_pointer_create(id, &id_ptr);

        if(RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop))
            RNA_property_update_main(G.main, scene, &ptr, prop);
    }
    else {
        /* in other case we do standard depsgaph update, ideally
           we'd be calling property update functions here too ... */
        DAG_id_tag_update(id, OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME); // XXX or do we want something more restrictive?
    }
}
static void graph_panel_key_properties(const bContext *C, Panel *pa)
{
	bAnimListElem *ale;
	FCurve *fcu;
	BezTriple *bezt, *prevbezt;
	
	uiLayout *layout = pa->layout;
	uiLayout *col;
	uiBlock *block;

	if (!graph_panel_context(C, &ale, &fcu))
		return;
	
	block = uiLayoutGetBlock(layout);
	uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL);
	
	/* only show this info if there are keyframes to edit */
	if (get_active_fcurve_keyframe_edit(fcu, &bezt, &prevbezt)) {
		PointerRNA bezt_ptr, id_ptr, fcu_prop_ptr;
		PropertyRNA *fcu_prop = NULL;
		uiBut *but;
		int unit = B_UNIT_NONE;
		
		/* RNA pointer to keyframe, to allow editing */
		RNA_pointer_create(ale->id, &RNA_Keyframe, bezt, &bezt_ptr);
		
		/* get property that F-Curve affects, for some unit-conversion magic */
		RNA_id_pointer_create(ale->id, &id_ptr);
		if (RNA_path_resolve(&id_ptr, fcu->rna_path, &fcu_prop_ptr, &fcu_prop) && fcu_prop) {
			/* determine the unit for this property */
			unit = RNA_SUBTYPE_UNIT(RNA_property_subtype(fcu_prop));
		}		
		
		/* interpolation */
		col = uiLayoutColumn(layout, FALSE);
		uiItemR(col, &bezt_ptr, "interpolation", 0, NULL, ICON_NONE);
			
		/* numerical coordinate editing 
		 *  - we use the button-versions of the calls so that we can attach special update handlers
		 *    and unit conversion magic that cannot be achieved using a purely RNA-approach
		 */
		// XXX: 
		col = uiLayoutColumn(layout, TRUE);
		/* keyframe itself */
		{
			uiItemL(col, IFACE_("Key:"), ICON_NONE);

			but = uiDefButR(block, NUM, B_REDR, IFACE_("Frame"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "co", 0, 0, 0, -1, -1, NULL);
			uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt);

			but = uiDefButR(block, NUM, B_REDR, IFACE_("Value"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "co", 1, 0, 0, -1, -1, NULL);
			uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt);
			uiButSetUnitType(but, unit);
		}

		/* previous handle - only if previous was Bezier interpolation */
		if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) {
			uiItemL(col, IFACE_("Left Handle:"), ICON_NONE);

			but = uiDefButR(block, NUM, B_REDR, "X", 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "handle_left", 0, 0, 0, -1, -1, NULL);
			uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);

			but = uiDefButR(block, NUM, B_REDR, "Y", 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "handle_left", 1, 0, 0, -1, -1, NULL);
			uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);
			uiButSetUnitType(but, unit);
		}

		/* next handle - only if current is Bezier interpolation */
		if (bezt->ipo == BEZT_IPO_BEZ) {
			uiItemL(col, IFACE_("Right Handle:"), ICON_NONE);

			but = uiDefButR(block, NUM, B_REDR, "X", 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "handle_right", 0, 0, 0, -1, -1, NULL);
			uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);

			but = uiDefButR(block, NUM, B_REDR, "Y", 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "handle_right", 1, 0, 0, -1, -1, NULL);
			uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);
			uiButSetUnitType(but, unit);
		}
	}
	else {
		if ((fcu->bezt == NULL) && (fcu->modifiers.first)) {
			/* modifiers only - so no keyframes to be active */
			uiItemL(layout, IFACE_("F-Curve only has F-Modifiers"), ICON_NONE);
			uiItemL(layout, IFACE_("See Modifiers panel below"), ICON_INFO);
		}
		else if (fcu->fpt) {
			/* samples only */
			uiItemL(layout, IFACE_("F-Curve doesn't have any keyframes as it only contains sampled points"),
			        ICON_NONE);
		}
		else
			uiItemL(layout, IFACE_("No active keyframe on F-Curve"), ICON_NONE);
	}
	
	MEM_freeN(ale);
}
Beispiel #10
0
static char *rna_ColorRampElement_path(PointerRNA *ptr)
{
	PointerRNA ramp_ptr;
	PropertyRNA *prop;
	char *path = NULL;
	int index;
	
	/* helper macro for use here to try and get the path
	 *	- this calls the standard code for getting a path to a texture...
	 */

#define COLRAMP_GETPATH                                                       \
{                                                                             \
	prop = RNA_struct_find_property(&ramp_ptr, "elements");                   \
	if (prop) {                                                               \
		index = RNA_property_collection_lookup_index(&ramp_ptr, prop, ptr);   \
		if (index != -1) {                                                    \
			char *texture_path = rna_ColorRamp_path(&ramp_ptr);               \
			path = BLI_sprintfN("%s.elements[%d]", texture_path, index);      \
			MEM_freeN(texture_path);                                          \
		}                                                                     \
	}                                                                         \
} (void)0

	/* determine the path from the ID-block to the ramp */
	/* FIXME: this is a very slow way to do it, but it will have to suffice... */
	if (ptr->id.data) {
		ID *id = ptr->id.data;
		
		switch (GS(id->name)) {
			case ID_MA: /* 2 cases for material - diffuse and spec */
			{
				Material *ma = (Material *)id;
				
				/* try diffuse first */
				if (ma->ramp_col) {
					RNA_pointer_create(id, &RNA_ColorRamp, ma->ramp_col, &ramp_ptr);
					COLRAMP_GETPATH;
				}
				/* try specular if not diffuse */
				if (!path && ma->ramp_spec) {
					RNA_pointer_create(id, &RNA_ColorRamp, ma->ramp_spec, &ramp_ptr);
					COLRAMP_GETPATH;
				}
				break;
			}
			case ID_NT:
			{
				bNodeTree *ntree = (bNodeTree *)id;
				bNode *node;
				
				for (node = ntree->nodes.first; node; node = node->next) {
					if (ELEM(node->type, SH_NODE_VALTORGB, CMP_NODE_VALTORGB, TEX_NODE_VALTORGB)) {
						RNA_pointer_create(id, &RNA_ColorRamp, node->storage, &ramp_ptr);
						COLRAMP_GETPATH;
					}
				}
				break;
			}
			case ID_LS:
			{
				ListBase listbase;
				LinkData *link;

				BKE_linestyle_modifier_list_color_ramps((FreestyleLineStyle *)id, &listbase);
				for (link = (LinkData *)listbase.first; link; link = link->next) {
					RNA_pointer_create(id, &RNA_ColorRamp, link->data, &ramp_ptr);
					COLRAMP_GETPATH;
				}
				BLI_freelistN(&listbase);
				break;
			}

			default: /* everything else should have a "color_ramp" property */
			{
				/* create pointer to the ID block, and try to resolve "color_ramp" pointer */
				RNA_id_pointer_create(id, &ramp_ptr);
				if (RNA_path_resolve(&ramp_ptr, "color_ramp", &ramp_ptr, &prop)) {
					COLRAMP_GETPATH;
				}
				break;
			}
		}
	}
	
	/* cleanup the macro we defined */
#undef COLRAMP_GETPATH
	
	return path;
}
Beispiel #11
0
/* Write into "name" buffer, the name of the property (retrieved using RNA from the curve's settings),
 * and return the icon used for the struct that this property refers to 
 * WARNING: name buffer we're writing to cannot exceed 256 chars (check anim_channels_defines.c for details)
 */
int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
{
	int icon = 0;
	
	/* sanity checks */
	if (name == NULL)
		return icon;
	else if (ELEM3(NULL, id, fcu, fcu->rna_path)) {
		if (fcu == NULL)
			strcpy(name, "<invalid>");
		else if (fcu->rna_path == NULL)
			strcpy(name, "<no path>");
		else /* id == NULL */
			BLI_snprintf(name, 256, "%s[%d]", fcu->rna_path, fcu->array_index);
	}
	else {
		PointerRNA id_ptr, ptr;
		PropertyRNA *prop;
		
		/* get RNA pointer, and resolve the path */
		RNA_id_pointer_create(id, &id_ptr);
		
		/* try to resolve the path */
		if (RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop)) {
			const char *structname = NULL, *propname = NULL;
			char arrayindbuf[16];
			const char *arrayname = NULL;
			short free_structname = 0;
			
			/* For now, name will consist of 3 parts: struct-name, property name, array index
			 * There are several options possible:
			 *	1) <struct-name>.<property-name>.<array-index>
			 *		i.e. Bone1.Location.X, or Object.Location.X
			 *	2) <array-index> <property-name> (<struct name>)
			 *		i.e. X Location (Bone1), or X Location (Object)
			 *	
			 * Currently, option 2 is in use, to try and make it easier to quickly identify F-Curves (it does have
			 * problems with looking rather odd though). Option 1 is better in terms of revealing a consistent sense of 
			 * hierarchy though, which isn't so clear with option 2.
			 */
			
			/* for structname
			 *	- as base, we use a custom name from the structs if one is available 
			 *	- however, if we're showing subdata of bones (probably there will be other exceptions later)
			 *	  need to include that info too since it gets confusing otherwise
			 *	- if a pointer just refers to the ID-block, then don't repeat this info
			 *	  since this just introduces clutter
			 */
			if (strstr(fcu->rna_path, "bones") && strstr(fcu->rna_path, "constraints")) {
				/* perform string 'chopping' to get "Bone Name : Constraint Name" */
				char *pchanName = BLI_getQuotedStr(fcu->rna_path, "bones[");
				char *constName = BLI_getQuotedStr(fcu->rna_path, "constraints[");
				
				/* assemble the string to display in the UI... */
				structname = BLI_sprintfN("%s : %s", pchanName, constName);
				free_structname = 1;
				
				/* free the temp names */
				if (pchanName) MEM_freeN(pchanName);
				if (constName) MEM_freeN(constName);
			}
			else if (ptr.data != ptr.id.data) {
				PropertyRNA *nameprop = RNA_struct_name_property(ptr.type);
				if (nameprop) {
					/* this gets a string which will need to be freed */
					structname = RNA_property_string_get_alloc(&ptr, nameprop, NULL, 0, NULL);
					free_structname = 1;
				}
				else
					structname = RNA_struct_ui_name(ptr.type);
			}
			
			/* Property Name is straightforward */
			propname = RNA_property_ui_name(prop);
			
			/* Array Index - only if applicable */
			if (RNA_property_array_length(&ptr, prop)) {
				char c = RNA_property_array_item_char(prop, fcu->array_index);
				
				/* we need to write the index to a temp buffer (in py syntax) */
				if (c) BLI_snprintf(arrayindbuf, sizeof(arrayindbuf), "%c ", c);
				else BLI_snprintf(arrayindbuf, sizeof(arrayindbuf), "[%d]", fcu->array_index);
				
				arrayname = &arrayindbuf[0];
			}
			else {
				/* no array index */
				arrayname = "";
			}
			
			/* putting this all together into the buffer */
			// XXX we need to check for invalid names...
			// XXX the name length limit needs to be passed in or as some define
			if (structname)
				BLI_snprintf(name, 256, "%s%s (%s)", arrayname, propname, structname); 
			else
				BLI_snprintf(name, 256, "%s%s", arrayname, propname); 
			
			/* free temp name if nameprop is set */
			if (free_structname)
				MEM_freeN((void *)structname);
			
			
			/* Icon for this property's owner:
			 *	use the struct's icon if it is set
			 */
			icon = RNA_struct_ui_icon(ptr.type);
			
			/* valid path - remove the invalid tag since we now know how to use it saving
			 * users manual effort to reenable using "Revive Disabled FCurves" [#29629]
			 */
			fcu->flag &= ~FCURVE_DISABLED;
		}
		else {
			/* invalid path */
			BLI_snprintf(name, 256, "\"%s[%d]\"", fcu->rna_path, fcu->array_index);
			
			/* icon for this should be the icon for the base ID */
			// TODO: or should we just use the error icon?
			icon = RNA_struct_ui_icon(id_ptr.type);
			
			/* tag F-Curve as disabled - as not usable path */
			fcu->flag |= FCURVE_DISABLED;
		}
	}
	
	/* return the icon that the active data had */
	return icon;
}
Beispiel #12
0
static int override_remove_button_exec(bContext *C, wmOperator *op)
{
  Main *bmain = CTX_data_main(C);
  PointerRNA ptr, id_refptr, src;
  PropertyRNA *prop;
  int index;
  const bool all = RNA_boolean_get(op->ptr, "all");

  /* try to reset the nominated setting to its default value */
  UI_context_active_but_prop_get(C, &ptr, &prop, &index);

  ID *id = ptr.id.data;
  IDOverrideStaticProperty *oprop = RNA_property_override_property_find(&ptr, prop);
  BLI_assert(oprop != NULL);
  BLI_assert(id != NULL && id->override_static != NULL);

  const bool is_template = (id->override_static->reference == NULL);

  /* We need source (i.e. linked data) to restore values of deleted overrides...
   * If this is an override template, we obviously do not need to restore anything. */
  if (!is_template) {
    RNA_id_pointer_create(id->override_static->reference, &id_refptr);
    if (!RNA_path_resolve(&id_refptr, oprop->rna_path, &src, NULL)) {
      BLI_assert(0 && "Failed to create matching source (linked data) RNA pointer");
    }
  }

  if (!all && index != -1) {
    bool is_strict_find;
    /* Remove override operation for given item,
     * add singular operations for the other items as needed. */
    IDOverrideStaticPropertyOperation *opop = BKE_override_static_property_operation_find(
        oprop, NULL, NULL, index, index, false, &is_strict_find);
    BLI_assert(opop != NULL);
    if (!is_strict_find) {
      /* No specific override operation, we have to get generic one,
       * and create item-specific override operations for all but given index,
       * before removing generic one. */
      for (int idx = RNA_property_array_length(&ptr, prop); idx--;) {
        if (idx != index) {
          BKE_override_static_property_operation_get(
              oprop, opop->operation, NULL, NULL, idx, idx, true, NULL, NULL);
        }
      }
    }
    BKE_override_static_property_operation_delete(oprop, opop);
    if (!is_template) {
      RNA_property_copy(bmain, &ptr, &src, prop, index);
    }
    if (BLI_listbase_is_empty(&oprop->operations)) {
      BKE_override_static_property_delete(id->override_static, oprop);
    }
  }
  else {
    /* Just remove whole generic override operation of this property. */
    BKE_override_static_property_delete(id->override_static, oprop);
    if (!is_template) {
      RNA_property_copy(bmain, &ptr, &src, prop, -1);
    }
  }

  return operator_button_property_finish(C, &ptr, prop);
}
Beispiel #13
0
/* Given a KeyingSet and context info (if required), modify keyframes for the channels specified
 * by the KeyingSet. This takes into account many of the different combinations of using KeyingSets.
 * Returns the number of channels that keyframes were added to
 */
int ANIM_apply_keyingset (bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
{
	Scene *scene= CTX_data_scene(C);
	ReportList *reports = CTX_wm_reports(C);
	KS_Path *ksp;
	int kflag=0, success= 0;
	char *groupname= NULL;
	
	/* sanity checks */
	if (ks == NULL)
		return 0;
	
	/* get flags to use */
	if (mode == MODIFYKEY_MODE_INSERT) {
		/* use KeyingSet's flags as base */
		kflag= ks->keyingflag;
		
		/* suppliment with info from the context */
		kflag |= ANIM_get_keyframing_flags(scene, 1);
	}
	else if (mode == MODIFYKEY_MODE_DELETE)
		kflag= 0;
	
	/* if relative Keying Sets, poll and build up the paths */
	success = ANIM_validate_keyingset(C, dsources, ks);
	
	if (success != 0) {
		/* return error code if failed */
		return success;
	}
	
	/* apply the paths as specified in the KeyingSet now */
	for (ksp= ks->paths.first; ksp; ksp= ksp->next) { 
		int arraylen, i;
		short kflag2;
		
		/* skip path if no ID pointer is specified */
		if (ksp->id == NULL) {
			BKE_reportf(reports, RPT_WARNING,
				"Skipping path in Keying Set, as it has no ID (KS = '%s', Path = '%s'[%d])",
				ks->name, ksp->rna_path, ksp->array_index);
			continue;
		}
		
		/* since keying settings can be defined on the paths too, extend the path before using it */
		kflag2 = (kflag | ksp->keyingflag);
		
		/* get pointer to name of group to add channels to */
		if (ksp->groupmode == KSP_GROUP_NONE)
			groupname= NULL;
		else if (ksp->groupmode == KSP_GROUP_KSNAME)
			groupname= ks->name;
		else
			groupname= ksp->group;
		
		/* init arraylen and i - arraylen should be greater than i so that
		 * normal non-array entries get keyframed correctly
		 */
		i= ksp->array_index;
		arraylen= i;
		
		/* get length of array if whole array option is enabled */
		if (ksp->flag & KSP_FLAG_WHOLE_ARRAY) {
			PointerRNA id_ptr, ptr;
			PropertyRNA *prop;
			
			RNA_id_pointer_create(ksp->id, &id_ptr);
			if (RNA_path_resolve(&id_ptr, ksp->rna_path, &ptr, &prop) && prop)
				arraylen= RNA_property_array_length(&ptr, prop);
		}
		
		/* we should do at least one step */
		if (arraylen == i)
			arraylen++;
		
		/* for each possible index, perform operation 
		 *	- assume that arraylen is greater than index
		 */
		for (; i < arraylen; i++) {
			/* action to take depends on mode */
			if (mode == MODIFYKEY_MODE_INSERT)
				success += insert_keyframe(reports, ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2);
			else if (mode == MODIFYKEY_MODE_DELETE)
				success += delete_keyframe(reports, ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2);
		}
		
		/* set recalc-flags */
		switch (GS(ksp->id->name)) {
			case ID_OB: /* Object (or Object-Related) Keyframes */
			{
				Object *ob= (Object *)ksp->id;
				
				ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; // XXX: only object transforms only?
			}
				break;
		}
		
		/* send notifiers for updates (this doesn't require context to work!) */
		WM_main_add_notifier(NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
	}
	
	/* return the number of channels successfully affected */
	return success;
}
Beispiel #14
0
/* Main Driver Management API calls:
 * 	Add a new driver for the specified property on the given ID block
 */
short ANIM_add_driver (ReportList *reports, ID *id, const char rna_path[], int array_index, short flag, int type)
{	
	PointerRNA id_ptr, ptr;
	PropertyRNA *prop;
	FCurve *fcu;
	int array_index_max;
	int done = 0;
	
	/* validate pointer first - exit if failure */
	RNA_id_pointer_create(id, &id_ptr);
	if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) {
		BKE_reportf(reports, RPT_ERROR, 
			"Could not add Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", 
			id->name, rna_path);
		return 0;
	}
	
	/* key entire array convenience method */
	if (array_index == -1) {
		array_index_max= RNA_property_array_length(&ptr, prop);
		array_index= 0;
	}
	else
		array_index_max= array_index;
	
	/* maximum index should be greater than the start index */
	if (array_index == array_index_max)
		array_index_max += 1;
	
	/* will only loop once unless the array index was -1 */
	for (; array_index < array_index_max; array_index++) {
		/* create F-Curve with Driver */
		fcu= verify_driver_fcurve(id, rna_path, array_index, 1);
		
		if (fcu && fcu->driver) {
			ChannelDriver *driver= fcu->driver;
			
			/* set the type of the driver */
			driver->type= type;
			
			/* creating drivers for buttons will create the driver(s) with type 
			 * "scripted expression" so that their values won't be lost immediately,
			 * so here we copy those values over to the driver's expression
			 */
			if (type == DRIVER_TYPE_PYTHON) {
				PropertyType proptype= RNA_property_type(prop);
				int array= RNA_property_array_length(&ptr, prop);
				char *expression= driver->expression;
				int val, maxlen= sizeof(driver->expression);
				float fval;
				
				if (proptype == PROP_BOOLEAN) {
					if (!array) val= RNA_property_boolean_get(&ptr, prop);
					else val= RNA_property_boolean_get_index(&ptr, prop, array_index);
					
					BLI_strncpy(expression, (val)? "True": "False", maxlen);
				}
				else if (proptype == PROP_INT) {
					if (!array) val= RNA_property_int_get(&ptr, prop);
					else val= RNA_property_int_get_index(&ptr, prop, array_index);
					
					BLI_snprintf(expression, maxlen, "%d", val);
				}
				else if (proptype == PROP_FLOAT) {
					if (!array) fval= RNA_property_float_get(&ptr, prop);
					else fval= RNA_property_float_get_index(&ptr, prop, array_index);
					
					BLI_snprintf(expression, maxlen, "%.3f", fval);
				}
			}
			
			/* for easier setup of drivers from UI, a driver variable should be 
			 * added if flag is set (UI calls only)
			 */
			if (flag & CREATEDRIVER_WITH_DEFAULT_DVAR) {
				/* assume that users will mostly want this to be of type "Transform Channel" too,
				 * since this allows the easiest setting up of common rig components
				 */
				DriverVar *dvar = driver_add_new_variable(driver);
				driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN);
			}
		}
		
		/* set the done status */
		done += (fcu != NULL);
	}
	
	/* done */
	return done;
}