Esempio n. 1
0
static void screen_opengl_render_end(bContext *C, OGLRender *oglrender)
{
	Main *bmain = CTX_data_main(C);
	Scene *scene = oglrender->scene;

	if (oglrender->mh) {
		if (BKE_imtype_is_movie(scene->r.im_format.imtype))
			oglrender->mh->end_movie();
	}

	if (oglrender->timer) { /* exec will not have a timer */
		scene->r.cfra = oglrender->cfrao;
		BKE_scene_update_for_newframe(bmain, scene, screen_opengl_layers(oglrender));

		WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer);
	}

	WM_cursor_modal_restore(oglrender->win);

	WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene);

	U.obcenter_dia = oglrender->obcenter_dia_back;

	GPU_offscreen_free(oglrender->ofs);

	oglrender->scene->customdata_mask_modal = 0;

	CTX_wm_area_set(C, oglrender->prevsa);
	CTX_wm_region_set(C, oglrender->prevar);

	MEM_freeN(oglrender);
}
Esempio n. 2
0
static void rna_Scene_frame_set(Scene *scene, int frame, float subframe)
{
	double cfra = (double)frame + (double)subframe;

	CLAMP(cfra, MINAFRAME, MAXFRAME);
	BKE_scene_frame_set(scene, cfra);

#ifdef WITH_PYTHON
	BPy_BEGIN_ALLOW_THREADS;
#endif

	BKE_scene_update_for_newframe(G.main->eval_ctx, G.main, scene, (1 << 20) - 1);

#ifdef WITH_PYTHON
	BPy_END_ALLOW_THREADS;
#endif

	BKE_scene_camera_switch_update(scene);

	/* don't do notifier when we're rendering, avoid some viewport crashes
	 * redrawing while the data is being modified for render */
	if (!G.is_rendering) {
		/* cant use NC_SCENE|ND_FRAME because this causes wm_event_do_notifiers to call
		 * BKE_scene_update_for_newframe which will loose any un-keyed changes [#24690] */
		/* WM_main_add_notifier(NC_SCENE|ND_FRAME, scene); */
		
		/* instead just redraw the views */
		WM_main_add_notifier(NC_WINDOW, NULL);
	}
}
Esempio n. 3
0
static void screen_opengl_render_end(bContext *C, OGLRender *oglrender)
{
	Main *bmain = CTX_data_main(C);
	Scene *scene = oglrender->scene;
	size_t i;

	if (oglrender->mh) {
		if (BKE_imtype_is_movie(scene->r.im_format.imtype)) {
			for (i = 0; i < oglrender->totvideos; i++) {
				oglrender->mh->end_movie(oglrender->movie_ctx_arr[i]);
				oglrender->mh->context_free(oglrender->movie_ctx_arr[i]);
			}
		}

		if (oglrender->movie_ctx_arr) {
			MEM_freeN(oglrender->movie_ctx_arr);
		}
	}

	if (oglrender->timer) { /* exec will not have a timer */
		scene->r.cfra = oglrender->cfrao;
		BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender));

		WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer);
	}

	WM_cursor_modal_restore(oglrender->win);

	WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene);

	if (oglrender->fx)
		GPU_fx_compositor_destroy(oglrender->fx);

	GPU_offscreen_free(oglrender->ofs);

	oglrender->scene->customdata_mask_modal = 0;

	CTX_wm_area_set(C, oglrender->prevsa);
	CTX_wm_region_set(C, oglrender->prevar);

	MEM_freeN(oglrender);
}
Esempio n. 4
0
static void rna_Scene_frame_set(Scene *scene, int frame, float subframe)
{
	float cfra = (float)frame + subframe;

	scene->r.cfra = floorf(cfra);
	scene->r.subframe = cfra - floorf(cfra);
	
	CLAMP(scene->r.cfra, MINAFRAME, MAXFRAME);
	BKE_scene_update_for_newframe(G.main, scene, (1 << 20) - 1);
	BKE_scene_camera_switch_update(scene);

	/* don't do notifier when we're rendering, avoid some viewport crashes
	 * redrawing while the data is being modified for render */
	if (!G.is_rendering) {
		/* cant use NC_SCENE|ND_FRAME because this causes wm_event_do_notifiers to call
		 * BKE_scene_update_for_newframe which will loose any un-keyed changes [#24690] */
		/* WM_main_add_notifier(NC_SCENE|ND_FRAME, scene); */
		
		/* instead just redraw the views */
		WM_main_add_notifier(NC_WINDOW, NULL);
	}
}
Esempio n. 5
0
/* update scene for current frame */
static void motionpaths_calc_update_scene(Scene *scene)
{
#if 1 // 'production' optimisations always on
	Base *base, *last = NULL;
	
	/* only stuff that moves or needs display still */
	DAG_scene_update_flags(G.main, scene, scene->lay, TRUE);
	
	/* find the last object with the tag 
	 *	- all those afterwards are assumed to not be relevant for our calculations
	 */
	// optimize further by moving out...
	for (base = scene->base.first; base; base = base->next) {
		if (base->object->flag & BA_TEMP_TAG)
			last = base;
	}
	
	/* perform updates for tagged objects */
	// XXX: this will break if rigs depend on scene or other data that 
	// is animated but not attached to/updatable from objects
	for (base = scene->base.first; base; base = base->next) {
		/* update this object */
		BKE_object_handle_update(scene, base->object);
		
		/* if this is the last one we need to update, let's stop to save some time */
		if (base == last)
			break;
	}
#else // original, 'always correct' version
	  /* do all updates
	   *  - if this is too slow, resort to using a more efficient way
	   *    that doesn't force complete update, but for now, this is the
	   *    most accurate way!
	   */
	BKE_scene_update_for_newframe(G.main, scene, scene->lay); // XXX this is the best way we can get anything moving
#endif
}
Esempio n. 6
0
int RE_engine_render(Render *re, int do_all)
{
	RenderEngineType *type = RE_engines_find(re->r.engine);
	RenderEngine *engine;
	int persistent_data = re->r.mode & R_PERSISTENT_DATA;

	/* verify if we can render */
	if (!type->render)
		return 0;
	if ((re->r.scemode & R_BUTS_PREVIEW) && !(type->flag & RE_USE_PREVIEW))
		return 0;
	if (do_all && !(type->flag & RE_USE_POSTPROCESS))
		return 0;
	if (!do_all && (type->flag & RE_USE_POSTPROCESS))
		return 0;

	/* update animation here so any render layer animation is applied before
	 * creating the render result */
	if ((re->r.scemode & (R_NO_FRAME_UPDATE | R_BUTS_PREVIEW)) == 0) {
		unsigned int lay = re->lay;

		/* don't update layers excluded on all render layers */
		if (type->flag & RE_USE_EXCLUDE_LAYERS) {
			SceneRenderLayer *srl;
			unsigned int non_excluded_lay = 0;

			if (re->r.scemode & R_SINGLE_LAYER) {
				srl = BLI_findlink(&re->r.layers, re->r.actlay);
				if (srl)
					non_excluded_lay |= ~srl->lay_exclude;
			}
			else {
				for (srl = re->r.layers.first; srl; srl = srl->next)
					if (!(srl->layflag & SCE_LAY_DISABLE))
						non_excluded_lay |= ~srl->lay_exclude;
			}

			lay &= non_excluded_lay;
		}

		BKE_scene_update_for_newframe(re->main, re->scene, lay);
	}

	/* create render result */
	BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
	if (re->result == NULL || !(re->r.scemode & R_BUTS_PREVIEW)) {
		int savebuffers = RR_USE_MEM;

		if (re->result)
			render_result_free(re->result);

		if ((type->flag & RE_USE_SAVE_BUFFERS) && (re->r.scemode & R_EXR_TILE_FILE))
			savebuffers = RR_USE_EXR;
		re->result = render_result_new(re, &re->disprect, 0, savebuffers, RR_ALL_LAYERS);
	}
	BLI_rw_mutex_unlock(&re->resultmutex);

	if (re->result == NULL)
		return 1;

	/* set render info */
	re->i.cfra = re->scene->r.cfra;
	BLI_strncpy(re->i.scene_name, re->scene->id.name + 2, sizeof(re->i.scene_name));
	re->i.totface = re->i.totvert = re->i.totstrand = re->i.totlamp = re->i.tothalo = 0;

	/* render */
	engine = re->engine;

	if (!engine) {
		engine = RE_engine_create(type);
		re->engine = engine;
	}

	engine->flag |= RE_ENGINE_RENDERING;

	/* TODO: actually link to a parent which shouldn't happen */
	engine->re = re;

	if (re->flag & R_ANIMATION)
		engine->flag |= RE_ENGINE_ANIMATION;
	if (re->r.scemode & R_BUTS_PREVIEW)
		engine->flag |= RE_ENGINE_PREVIEW;
	engine->camera_override = re->camera_override;

	engine->resolution_x = re->winx;
	engine->resolution_y = re->winy;

	RE_parts_init(re, FALSE);
	engine->tile_x = re->partx;
	engine->tile_y = re->party;

	if (re->result->do_exr_tile)
		render_result_exr_file_begin(re);

	if (type->update)
		type->update(engine, re->main, re->scene);
	
	if (type->render)
		type->render(engine, re->scene);

	engine->tile_x = 0;
	engine->tile_y = 0;
	engine->flag &= ~RE_ENGINE_RENDERING;

	render_result_free_list(&engine->fullresult, engine->fullresult.first);

	/* re->engine becomes zero if user changed active render engine during render */
	if (!persistent_data || !re->engine) {
		RE_engine_free(engine);
		re->engine = NULL;
	}

	if (re->result->do_exr_tile) {
		BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
		render_result_exr_file_end(re);
		BLI_rw_mutex_unlock(&re->resultmutex);
	}

	RE_parts_free(re);

	if (BKE_reports_contain(re->reports, RPT_ERROR))
		G.is_break = TRUE;
	
	return 1;
}
Esempio n. 7
0
static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
{
	Main *bmain = CTX_data_main(C);
	OGLRender *oglrender = op->customdata;
	Scene *scene = oglrender->scene;
	char name[FILE_MAX];
	bool ok = false;
	const bool view_context = (oglrender->v3d != NULL);
	bool is_movie;
	RenderResult *rr;

	/* go to next frame */
	if (CFRA < oglrender->nfra)
		CFRA++;
	while (CFRA < oglrender->nfra) {
		unsigned int lay = screen_opengl_layers(oglrender);

		if (lay & 0xFF000000)
			lay &= 0xFF000000;

		BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, lay);
		CFRA++;
	}

	is_movie = BKE_imtype_is_movie(scene->r.im_format.imtype);

	if (!is_movie) {
		BKE_image_path_from_imformat(
		        name, scene->r.pic, oglrender->bmain->name, scene->r.cfra,
		        &scene->r.im_format, (scene->r.scemode & R_EXTENSION) != 0, true, NULL);

		if ((scene->r.mode & R_NO_OVERWRITE) && BLI_exists(name)) {
			BKE_reportf(op->reports, RPT_INFO, "Skipping existing frame \"%s\"", name);
			ok = true;
			goto finally;
		}
	}

	WM_cursor_time(oglrender->win, scene->r.cfra);

	BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender));

	if (view_context) {
		if (oglrender->rv3d->persp == RV3D_CAMOB && oglrender->v3d->camera && oglrender->v3d->scenelock) {
			/* since BKE_scene_update_for_newframe() is used rather
			 * then ED_update_for_newframe() the camera needs to be set */
			if (BKE_scene_camera_switch_update(scene)) {
				oglrender->v3d->camera = scene->camera;
			}
		}
	}
	else {
		BKE_scene_camera_switch_update(scene);
	}

	/* render into offscreen buffer */
	screen_opengl_render_apply(oglrender);

	/* save to disk */
	rr = RE_AcquireResultRead(oglrender->re);

	if (is_movie) {
		ok = RE_WriteRenderViewsMovie(oglrender->reports, rr, scene, &scene->r, oglrender->mh, oglrender->sizex,
		                              oglrender->sizey, oglrender->movie_ctx_arr, oglrender->totvideos, PRVRANGEON != 0);
		if (ok) {
			printf("Append frame %d", scene->r.cfra);
			BKE_reportf(op->reports, RPT_INFO, "Appended frame: %d", scene->r.cfra);
		}
	}
	else {
		ok = RE_WriteRenderViewsImage(op->reports, rr, scene, scene->camera, true, name);
		if (ok) {
			printf("Saved: %s", name);
			BKE_reportf(op->reports, RPT_INFO, "Saved file: %s", name);
		}
		else {
			printf("Write error: cannot save %s\n", name);
			BKE_reportf(op->reports, RPT_ERROR, "Write error: cannot save %s", name);
		}
	}

	RE_ReleaseResult(oglrender->re);


	/* movie stats prints have no line break */
	printf("\n");


