Exemple #1
0
static void rna_GPencil_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
{
	WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
}
static void rna_Paint_brush_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
	Brush *br = (Brush *)ptr->data;
	BKE_paint_invalidate_overlay_all();
	WM_main_add_notifier(NC_BRUSH | NA_EDITED, br);
}
static void render_endjob(void *rjv)
{
	RenderJob *rj = rjv;

	/* this render may be used again by the sequencer without the active 'Render' where the callbacks
	 * would be re-assigned. assign dummy callbacks to avoid referencing freed renderjobs bug [#24508] */
	RE_InitRenderCB(rj->re);

	if (rj->main != G.main)
		BKE_main_free(rj->main);

	/* else the frame will not update for the original value */
	if (rj->anim && !(rj->scene->r.scemode & R_NO_FRAME_UPDATE)) {
		/* possible this fails of loading new file while rendering */
		if (G.main->wm.first) {
			ED_update_for_newframe(G.main, rj->scene, 1);
		}
	}
	
	/* XXX above function sets all tags in nodes */
	ntreeCompositClearTags(rj->scene->nodetree);
	
	/* potentially set by caller */
	rj->scene->r.scemode &= ~R_NO_FRAME_UPDATE;
	
	if (rj->srl) {
		nodeUpdateID(rj->scene->nodetree, &rj->scene->id);
		WM_main_add_notifier(NC_NODE | NA_EDITED, rj->scene);
	}

	if (rj->sa) {
		render_image_restore_layer(rj);
	}

	/* XXX render stability hack */
	G.is_rendering = false;
	WM_main_add_notifier(NC_SCENE | ND_RENDER_RESULT, NULL);

	/* Partial render result will always update display buffer
	 * for first render layer only. This is nice because you'll
	 * see render progress during rendering, but it ends up in
	 * wrong display buffer shown after rendering.
	 *
	 * The code below will mark display buffer as invalid after
	 * rendering in case multiple layers were rendered, which
	 * ensures display buffer matches render layer after
	 * rendering.
	 *
	 * Perhaps proper way would be to toggle active render
	 * layer in image editor and job, so we always display
	 * layer being currently rendered. But this is not so much
	 * trivial at this moment, especially because of external
	 * engine API, so lets use simple and robust way for now
	 *                                          - sergey -
	 */
	if (rj->scene->r.layers.first != rj->scene->r.layers.last ||
	    rj->image_outdated)
	{
		void *lock;
		Image *ima = rj->image;
		ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &rj->iuser, &lock);

		if (ibuf)
			ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;

		BKE_image_release_ibuf(ima, ibuf, lock);
	}

	/* Finally unlock the user interface (if it was locked). */
	if (rj->interface_locked) {
		Scene *scene;

		/* Interface was locked, so window manager couldn't have been changed
		 * and using one from Global will unlock exactly the same manager as
		 * was locked before running the job.
		 */
		WM_set_locked_interface(G.main->wm.first, false);

		/* We've freed all the derived caches before rendering, which is
		 * effectively the same as if we re-loaded the file.
		 *
		 * So let's not try being smart here and just reset all updated
		 * scene layers and use generic DAG_on_visible_update.
		 */
		for (scene = G.main->scene.first; scene; scene = scene->id.next) {
			scene->lay_updated = 0;
		}

		DAG_on_visible_update(G.main, false);
	}
}
Exemple #4
0
static void render_endjob(void *rjv)
{
	RenderJob *rj = rjv;

	/* this render may be used again by the sequencer without the active 'Render' where the callbacks
	 * would be re-assigned. assign dummy callbacks to avoid referencing freed renderjobs bug [#24508] */
	RE_InitRenderCB(rj->re);

	if (rj->main != G.main)
		free_main(rj->main);

	/* else the frame will not update for the original value */
	if (!(rj->scene->r.scemode & R_NO_FRAME_UPDATE)) {
		/* possible this fails of loading new file while rendering */
		if (G.main->wm.first) {
			ED_update_for_newframe(G.main, rj->scene, 1);
		}
	}
	
	/* XXX above function sets all tags in nodes */
	ntreeCompositClearTags(rj->scene->nodetree);
	
	/* potentially set by caller */
	rj->scene->r.scemode &= ~R_NO_FRAME_UPDATE;
	
	if (rj->srl) {
		nodeUpdateID(rj->scene->nodetree, &rj->scene->id);
		WM_main_add_notifier(NC_NODE | NA_EDITED, rj->scene);
	}

	/* XXX render stability hack */
	G.is_rendering = FALSE;
	WM_main_add_notifier(NC_WINDOW, NULL);

	/* Partial render result will always update display buffer
	 * for first render layer only. This is nice because you'll
	 * see render progress during rendering, but it ends up in
	 * wrong display buffer shown after rendering.
	 *
	 * The code below will mark display buffer as invalid after
	 * rendering in case multiple layers were rendered, which
	 * ensures display buffer matches render layer after
	 * rendering.
	 *
	 * Perhaps proper way would be to toggle active render
	 * layer in image editor and job, so we always display
	 * layer being currently rendered. But this is not so much
	 * trivial at this moment, especially because of external
	 * engine API, so lets use simple and robust way for now
	 *                                          - sergey -
	 */
	if (rj->scene->r.layers.first != rj->scene->r.layers.last) {
		void *lock;
		Image *ima = rj->image;
		ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &rj->iuser, &lock);

		if (ibuf)
			ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;

		BKE_image_release_ibuf(ima, ibuf, lock);
	}
}
Exemple #5
0
static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *reports,
                                          const char *name, int type, int channel,
                                          int frame_start, int frame_end,
                                          Sequence *seq1, Sequence *seq2, Sequence *seq3)
{
	Scene *scene = (Scene *)id;
	Sequence *seq;
	struct SeqEffectHandle sh;
	int num_inputs = BKE_sequence_effect_get_num_inputs(type);

	switch (num_inputs) {
		case 0:
			if (frame_end <= frame_start) {
				BKE_report(reports, RPT_ERROR, "Sequences.new_effect: end frame not set");
				return NULL;
			}
			break;
		case 1:
			if (seq1 == NULL) {
				BKE_report(reports, RPT_ERROR, "Sequences.new_effect: effect takes 1 input sequence");
				return NULL;
			}
			break;
		case 2:
			if (seq1 == NULL || seq2 == NULL) {
				BKE_report(reports, RPT_ERROR, "Sequences.new_effect: effect takes 2 input sequences");
				return NULL;
			}
			break;
		case 3:
			if (seq1 == NULL || seq2 == NULL || seq3 == NULL) {
				BKE_report(reports, RPT_ERROR, "Sequences.new_effect: effect takes 3 input sequences");
				return NULL;
			}
			break;
		default:
			BKE_reportf(reports, RPT_ERROR,
			            "Sequences.new_effect: effect expects more than 3 inputs (%d, should never happen!)",
			            num_inputs);
			return NULL;
	}

	seq = alloc_generic_sequence(ed, name, frame_start, channel, type, NULL);

	sh = BKE_sequence_get_effect(seq);

	seq->seq1 = seq1;
	seq->seq2 = seq2;
	seq->seq3 = seq3;

	sh.init(seq);

	if (!seq1) { /* effect has no deps */
		seq->len = 1;
		BKE_sequence_tx_set_final_right(seq, frame_end);
	}

	seq->flag |= SEQ_USE_EFFECT_DEFAULT_FADE;

	BKE_sequence_calc_disp(scene, seq);

	WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene);

	return seq;
}
Exemple #6
0
static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
                                     StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
    ARegionType *art;
    PanelType *pt, dummypt = {NULL};
    Panel dummypanel= {NULL};
    PointerRNA dummyptr;
    int have_function[3];

    /* setup dummy panel & panel type to store static properties in */
    dummypanel.type= &dummypt;
    RNA_pointer_create(NULL, &RNA_Panel, &dummypanel, &dummyptr);

    /* validate the python class */
    if(validate(&dummyptr, data, have_function) != 0)
        return NULL;

    if(strlen(identifier) >= sizeof(dummypt.idname)) {
        BKE_reportf(reports, RPT_ERROR, "registering panel class: '%s' is too long, maximum length is %d",
                    identifier, (int)sizeof(dummypt.idname));
        return NULL;
    }

    if(!(art=region_type_find(reports, dummypt.space_type, dummypt.region_type)))
        return NULL;

    /* check if we have registered this panel type before, and remove it */
    for(pt=art->paneltypes.first; pt; pt=pt->next) {
        if(strcmp(pt->idname, dummypt.idname) == 0) {
            if(pt->ext.srna)
                rna_Panel_unregister(bmain, pt->ext.srna);
            else
                BLI_freelinkN(&art->paneltypes, pt);
            break;
        }
    }

    /* create a new panel type */
    pt= MEM_callocN(sizeof(PanelType), "python buttons panel");
    memcpy(pt, &dummypt, sizeof(dummypt));

    pt->ext.srna= RNA_def_struct(&BLENDER_RNA, pt->idname, "Panel");
    pt->ext.data= data;
    pt->ext.call= call;
    pt->ext.free= free;
    RNA_struct_blender_type_set(pt->ext.srna, pt);
    RNA_def_struct_flag(pt->ext.srna, STRUCT_NO_IDPROPERTIES);

    pt->poll= (have_function[0])? panel_poll: NULL;
    pt->draw= (have_function[1])? panel_draw: NULL;
    pt->draw_header= (have_function[2])? panel_draw_header: NULL;

    /* XXX use "no header" flag for some ordering of panels until we have real panel ordering */
    if(pt->flag & PNL_NO_HEADER) {
        PanelType *pth = art->paneltypes.first;
        while(pth && pth->flag & PNL_NO_HEADER)
            pth=pth->next;

        if(pth)
            BLI_insertlinkbefore(&art->paneltypes, pth, pt);
        else
            BLI_addtail(&art->paneltypes, pt);
    }
    else
        BLI_addtail(&art->paneltypes, pt);

    /* update while blender is running */
    WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL);

    return pt->ext.srna;
}
static void rna_Armature_redraw_data(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
	ID *id = ptr->id.data;
	
	WM_main_add_notifier(NC_GEOM | ND_DATA, id);
}
Exemple #8
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;
	const 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;
		
		/* supplement 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_property(&id_ptr, ksp->rna_path, &ptr, &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;
				
				// XXX: only object transforms?
				DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
				break;
			}
		}
		
		/* send notifiers for updates (this doesn't require context to work!) */
		WM_main_add_notifier(NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
	}
	
	/* return the number of channels successfully affected */
	return success;
}
static void preview_endjob(void *data)
{
	PreviewJob *pj = data;

	WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, pj->scene);
}
Exemple #10
0
static void rna_ImaPaint_viewport_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
{
    /* not the best solution maybe, but will refresh the 3D viewport */
    WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
}
Exemple #11
0
static void rna_Text_write(Text *text, const char *str)
{
	BKE_text_write(text, str);
	WM_main_add_notifier(NC_TEXT|NA_EDITED, text);
}
Exemple #12
0
static void rna_Text_clear(Text *text)
{
	BKE_text_clear(text);
	WM_main_add_notifier(NC_TEXT|NA_EDITED, text);
}
Exemple #13
0
static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
                                    StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
	MenuType *mt, dummymt = {NULL};
	Menu dummymenu = {NULL};
	PointerRNA dummymtr;
	int have_function[2];
	size_t over_alloc = 0; /* warning, if this becomes a bess, we better do another alloc */
	size_t description_size = 0;
	char _menu_descr[RNA_DYN_DESCR_MAX];

	/* setup dummy menu & menu type to store static properties in */
	dummymenu.type = &dummymt;
	_menu_descr[0] = '\0';
	dummymenu.type->description = _menu_descr;
	RNA_pointer_create(NULL, &RNA_Menu, &dummymenu, &dummymtr);

	/* We have to set default context! Else we get a void string... */
	strcpy(dummymt.translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);

	/* validate the python class */
	if (validate(&dummymtr, data, have_function) != 0)
		return NULL;
	
	if (strlen(identifier) >= sizeof(dummymt.idname)) {
		BKE_reportf(reports, RPT_ERROR, "Registering menu class: '%s' is too long, maximum length is %d",
		            identifier, (int)sizeof(dummymt.idname));
		return NULL;
	}

	/* check if we have registered this menu type before, and remove it */
	mt = WM_menutype_find(dummymt.idname, true);
	if (mt && mt->ext.srna)
		rna_Menu_unregister(bmain, mt->ext.srna);
	
	/* create a new menu type */
	if (_menu_descr[0]) {
		description_size = strlen(_menu_descr) + 1;
		over_alloc += description_size;
	}

	mt = MEM_callocN(sizeof(MenuType) + over_alloc, "python buttons menu");
	memcpy(mt, &dummymt, sizeof(dummymt));

	if (_menu_descr[0]) {
		char *buf = (char *)(mt + 1);
		memcpy(buf, _menu_descr, description_size);
		mt->description = buf;
	}
	else
		mt->description = "";

	mt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, mt->idname, &RNA_Menu);
	RNA_def_struct_translation_context(mt->ext.srna, mt->translation_context);
	mt->ext.data = data;
	mt->ext.call = call;
	mt->ext.free = free;
	RNA_struct_blender_type_set(mt->ext.srna, mt);
	RNA_def_struct_flag(mt->ext.srna, STRUCT_NO_IDPROPERTIES);

	mt->poll = (have_function[0]) ? menu_poll : NULL;
	mt->draw = (have_function[1]) ? menu_draw : NULL;

	WM_menutype_add(mt);

	/* update while blender is running */
	WM_main_add_notifier(NC_WINDOW, NULL);
	
	return mt->ext.srna;
}
Exemple #14
0
static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
                                     StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
	ARegionType *art;
	PanelType *pt, dummypt = {NULL};
	Panel dummypanel = {NULL};
	PointerRNA dummyptr;
	int have_function[3];

	/* setup dummy panel & panel type to store static properties in */
	dummypanel.type = &dummypt;
	RNA_pointer_create(NULL, &RNA_Panel, &dummypanel, &dummyptr);

	/* We have to set default context! Else we get a void string... */
	strcpy(dummypt.translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);

	/* validate the python class */
	if (validate(&dummyptr, data, have_function) != 0)
		return NULL;
		
	if (strlen(identifier) >= sizeof(dummypt.idname)) {
		BKE_reportf(reports, RPT_ERROR, "Registering panel class: '%s' is too long, maximum length is %d",
		            identifier, (int)sizeof(dummypt.idname));
		return NULL;
	}

	if ((dummypt.category[0] == '\0') && (dummypt.region_type == RGN_TYPE_TOOLS)) {
		/* Use a fallback, otherwise an empty value will draw the panel in every category. */
		strcpy(dummypt.category, PNL_CATEGORY_FALLBACK);
	}

	if (!(art = region_type_find(reports, dummypt.space_type, dummypt.region_type)))
		return NULL;

	/* check if we have registered this panel type before, and remove it */
	for (pt = art->paneltypes.first; pt; pt = pt->next) {
		if (STREQ(pt->idname, dummypt.idname)) {
			if (pt->ext.srna)
				rna_Panel_unregister(bmain, pt->ext.srna);
			else
				BLI_freelinkN(&art->paneltypes, pt);
			break;
		}
	}
	
	/* create a new panel type */
	pt = MEM_callocN(sizeof(PanelType), "python buttons panel");
	memcpy(pt, &dummypt, sizeof(dummypt));

	pt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, pt->idname, &RNA_Panel);
	RNA_def_struct_translation_context(pt->ext.srna, pt->translation_context);
	pt->ext.data = data;
	pt->ext.call = call;
	pt->ext.free = free;
	RNA_struct_blender_type_set(pt->ext.srna, pt);
	RNA_def_struct_flag(pt->ext.srna, STRUCT_NO_IDPROPERTIES);

	pt->poll = (have_function[0]) ? panel_poll : NULL;
	pt->draw = (have_function[1]) ? panel_draw : NULL;
	pt->draw_header = (have_function[2]) ? panel_draw_header : NULL;

	/* XXX use "no header" flag for some ordering of panels until we have real panel ordering */
	if (pt->flag & PNL_NO_HEADER) {
		PanelType *pth = art->paneltypes.first;
		while (pth && pth->flag & PNL_NO_HEADER)
			pth = pth->next;

		if (pth)
			BLI_insertlinkbefore(&art->paneltypes, pth, pt);
		else
			BLI_addtail(&art->paneltypes, pt);
	}
	else
		BLI_addtail(&art->paneltypes, pt);

	/* update while blender is running */
	WM_main_add_notifier(NC_WINDOW, NULL);
	
	return pt->ext.srna;
}