Ejemplo n.º 1
0
PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
{
	const char *path, *path_full;
	int index = -1;

	PYRNA_STRUCT_CHECK_OBJ(self);

	if (!PyArg_ParseTuple(args, "s|i:driver_add", &path, &index))
		return NULL;

	if (pyrna_struct_anim_args_parse(&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) == -1) {
		return NULL;
	}
	else {
		PyObject *ret = NULL;
		ReportList reports;
		int result;

		BKE_reports_init(&reports, RPT_STORE);

		result = ANIM_add_driver(&reports, (ID *)self->ptr.id.data, path_full, index, 
		                         CREATEDRIVER_WITH_FMODIFIER, DRIVER_TYPE_PYTHON);

		if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1)
			return NULL;

		if (result) {
			ID *id = self->ptr.id.data;
			AnimData *adt = BKE_animdata_from_id(id);
			FCurve *fcu;

			PointerRNA tptr;

			if (index == -1) { /* all, use a list */
				int i = 0;
				ret = PyList_New(0);
				while ((fcu = list_find_fcurve(&adt->drivers, path_full, i++))) {
					RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
					PyList_APPEND(ret, pyrna_struct_CreatePyObject(&tptr));
				}
			}
			else {
				fcu = list_find_fcurve(&adt->drivers, path_full, index);
				RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
				ret = pyrna_struct_CreatePyObject(&tptr);
			}
			
			WM_event_add_notifier(BPy_GetContext(), NC_ANIMATION | ND_FCURVES_ORDER, NULL);
		}
		else {
			/* XXX, should be handled by reports, */
			PyErr_SetString(PyExc_TypeError, "bpy_struct.driver_add(): failed because of an internal error");
			return NULL;
		}

		MEM_freeN((void *)path_full);

		return ret;
	}
}
Ejemplo n.º 2
0
/* helper call for drawing influence/time control curves for a given NLA-strip */
static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc)
{
	const float yheight = ymaxc - yminc;
	
	/* drawing color is simply a light-gray */
	// TODO: is this color suitable?
	// XXX nasty hacked color for now... which looks quite bad too...
	glColor3f(0.7f, 0.7f, 0.7f);
	
	/* draw with AA'd line */
	glEnable(GL_LINE_SMOOTH);
	glEnable(GL_BLEND);
	
	/* influence -------------------------- */
	if (strip->flag & NLASTRIP_FLAG_USR_INFLUENCE) {
		FCurve *fcu = list_find_fcurve(&strip->fcurves, "influence", 0);
		float cfra;
		
		/* plot the curve (over the strip's main region) */
		glBegin(GL_LINE_STRIP);
		/* sample at 1 frame intervals, and draw
		 *	- min y-val is yminc, max is y-maxc, so clamp in those regions
		 */
		for (cfra = strip->start; cfra <= strip->end; cfra += 1.0f) {
			float y = evaluate_fcurve(fcu, cfra);
			CLAMP(y, 0.0f, 1.0f);
			glVertex2f(cfra, ((y * yheight) + yminc));
		}
		glEnd(); // GL_LINE_STRIP
	}
	else {
		/* use blend in/out values only if both aren't zero */
		if ((IS_EQF(strip->blendin, 0.0f) && IS_EQF(strip->blendout, 0.0f)) == 0) {
			glBegin(GL_LINE_STRIP);
			/* start of strip - if no blendin, start straight at 1, otherwise from 0 to 1 over blendin frames */
			if (IS_EQF(strip->blendin, 0.0f) == 0) {
				glVertex2f(strip->start,                    yminc);
				glVertex2f(strip->start + strip->blendin,   ymaxc);
			}
			else
				glVertex2f(strip->start, ymaxc);
					
			/* end of strip */
			if (IS_EQF(strip->blendout, 0.0f) == 0) {
				glVertex2f(strip->end - strip->blendout,    ymaxc);
				glVertex2f(strip->end,                      yminc);
			}
			else
				glVertex2f(strip->end, ymaxc);
			glEnd(); // GL_LINE_STRIP
		}
	}
	
	/* time -------------------------- */
	// XXX do we want to draw this curve? in a different color too?
	
	/* turn off AA'd lines */
	glDisable(GL_LINE_SMOOTH);
	glDisable(GL_BLEND);
}
Ejemplo n.º 3
0
static FCurve *rna_Action_fcurve_find(bAction *act, ReportList *reports, const char *data_path, int index)
{
	if (data_path[0] == '\0') {
		BKE_report(reports, RPT_ERROR, "F-Curve data path empty, invalid argument");
		return NULL;
	}

	/* Returns NULL if not found. */
	return list_find_fcurve(&act->curves, data_path, index);
}
Ejemplo n.º 4
0
static FCurve *rna_Driver_find(AnimData *adt, ReportList *reports, const char *data_path, int index)
{
	if (data_path[0] == '\0') {
		BKE_report(reports, RPT_ERROR, "F-Curve data path empty, invalid argument");
		return NULL;
	}

	/* Returns NULL if not found. */
	return list_find_fcurve(&adt->drivers, data_path, index);
}
Ejemplo n.º 5
0
static FCurve *rna_NlaStrip_fcurve_find(NlaStrip *strip, ReportList *reports, const char *data_path, int index)
{
	if (data_path[0] == '\0') {
		BKE_report(reports, RPT_ERROR, "F-Curve data path empty, invalid argument");
		return NULL;
	}

	/* Returns NULL if not found. */
	return list_find_fcurve(&strip->fcurves, data_path, index);
}
Ejemplo n.º 6
0
static FCurve *ui_but_get_fcurve(uiBut *but, bAction **action, int *driven)
{
	FCurve *fcu= NULL;

	*driven= 0;

	/* there must be some RNA-pointer + property combo for this button */
	if(but->rnaprop && but->rnapoin.id.data && 
		RNA_property_animateable(&but->rnapoin, but->rnaprop)) 
	{
		AnimData *adt= BKE_animdata_from_id(but->rnapoin.id.data);
		char *path;
		
		if(adt) {
			if((adt->action && adt->action->curves.first) || (adt->drivers.first)) {
				/* XXX this function call can become a performance bottleneck */
				path= RNA_path_from_ID_to_property(&but->rnapoin, but->rnaprop);

				if(path) {
					/* animation takes priority over drivers */
					if(adt->action && adt->action->curves.first)
						fcu= list_find_fcurve(&adt->action->curves, path, but->rnaindex);
					
					/* if not animated, check if driven */
					if(!fcu && (adt->drivers.first)) {
						fcu= list_find_fcurve(&adt->drivers, path, but->rnaindex);
						
						if(fcu)
							*driven= 1;
					}

					if(fcu && action)
						*action= adt->action;

					MEM_freeN(path);
				}
			}
		}
	}

	return fcu;
}
Ejemplo n.º 7
0
/* Get (or add relevant data to be able to do so) F-Curve from the driver stack, 
 * for the given Animation Data block. This assumes that all the destinations are valid.
 *	
 *	- add:	0 - don't add anything if not found, 
 *			1 - add new Driver FCurve, 
 *			-1 - add new Driver FCurve without driver stuff (for pasting)
 */