finally:  /* Step the frame and bail early if needed */

	/* go to next frame */
	oglrender->nfra += scene->r.frame_step;

	/* stop at the end or on error */
	if (CFRA >= PEFRA || !ok) {
		screen_opengl_render_end(C, op->customdata);
		return 0;
	}

	return 1;
}
Esempio n. 8
0
static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
{
	Main *bmain = CTX_data_main(C);
	OGLRender *oglrender = op->customdata;
	Scene *scene = oglrender->scene;
	ImBuf *ibuf, *ibuf_save = NULL;
	void *lock;
	char name[FILE_MAX];
	int ok = 0;
	const short view_context = (oglrender->v3d != NULL);
	Object *camera = NULL;
	int is_movie;

	/* go to next frame */
	if (CFRA < oglrender->nfra)
		CFRA++;
	while (CFRA < oglrender->nfra) {
		unsigned int lay = screen_opengl_layers(oglrender);

		if (lay & 0xFF000000)
			lay &= 0xFF000000;

		BKE_scene_update_for_newframe(bmain, scene, lay);
		CFRA++;
	}

	is_movie = BKE_imtype_is_movie(scene->r.im_format.imtype);

	if (!is_movie) {
		BKE_makepicstring(name, scene->r.pic, oglrender->bmain->name, scene->r.cfra, &scene->r.im_format, scene->r.scemode & R_EXTENSION, TRUE);

		if ((scene->r.mode & R_NO_OVERWRITE) && BLI_exists(name)) {
			BKE_reportf(op->reports, RPT_INFO, "Skipping existing frame \"%s\"", name);
			ok = true;
			goto finally;
		}
	}

	WM_cursor_time(oglrender->win, scene->r.cfra);

	BKE_scene_update_for_newframe(bmain, scene, screen_opengl_layers(oglrender));

	if (view_context) {
		if (oglrender->rv3d->persp == RV3D_CAMOB && oglrender->v3d->camera && oglrender->v3d->scenelock) {
			/* since BKE_scene_update_for_newframe() is used rather
			 * then ED_update_for_newframe() the camera needs to be set */
			if (BKE_scene_camera_switch_update(scene)) {
				oglrender->v3d->camera = scene->camera;
			}

			camera = oglrender->v3d->camera;
		}
	}
	else {
		BKE_scene_camera_switch_update(scene);

		camera = scene->camera;
	}

	/* render into offscreen buffer */
	screen_opengl_render_apply(oglrender);

	/* save to disk */
	ibuf = BKE_image_acquire_ibuf(oglrender->ima, &oglrender->iuser, &lock);

	if (ibuf) {
		int needs_free = FALSE;

		ibuf_save = ibuf;

		if (is_movie || !BKE_imtype_requires_linear_float(scene->r.im_format.imtype)) {
			ibuf_save = IMB_colormanagement_imbuf_for_write(ibuf, true, true, &scene->view_settings,
			                                                &scene->display_settings, &scene->r.im_format);

			needs_free = TRUE;
		}

		/* color -> grayscale */
		/* editing directly would alter the render view */
		if (scene->r.im_format.planes == R_IMF_PLANES_BW) {
			ImBuf *ibuf_bw = IMB_dupImBuf(ibuf_save);
			IMB_color_to_bw(ibuf_bw);

			if (needs_free)
				IMB_freeImBuf(ibuf_save);

			ibuf_save = ibuf_bw;
		}
		else {
			/* this is lightweight & doesnt re-alloc the buffers, only do this
			 * to save the correct bit depth since the image is always RGBA */
			ImBuf *ibuf_cpy = IMB_allocImBuf(ibuf_save->x, ibuf_save->y, scene->r.im_format.planes, 0);

			ibuf_cpy->rect = ibuf_save->rect;
			ibuf_cpy->rect_float = ibuf_save->rect_float;
			ibuf_cpy->zbuf_float = ibuf_save->zbuf_float;

			if (needs_free) {
				ibuf_cpy->mall = ibuf_save->mall;
				ibuf_save->mall = 0;
				IMB_freeImBuf(ibuf_save);
			}

			ibuf_save = ibuf_cpy;
		}

		if (is_movie) {
			ok = oglrender->mh->append_movie(&scene->r, PSFRA, CFRA, (int *)ibuf_save->rect,
			                                 oglrender->sizex, oglrender->sizey, oglrender->reports);
			if (ok) {
				printf("Append frame %d", scene->r.cfra);
				BKE_reportf(op->reports, RPT_INFO, "Appended frame: %d", scene->r.cfra);
			}
		}
		else {
			ok = BKE_imbuf_write_stamp(scene, camera, ibuf_save, name, &scene->r.im_format);

			if (ok == 0) {
				printf("Write error: cannot save %s\n", name);
				BKE_reportf(op->reports, RPT_ERROR, "Write error: cannot save %s", name);
			}
			else {
				printf("Saved: %s", name);
				BKE_reportf(op->reports, RPT_INFO, "Saved file: %s", name);
			}
		}

		if (needs_free)
			IMB_freeImBuf(ibuf_save);
	}

	BKE_image_release_ibuf(oglrender->ima, ibuf, lock);

	/* movie stats prints have no line break */
	printf("\n");


finally:  /* Step the frame and bail early if needed */

	/* go to next frame */
	oglrender->nfra += scene->r.frame_step;

	/* stop at the end or on error */
	if (CFRA >= PEFRA || !ok) {
		screen_opengl_render_end(C, op->customdata);
		return 0;
	}

	return 1;
}
Esempio n. 9
0
static void screen_opengl_render_end(bContext *C, OGLRender *oglrender)
{
	Main *bmain = CTX_data_main(C);
	Scene *scene = oglrender->scene;
	int i;

	if (oglrender->is_animation) {
		BLI_task_pool_work_and_wait(oglrender->task_pool);
		BLI_task_pool_free(oglrender->task_pool);
		/* Depending on various things we might or might not use global scheduler. */
		if (oglrender->task_scheduler != NULL) {
			BLI_task_scheduler_free(oglrender->task_scheduler);
		}
		BLI_spin_end(&oglrender->reports_lock);
	}
	BLI_mutex_end(&oglrender->task_mutex);
	BLI_condition_end(&oglrender->task_condition);

#ifdef DEBUG_TIME
	printf("Total render time: %f\n", PIL_check_seconds_timer() - oglrender->time_start);
#endif

	if (oglrender->mh) {
		if (BKE_imtype_is_movie(scene->r.im_format.imtype)) {
			for (i = 0; i < oglrender->totvideos; i++) {
				oglrender->mh->end_movie(oglrender->movie_ctx_arr[i]);
				oglrender->mh->context_free(oglrender->movie_ctx_arr[i]);
			}
		}

		if (oglrender->movie_ctx_arr) {
			MEM_freeN(oglrender->movie_ctx_arr);
		}
	}

	if (oglrender->timer) { /* exec will not have a timer */
		scene->r.cfra = oglrender->cfrao;
		BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender));

		WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer);
	}

	WM_cursor_modal_restore(oglrender->win);

	WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene);

	if (oglrender->fx)
		GPU_fx_compositor_destroy(oglrender->fx);

	GPU_offscreen_free(oglrender->ofs);

	if (oglrender->is_sequencer) {
		MEM_freeN(oglrender->seq_data.ibufs_arr);
	}

	oglrender->scene->customdata_mask_modal = 0;

	CTX_wm_area_set(C, oglrender->prevsa);
	CTX_wm_region_set(C, oglrender->prevar);

	MEM_freeN(oglrender);
}