FCurve *verify_driver_fcurve (ID *id, const char rna_path[], const int array_index, short add)
{
	AnimData *adt;
	FCurve *fcu;
	
	/* sanity checks */
	if ELEM(NULL, id, rna_path)
		return NULL;
	
	/* init animdata if none available yet */
	adt= BKE_animdata_from_id(id);
	if ((adt == NULL) && (add))
		adt= BKE_id_add_animdata(id);
	if (adt == NULL) { 
		/* if still none (as not allowed to add, or ID doesn't have animdata for some reason) */
		return NULL;
	}
		
	/* try to find f-curve matching for this setting 
	 *	- add if not found and allowed to add one
	 *		TODO: add auto-grouping support? how this works will need to be resolved
	 */
	fcu= list_find_fcurve(&adt->drivers, rna_path, array_index);
	
	if ((fcu == NULL) && (add)) {
		/* use default settings to make a F-Curve */
		fcu= MEM_callocN(sizeof(FCurve), "FCurve");
		
		fcu->flag = (FCURVE_VISIBLE|FCURVE_SELECTED);
		
		/* store path - make copy, and store that */
		fcu->rna_path= BLI_strdupn(rna_path, strlen(rna_path));
		fcu->array_index= array_index;
		
		/* if add is negative, don't init this data yet, since it will be filled in by the pasted driver */
		if (add > 0) {
			/* add some new driver data */
			fcu->driver= MEM_callocN(sizeof(ChannelDriver), "ChannelDriver");
			
			/* add simple generator modifier for driver so that there is some visible representation */
			add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR);
		}
		
		/* just add F-Curve to end of driver list */
		BLI_addtail(&adt->drivers, fcu);
	}
	
	/* return the F-Curve */
	return fcu;
}
Ejemplo n.º 8
0
/* Get (or add relevant data to be able to do so) F-Curve from the driver stack, 
 * for the given Animation Data block. This assumes that all the destinations are valid.
 *	
 *	- add:	0 - don't add anything if not found, 
 *			1 - add new Driver FCurve (with keyframes for visual tweaking),
 *			2 - add new Driver FCurve (with generator, for script backwards compatibility)
 *			-1 - add new Driver FCurve without driver stuff (for pasting)
 */
FCurve *verify_driver_fcurve(ID *id, const char rna_path[], const int array_index, short add)
{
	AnimData *adt;
	FCurve *fcu;
	
	/* sanity checks */
	if (ELEM(NULL, id, rna_path))
		return NULL;
	
	/* init animdata if none available yet */
	adt = BKE_animdata_from_id(id);
	if ((adt == NULL) && (add))
		adt = BKE_id_add_animdata(id);
	if (adt == NULL) {
		/* if still none (as not allowed to add, or ID doesn't have animdata for some reason) */
		return NULL;
	}
		
	/* try to find f-curve matching for this setting 
	 *	- add if not found and allowed to add one
	 *		TODO: add auto-grouping support? how this works will need to be resolved
	 */
	fcu = list_find_fcurve(&adt->drivers, rna_path, array_index);
	
	if ((fcu == NULL) && (add)) {
		/* use default settings to make a F-Curve */
		fcu = MEM_callocN(sizeof(FCurve), "FCurve");
		
		fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED);
		
		/* store path - make copy, and store that */
		fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path));
		fcu->array_index = array_index;
		
		/* if add is negative, don't init this data yet, since it will be filled in by the pasted driver */
		if (add > 0) {
			BezTriple *bezt;
			size_t i;
			
			/* add some new driver data */
			fcu->driver = MEM_callocN(sizeof(ChannelDriver), "ChannelDriver");
			fcu->driver->flag |= DRIVER_FLAG_SHOWDEBUG;
			
			/* F-Modifier or Keyframes? */
			// FIXME: replace these magic numbers with defines
			if (add == 2) {
				/* Python API Backwards compatibility hack:
				 * Create FModifier so that old scripts won't break
				 * for now before 2.7 series -- (September 4, 2013)
				 */
				add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR);
			}
			else {
				/* add 2 keyframes so that user has something to work with 
				 * - These are configured to 0,0 and 1,1 to give a 1-1 mapping
				 *   which can be easily tweaked from there.
				 */
				insert_vert_fcurve(fcu, 0.0f, 0.0f, INSERTKEY_FAST);
				insert_vert_fcurve(fcu, 1.0f, 1.0f, INSERTKEY_FAST);
				
				/* configure this curve to extrapolate */
				for (i = 0, bezt = fcu->bezt;  (i < fcu->totvert) && bezt;  i++, bezt++) {
					bezt->h1 = bezt->h2 = HD_VECT;
				}
				
				fcu->extend = FCURVE_EXTRAPOLATE_LINEAR;
				calchandles_fcurve(fcu);
			}
		}
		
		/* just add F-Curve to end of driver list */
		BLI_addtail(&adt->drivers, fcu);
	}
	
	/* return the F-Curve */
	return fcu;
}
Ejemplo n.º 9
0
/* helper call for drawing influence/time control curves for a given NLA-strip */
static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, unsigned int pos)
{
  const float yheight = ymaxc - yminc;

  immUniformColor3f(0.7f, 0.7f, 0.7f);

  /* draw with AA'd line */
  GPU_line_smooth(true);
  GPU_blend(true);

  /* influence -------------------------- */
  if (strip->flag & NLASTRIP_FLAG_USR_INFLUENCE) {
    FCurve *fcu = list_find_fcurve(&strip->fcurves, "influence", 0);
    float cfra;

    /* plot the curve (over the strip's main region) */
    if (fcu) {
      immBegin(GPU_PRIM_LINE_STRIP, abs((int)(strip->end - strip->start) + 1));

      /* sample at 1 frame intervals, and draw
       * - min y-val is yminc, max is y-maxc, so clamp in those regions
       */
      for (cfra = strip->start; cfra <= strip->end; cfra += 1.0f) {
        float y = evaluate_fcurve(fcu, cfra); /* assume this to be in 0-1 range */
        CLAMP(y, 0.0f, 1.0f);
        immVertex2f(pos, cfra, ((y * yheight) + yminc));
      }

      immEnd();
    }
  }
  else {
    /* use blend in/out values only if both aren't zero */
    if ((IS_EQF(strip->blendin, 0.0f) && IS_EQF(strip->blendout, 0.0f)) == 0) {
      immBeginAtMost(GPU_PRIM_LINE_STRIP, 4);

      /* start of strip - if no blendin, start straight at 1,
       * otherwise from 0 to 1 over blendin frames */
      if (IS_EQF(strip->blendin, 0.0f) == 0) {
        immVertex2f(pos, strip->start, yminc);
        immVertex2f(pos, strip->start + strip->blendin, ymaxc);
      }
      else {
        immVertex2f(pos, strip->start, ymaxc);
      }

      /* end of strip */
      if (IS_EQF(strip->blendout, 0.0f) == 0) {
        immVertex2f(pos, strip->end - strip->blendout, ymaxc);
        immVertex2f(pos, strip->end, yminc);
      }
      else {
        immVertex2f(pos, strip->end, ymaxc);
      }

      immEnd();
    }
  }

  /* turn off AA'd lines */
  GPU_line_smooth(false);
  GPU_blend(false);
}