1
1

Compare commits

...

378 Commits

Author SHA1 Message Date
Dalai Felinto
3519a9f517 Merge remote-tracking branch 'origin/master' into multiview 2015-04-06 10:37:12 -03:00
Dalai Felinto
bdf398daa8 Fix blenderplayer build 2015-04-06 00:22:57 -03:00
Dalai Felinto
25d55cb560 Subversion bump, and doversion last changes 2015-04-05 02:34:50 -03:00
Dalai Felinto
259c649a0f Merge remote-tracking branch 'origin/master' into multiview 2015-04-05 02:11:15 -03:00
Dalai Felinto
a400c95c94 Merge remote-tracking branch 'origin/master' into multiview 2015-04-03 08:58:07 -03:00
Dalai Felinto
cc6c55c4af Time Sequential mode disable in Release mode until we get it working properly 2015-04-02 19:30:12 -03:00
Dalai Felinto
6ffd218444 From review: remove "it is used for temporary storage only" comment in RE_pipeline.h 2015-04-02 19:16:27 -03:00
Dalai Felinto
3fbab3bbba rephrase the TODOs to be MULTIVIEW_TODO (as we do for OCIO_TODO) 2015-04-02 19:07:02 -03:00
Dalai Felinto
af38ace3ae Removing XXX MV: envmap is fine as it is (without multiview) 2015-04-02 18:54:50 -03:00
Dalai Felinto
ed94a8def2 Removing XXX MV: new TODO acolrect and scolrect are not supported by multiview 2015-04-02 18:52:46 -03:00
Dalai Felinto
717d10154b Removing XXX MV: field rendering is working fine for multiview (+ cleanup) 2015-04-02 18:24:00 -03:00
Dalai Felinto
7f02b9e869 From review: use stereo3d *everywhere* =) 2015-04-02 17:56:22 -03:00
Dalai Felinto
bbf2305155 From review: sorted API/cleanups 2015-04-02 17:54:54 -03:00
Dalai Felinto
7fc167f10f Removing XXX MV: replace XXX MV by todo 2015-04-02 15:19:40 -03:00
Dalai Felinto
ed5515dec3 From review: only show "Set Stereo 3D" when multiview is on 2015-04-02 15:13:18 -03:00
Dalai Felinto
4f0f84fb05 Removing XXX MV: implement touch/overwrite for multiview 2015-04-02 15:11:05 -03:00
Dalai Felinto
4728dbd309 render_result_rescale: handle only one view since it is called by view3d rendering only 2015-04-02 12:39:57 -03:00
Dalai Felinto
2179f01ef4 Removing XXX MV: render_result_rescale is only called by view3d rendering, so it is fine to rescale only one rect 2015-04-02 11:55:20 -03:00
Dalai Felinto
18dab1fa80 Remove dead code (rna_Node_image_view_update) 2015-04-02 11:55:20 -03:00
Julian Eisel
781efee98d Multiview: Fix "mixed declarations and code" error 2015-04-02 16:31:33 +02:00
Dalai Felinto
2bfabfd4b1 Removing XXX MV: implement RE_layer_load_from_file() - for one view only 2015-04-02 09:29:35 -03:00
Dalai Felinto
2a69362b2b Merge remote-tracking branch 'origin/master' into multiview 2015-04-02 09:09:29 -03:00
Dalai Felinto
a2ff63ca09 Sequencer cleanup: create seq_render_image_strip() function 2015-04-01 15:03:18 -03:00
Dalai Felinto
35f1662d25 Sequencer cleanup: create seq_render_movie_strip() function 2015-04-01 15:02:13 -03:00
Dalai Felinto
8c064a83cf From review: Sequencer Scene strips were forcing rendering to happen multiple times
This was more a cache issue. Images and Movies were having the same
problem, but they went unnoticed.

This is not an ideal solution, but it works decently enough. @psy-fi may
want to pitch in on that.
2015-04-01 14:47:39 -03:00
Dalai Felinto
3e1790feb1 From review: opengl rendering not working when multiview is on and not viewing from camera 2015-03-31 19:06:39 -03:00
Dalai Felinto
c6d2db21d3 From review: Sequencer was not only drawing stereo when only backdrop was on 2015-03-31 14:33:23 -03:00
Dalai Felinto
52ca9a1921 Fix opengl render using wrong perspective when rendering outside camera view 2015-03-31 14:25:12 -03:00
Dalai Felinto
83a729e471 From review: D shortcut is taken by grease pencil 2015-03-31 13:48:27 -03:00
Dalai Felinto
d3b915c273 From review: use GL_TRUE/GL_FALSE whenever possible 2015-03-31 13:44:23 -03:00
Dalai Felinto
ced7d8fb79 Remove never implemented BLURAY mode 2015-03-31 10:43:45 -03:00
Dalai Felinto
926a56a5a6 Merge remote-tracking branch 'origin/master' into multiview
Way too many conflicts this time, and the last merge was less than 10
days ago! Sequencer was what changed the most (the proxy commits in
master) but I think the changes are all good in multiview now (I haven't
tested them, but the code seems fine).

Conflicts:
	intern/cycles/blender/blender_camera.cpp
	source/blender/blenkernel/BKE_sequencer.h
	source/blender/blenkernel/BKE_writeavi.h
	source/blender/blenkernel/BKE_writeffmpeg.h
	source/blender/blenkernel/BKE_writeframeserver.h
	source/blender/blenkernel/intern/sequencer.c
	source/blender/blenkernel/intern/writeavi.c
	source/blender/blenkernel/intern/writeffmpeg.c
	source/blender/blenkernel/intern/writeframeserver.c
	source/blender/blenloader/intern/versioning_270.c
	source/blender/editors/render/render_opengl.c
	source/blender/editors/screen/screendump.c
	source/blender/imbuf/intern/indexer.c
	source/blender/makesrna/intern/rna_scene_api.c
	source/blender/quicktime/apple/qtkit_export.m
	source/blender/quicktime/quicktime_export.h
	source/blender/render/intern/source/external_engine.c
	source/blender/render/intern/source/pipeline.c
2015-03-30 23:28:13 -03:00
Dalai Felinto
156b1ccba0 From review: add_passes() - change COMBINED pass to mimic what we were doing for rl->rect before 2015-03-23 19:27:00 +01:00
Dalai Felinto
e426e18f77 From review: add_filt_passes() - change COMBINED pass filtering and remove commented out code
Note: I don't know which difference does it make to the user, but better to stick to what master is doing
2015-03-23 19:01:42 +01:00
Dalai Felinto
1fb36fe650 From review: cleanup and put define net to the size as we do in DNA 2015-03-23 18:33:05 +01:00
Dalai Felinto
2055cced49 From review: Normalize the result of RE_GetCameraModelMatrix()
(and change Cycles accordingly)
2015-03-23 18:24:07 +01:00
Dalai Felinto
20c043d422 From review: do not do cleanup only 2015-03-23 18:13:43 +01:00
Dalai Felinto
bcc3cb7a75 From review: Rename RE_engine_actview_set > RE_engine_active_view_set 2015-03-23 18:07:37 +01:00
Dalai Felinto
0a1942fbb4 Show Multi-View for EXR images only in wite/save related UIs 2015-03-23 17:59:03 +01:00
Dalai Felinto
7ad48ff467 Merge remote-tracking branch 'origin/master' into multiview
Conflicts:
	source/blender/render/intern/source/external_engine.c
2015-03-21 14:09:59 +01:00
Dalai Felinto
fb658d87ff Removing XXX MV: sequencer already supports multiview movies 2015-03-20 17:55:41 +01:00
Dalai Felinto
82b26c553d Removing XXX MV: remove renderlayer.rect from the API 2015-03-20 16:57:02 +01:00
Dalai Felinto
458a78d7f9 renaming MV to XXX MV 2015-03-20 16:53:56 +01:00
Dalai Felinto
8f3f8e66be Removing XXX MV: viewport render preview does not support multiview 2015-03-20 16:50:49 +01:00
Dalai Felinto
106d00eec0 Assert that shouldn't happen but that happens sometimes, still to be investigated throughly 2015-03-20 16:45:05 +01:00
Dalai Felinto
34cfd02806 From review: check compositor viewer node image only as part of initExecution
I actually put it under ::initImage(), this way it runs only for the active output viewer
2015-03-20 16:45:05 +01:00
Dalai Felinto
39423a894c Image node, small fix, though it doesn't fix the main issue I'm facing 2015-03-20 14:58:37 +01:00
Dalai Felinto
83cef40fa6 From review: UI re-arrangement for Camera Stereoscopy panel 2015-03-20 12:19:30 +01:00
Dalai Felinto
347339d653 From review: redraw window when scene.use_multiview changes 2015-03-20 12:04:47 +01:00
Dalai Felinto
48ab2d5984 Merge remote-tracking branch 'origin/master' into multiview
Conflicts:
	source/blender/makesrna/intern/rna_scene.c
2015-03-20 11:33:30 +01:00
Dalai Felinto
6df28be1f7 From review: fix Cycles tiles udpate not working *
* note: I tried passing b_combined_pass to the do_write_update_render_result() function
but b_rlay is created in do_write_update_render_tile, thus it's not the same that we have on run().
2015-03-20 01:47:34 +01:00
Dalai Felinto
92780acaeb From review: b_rlay.passes.find_by_type(type, view)
This is working, but the code that requires this is not working yet. So it will not be committed together
2015-03-19 20:51:46 +01:00
Dalai Felinto
3cb5a07783 Revert "From review: Cycles: use scene.views instead of render_result.views"
This reverts commit 43e10a6853.

render_result.views is already taken into account whether the views are enabled,
if they can be rendered (e.g., Stereo mode shows only left and right) and when
multiview is off, it has a "" fallback view.

Leaving it as it was for the time being.
2015-03-19 16:32:51 +01:00
Dalai Felinto
43e10a6853 From review: Cycles: use scene.views instead of render_result.views 2015-03-19 14:26:35 +01:00
Dalai Felinto
38b854a544 From review: use b_rview_name 2015-03-19 14:21:31 +01:00
Dalai Felinto
1566cb3291 Merge remote-tracking branch 'origin/master' into multiview 2015-03-19 12:49:42 +01:00
Dalai Felinto
3302e5cc49 Fix crash when saving stereo images from uv/image editor 2015-03-18 17:53:48 +01:00
5370c00e6b Remove redundant initializers 2015-03-18 13:22:26 +11:00
21f6e13835 Cleanup: style 2015-03-18 13:22:25 +11:00
270b487360 Revert "Small cleanup (int to bool)"
This reverts commit 1a574e51fe.

This is only needed when the value is cast to a bool
2015-03-18 13:22:09 +11:00
Dalai Felinto
82139c399f Fix Cycles stereo UI to follow (not even that) recent Blender changes 2015-03-18 00:49:51 +01:00
Dalai Felinto
45d76c110f From review: add tooltips to convergence_mode
And add unique tooltip for viewport_distance
2015-03-17 18:16:16 +01:00
Dalai Felinto
cc4129b7bb From review: replace some 'goto: monoview' with is_multiview_loaded
We still have the monoview_image and monoview_movie. It's easy to change them but I don't know, I find the code slightly more clean by using it :/
2015-03-17 17:37:30 +01:00
Dalai Felinto
93ca780e4d Move 'Update Views' to the _ex panel, and fix crash on update routine 2015-03-17 17:00:28 +01:00
Dalai Felinto
6da622c95f Merge remote-tracking branch 'origin/master' into multiview 2015-03-17 16:55:43 +01:00
Dalai Felinto
1a574e51fe Small cleanup (int to bool) 2015-03-17 15:15:51 +01:00
Dalai Felinto
56ec0bd871 From review: left over from Dr. Epilepsy mode removal 2015-03-17 14:57:02 +01:00
Dalai Felinto
27a69cf4b0 From review: better error message when active camera is not multi-view 2015-03-17 14:57:02 +01:00
Dalai Felinto
e6a45d88d8 Fallback to the zero ibuf, not the last one 2015-03-17 14:57:02 +01:00
f21db785d9 Cleanup: minor edits 2015-03-17 23:55:15 +11:00
fa5c238950 Cleanup: headers, minor edits 2015-03-17 19:09:46 +11:00
04a9635686 Support for building without EXR 2015-03-17 19:06:36 +11:00
fd5573c700 Cleanup: minor edits
drawcamera_stereo3d had shadowed 'scale' var, rename to make unique
2015-03-17 18:02:14 +11:00
fcbf89b4d6 stereoimbuf: replace array with struct since index lookups
Index access weren't used anywhere and made it a little harder to follow.
2015-03-17 16:17:36 +11:00
606e290500 Correct bool/flag use 2015-03-17 15:59:58 +11:00
9c30eaa675 Cleanup: imbuf API
use extra arg for IMB_ImBufFromStereo which used the first argument for both input and output.
also no need to use pointer-to-pointer in function body.
2015-03-17 15:57:58 +11:00
ea3aeb974f Cleanup: API naming - use BKE_scene_multiview_*** prefix 2015-03-17 15:35:22 +11:00
f66f765c79 Cleanup: API naming - use BKE_camera_multiview_*** prefix 2015-03-17 13:39:00 +11:00
715db49f42 Cleanup: remove redundant casts, vars
some odd expressions:
  "(RenderView *)(&rr->views)->first" -> "rr->views.first"
2015-03-17 13:22:01 +11:00
7b17b02669 Cleanup: warning 2015-03-17 12:56:01 +11:00
f53ee18e0e Merge branch 'master' into multiview 2015-03-17 12:42:55 +11:00
Dalai Felinto
bf3a031e9b Fix segfault (thank you ASAN) when changing number of views in compositor 2015-03-16 21:32:36 +01:00
Dalai Felinto
a6a8cb846a Compositor: fix issue when selecting individual view for non-matching image filepaths since the first image 2015-03-16 16:41:51 +01:00
Dalai Felinto
14c9d575ce Fix warning/real bug introduced during removal of scene dependency for Images 2015-03-16 16:31:47 +01:00
Dalai Felinto
f426d4b173 Small cleanups for eventual merge 2015-03-16 16:00:11 +01:00
Dalai Felinto
99779ccb6f From (original) review: NODE_UPDATE_RNA > NODE_UPDATE_OPERATOR 2015-03-16 15:30:15 +01:00
Dalai Felinto
a1a5bff7d9 Dr. Epilepsy R.I.P.
I talked with Francesco and Gabriel and we agreed that this mode was not needed.
(or rather, it would require a major hack in Blender UI to force redraw of everything all the time, which is overkill for something that would likely never get used).
2015-03-16 14:37:45 +01:00
Dalai Felinto
7092a7a737 Don't render if there are no active views, or any missing camera
As suggested during review, it's good to prevent rendering when there is
a missing camera or all views are disabled.
2015-03-16 14:07:55 +01:00
Dalai Felinto
f862307b5a Fix commented out fallback ENUM value 2015-03-16 12:12:25 +01:00
Dalai Felinto
281b49cfa8 Merge remote-tracking branch 'origin/master' into multiview
Conflicts:
	source/blender/blenkernel/intern/packedFile.c
	source/blender/editors/space_view3d/view3d_draw.c
	source/blender/makesrna/intern/rna_scene.c
2015-03-15 18:08:06 +01:00
Dalai Felinto
84ac66445f Style cleanup 2015-03-06 18:36:49 -03:00
Dalai Felinto
9697d1375f Removing the need of Scene for image packing operator
The scene was originally used to determine the suffices of the packed
image. This was only used when the packed image was a Stereo3D image,
and packed as PNG.

We now resort to the default suggested _L, _R suffices for this case.
2015-03-06 17:40:23 -03:00
Dalai Felinto
c71d3a6232 Removing option to use %, and use BLI_path_suffix instead of BLI_path_view 2015-03-05 15:08:52 -03:00
Dalai Felinto
20e023541c Generated Image: Hide from UI the option to create stereo 3d image
We have no tools to properly draw in stereo *yet*.
2015-03-05 10:58:10 -03:00
Dalai Felinto
f6bd5b34e0 Merge remote-tracking branch 'origin/master' into multiview
Conflicts:
	source/blender/windowmanager/intern/wm_window.c
2015-03-04 18:55:07 -03:00
Dalai Felinto
5891dba59f Sequencer: Implement 'Use Multi-View' for sequencer strips as well.
Note: Sequencer still needs the same cleanup we did for Image/Movie
datablocks regarding the load functions.

The Sequencer code flow is very differnt than regular image I/O though. So
I'm leaving the sequencer cleanup for after I get the other suggested
changes implemented in the Image code (i.e., more separation be image
and Scene/RenderData).
2015-02-25 16:34:54 -03:00
Dalai Felinto
d6dcae331e From review: Add Use Multi-View UI option
New flag to determine if the image is or not a potential multiview
The flag is to be used in the UI while IMA_IS_MULTIIEW and IMA_IS_STEREO
are used internally when the image actually is a Multi-View image.

It is working now for Image Editor, Compositor, and even Image textures
(though the latter may be misleading since the rendering always take the
1st ibuf when it comes to textures - not that we can't shouldn't
implement that later).
2015-02-25 16:32:48 -03:00
Dalai Felinto
ec6b87e89f Bitwise flags typo 2015-02-25 16:32:47 -03:00
Dalai Felinto
9b5bb695dd RNA: use 1/0 for image_save_as + check the correct flag (MULTIVIEW instead of STEREO) 2015-02-25 16:32:47 -03:00
Dalai Felinto
4156618620 Fix operator tied to the "D" shortcut (set_stereo_3d)
Note: the idea of this operator is to quickly toggle fullscreen when
required by some stereo modes. At the moment it's showing the menu,
which is not useful, to be improved soon.
2015-02-25 16:31:30 -03:00
Dalai Felinto
d845727661 Merge remote-tracking branch 'origin/master' into multiview 2015-02-23 12:35:06 -03:00
Dalai Felinto
a07a020e5e Fix assert issue from recent RNA changes to prevent non 0/1 values 2015-02-23 11:53:11 -03:00
Dalai Felinto
6bed3b60d6 Merge remote-tracking branch 'origin/master' into multiview 2015-02-23 10:17:25 -03:00
Dalai Felinto
8ca0401d67 Merge remote-tracking branch 'origin/master' into multiview
Conflicts:
	source/blender/blenkernel/intern/image.c
	source/blender/editors/space_sequencer/sequencer_draw.c
2015-02-20 18:35:48 -02:00
Dalai Felinto
3694692aec Merge remote-tracking branch 'origin/master' into multiview
So many conflicts ;) well, we survived the Viewport Shader project
merge

Conflicts:
	source/blender/blenkernel/BKE_camera.h
	source/blender/blenkernel/intern/camera.c
	source/blender/blenloader/intern/versioning_270.c
	source/blender/compositor/nodes/COM_ImageNode.cpp
	source/blender/editors/include/ED_view3d.h
	source/blender/editors/render/render_opengl.c
	source/blender/editors/space_view3d/view3d_draw.c
	source/blender/makesdna/DNA_scene_types.h
	source/blender/makesdna/DNA_view3d_types.h
	source/blender/makesrna/intern/rna_camera.c
	source/blender/makesrna/intern/rna_scene.c
	source/blender/makesrna/intern/rna_space.c
2015-02-13 17:16:47 -02:00
Dalai Felinto
3f795ec6f3 Remove Left/Right commented out code in UI, until we handle this correctly 2015-02-10 02:18:15 -02:00
Dalai Felinto
9a6d9c16f3 Image: refactor image_load_sequence_file() function as suggested on review 2015-02-10 02:09:12 -02:00
Dalai Felinto
dce6d7b1ec small cleanup on image.c 2015-02-10 02:08:30 -02:00
Dalai Felinto
2cfe4f6858 Image: refactor image_load_movie_file() function as suggested on review 2015-02-10 00:54:07 -02:00
Dalai Felinto
f7f6a44022 Merge remote-tracking branch 'origin/master' into multiview
Conflicts:
	source/blender/blenkernel/intern/image.c
	source/blender/editors/space_node/drawnode.c
	source/blender/makesrna/intern/rna_image_api.c
2015-02-09 22:36:44 -02:00
Dalai Felinto
1f3114ef63 Image: refactor image_load_image_file() function as suggested on review
I still need to do the same treatment for image_load_movie_file()
(and potentially for image_load_sequence_file() I have to check if it's
also the case)

Some of the image loading routines in the sequencer could have this
treatment as well.

Also I think that the whole:

"image is an ID block which might be used by multiple users. it should be
self-contained in terms what it is."

Is not a problem anymore. But I need to dig further, because I don't
remmeber if we are using ImageView elsewhere or not.
2015-02-05 23:33:06 -02:00
Dalai Felinto
6478240648 ouch, typo on bitflag operation on image update views format
This should be causing issues, but I have not noticed any. Better fixed than not anyways.
2015-02-05 23:24:07 -02:00
Dalai Felinto
56cf38b00a Code cleanup: create image_add_view function 2015-02-05 23:24:06 -02:00
Dalai Felinto
1a8769917c Merge remote-tracking branch 'origin/master' into multiview
(aka the typo fix commit in master, just to prevent having to solve this
conflict if someone else had fixed this first ;)

Conflicts:
	source/blender/blenkernel/intern/sequencer.c
2015-02-04 17:43:55 -02:00
Dalai Felinto
39037fe06c Merge commit 'origin/master~' into multiview
Conflicts:
	source/blender/blenkernel/intern/sequencer.c
2015-02-04 17:41:39 -02:00
Dalai Felinto
089c6d6694 Fix for unfreed memory after bad merge (re: sequencer proxies) 2015-02-04 17:06:37 -02:00
Dalai Felinto
ebdedf8a96 Merge remote-tracking branch 'origin/master' into multiview
The conflict solving included a change in openexr_api.cpp (to have
COMBINED always on head) that I'm not sure I should go ahead with.

So this little bit may be reverted later.

Conflicts:
	intern/cycles/blender/blender_camera.cpp
	source/blender/blenkernel/BKE_sequencer.h
	source/blender/blenkernel/intern/image.c
	source/blender/blenkernel/intern/sequencer.c
	source/blender/blenkernel/intern/writeframeserver.c
	source/blender/editors/include/ED_view3d.h
	source/blender/editors/sculpt_paint/paint_image_proj.c
	source/blender/editors/space_sequencer/sequencer_edit.c
	source/blender/imbuf/IMB_imbuf_types.h
	source/blender/imbuf/intern/openexr/openexr_api.cpp
	source/blender/makesdna/DNA_image_types.h
	source/blender/makesrna/intern/rna_image.c
	source/blender/render/intern/source/render_result.c
	source/blender/windowmanager/intern/wm_files.c
2015-02-04 11:19:01 -02:00
Dalai Felinto
34069b71c4 Fix missing panels (likely removed in a oerge conflict "fix") 2015-02-04 09:46:22 -02:00
4338e1298f Merge branch 'master' into multiview
Conflicts:
	source/blender/blenkernel/BKE_image.h
	source/blender/blenkernel/intern/image.c
	source/blender/blenkernel/intern/ocean.c
	source/blender/blenkernel/intern/writeavi.c
	source/blender/compositor/operations/COM_OutputFileOperation.cpp
	source/blender/editors/object/object_bake_api.c
	source/blender/editors/render/render_opengl.c
	source/blender/editors/screen/screendump.c
	source/blender/makesrna/intern/rna_scene_api.c
	source/blender/render/intern/source/pipeline.c
2015-01-24 19:21:07 +11:00
fb7efc0541 cleanup: strict warnings 2015-01-24 17:07:47 +11:00
21d3acb79f Merge branch 'master' into multiview
Conflicts:
	source/blender/render/intern/source/render_result.c
2015-01-24 16:52:24 +11:00
6ccc61c346 Cleanup: style 2015-01-24 16:50:13 +11:00
Dalai Felinto
fc9622a167 Sequencer Proxy: Images - add the view suffix only when view_id > 0
This way proxies created for monoscopic image strips created in previous Blenders work out of the box
2015-01-21 16:29:25 -02:00
Dalai Felinto
4c050676e8 Sequencer Proxy: Image - Avoid creating unecessary proxy image files 2015-01-21 16:29:25 -02:00
Dalai Felinto
2e207f9154 Sequencer Proxy: movies sequences in a working state, aka everything working
Proxies in the Sequencer are fully working with Multiview.
The code can be cleaned up a bit, but at least it's entirely functional.

Note, for images we generate one proxy image per view (per frame), while
for movies we generate one proxy movie per movie (so an anaglyph movie
will generate only one proxy).

Tested cases:
* Image sequence - mono
* Image sequence - 3d top-bottom encoded
* Image sequence - 3d left-right pair
* Movie sequence - mono
* Movie sequence - 3d top-bottom encoded
* Movie sequence - 3d left-right pair
2015-01-21 16:29:24 -02:00
Dalai Felinto
11cb2ab919 Small refactor using BKE_scene_view_id_suffix_get() 2015-01-21 16:29:24 -02:00
Dalai Felinto
2da034db2f Merge remote-tracking branch 'origin/master' into multiview
Conflicts:
	intern/cycles/blender/addon/ui.py
	source/blender/makesrna/intern/rna_space.c
2015-01-21 16:28:49 -02:00
Dalai Felinto
7095b9555e Fix some building issues (hopefully) 2015-01-16 19:56:43 -02:00
Dalai Felinto
55d75953ce Movie Writing: changes to encapsulate the elements (as oppose to have
everything static)

You can now export individual streams of videos (e.g., Movie_L.mov,
Movie_R.mov) safely! =)

Before that not only were the names clashing (as I initially thought)
but in fact the whole video streaming was mixed up (when you had to
export more than one video simultaneously).

The way to solve this is to *stop* using static elements and to create a
context to store the current movie data.

This commits involves a lot of changes, but I believe things are working
well. In fact the way I was handling MovieHandler was wrong (creating
arrays and all that), so I'm really glad I got to this.

Note: I couldn't test Frameserver, in fact test with the general codecs
(using multiview or not) are appreciated.

Thanks for Sergey Sharybin for the suggestions that lead to this
solution.
2015-01-16 19:28:40 -02:00
Dalai Felinto
a2ee2d866f Merge remote-tracking branch 'origin/master' into multiview 2015-01-16 19:15:15 -02:00
Dalai Felinto
6b0b2783d6 From review: name arrays with _arr suffix 2015-01-16 01:38:35 -02:00
Dalai Felinto
e692b3d1e3 Partial Fix for Movie Exporting name clash
Before if we exported (from anywhere) videos in the Individual Views
format the _L and _R videos would have the same name. Not anymore.

This was required before I finish the support for Movie proxies in the
sequencer. Or maybe not required, but at least related, and I wanted to
get this over with before finish up the proxies anyways.

Big Important Note:
===================
This is still not working for video formats that rely on the
writeffmpeg.c file. (not that I tested the other formats, but I know
it's breaking with MPEG + Quickime + H.264.

The code in that file uses a lot of statics, and they make it impossible
to writei two movies simultaneously.

That may be why we don't have an option to export videos from the 'File
Output' compositor node.

I thought about two ways of going around that:

1) do something similar with how we handle Render structs, so instead of
having one static of each property we store a whole struct in a listbase
and populate it with the needed elements.

2) we quit using static elements and pass a custom struct to the
mh.* functions (start_movie, append_movie, ...). And we store this
struct in the mf struct.
2015-01-16 01:29:53 -02:00
Dalai Felinto
56be796099 Merge remote-tracking branch 'origin/master' into multiview 2015-01-15 14:28:13 -02:00
Dalai Felinto
b6f853a4fc Sequencer Proxy: image sequence in a working state
Tested: mono, top-bottom and individual views (_L, _R) image sequences

We are creating a proxy file for each individual view, even when the
image is 3D encoded (e.g., a top-bottom image will generate 2 proxy
files).

On-going Development Notes:

1) 3D Movies relying on individual files (_R, _L) are not generating the
proxies correctly at the moment (probably due to name clashing and the
fact that movie names are handled depth inside the code - which is a
known cause for another issue to be fixed when the user tries to export
a movie animation in the Invidual Views mode).

2) At the moment we are looping over all possible available views,
instead of getting from the current Sequencer. We should probably change
that.
2015-01-14 12:06:44 -02:00
Dalai Felinto
ec4670d857 Fix for left/right sequencer image strip not loading (since recent cleanup for review) 2015-01-09 18:36:47 -02:00
Dalai Felinto
a5a614e78e From review: add a suffix to arrays names 2015-01-09 16:46:47 -02:00
Dalai Felinto
2ae2e54a92 Merge remote-tracking branch 'origin/master' into multiview
Conflicts:
	release/scripts/startup/bl_ui/space_sequencer.py
	source/blender/blenkernel/BKE_sequencer.h
	source/blender/blenkernel/intern/camera.c
	source/blender/blenkernel/intern/sequencer.c
	source/blender/blenloader/intern/versioning_270.c
	source/blender/editors/include/ED_view3d.h
	source/blender/editors/render/render_opengl.c
	source/blender/editors/render/render_preview.c
	source/blender/editors/space_sequencer/sequencer_add.c
	source/blender/editors/space_sequencer/sequencer_draw.c
	source/blender/editors/space_view3d/view3d_draw.c
	source/blender/makesrna/intern/rna_color.c
	source/blender/makesrna/intern/rna_image.c
	source/blender/render/extern/include/RE_pipeline.h
	source/blender/render/intern/source/external_engine.c
	source/blender/render/intern/source/pipeline.c
	source/blender/windowmanager/intern/wm_files.c
2015-01-06 11:06:05 -02:00
Dalai Felinto
7d24f22b79 Sequencer: fix for random crashes (after duplicating or cutting strips) 2014-12-02 20:40:49 -02:00
Dalai Felinto
fb01c00286 Merge remote-tracking branch 'origin/master' into multiview
Conflicts:
	source/blender/editors/space_view3d/view3d_draw.c
2014-11-26 16:57:02 -02:00
Dalai Felinto
a96b382206 From review: leftover from d9d94d0c (remove viewname from RE_display_update_cb) 2014-11-26 16:35:36 -02:00
Dalai Felinto
0d5c4fceef From review: keep err_out at the end of draw_offscreen_imbuf*() routines 2014-11-26 16:19:00 -02:00
Dalai Felinto
b9db39ab5e From review: all chars in blender are unsigned, no need special math
utils function just cast/call the _char functions
2014-11-26 12:15:23 -02:00
Dalai Felinto
dd3a2979a3 From review: use !=0 when handling flags 2014-11-26 11:11:15 -02:00
Dalai Felinto
67a2def60a From review: favour anonymous Enum over defines 2014-11-26 11:11:15 -02:00
Dalai Felinto
a74c5742cc From review: rename 'eye' to 'multiview_eye' 2014-11-26 11:11:15 -02:00
Dalai Felinto
289c8d6c6c From review: rename views_setup by views_format 2014-11-26 11:11:14 -02:00
Dalai Felinto
fb2577ab31 From review: rename 'use_multiple_views' to 'use_multiview' 2014-11-26 11:11:14 -02:00
Dalai Felinto
e150f4f268 From review: use _arr for arrays 2014-11-26 11:11:13 -02:00
Dalai Felinto
fb37fd9961 From review: use STRPREFIX instead of strstr 2014-11-26 09:57:18 -02:00
Dalai Felinto
7e62853719 From review: cleanup top-bottom and side-by-side drawing loops 2014-11-26 09:51:45 -02:00
Dalai Felinto
a6e05ad1dc From review: replace sprintf by BLI_snprintf 2014-11-25 23:34:48 -02:00
Dalai Felinto
a87fd88c6b From review: small change and a new TODO to the list:
If a movie fails for one view what to do?
2014-11-25 23:33:39 -02:00
Dalai Felinto
4c5c103258 Bugfix: ammend from previous commit, camera border was still failing in some cases 2014-11-25 19:27:32 -02:00
Dalai Felinto
803bf25dc8 Bugfix: camera border not showing when 'show_stereo_3d_cameras' is disabled
(reported on review)
2014-11-25 18:33:01 -02:00
Dalai Felinto
76ad40fbf7 From review: changes in BKE_image_has_anim() and BKE_image_has_packedfile()
Comments by Sergey Sharybin:

* If packedFile becomes NULL for some and ima->packedfiles has still
  elements this sounds like a horrible error happened somewhere.

* If anims has items then the image is an animation. Imagine situation
  when you load movie file in image editor, save .blend file, then
  remove the movie file and re-load the file. Seems this case should be
  considered image is an animation i guess.
2014-11-25 14:55:19 -02:00
Dalai Felinto
cc7b45ae1f From review: revert uneeded change in branch 2014-11-25 13:44:39 -02:00
Dalai Felinto
589209412d From review: use BLI_duplicatelist and fix for copy_image_anims
It makes no sense to have a ImageAnima when the struct anim itself is
NULL;
2014-11-25 13:39:30 -02:00
Dalai Felinto
0b4c9043e2 From review: image is calloc'ed, no need to initialize ListBases to NULL 2014-11-25 13:39:30 -02:00
Dalai Felinto
046a5babb0 From review: use BLI_freelistN 2014-11-25 13:39:29 -02:00
Dalai Felinto
d9d94d0cfc From review: use viewname from the active render engine (instead of passing it to RE_display_update_cb) 2014-11-25 13:39:29 -02:00
Dalai Felinto
774d02930d From review: fixing GPL header 2014-11-25 13:39:29 -02:00
Dalai Felinto
f17f665e0c From review: SwitchViewNode - use BLI_findstringindex 2014-11-25 13:39:29 -02:00
Dalai Felinto
293b795e9b From review: renaming functions: adding _get 2014-11-25 13:39:28 -02:00
Dalai Felinto
967d65960d From review: using image signal to handle needed updates after reload or image free 2014-11-25 13:39:28 -02:00
Dalai Felinto
610c4273ec From Review: clarify function explanation 2014-11-25 13:39:27 -02:00
Dalai Felinto
7fefdaadc8 Merge remote-tracking branch 'origin/master' into multiview
Conflicts:
	source/blender/editors/space_view3d/view3d_draw.c
	source/blender/makesdna/DNA_view3d_types.h
	source/blender/makesdna/DNA_space_types.h
2014-11-25 13:35:58 -02:00
1b1090081b cleanup & use STREQ macro 2014-11-24 16:38:40 +01:00
Dalai Felinto
a5176676b8 From review: small changes
* Remove double promotion as suggested on review
* Remove extra space and lines in python file
* Undo unecessary change in BKE_camera_object_dof_distance
* Rename stereo_3d operator to set_stereo_3d
* Remove unused variable in python
* Remove unecessary include
2014-11-24 13:28:10 -02:00
6f81acd7f9 cleanup: use empty checks instead of counting 2014-11-24 13:06:52 +01:00
281db468f1 picky - naming, arrays were named same as single vars 2014-11-24 13:01:52 +01:00
Dalai Felinto
54596a84f5 Fixing build with OPENEXR disabled 2014-11-24 09:59:33 -02:00
d73d9629fb picky - naming 2014-11-24 12:49:24 +01:00
3480409ae8 fix for building with glew-mx
(dont include GL/glew.h direct anymore)
2014-11-24 12:38:56 +01:00
c0c2881a92 minor edits to last commit 2014-11-24 12:24:42 +01:00
cf1054bb75 Support builds without EXR 2014-11-24 12:23:05 +01:00
8f4f6f3405 Merge branch 'master' into multiview 2014-11-24 12:05:57 +01:00
bce859c805 cleanup: clarify src/dst listbase copy 2014-11-24 10:55:36 +01:00
22995bf9dc correct bool/flag use 2014-11-24 10:27:35 +01:00
0fb6b7a71f Merge branch 'master' into multiview 2014-11-24 09:58:21 +01:00
Dalai Felinto
7f1ebeb6ca Merge remote-tracking branch 'origin/master' into multiview 2014-11-23 22:40:37 -02:00
Dalai Felinto
9674b10798 Sequencer: no functional change 2014-11-22 13:28:45 -02:00
Dalai Felinto
058ec78f87 Sequencer: small style cleanup 2014-11-22 13:23:14 -02:00
Dalai Felinto
ba81c53ba4 Sequencer: Fix for monoview videos showing blank for missing views 2014-11-20 11:00:13 -02:00
Dalai Felinto
70bb90e1e0 Sequencer: small style cleanup, and small code order change 2014-11-20 10:58:28 -02:00
Dalai Felinto
e438d861ed Sequencer: unify the code to get the name of the files when using multiview + individual images 2014-11-20 10:55:28 -02:00
Dalai Felinto
ef109f9032 Sequencer: small refactoring of the multiview image rendering code 2014-11-20 10:55:28 -02:00
Dalai Felinto
b132cbda03 Sequencer: remove unecessary 1-liner 2014-11-20 10:55:27 -02:00
Dalai Felinto
0b03ccbbcd Replace BLI_listbase_count() by BLI_listbase_count_ex() when possible 2014-11-20 10:55:11 -02:00
Dalai Felinto
8eb050c058 Merge remote-tracking branch 'origin/master' into multiview
Include manual fixes for BLI_listbase renames
2014-11-20 10:49:36 -02:00
Dalai Felinto
52bc4bff69 Sequencer: final bits of seq->anim stripped away (in favour of seq->anims)
Sequencer core todos:
====================

* Check on proxies

* I may need a permanent flag to indicate something is multiview/stereo,
  to prevent overhead on rendering uncached. That should also prevent:

* Fix issue of mono-videos (when in multiview) not showing a valid view
  for all the views.

* Add multiview option to rna_sequencer_api add_movie_strip

* (optional) Remove duplicate code of creating anims for all views

* Test, Test, Test
2014-11-19 12:20:40 -02:00
Dalai Felinto
5352fef28f Sequencer: proxy rebuild changes 2014-11-19 09:38:30 -02:00
Dalai Felinto
af29905d48 Sequencer: solve warning (misusing context) 2014-11-19 01:09:25 -02:00
Dalai Felinto
6725532363 Sequencer: show option to open multiview/stereo 3d movies/images, and pre-load them 2014-11-19 01:03:12 -02:00
Dalai Felinto
a094c395c0 Merge remote-tracking branch 'origin/master' into multiview
Conflicts:
	source/blender/editors/space_image/image_buttons.c
2014-11-14 10:51:49 -02:00
Dalai Felinto
d13789ccdc Fix crash (blender hanging) when rendering a sequencer strip twice 2014-10-29 15:21:07 -02:00
Dalai Felinto
7edc16245a Prevent crash when sequencer strip returns a NULL ibuf 2014-10-29 15:20:58 -02:00
Dalai Felinto
6dcbd52c44 Merge remote-tracking branch 'origin/master' into multiview 2014-10-29 15:20:44 -02:00
Dalai Felinto
0a6402535d fix blenderplayer 2014-10-24 04:45:05 +02:00
Dalai Felinto
7d36655e51 Sequencer: Multi-View/Stereo 3D video strips partial support
What is working:
* To load a movie and have it load all the respective views/files
* To load a movie and set it to be loaded as Stereo 3D

What is not working:
* Proxies
* Some parts relative to re-loading
* 2 // XXX MV SEQ MOV where we are still using seq->anim
2014-10-24 02:28:06 +02:00
Dalai Felinto
6d6e0a7736 Sequencer: Support for stereo 3d image strips
Note: there is a bug when you render the image and try to render another frame. It seems like a lock problem (blender just hangs).
So as with anything else in this branch do not use it with production files that you have no backup.
2014-10-23 19:46:59 +02:00
Dalai Felinto
53f3860622 after merge fix 2014-10-22 23:12:30 +02:00
Dalai Felinto
df888ef0cf Merge remote-tracking branch 'origin/master' into multiview 2014-10-22 22:53:55 +02:00
Dalai Felinto
4ef8927781 Sequencer render of scene strips working fine
Basically the issue was that rr was being freed and re-allocated inside
the BKE_sequencer_give_ibuf() function - more specifically after
RE_InitState() calls render_result_free().

Thanks to Jens Verwiebe for the help in cross-debug this.
2014-10-16 18:21:41 -03:00
Dalai Felinto
0e163beaf1 Sequencer, scene render (work in progress)
Rendering crashes after a few attempts (or a few frames when rendering a
sequencer). It seems memory related.

The overall problem is that the re->result is not consistent across the
entire render session it seems. Still investigating.
2014-10-16 17:20:11 -03:00
Dalai Felinto
aad21b5e17 quiet warning 2014-10-15 13:12:40 -03:00
Dalai Felinto
f8812fab51 more ifdef WITH_OPENEXR 2014-10-14 23:34:16 -03:00
Dalai Felinto
df0b4840ed Sequencer: OpenGL preview and OpenGL render working correctly 2014-10-14 20:17:08 -03:00
Dalai Felinto
59bf863273 Merge remote-tracking branch 'origin/master' into multiview
Note: this also includes some house-keeping in the image_buttons.c to
handle the recent changes in the file.

Conflicts:
	release/datafiles/locale
	source/blender/blenloader/intern/versioning_270.c
	source/blender/editors/space_image/image_buttons.c
2014-10-14 19:39:52 -03:00
Dalai Felinto
5ed6e4a029 Sequencer Multi-View/Stereo 3D initial commit
What works:
* Scene strips.
* Any non-image strips.

What doesn't work well:
* OpenGL Render (and preview) from sequencer is buggy (it doesn't use
  the correct camera shift). It's particularly bad for Stereo 3D.
* Right now there is no way of previewing only a view (e.g., left)
  in a way it's the same we do with the Compositor backdrop.

What doesn't work yet:
* Any image or movie strip (they work as mono at the moment).
2014-10-14 15:02:35 -03:00
Dalai Felinto
08f2122d7a Merge remote-tracking branch 'origin/master' into multiview
Conflicts:
	source/blender/blenkernel/intern/image.c
	source/blender/blenloader/intern/versioning_270.c
	source/blender/editors/sculpt_paint/paint_image_proj.c
	source/blender/editors/space_image/image_buttons.c
	source/blender/editors/space_image/image_ops.c
	source/blender/editors/space_view3d/view3d_draw.c
	source/blender/makesdna/DNA_image_types.h
	source/blender/makesdna/DNA_userdef_types.h
	source/blender/makesrna/intern/rna_image.c
	source/blender/makesrna/intern/rna_render.c
	source/blender/render/extern/include/RE_pipeline.h
	source/blender/render/intern/source/pipeline.c
	source/blender/render/intern/source/render_result.c
2014-10-10 12:31:14 -03:00
Dalai Felinto
20a7889df1 Fix for crashes on release build when rendering, big kudos for Lukas Toenne 2014-09-25 20:21:15 +02:00
Dalai Felinto
306732ec56 Merge remote-tracking branch 'origin/master' into multiview
Conflicts:
	release/datafiles/locale
	source/blender/blenloader/intern/versioning_270.c
2014-09-25 20:21:06 +02:00
Dalai Felinto
1a8cf4f8a4 Change Viewport "stereo 3d" option for Multi-View scene setup
This may not be clear enough, and I still want to run this by Francesco Siddi. But basically the idea here is that when using the Multi-View option you should only get the option to see the "Stereo 3D" (when there is a left and right cameras) or the "views" which is the current selected view
2014-09-24 18:13:56 +02:00
Dalai Felinto
04a361f090 Missing file from the last renamse (basic stereo > stereo 3d / advanced stereo > multiview) 2014-09-24 14:15:03 +02:00
Dalai Felinto
482eac61a2 Rename 'Basic Stereo'/'Advanced Stereo' to 'Stereo 3D'/'Multi-View' 2014-09-23 12:41:32 +02:00
Dalai Felinto
3ce1849f25 Viewport 3D: support for Volume drawing for Advanced Setup (Multi-View) too
(and flipped red-cyan volume colors to match what you see from the
camera)
2014-09-23 12:15:33 +02:00
Dalai Felinto
407d60330d Use Red-Cyan for the volume drawing 2014-09-23 00:00:55 +02:00
Dalai Felinto
5b16c78913 Viewport 3D: Drawing of Stereo Cameras, Convergence Plane and Volume
This also includes:
* Unification of the view_matrix and model_matrix functions.
* Fix for Toe-in formula
* Fix for viewport bug when camera scale was not uniform
2014-09-22 23:10:19 +02:00
Dalai Felinto
f9cb232851 Merge remote-tracking branch 'origin/master' into multiview
Conflicts:
	source/blender/render/intern/source/pipeline.c
2014-09-22 23:10:01 +02:00
Dalai Felinto
b62b55b03b Fix individual images saving having color management applied to one views (caminandes bug)
(and some code shuffling around)

Note: the only part of save_image_doit that is not fully ok is when the
user save a stereo encoded format (e.g., Anaglyph) and has the 'save as
copy' option unchecked. Personally I think we shouldn't support this
combination (user looses data this way), or we should re-load the image
(which is not nice if the format is lossly like jpeg).
2014-09-20 18:47:47 +02:00
Dalai Felinto
7b0c812a5b Fix blenderplayer compile 2014-09-20 15:56:47 +02:00
Dalai Felinto
53b48b9568 Cycles fix for multiview (it was not working since the view_id -> viewname change 2014-09-20 15:47:00 +02:00
Dalai Felinto
11270fc3f1 Fix for Cycles Motion Blur 2014-09-20 15:47:00 +02:00
Dalai Felinto
a1a66a8887 Cycles multiview rendering
Note: since the view_id -> viewname change the render in cycles saves
both views to the same view. So this commit gets Cycles to work with the
new method for getting the camera matrices BUT it doesn't address this
other problem.
2014-09-20 15:47:00 +02:00
Dalai Felinto
a913047549 Builtin Stereo Camera: replace hack cameras to a real matrix approach
Note: Cycles is not working with this yet
2014-09-20 15:47:00 +02:00
Dalai Felinto
6593212027 Merge remote-tracking branch 'origin/master' into multiview 2014-09-20 15:46:29 +02:00
89dd233d5f Cleanup 2014-09-19 14:26:47 +10:00
97a7d3d7b1 Correct flag -> bool use 2014-09-19 14:26:33 +10:00
5bf989d609 Merge branch 'master' into multiview 2014-09-19 14:25:18 +10:00
Dalai Felinto
c5211463f9 Fix crash on "cache exr" 2014-09-18 19:40:49 +02:00
Dalai Felinto
8d4c498cb8 De-duplicate some logic + make comment more clear + revert unintented
change from master
2014-09-18 14:34:07 +02:00
Dalai Felinto
560ee80286 169 Style-Cleanup (thanks Campbell Barton) 2014-09-18 11:51:23 +02:00
04516721a0 Cleanup: de-duplicate some logic 2014-09-18 19:05:42 +10:00
6f662de83a Merge branch 'master' into multiview 2014-09-18 18:54:59 +10:00
e11fd354d4 Fix for off-by-2 size with BKE_camera_multiview_advanced
Also move scene-base search into its own function.
2014-09-18 18:53:00 +10:00
3c70ec25c8 Cleanup: style/spelling 2014-09-18 18:38:56 +10:00
Dalai Felinto
268ab9e1b7 Bug/Typo in image_update_multiview_flag, caught by Campbell Barton, thanks :) 2014-09-18 10:14:35 +02:00
Dalai Felinto
876bc2b947 Compositor: final fix for access-memory after freed - note: valgrind caught this while asan did not 2014-09-17 15:42:36 +02:00
Dalai Felinto
c95e71a5fe Compositor: use ths suffix (not the view name) for the File Output filenames 2014-09-17 14:54:46 +02:00
Dalai Felinto
176bbdc3cf Compositor: remove (unify) duplicated code 2014-09-17 14:06:38 +02:00
Dalai Felinto
3232751301 OpenEXR Single and Multilayer working for Compositor, remove Stereo 3D
option for Multilayer OpenEXR and remove unused code, general cleanup

Note: I removed the function that allowed to save Multipart OpenEXR.
We are sticking to single part OpenEXR to be in compliance with OpenEXR
1.x
2014-09-17 14:06:37 +02:00
Dalai Felinto
cb12fac477 OpenEXR: cleanup (using C++ reference when possible) 2014-09-17 14:06:37 +02:00
Dalai Felinto
fd5ee4dd18 Support for saving singlelayer multiview openexr from Image Editor
Note, this approach could be generalized to any multiview format, but at
the moment only OpenExr supports that.
2014-09-17 14:06:37 +02:00
Dalai Felinto
c588080245 Image Node: support multiview depth pass 2014-09-17 14:06:37 +02:00
Dalai Felinto
bf72d65607 Change S3D_UNSQUEEZED to SQUEEZED to make unsqueezed the default 2014-09-17 14:06:37 +02:00
Dalai Felinto
fc35c8ae26 support for stereo 3d encoded (top-bottom, anaglyph, ...) depth channel 2014-09-17 14:06:37 +02:00
Dalai Felinto
87d67a0c46 Fix is_float test for ibufs without z 2014-09-17 14:06:37 +02:00
Dalai Felinto
4bb1566944 Fix unfreed memory on duplicated windows and others 2014-09-17 14:06:37 +02:00
Dalai Felinto
7739ac8691 Window Menu option to change stereo display options 2014-09-17 14:06:37 +02:00
Dalai Felinto
153696489d Fix blenderplayer build 2014-09-17 14:06:36 +02:00
Dalai Felinto
f4759ed978 Fix anaglyph not working in OSX
Aka initial values for stereo 3d format struct were not zero in OSX
2014-09-17 14:06:36 +02:00
Dalai Felinto
304f81b086 Make sure left is always the first view 2014-09-17 14:06:36 +02:00
Dalai Felinto
85eadbf776 Depth (Z) support for single layer multiview openexr 2014-09-17 14:06:36 +02:00
Dalai Felinto
c36dfb5950 Support OpenEXR opening of single layer multiview files 2014-09-17 14:06:36 +02:00
Dalai Felinto
2910b0c77f Writing Multiview single layer-ish openexr from compositor 2014-09-17 14:06:36 +02:00
Dalai Felinto
d75a10e986 Getting rid of the OpenEXR Multiview in the UI 2014-09-17 14:06:36 +02:00
Dalai Felinto
f964ccd582 Show multiview option for OpenEXR formats 2014-09-17 14:06:36 +02:00
Dalai Felinto
fd377e2612 Merge remote-tracking branch 'origin/master' into multiview 2014-09-17 14:04:46 +02:00
Dalai Felinto
b0373525ca Use Image multiview settings as default when trying to save it 2014-09-11 18:53:59 +02:00
Dalai Felinto
1111b2101e Support image views format change in the image panel - so user can drag&drop images and change their type afterwards 2014-09-11 15:45:16 +02:00
Dalai Felinto
dbf135f53e Fix for image display not updating before selecting a view (left over from the ima->views change) 2014-09-11 12:05:22 +02:00
Dalai Felinto
2a7f2287e6 Fix crashes when for stereo3d_format update where there is no id 2014-09-11 11:14:43 +02:00
Dalai Felinto
9ba7bb0e61 Missing RNA access to image->packedfiles and fix image.packed_file for
backward compatibility

(it now points to the first packed file)
2014-09-11 01:59:20 +02:00
Dalai Felinto
2d1218a76e Expose Image Stereo 3d format in the Properties Panel
This allow the users to change the stereo type after loading the image (in case the wrong encoding was wrongly pick)

Note: we do not let the user change between stereo and views after loading
2014-09-11 01:04:42 +02:00
Dalai Felinto
c1a25c10c3 Silence false positive detected by valgrind 2014-09-10 23:30:14 +02:00
Dalai Felinto
008474521e Fix unfreed memory when RenderResult were requested to be filled with all views 2014-09-10 23:16:08 +02:00
Dalai Felinto
d73683af12 Fix unfreed memory when using sequence of files
(I have fixed it movie and image but forgot about the above)
2014-09-10 19:18:15 +02:00
Dalai Felinto
6a324c1967 Fix image not re-scale when "Fields" is toggled twice 2014-09-10 18:57:37 +02:00
Dalai Felinto
0095ac2186 Fix unfreed memories issue
(the problem was that I was creating multiple ImBufs in the load functions, and was not deferring them)
2014-09-10 17:04:03 +02:00
Dalai Felinto
04cd487448 Fix blenderplayer build 2014-09-10 17:04:03 +02:00
Dalai Felinto
af178735ad Remove unused function (BKE_image_cache_count and IMB_moviecache_count) 2014-09-10 17:04:03 +02:00
Dalai Felinto
626a2865f5 use BLI_str_rpartition() instead of my own (thanks Campbell) - and the code seems to be UTF8-safe :) 2014-09-10 12:39:49 +02:00
Dalai Felinto
b3685a8ea3 Image Editor saving of image in 3d (individual views) working
Note: I need to go over this function again to see if I'm handling the
'save as copy' == false correctly. If the image is saved to a
destructive format, in that case we should change the current image (and
I'm almost sure I overlooked that).

This function can likely be simplified as well now that I'm more
comfortable with the whole image pipeline.
2014-09-09 22:58:19 +02:00
Dalai Felinto
d2363db238 Packing of multiview images working
Notes:
* This will pack multiple images if the format is R_IMF_VIEWS_INDIVIDUAL
* When packing as PNG we convert the views_format to R_IMF_VIEWS_INDIVIDUAL
* Technically we could use the same principle to pack a sequence of images (with some changes of course, since this approach relies on ImageView
2014-09-09 22:57:29 +02:00
Dalai Felinto
53edcd5f97 Merge remote-tracking branch 'origin/master' into multiview 2014-09-09 22:56:27 +02:00
Dalai Felinto
69bac908da Stereo 3d Movie support 2014-09-09 11:51:45 +02:00
Dalai Felinto
192039c355 remove ambiguity in if statement 2014-09-08 20:46:19 +02:00
Dalai Felinto
a4e537d0f4 Image Editor saving of Image in 3d working (it was working for RenderResult images only in the past) 2014-09-08 19:46:08 +02:00
Dalai Felinto
655804f23e Generated Images only give 3d option if scene is Multiview 2014-09-08 18:42:55 +02:00
Dalai Felinto
14da4996cc Import of all stereo encoded formats (anaglyph, interlace, top-bottom, ...)
This is supported at the moment for single-layer formats only. It works
fine though. The user must be aware that some formats are
highly-destructive and won't never be recovered 1:1 (e.g., interlace and
anaglyph)
2014-09-08 17:20:16 +02:00
Dalai Felinto
04c20fd7b3 StereoDisplay is now Stereo3dFormat and and removal of UserDef properties
* All the datablocks that uses stereo3d_format now store a pointer not the struct
2014-09-07 01:11:51 +02:00
Dalai Felinto
483b9532a5 Store StereoDisplay in the image dna to use when re-saving the image 2014-09-07 01:10:27 +02:00
Dalai Felinto
2d677941f5 General UI and some cleanups 2014-09-07 00:21:58 +02:00
Dalai Felinto
58880ec965 Generated Image now has a '3D Stereo' option (when stereo3d is on) 2014-09-07 00:21:58 +02:00
Dalai Felinto
4dd894d1f5 Support for painting of stereo images (no real depth painting yet)
Idea poll:
When in stereo mode you paint we paint to both buffers at the same time,
however the brush should get an offset parameter (pixel separation) that would
allow the user to paint in depth.

The brush 'icon' (the circle thing) could also be drawn with this
offset.

Bonus: make grease pencil (View mode) do the same thing. Basicaly we can
add a 'viewoffset' property to each line and use it at drawing time (no
idea of GPencil code, just speculating).
2014-09-07 00:14:03 +02:00
Dalai Felinto
26f38f3fc0 View3D Background Image stereo support 2014-09-07 00:13:53 +02:00
Dalai Felinto
8216fb119c Write/Read .blend for Image.views 2014-09-07 00:13:47 +02:00
Dalai Felinto
7ae4b8ef1a Image Sequence (0001_L.png, 0001_R.png, 0002_L.png, 0002_R.png, ...) support 2014-09-07 00:13:41 +02:00
Dalai Felinto
9e1d326892 Image Node supporting individual images as views 2014-09-07 00:13:34 +02:00
Dalai Felinto
afe8054596 Image support to multiview (not only RenderResult/Multilayer) 2014-09-07 00:13:27 +02:00
Dalai Felinto
a16fef8e61 Move code to reset Viewer Image cache to BKE_image.h 2014-09-07 00:12:59 +02:00
Dalai Felinto
529484ed77 Merge remote-tracking branch 'origin/master' into multiview 2014-09-07 00:11:49 +02:00
Dalai Felinto
2b606dc130 Filepath should include view even when rendering one view (if multiview is on)
When multiview is not used the filepath is as usual (e.g., Image.jpg).
 When multiview is on, even if only one view is enabled the view is incorporated
 into the file name (e.g., Image_L.jpg). That allows for the user to re-render
 individual images.
2014-09-02 11:54:57 +02:00
Dalai Felinto
b239314f29 Refactor to use view name instead of view id
This was is partly from the original code review round. At that time
Brecht Van Lommel suggested using names for the API instead of integers
(as we do for RenderLayers). I went a bit further and changed *most* of
the code to use strings.

The only parts that still use view_id are the ones closely related to UserImage.

That simplify the code and should make the code easier to understand,
review and maintain.

I tested many (if not all) of the supported areas, and apparently things
are working. But given the size of the intervention I wouldn't be
surprised if something stopped working, so please report.
2014-09-02 11:54:34 +02:00
Dalai Felinto
26ca7deae9 Merge remote-tracking branch 'origin/master' into multiview 2014-08-29 17:41:07 +02:00
Dalai Felinto
1c33e9bb4d Fix blenderplayer stub 2014-08-29 17:40:16 +02:00
Dalai Felinto
2c35b52d16 OpenGL Preview Export - final
Animation exporting works, stereo output works, ... =)
2014-08-29 16:08:04 +02:00
Dalai Felinto
ea85ef9a17 Fix for is_mono test
(meaning we were doing multiview in some times when we should be doing
mono rendering)
2014-08-29 16:07:28 +02:00
Dalai Felinto
055c4feeb5 Rename scene multiview util functions 2014-08-29 16:07:18 +02:00
Dalai Felinto
8884eb8882 OpenGL Preview Export (work in progress)
OpenGL Preview Export is working for still images, and not breaking for sequencer, movie, ...

That includes some refactoring to unify the code of render_opengl.c and
pipeline.c (the part related to saving).

Next tasks:
* Get it to work for the movie opengl preview
* Get the sequencer 3dview preview to show in stereo
* Get the sequencer OpenGL still/movie to export in stereo
2014-08-29 00:27:55 +02:00
Dalai Felinto
c00d8fdb09 cleanup make all the "MV" todo notes into "XXX MV" for quick reference later 2014-08-28 11:58:43 +02:00
Dalai Felinto
cc4236efda Cleanup: remove warnings, remove duplicated code, fix util function
(and force the material thumbnail preview to be monoscopic)
2014-08-28 11:56:45 +02:00
Dalai Felinto
c556dc44da Merge remote-tracking branch 'origin/master' into multiview
Conflicts:
	source/blender/blenkernel/BKE_scene.h
	source/blender/blenkernel/intern/scene.c
	source/blender/blenloader/intern/versioning_270.c
2014-08-28 11:53:11 +02:00
Dalai Felinto
327007e933 New Stereo Output option: Squeezed Frame
So now top-bottom and side-by-side can be saved as squeezed (default) or unqueezed (old).
2014-08-26 19:02:56 +02:00
Dalai Felinto
610a66bf8c Compositor: Image Node to work correctly with MultiView images 2014-08-26 02:44:17 +02:00
Dalai Felinto
920d6403f4 Merge remote-tracking branch 'origin/master' into multiview 2014-08-26 02:43:53 +02:00
Dalai Felinto
8b96cf5d0b Disabling Stereo Output for Multilayer
This is doable, but again it is a lot of work for something that probably no one will use.
I do not know why I even coded multlayer+stereo output for regular rendering and image editor :|
I will see, maybe I implement that later, but just do not want to bother with this now.
2014-08-25 16:40:16 +02:00
Dalai Felinto
ca14760dad Compositor: File Output Multiview
Multiview now also working when used for the individual inputs. Multiview with multiple layers was already working.
Only remaining bit to work is Multilayer + StereoOutput
2014-08-25 16:20:24 +02:00
Dalai Felinto
4f1e311d1b Compositor: File Output
File output working for stereo output
(so each individual input can be outputted as a separated stereo format)

Not supported at the moment:
* Multilayer + stereo output

Not fully working (though it should):
* Multiview
2014-08-25 15:47:17 +02:00
Dalai Felinto
45159fa2e3 Split Viewer: 1-line fix, all viewers working now =) 2014-08-22 11:22:04 +02:00
Dalai Felinto
477daa9337 Compositor handling all views on update (so you can edit the views
individually and see the updates) and viewer node fully working.

SplitViewer Node on the other hand is not working :| not sure why yet.
But apart from SplitViewer and the FileOutput node (easy fix, I'll work
on it shortly), the compositor should be fully functional for
multiview.
2014-08-21 22:36:39 +02:00
Dalai Felinto
273345ed84 Merge remote-tracking branch 'origin/master' into multiview 2014-08-21 13:18:00 +02:00
Dalai Felinto
16d58a115b Compositor Backdrop
Note: the one remaining bit that has to be addressed in compositor is
the re-runs (e.g., when you adjust a node).

I also suspect that multiple viewer nodes are a problem at the moment,
but I believe it's related to the re-run problem. Which then should be
re-visited once re-run is fixed.
2014-08-19 19:33:58 +02:00
Dalai Felinto
f424d433f6 Viewer Node: further fixing
* creating float buffers for new viewer
* give correct view count when using basic stereo
* update image when changing menu
* only get rid of old cache when needed
* crash when using backdrop
2014-08-19 18:00:53 +02:00
Dalai Felinto
92d846c7bb Viewer Node: remove unused buffers when number of views change 2014-08-19 15:22:05 +02:00
Dalai Felinto
1e2ddc45c1 Viewer Node: Backend work to get viewer node working for multiview 2014-08-19 15:22:04 +02:00
Dalai Felinto
a79d4e0c1e Merge remote-tracking branch 'origin/master' into multiview 2014-08-19 15:21:57 +02:00
2f839c26ac Make blenderplayer compile again 2014-08-15 18:07:59 +02:00
Dalai Felinto
79a3861413 Fixup for stereo output (side-by-side, top-bottom) 2014-08-15 17:28:59 +02:00
Dalai Felinto
9475d5e8c2 Stereo Output for Multilayer when rendering or saving from Image Editor
We now do stereo-magic to ALL layers of multilayers.

The only remaining part of stereo output is for videos when saved with
individual views (the naming scheme at the moment is handled inside the
movie code), to be tackled later (TODO).
2014-08-14 19:55:13 +02:00
Dalai Felinto
3fbc866077 Stereo output core - support rect/rectf instead of ImBufs only (for openexr multilayer) 2014-08-14 19:54:58 +02:00
Dalai Felinto
1e3a4891be Fix sanitized memory for rna_camera
(thanks to -fsanitize=address and Lukas Toenne ;)
2014-08-14 19:54:51 +02:00
Dalai Felinto
7f706ce3ab Merge remote-tracking branch 'origin/master' into multiview 2014-08-14 19:54:20 +02:00
Dalai Felinto
fd14bbeee1 Export Stereo Output during render too (also works for animation) 2014-08-13 12:14:48 +02:00
Dalai Felinto
4d4841f810 Support for Movie Multiview Output (Individual Images or Stereo 3D) 2014-08-13 12:14:38 +02:00
Dalai Felinto
d428079782 expose IMB_stereo_dimensions 2014-08-13 12:14:29 +02:00
Dalai Felinto
f955759ba8 Moving RE_ render result + multiview related functions to renderresult.c
and related cleanup
2014-08-13 12:14:15 +02:00
Dalai Felinto
eb19c93cb2 adapt more render functions to use view_id 2014-08-13 12:14:01 +02:00
Dalai Felinto
77598ecd38 Merge remote-tracking branch 'origin/master' into multiview 2014-08-13 12:13:00 +02:00
Dalai Felinto
f220d46679 Merge remote-tracking branch 'origin/master' into multiview 2014-08-11 19:30:44 +02:00
Dalai Felinto
c65d6abd3b Fix export stereo images from Image Editor when the image was a render
This fix is a worka around (I duplicate the ImBuf) to prevent locking
due to both buffers being related to the same element (LOCK_VIEWER).

That's an issue exclusive of rendered images (it wasn't happening for
MultiView EXRs).

To render/animate the scene directly to stereo output is not possible at
the moment. Only saving from Image Editor has it fully supported.
2014-08-11 19:28:06 +02:00
Dalai Felinto
6bd7e44a40 quite warning 2014-08-11 19:28:05 +02:00
Dalai Felinto
a4ac20287c Side By Side Stereo Output mode + small cleanups 2014-08-09 00:23:49 -03:00
Dalai Felinto
97c8c290e8 Interlace Output Stereo Modes 2014-08-08 23:41:21 -03:00
Dalai Felinto
3051deeddd Top-Bottom Stereo Output mode
(note: we probably need a compressed option for this mode)
2014-08-08 17:39:40 +02:00
Dalai Felinto
f56325f0c1 cosmetic change 2014-08-08 17:39:40 +02:00
Dalai Felinto
737e70e4f3 All anaglyph stereo output modes working =) 2014-08-08 16:30:14 +02:00
Dalai Felinto
7f3c4200aa placeholders for all the stereo 3d image formats 2014-08-08 16:05:04 +02:00
Dalai Felinto
04b6f38a64 fix for missing casting from int to uchar * for non float stereo images 2014-08-08 16:04:54 +02:00
Dalai Felinto
43ffe6ef0c fix for non-float stereo images 2014-08-08 15:41:10 +02:00
Dalai Felinto
e85098266d multiview changes to use the new ImBuf functions to get ready-to-render ImBuf 2014-08-08 15:13:35 +02:00
Dalai Felinto
01e15e5037 Core changes to be able to get a ready-to-render ImBuf
Note: this could be done in master even
2014-08-08 15:13:14 +02:00
Dalai Felinto
c47cd40944 Merge remote-tracking branch 'origin/master' into multiview 2014-08-07 20:19:33 +02:00
Dalai Felinto
09c6b31395 New Stereo Image Output options (work in progress)
Now there is a new menu to let the user pick whether to export the image as Individual images, or as Stereo 3D.
The only mode currently working is Anaglyph (and it goes better with RGBA output).

It includes a big refactor of my original approach to save_image_doit

I'm wait to decide the best design with Sergey before implementing the other modes (and finishing anaglyph to handle all cases, spaces).
2014-08-07 20:14:58 +02:00
Dalai Felinto
a76a84225c Fix crash when opened EXR image had views not present in the scene views 2014-08-05 18:00:59 +02:00
Dalai Felinto
f230d15ce1 fix for exr images not loading in Linux
Note to self, go over the code and try to find other cases when I used BLI_snprintf to make sure I didnt use the same string as source and dest (it works in OSX, but not in Linux)
2014-08-05 15:32:21 +02:00
Dalai Felinto
4e85d8daea multiview: bug when saving image
When I implement the OpenEXR changes I will revisit save_image_doit and
do a final cleanup. But for now it's working again as it should.
2014-08-01 15:03:28 -03:00
Dalai Felinto
5ec6e7091e multiview: fix for hanging cursor when saving image (problem introduced after a merge) 2014-08-01 13:27:31 -03:00
Dalai Felinto
bf86d65273 Merge remote-tracking branch 'upstream/master' into multiview 2014-07-30 11:15:23 -03:00
Dalai Felinto
5c1da8a78a multiview: allow stereo display as a per window settings
That now means the D operator (stereo_toggle) can also be used to change
the stereo display settings of the current 'window'.

The 'toggle' part is currently not entirely functional because among
other things I still need to integrate the fullscreen editor operator in
the branch, so it can be integrated in this operator too.

This is advanced, but only advanced users should be needing multiple
displays to work in 3d (and those users can add their own shortcuts for
that, if we document it all well).

Same goes for pie-menus, we have approximately ten 3d modes, the mode
switch could very well fit in a pie-menu.

If a new file is loaded with 'Load UI' it will re-set the 'stereo
display' settings to the user preference ones. Otherwise it will keep
the windows to be whatever they were. So although the
wmWindow.stereo_display is saved in the file, it's never used.
2014-07-28 23:41:39 -03:00
Dalai Felinto
05c8590896 multiview: remove old clean ui operator
This functionality is still necessary, but it was refactored and sent
for review independently in D678 (https://developer.blender.org/D678)
2014-07-25 17:32:13 -03:00
Dalai Felinto
6311911466 Merge remote-tracking branch 'upstream/master' into multiview
(removed the multiview splashscreen as well to prevent future issues and
not to increase the git repo size by much)

Conflicts:
	release/datafiles/splash.png
	source/blender/blenloader/intern/versioning_270.c
	source/blender/makesdna/DNA_scene_types.h
	source/blender/makesrna/intern/rna_scene.c
	source/blender/makesrna/intern/rna_userdef.c
	source/blender/render/intern/include/render_types.h
	source/blender/render/intern/source/pipeline.c
	source/blender/windowmanager/intern/wm_draw.c
2014-07-24 23:25:08 -03:00
Dalai Felinto
361ed81048 Merge remote-tracking branch 'upstream/master' into multiview
Conflicts:
	source/blender/imbuf/intern/openexr/openexr_api.cpp
2014-06-11 03:26:57 -03:00
Dalai Felinto
136823c3d1 silence warning (GLubyte) and float cleanup 2014-05-28 01:30:30 -03:00
Dalai Felinto
633f55ac6b fix for drawing glitches when stereo was on 2014-05-28 00:54:43 -03:00
Dalai Felinto
029938fb96 fix for crash when baking 2014-05-27 22:50:17 -03:00
Dalai Felinto
e611409068 Merge remote-tracking branch 'upstream/master' into multiview
Conflicts:
	source/blender/blenloader/intern/versioning_270.c
2014-05-27 22:36:32 -03:00
Dalai Felinto
4bd686cc95 Pivot for built-in (as know as basic) stereo camera
That includes a fix for Toe-In which wasn't 100% correct.
2014-05-27 22:21:49 -03:00
Dalai Felinto
e480f93e21 Image Editor: set COMBINED as default passtype and fallback iuser
settings when changing image

Before you may get no update when changing images. Now it makes sure the
passtype, view, ... is always valid for the current image (otherwise it
fallbacks to default).
2014-05-27 15:51:16 -03:00
Dalai Felinto
65510c0bcd small cleanups 2014-05-27 12:49:15 -03:00
Dalai Felinto
0147d96aea Improved solution for Basic Camera rendering
I'm now duplicating the main camera memory instead of adding it in
bmain, same for camera datablock. This way the left and right cameras
are entirely invisible to the user.
2014-05-23 19:38:39 -03:00
Dalai Felinto
dd7469df12 Support for Basica camera rendering
Note: as of now this is creating multiple camera datablocks (and
unlinked objects) in the scene. I tried freeing them in the
render_free_stereo() routine, but it only set usercount to zero (so they
are still visible) and I get a crash when I leave Blender.
2014-05-23 15:58:11 -03:00
Dalai Felinto
edeeb7866f cleanup, using r_ for return parameters 2014-05-23 12:41:26 -03:00
Dalai Felinto
0f56e3d6ed Merge remote-tracking branch 'upstream/master' into multiview
Conflicts:
	source/blender/blenloader/intern/versioning_270.c
2014-05-23 10:20:55 -03:00
Dalai Felinto
9c2dd855ea Image Editor fixup, now ImageUser is always initialized properly, stereo
image loads right away and render images also display correctly
2014-05-23 10:10:59 -03:00
Dalai Felinto
0bfc90a317 Multiview: refactor of UV/Image editor and image flags
* showing 3d only when image is 3d and show 3d is on
* improve logic in 3dview to only handle 3d when in camera
* setting show_stereo as default mode for image editor
* image and Imageuser flags re-arranged
* image IMA_IS_STEREO flag set when opening image =)

* missing: rendered image needs to be tagged as IMA_IS_STEREO too
* also in some cases I need to force to see a different render layer to
  get everything working
2014-05-10 15:01:22 -03:00
Dalai Felinto
205afa0a06 Multiview: fix for crash when stereo was off 2014-05-10 15:01:22 -03:00
Dalai Felinto
c7bcd6310b Multiview: support cltr+click rename for non left/right views 2014-05-10 15:01:22 -03:00
Dalai Felinto
99c988ce84 Multiview Base Commit 10/10: Splash Screen
This is part of the multiview rebase from a github to git.blender.org
repository. The rebase was made based on file areas, so build is likely
broken in some of those parts, but it bulds fine in the end.

The documentation and sample files were removed and now live in:
https://github.com/dfelinto/multiview-samples

The original git history can be found in:
https://github.com/dfelinto/blender/tree/multiview-pre-b3d

Code contributors of the original branch in github:
* Alexey Akishin
* Gabriel Caraballo

Original design made in contribution with Francesco Siddi
Original branch and design partially reviewed by Brecht Van Lommel
2014-05-10 15:01:22 -03:00
Dalai Felinto
baaf31864a Multiview Base Commit 9/10: Cycles Render
This is part of the multiview rebase from a github to git.blender.org
repository. The rebase was made based on file areas, so build is likely
broken in some of those parts, but it bulds fine in the end.

The documentation and sample files were removed and now live in:
https://github.com/dfelinto/multiview-samples

The original git history can be found in:
https://github.com/dfelinto/blender/tree/multiview-pre-b3d

Code contributors of the original branch in github:
* Alexey Akishin
* Gabriel Caraballo

Original design made in contribution with Francesco Siddi
Original branch and design partially reviewed by Brecht Van Lommel
2014-05-10 15:01:22 -03:00
Dalai Felinto
a0b49f357a Multiview Base Commit 8/10: Viewport 3D (camera)
This is part of the multiview rebase from a github to git.blender.org
repository. The rebase was made based on file areas, so build is likely
broken in some of those parts, but it bulds fine in the end.

The documentation and sample files were removed and now live in:
https://github.com/dfelinto/multiview-samples

The original git history can be found in:
https://github.com/dfelinto/blender/tree/multiview-pre-b3d

Code contributors of the original branch in github:
* Alexey Akishin
* Gabriel Caraballo

Original design made in contribution with Francesco Siddi
Original branch and design partially reviewed by Brecht Van Lommel
2014-05-10 15:01:22 -03:00
Dalai Felinto
5bd7ed4298 Multiview Base Commit 7/10: Window Manager (to draw in stereo 3d)
This is part of the multiview rebase from a github to git.blender.org
repository. The rebase was made based on file areas, so build is likely
broken in some of those parts, but it bulds fine in the end.

The documentation and sample files were removed and now live in:
https://github.com/dfelinto/multiview-samples

The original git history can be found in:
https://github.com/dfelinto/blender/tree/multiview-pre-b3d

Code contributors of the original branch in github:
* Alexey Akishin
* Gabriel Caraballo

Original design made in contribution with Francesco Siddi
Original branch and design partially reviewed by Brecht Van Lommel
2014-05-10 15:01:21 -03:00
Dalai Felinto
042cf19838 Multiview Base Commit 6/10: Compositor
This is part of the multiview rebase from a github to git.blender.org
repository. The rebase was made based on file areas, so build is likely
broken in some of those parts, but it bulds fine in the end.

The documentation and sample files were removed and now live in:
https://github.com/dfelinto/multiview-samples

The original git history can be found in:
https://github.com/dfelinto/blender/tree/multiview-pre-b3d

Code contributors of the original branch in github:
* Alexey Akishin
* Gabriel Caraballo

Original design made in contribution with Francesco Siddi
Original branch and design partially reviewed by Brecht Van Lommel
2014-05-10 15:01:20 -03:00
Dalai Felinto
aef5800b8c Multiview Base Commit 5/10: User Interface (renderlayers panel and
preferences)

This is part of the multiview rebase from a github to git.blender.org
repository. The rebase was made based on file areas, so build is likely
broken in some of those parts, but it bulds fine in the end.

The documentation and sample files were removed and now live in:
https://github.com/dfelinto/multiview-samples

The original git history can be found in:
https://github.com/dfelinto/blender/tree/multiview-pre-b3d

Code contributors of the original branch in github:
* Alexey Akishin
* Gabriel Caraballo

Original design made in contribution with Francesco Siddi
Original branch and design partially reviewed by Brecht Van Lommel
2014-05-10 15:01:20 -03:00
Dalai Felinto
f4eae173c2 Multiview Base Commit 4/10: Everything else - integrating multiview in
render pipeline

This is part of the multiview rebase from a github to git.blender.org
repository. The rebase was made based on file areas, so build is likely
broken in some of those parts, but it bulds fine in the end.

The documentation and sample files were removed and now live in:
https://github.com/dfelinto/multiview-samples

The original git history can be found in:
https://github.com/dfelinto/blender/tree/multiview-pre-b3d

Code contributors of the original branch in github:
* Alexey Akishin
* Gabriel Caraballo

Original design made in contribution with Francesco Siddi
Original branch and design partially reviewed by Brecht Van Lommel
2014-05-10 15:01:20 -03:00
Dalai Felinto
63d30c704d Multiview Base Commit 3/10: OpenEXR/Imbuf - support for MultiPart EXR
This is part of the multiview rebase from a github to git.blender.org
repository. The rebase was made based on file areas, so build is likely
broken in some of those parts, but it bulds fine in the end.

The documentation and sample files were removed and now live in:
https://github.com/dfelinto/multiview-samples

The original git history can be found in:
https://github.com/dfelinto/blender/tree/multiview-pre-b3d

Code contributors of the original branch in github:
* Alexey Akishin
* Gabriel Caraballo

Original design made in contribution with Francesco Siddi
Original branch and design partially reviewed by Brecht Van Lommel
2014-05-10 15:01:20 -03:00
Dalai Felinto
04b98f6118 Multiview Base Commit 2/10: Camera
This is part of the multiview rebase from a github to git.blender.org
repository. The rebase was made based on file areas, so build is likely
broken in some of those parts, but it bulds fine in the end.

The documentation and sample files were removed and now live in:
https://github.com/dfelinto/multiview-samples

The original git history can be found in:
https://github.com/dfelinto/blender/tree/multiview-pre-b3d

Code contributors of the original branch in github:
* Alexey Akishin
* Gabriel Caraballo

Original design made in contribution with Francesco Siddi
Original branch and design partially reviewed by Brecht Van Lommel
2014-05-10 15:01:20 -03:00
Dalai Felinto
92a1b76e29 Multiview Base Commit 1/10: Image
This is part of the multiview rebase from a github to git.blender.org
repository. The rebase was made based on file areas, so build is likely
broken in some of those parts, but it bulds fine in the end.

The documentation and sample files were removed and now live in:
https://github.com/dfelinto/multiview-samples

The original git history can be found in:
https://github.com/dfelinto/blender/tree/multiview-pre-b3d

Code contributors of the original branch in github:
* Alexey Akishin
* Gabriel Caraballo

Original design made in contribution with Francesco Siddi
Original branch and design partially reviewed by Brecht Van Lommel
2014-05-10 15:01:20 -03:00
175 changed files with 11954 additions and 2202 deletions

View File

@@ -18,7 +18,7 @@
import bpy
from bpy.types import Panel, Menu, Operator
from bpy.types import Panel, Menu, Operator, UIList
class CYCLES_MT_sampling_presets(Menu):
@@ -413,6 +413,49 @@ class CyclesRender_PT_layer_passes(CyclesButtonsPanel, Panel):
col.prop(rl, "use_pass_environment")
class CyclesRender_PT_views(CyclesButtonsPanel, Panel):
bl_label = "Views"
bl_context = "render_layer"
def draw_header(self, context):
rd = context.scene.render
self.layout.prop(rd, "use_multiview", text="")
def draw(self, context):
layout = self.layout
scene = context.scene
rd = scene.render
rv = rd.views.active
layout.active = rd.use_multiview
basic_stereo = (rd.views_format == 'STEREO_3D')
row = layout.row()
row.prop(rd, "views_format", expand=True)
if basic_stereo:
row = layout.row()
row.template_list("RENDERLAYER_UL_renderviews", "name", rd, "stereo_views", rd.views, "active_index", rows=2)
row = layout.row()
row.label(text="File Suffix:")
row.prop(rv, "file_suffix", text="")
else:
row = layout.row()
row.template_list("RENDERLAYER_UL_renderviews", "name", rd, "views", rd.views, "active_index", rows=2)
col = row.column(align=True)
col.operator("scene.render_view_add", icon='ZOOMIN', text="")
col.operator("scene.render_view_remove", icon='ZOOMOUT', text="")
row = layout.row()
row.label(text="Camera Suffix:")
row.prop(rv, "camera_suffix", text="")
class Cycles_PT_post_processing(CyclesButtonsPanel, Panel):
bl_label = "Post Processing"
bl_options = {'DEFAULT_CLOSED'}
@@ -1428,6 +1471,7 @@ def get_panels():
"DATA_PT_vertex_colors",
"DATA_PT_camera",
"DATA_PT_camera_display",
"DATA_PT_camera_stereoscopy",
"DATA_PT_camera_safe_areas",
"DATA_PT_lens",
"DATA_PT_speaker",

View File

@@ -95,7 +95,7 @@ static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings b_render
bcam->full_height = render_resolution_y(b_render);
}
static float blender_camera_focal_distance(BL::Object b_ob, BL::Camera b_camera)
static float blender_camera_focal_distance(BL::RenderEngine b_engine, BL::Object b_ob, BL::Camera b_camera)
{
BL::Object b_dof_object = b_camera.dof_object();
@@ -103,14 +103,16 @@ static float blender_camera_focal_distance(BL::Object b_ob, BL::Camera b_camera)
return b_camera.dof_distance();
/* for dof object, return distance along camera Z direction */
Transform obmat = transform_clear_scale(get_transform(b_ob.matrix_world()));
BL::Array<float, 16> b_ob_matrix;
b_engine.camera_model_matrix(b_ob, b_ob_matrix);
Transform obmat = get_transform(b_ob_matrix);
Transform dofmat = get_transform(b_dof_object.matrix_world());
Transform mat = transform_inverse(obmat) * dofmat;
return fabsf(transform_get_column(&mat, 3).z);
}
static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob, bool skip_panorama = false)
static void blender_camera_from_object(BlenderCamera *bcam, BL::RenderEngine b_engine, BL::Object b_ob, bool skip_panorama = false)
{
BL::ID b_ob_data = b_ob.data();
@@ -181,10 +183,10 @@ static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob, boo
bcam->apertureblades = RNA_int_get(&ccamera, "aperture_blades");
bcam->aperturerotation = RNA_float_get(&ccamera, "aperture_rotation");
bcam->focaldistance = blender_camera_focal_distance(b_ob, b_camera);
bcam->focaldistance = blender_camera_focal_distance(b_engine, b_ob, b_camera);
bcam->aperture_ratio = RNA_float_get(&ccamera, "aperture_ratio");
bcam->shift.x = b_camera.shift_x();
bcam->shift.x = b_engine.camera_shift_x(b_ob);
bcam->shift.y = b_camera.shift_y();
bcam->sensor_width = b_camera.sensor_width();
@@ -402,8 +404,10 @@ void BlenderSync::sync_camera(BL::RenderSettings b_render, BL::Object b_override
b_ob = b_override;
if(b_ob) {
blender_camera_from_object(&bcam, b_ob);
bcam.matrix = get_transform(b_ob.matrix_world());
BL::Array<float, 16> b_ob_matrix;
blender_camera_from_object(&bcam, b_engine, b_ob);
b_engine.camera_model_matrix(b_ob, b_ob_matrix);
bcam.matrix = get_transform(b_ob_matrix);
}
/* sync */
@@ -414,8 +418,9 @@ void BlenderSync::sync_camera(BL::RenderSettings b_render, BL::Object b_override
void BlenderSync::sync_camera_motion(BL::Object b_ob, float motion_time)
{
Camera *cam = scene->camera;
Transform tfm = get_transform(b_ob.matrix_world());
BL::Array<float, 16> b_ob_matrix;
b_engine.camera_model_matrix(b_ob, b_ob_matrix);
Transform tfm = get_transform(b_ob_matrix);
tfm = blender_camera_matrix(tfm, cam->type);
if(tfm != cam->matrix) {
@@ -433,10 +438,10 @@ void BlenderSync::sync_camera_motion(BL::Object b_ob, float motion_time)
/* Sync 3D View Camera */
static void blender_camera_view_subset(BL::RenderSettings b_render, BL::Scene b_scene, BL::Object b_ob, BL::SpaceView3D b_v3d,
static void blender_camera_view_subset(BL::RenderEngine b_engine, BL::RenderSettings b_render, BL::Scene b_scene, BL::Object b_ob, BL::SpaceView3D b_v3d,
BL::RegionView3D b_rv3d, int width, int height, BoundBox2D *view_box, BoundBox2D *cam_box);
static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height, bool skip_panorama = false)
static void blender_camera_from_view(BlenderCamera *bcam, BL::RenderEngine b_engine, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height, bool skip_panorama = false)
{
/* 3d view parameters */
bcam->nearclip = b_v3d.clip_start();
@@ -449,13 +454,13 @@ static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL:
BL::Object b_ob = (b_v3d.lock_camera_and_layers())? b_scene.camera(): b_v3d.camera();
if(b_ob) {
blender_camera_from_object(bcam, b_ob, skip_panorama);
blender_camera_from_object(bcam, b_engine, b_ob, skip_panorama);
if(!skip_panorama && bcam->type == CAMERA_PANORAMA) {
/* in panorama camera view, we map viewplane to camera border */
BoundBox2D view_box, cam_box;
blender_camera_view_subset(b_scene.render(), b_scene, b_ob, b_v3d, b_rv3d, width, height,
blender_camera_view_subset(b_engine, b_scene.render(), b_scene, b_ob, b_v3d, b_rv3d, width, height,
&view_box, &cam_box);
bcam->pano_viewplane = view_box.make_relative_to(cam_box);
@@ -493,7 +498,7 @@ static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL:
bcam->matrix = transform_inverse(get_transform(b_rv3d.view_matrix()));
}
static void blender_camera_view_subset(BL::RenderSettings b_render, BL::Scene b_scene, BL::Object b_ob, BL::SpaceView3D b_v3d,
static void blender_camera_view_subset(BL::RenderEngine b_engine, BL::RenderSettings b_render, BL::Scene b_scene, BL::Object b_ob, BL::SpaceView3D b_v3d,
BL::RegionView3D b_rv3d, int width, int height, BoundBox2D *view_box, BoundBox2D *cam_box)
{
BoundBox2D cam, view;
@@ -502,7 +507,7 @@ static void blender_camera_view_subset(BL::RenderSettings b_render, BL::Scene b_
/* get viewport viewplane */
BlenderCamera view_bcam;
blender_camera_init(&view_bcam, b_render);
blender_camera_from_view(&view_bcam, b_scene, b_v3d, b_rv3d, width, height, true);
blender_camera_from_view(&view_bcam, b_engine, b_scene, b_v3d, b_rv3d, width, height, true);
blender_camera_viewplane(&view_bcam, width, height,
&view, &view_aspect, &sensor_size);
@@ -510,7 +515,7 @@ static void blender_camera_view_subset(BL::RenderSettings b_render, BL::Scene b_
/* get camera viewplane */
BlenderCamera cam_bcam;
blender_camera_init(&cam_bcam, b_render);
blender_camera_from_object(&cam_bcam, b_ob, true);
blender_camera_from_object(&cam_bcam, b_engine, b_ob, true);
blender_camera_viewplane(&cam_bcam, cam_bcam.full_width, cam_bcam.full_height,
&cam, &cam_aspect, &sensor_size);
@@ -520,7 +525,8 @@ static void blender_camera_view_subset(BL::RenderSettings b_render, BL::Scene b_
*cam_box = cam * (1.0f/cam_aspect);
}
static void blender_camera_border_subset(BL::RenderSettings b_render,
static void blender_camera_border_subset(BL::RenderEngine b_engine,
BL::RenderSettings b_render,
BL::Scene b_scene,
BL::SpaceView3D b_v3d,
BL::RegionView3D b_rv3d,
@@ -531,7 +537,7 @@ static void blender_camera_border_subset(BL::RenderSettings b_render,
{
/* Determine camera viewport subset. */
BoundBox2D view_box, cam_box;
blender_camera_view_subset(b_render, b_scene, b_ob, b_v3d, b_rv3d, width, height,
blender_camera_view_subset(b_engine, b_render, b_scene, b_ob, b_v3d, b_rv3d, width, height,
&view_box, &cam_box);
/* Determine viewport subset matching given border. */
@@ -539,7 +545,7 @@ static void blender_camera_border_subset(BL::RenderSettings b_render,
*result = cam_box.subset(border);
}
static void blender_camera_border(BlenderCamera *bcam, BL::RenderSettings b_render, BL::Scene b_scene, BL::SpaceView3D b_v3d,
static void blender_camera_border(BlenderCamera *bcam, BL::RenderEngine b_engine, BL::RenderSettings b_render, BL::Scene b_scene, BL::SpaceView3D b_v3d,
BL::RegionView3D b_rv3d, int width, int height)
{
bool is_camera_view;
@@ -568,7 +574,8 @@ static void blender_camera_border(BlenderCamera *bcam, BL::RenderSettings b_rend
/* Determine camera border inside the viewport. */
BoundBox2D full_border;
blender_camera_border_subset(b_render,
blender_camera_border_subset(b_engine,
b_render,
b_scene,
b_v3d,
b_rv3d,
@@ -587,7 +594,8 @@ static void blender_camera_border(BlenderCamera *bcam, BL::RenderSettings b_rend
bcam->border.top = b_render.border_max_y();
/* Determine viewport subset matching camera border. */
blender_camera_border_subset(b_render,
blender_camera_border_subset(b_engine,
b_render,
b_scene,
b_v3d,
b_rv3d,
@@ -602,8 +610,8 @@ void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int
{
BlenderCamera bcam;
blender_camera_init(&bcam, b_scene.render());
blender_camera_from_view(&bcam, b_scene, b_v3d, b_rv3d, width, height);
blender_camera_border(&bcam, b_scene.render(), b_scene, b_v3d, b_rv3d, width, height);
blender_camera_from_view(&bcam, b_engine, b_scene, b_v3d, b_rv3d, width, height);
blender_camera_border(&bcam, b_engine, b_scene.render(), b_scene, b_v3d, b_rv3d, width, height);
blender_camera_sync(scene->camera, &bcam, width, height);
}

View File

@@ -331,9 +331,9 @@ static ShaderEvalType get_shader_type(const string& pass_type)
return SHADER_EVAL_BAKE;
}
static BL::RenderResult begin_render_result(BL::RenderEngine b_engine, int x, int y, int w, int h, const char *layername)
static BL::RenderResult begin_render_result(BL::RenderEngine b_engine, int x, int y, int w, int h, const char *layername, const char *viewname)
{
return b_engine.begin_result(x, y, w, h, layername);
return b_engine.begin_result(x, y, w, h, layername, viewname);
}
static void end_render_result(BL::RenderEngine b_engine, BL::RenderResult b_rr, bool cancel, bool do_merge_results)
@@ -350,7 +350,7 @@ void BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_upda
int h = params.height;
/* get render result */
BL::RenderResult b_rr = begin_render_result(b_engine, x, y, w, h, b_rlay_name.c_str());
BL::RenderResult b_rr = begin_render_result(b_engine, x, y, w, h, b_rlay_name.c_str(), b_rview_name.c_str());
/* can happen if the intersected rectangle gives 0 width or height */
if(b_rr.ptr.data == NULL) {
@@ -415,13 +415,14 @@ void BlenderSession::render()
/* render each layer */
BL::RenderSettings r = b_scene.render();
BL::RenderSettings::layers_iterator b_iter;
BL::RenderSettings::layers_iterator b_layer_iter;
BL::RenderResult::views_iterator b_view_iter;
for(r.layers.begin(b_iter); b_iter != r.layers.end(); ++b_iter) {
b_rlay_name = b_iter->name();
for(r.layers.begin(b_layer_iter); b_layer_iter != r.layers.end(); ++b_layer_iter) {
b_rlay_name = b_layer_iter->name();
/* temporary render result to find needed passes */
BL::RenderResult b_rr = begin_render_result(b_engine, 0, 0, 1, 1, b_rlay_name.c_str());
/* temporary render result to find needed passes and views */
BL::RenderResult b_rr = begin_render_result(b_engine, 0, 0, 1, 1, b_rlay_name.c_str(), NULL);
BL::RenderResult::layers_iterator b_single_rlay;
b_rr.layers.begin(b_single_rlay);
@@ -456,31 +457,41 @@ void BlenderSession::render()
}
}
/* free result without merging */
end_render_result(b_engine, b_rr, true, false);
buffer_params.passes = passes;
scene->film->pass_alpha_threshold = b_iter->pass_alpha_threshold();
scene->film->pass_alpha_threshold = b_layer_iter->pass_alpha_threshold();
scene->film->tag_passes_update(scene, passes);
scene->film->tag_update(scene);
scene->integrator->tag_update(scene);
/* update scene */
sync->sync_camera(b_render, b_engine.camera_override(), width, height);
sync->sync_data(b_v3d, b_engine.camera_override(), &python_thread_state, b_rlay_name.c_str());
for(b_rr.views.begin(b_view_iter); b_view_iter != b_rr.views.end(); ++b_view_iter) {
b_rview_name = b_view_iter->name();
/* update number of samples per layer */
int samples = sync->get_layer_samples();
bool bound_samples = sync->get_layer_bound_samples();
/* set the current view */
b_engine.active_view_set(b_rview_name.c_str());
if(samples != 0 && (!bound_samples || (samples < session_params.samples)))
session->reset(buffer_params, samples);
else
session->reset(buffer_params, session_params.samples);
/* update scene */
sync->sync_camera(b_render, b_engine.camera_override(), width, height);
sync->sync_data(b_v3d, b_engine.camera_override(), &python_thread_state, b_rlay_name.c_str());
/* render */
session->start();
session->wait();
/* update number of samples per layer */
int samples = sync->get_layer_samples();
bool bound_samples = sync->get_layer_bound_samples();
if(samples != 0 && (!bound_samples || (samples < session_params.samples)))
session->reset(buffer_params, samples);
else
session->reset(buffer_params, session_params.samples);
/* render */
session->start();
session->wait();
if(session->progress.get_cancel())
break;
}
/* free result without merging */
end_render_result(b_engine, b_rr, true, false);
if(session->progress.get_cancel())
break;
@@ -619,10 +630,12 @@ void BlenderSession::do_write_update_render_result(BL::RenderResult b_rr, BL::Re
b_pass.rect(&pixels[0]);
}
}
/* copy combined pass */
if(buffers->get_pass_rect(PASS_COMBINED, exposure, rtile.sample, 4, &pixels[0]))
b_rlay.rect(&pixels[0]);
else {
/* copy combined pass */
BL::RenderPass b_combined_pass(b_rlay.passes.find_by_type(BL::RenderPass::type_COMBINED, b_rview_name.c_str()));
if(buffers->get_pass_rect(PASS_COMBINED, exposure, rtile.sample, 4, &pixels[0]))
b_combined_pass.rect(&pixels[0]);
}
/* tag result as updated */
b_engine.update_result(b_rr);
@@ -841,6 +854,9 @@ void BlenderSession::update_status_progress()
scene += " | " + b_scene.name();
if(b_rlay_name != "")
scene += ", " + b_rlay_name;
if(b_rview_name != "")
scene += ", " + b_rview_name;
}
else {
BLI_timestr(total_time, time_str, sizeof(time_str));

View File

@@ -90,6 +90,7 @@ public:
BL::SpaceView3D b_v3d;
BL::RegionView3D b_rv3d;
string b_rlay_name;
string b_rview_name;
string last_status;
string last_error;

View File

@@ -135,6 +135,35 @@ class DATA_PT_lens(CameraButtonsPanel, Panel):
col.prop(cam, "clip_end", text="End")
class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel):
bl_label = "Stereoscopy"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@classmethod
def poll(cls, context):
render = context.scene.render
return (super().poll(context) and render.use_multiview \
and render.views_format == 'STEREO_3D')
def draw(self, context):
layout = self.layout
render = context.scene.render
st = context.camera.stereo
col = layout.column()
col.row().prop(st, "convergence_mode", expand=True)
if st.convergence_mode == 'PARALLEL':
col.prop(st, "viewport_convergence")
else:
col.prop(st, "convergence_distance")
col.prop(st, "interocular_distance")
col.label(text="Pivot:")
col.row().prop(st, "pivot", expand=True)
class DATA_PT_camera(CameraButtonsPanel, Panel):
bl_label = "Camera"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}

View File

@@ -404,6 +404,8 @@ class RENDER_PT_output(RenderButtonsPanel, Panel):
col.prop(rd, "use_render_cache")
layout.template_image_settings(image_settings, color_management=False)
if rd.use_multiview:
layout.template_image_views(image_settings)
if file_format == 'QUICKTIME':
quicktime = rd.quicktime

View File

@@ -167,5 +167,63 @@ class RENDERLAYER_PT_layer_passes(RenderLayerButtonsPanel, Panel):
self.draw_pass_type_buttons(col, rl, "refraction")
class RENDERLAYER_UL_renderviews(UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# assert(isinstance(item, bpy.types.SceneRenderView)
view = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
if view.name in {'left', 'right'}:
layout.label(view.name, icon_value=icon + (not view.use))
else:
layout.prop(view, "name", text="", index=index, icon_value=icon, emboss=False)
layout.prop(view, "use", text="", index=index)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label("", icon_value=icon + (not view.use))
class RENDERLAYER_PT_views(RenderLayerButtonsPanel, Panel):
bl_label = "Views"
COMPAT_ENGINES = {'BLENDER_RENDER'}
def draw_header(self, context):
rd = context.scene.render
self.layout.prop(rd, "use_multiview", text="")
def draw(self, context):
layout = self.layout
scene = context.scene
rd = scene.render
rv = rd.views.active
layout.active = rd.use_multiview
basic_stereo = rd.views_format == 'STEREO_3D'
row = layout.row()
row.prop(rd, "views_format", expand=True)
if basic_stereo:
row = layout.row()
row.template_list("RENDERLAYER_UL_renderviews", "name", rd, "stereo_views", rd.views, "active_index", rows=2)
row = layout.row()
row.label(text="File Suffix:")
row.prop(rv, "file_suffix", text="")
else:
row = layout.row()
row.template_list("RENDERLAYER_UL_renderviews", "name", rd, "views", rd.views, "active_index", rows=2)
col = row.column(align=True)
col.operator("scene.render_view_add", icon='ZOOMIN', text="")
col.operator("scene.render_view_remove", icon='ZOOMOUT', text="")
row = layout.row()
row.label(text="Camera Suffix:")
row.prop(rv, "camera_suffix", text="")
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)

View File

@@ -458,6 +458,10 @@ class IMAGE_HT_header(Header):
layout.prop_search(mesh.uv_textures, "active", mesh, "uv_textures", text="")
if ima:
if ima.is_stereo_3d:
row = layout.row()
row.prop(sima, "show_stereo_3d", text="")
# layers
layout.template_image_layers(ima, iuser)

View File

@@ -282,6 +282,10 @@ class INFO_MT_window(Menu):
layout.separator()
layout.operator("wm.console_toggle", icon='CONSOLE')
if context.scene.render.use_multiview:
layout.separator()
layout.operator("wm.set_stereo_3d", icon='CAMERA_STEREO')
class INFO_MT_help(Menu):
bl_label = "Help"

View File

@@ -659,6 +659,7 @@ class SEQUENCER_PT_input(SequencerButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
scene = context.scene
strip = act_strip(context)
@@ -672,7 +673,7 @@ class SEQUENCER_PT_input(SequencerButtonsPanel, Panel):
# Current element for the filename
elem = strip.strip_elem_from_frame(context.scene.frame_current)
elem = strip.strip_elem_from_frame(scene.frame_current)
if elem:
split = layout.split(percentage=0.2)
split.label(text="File:")
@@ -718,6 +719,19 @@ class SEQUENCER_PT_input(SequencerButtonsPanel, Panel):
col.prop(strip, "frame_offset_start", text="Start")
col.prop(strip, "frame_offset_end", text="End")
if scene.render.use_multiview and seq_type in {'IMAGE', 'MOVIE'}:
layout.prop(strip, "use_multiview")
col = layout.column()
col.active = strip.use_multiview
col.label(text="Views Format:")
col.row().prop(strip, "views_format", expand=True)
box = col.box()
box.active = strip.views_format == 'STEREO_3D'
box.template_image_stereo_3d(strip.stereo_3d_format)
class SEQUENCER_PT_sound(SequencerButtonsPanel, Panel):
bl_label = "Sound"

View File

@@ -2936,16 +2936,50 @@ class VIEW3D_PT_view3d_display(Panel):
row.prop(region, "use_box_clip")
class VIEW3D_PT_view3d_shading(Panel):
class VIEW3D_PT_view3d_stereo(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_label = "Shading"
bl_label = "Stereoscopy"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
scene = context.scene
multiview = scene.render.use_multiview
return context.space_data and multiview
def draw(self, context):
layout = self.layout
view = context.space_data
return (view)
basic_stereo = context.scene.render.views_format == 'STEREO_3D'
col = layout.column()
col.row().prop(view, "stereo_3d_camera", expand=True)
col.label(text="Display:")
row = col.row()
row.active = basic_stereo
row.prop(view, "show_stereo_3d_cameras")
row = col.row()
row.active = basic_stereo
split = row.split()
split.prop(view, "show_stereo_3d_convergence_plane")
split = row.split()
split.prop(view, "stereo_3d_convergence_plane_alpha", text="Alpha")
split.active = view.show_stereo_3d_convergence_plane
row = col.row()
split = row.split()
split.prop(view, "show_stereo_3d_volume")
split = row.split()
split.prop(view, "stereo_3d_volume_alpha", text="Alpha")
class VIEW3D_PT_view3d_shading(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_label = "Shading"
def draw(self, context):
layout = self.layout

View File

@@ -328,6 +328,7 @@ compositor_node_categories = [
NodeItem("CompositorNodeCombYUVA"),
NodeItem("CompositorNodeSepYCCA"),
NodeItem("CompositorNodeCombYCCA"),
NodeItem("CompositorNodeSwitchView"),
]),
CompositorNodeCategory("CMP_OP_FILTER", "Filter", items=[
NodeItem("CompositorNodeBlur"),

View File

@@ -42,7 +42,7 @@ extern "C" {
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
#define BLENDER_VERSION 274
#define BLENDER_SUBVERSION 3
#define BLENDER_SUBVERSION 4
/* Several breakages with 270, e.g. constraint deg vs rad */
#define BLENDER_MINVERSION 270
#define BLENDER_MINSUBVERSION 5

View File

@@ -136,6 +136,14 @@ bool BKE_camera_view_frame_fit_to_coords(
void BKE_camera_to_gpu_dof(struct Object *camera, struct GPUFXSettings *r_fx_settings);
/* Camera multi-view API */
struct Object *BKE_camera_multiview_render(struct Scene *scene, struct Object *camera, const char *viewname);
void BKE_camera_multiview_view_matrix(struct RenderData *rd, struct Object *camera, const bool is_left, float r_viewmat[4][4]);
void BKE_camera_multiview_model_matrix(struct RenderData *rd, struct Object *camera, const char *viewname, float r_modelmat[4][4]);
float BKE_camera_multiview_shift_x(struct RenderData *rd, struct Object *camera, const char *viewname);
void BKE_camera_multiview_params(struct RenderData *rd, struct CameraParams *params, struct Object *camera, const char *viewname);
#ifdef __cplusplus
}
#endif

View File

@@ -45,34 +45,34 @@ struct Object;
struct ImageFormatData;
struct ImagePool;
struct Main;
struct ReportList;
#define IMA_MAX_SPACE 64
void BKE_images_init(void);
void BKE_images_exit(void);
void BKE_image_free_packedfiles(struct Image *image);
void BKE_image_free_views(struct Image *image);
void BKE_image_free_buffers(struct Image *image);
/* call from library */
void BKE_image_free(struct Image *image);
void BKE_imbuf_stamp_info(struct Scene *scene, struct Object *camera, struct ImBuf *ibuf);
void BKE_image_stamp_buf(
struct Scene *scene, struct Object *camera,
unsigned char *rect, float *rectf, int width, int height, int channels);
void BKE_image_stamp_buf(struct Scene *scene, struct Object *camera, unsigned char *rect, float *rectf, int width, int height, int channels);
bool BKE_imbuf_alpha_test(struct ImBuf *ibuf);
int BKE_imbuf_write_stamp(struct Scene *scene, struct Object *camera, struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf);
void BKE_imbuf_write_prepare(struct ImBuf *ibuf, struct ImageFormatData *imf);
int BKE_imbuf_write(struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf);
int BKE_imbuf_write_as(struct ImBuf *ibuf, const char *name, struct ImageFormatData *imf, const bool is_copy);
void BKE_image_path_from_imformat(
char *string, const char *base, const char *relbase, int frame,
const struct ImageFormatData *im_format, const bool use_ext, const bool use_frames);
const struct ImageFormatData *im_format, const bool use_ext, const bool use_frames, const char *suffix);
void BKE_image_path_from_imtype(
char *string, const char *base, const char *relbase, int frame,
const char imtype, const bool use_ext, const bool use_frames);
bool BKE_image_path_ensure_ext_from_imformat(char *string, const struct ImageFormatData *im_format);
bool BKE_image_path_ensure_ext_from_imtype(char *string, const char imtype);
const char imtype, const bool use_ext, const bool use_frames, const char *suffix);
int BKE_image_path_ensure_ext_from_imformat(char *string, const struct ImageFormatData *im_format);
int BKE_image_path_ensure_ext_from_imtype(char *string, const char imtype);
char BKE_image_ftype_to_imtype(const int ftype);
int BKE_image_imtype_to_ftype(const char imtype);
@@ -103,6 +103,7 @@ void BKE_image_tag_time(struct Image *ima);
/* ImageUser is in Texture, in Nodes, Background Image, Image Window, .... */
/* should be used in conjunction with an ID * to Image. */
struct ImageUser;
struct RenderData;
struct RenderPass;
struct RenderResult;
@@ -172,11 +173,12 @@ struct Image *BKE_image_load_exists(const char *filepath);
/* adds image, adds ibuf, generates color or pattern */
struct Image *BKE_image_add_generated(
struct Main *bmain, unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, const float color[4]);
struct Main *bmain, unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, const float color[4], const bool stereo3d);
/* adds image from imbuf, owns imbuf */
struct Image *BKE_image_add_from_imbuf(struct ImBuf *ibuf);
/* for reload, refresh, pack */
void BKE_image_init_imageuser(struct Image *ima, struct ImageUser *iuser);
void BKE_image_signal(struct Image *ima, struct ImageUser *iuser, int signal);
void BKE_image_walk_all_users(const struct Main *mainp, void *customdata,
@@ -184,6 +186,8 @@ void BKE_image_walk_all_users(const struct Main *mainp, void *customdata,
/* ensures an Image exists for viewing nodes or render */
struct Image *BKE_image_verify_viewer(int type, const char *name);
/* ensures the view node cache is compatible with the scene views */
void BKE_image_verify_viewer_views(const struct RenderData *rd, struct Image *ima, struct ImageUser *iuser);
/* called on frame change or before render */
void BKE_image_user_frame_calc(struct ImageUser *iuser, int cfra, int fieldnr);
@@ -195,13 +199,23 @@ void BKE_image_update_frame(const struct Main *bmain, int cfra);
/* sets index offset for multilayer files */
struct RenderPass *BKE_image_multilayer_index(struct RenderResult *rr, struct ImageUser *iuser);
/* sets index offset for multiview files */
void BKE_image_multiview_index(struct Image *ima, struct ImageUser *iuser);
/* for multilayer images as well as for render-viewer */
bool BKE_image_is_multilayer(struct Image *ima);
struct RenderResult *BKE_image_acquire_renderresult(struct Scene *scene, struct Image *ima);
void BKE_image_release_renderresult(struct Scene *scene, struct Image *ima);
/* for multilayer images as well as for singlelayer */
bool BKE_image_is_openexr(struct Image *ima);
/* for multiple slot render, call this before render */
void BKE_image_backup_render(struct Scene *scene, struct Image *ima);
/* for singlelayer openexr saving */
bool BKE_image_save_openexr_multiview(struct Image *ima, struct ImBuf *ibuf, const char *filepath, const int flags);
/* goes over all textures that use images */
void BKE_image_free_all_textures(void);
@@ -212,6 +226,7 @@ void BKE_image_free_anim_ibufs(struct Image *ima, int except_frame);
void BKE_image_all_free_anim_ibufs(int except_frame);
void BKE_image_memorypack(struct Image *ima);
void BKE_image_packfiles(struct ReportList *reports, struct Image *ima, const char *basepath);
/* prints memory statistics for images */
void BKE_image_print_memlist(void);
@@ -243,7 +258,8 @@ float *BKE_image_get_float_pixels_for_frame(struct Image *image, int frame);
/* Guess offset for the first frame in the sequence */
int BKE_image_sequence_guess_offset(struct Image *image);
bool BKE_image_has_anim(struct Image *image);
bool BKE_image_has_packedfile(struct Image *image);
bool BKE_image_is_animated(struct Image *image);
bool BKE_image_is_dirty(struct Image *image);
void BKE_image_file_format_set(struct Image *image, int ftype);

View File

@@ -941,6 +941,7 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMateria
#define CMP_NODE_MAP_RANGE 319
#define CMP_NODE_PLANETRACKDEFORM 320
#define CMP_NODE_CORNERPIN 321
#define CMP_NODE_SWITCH_VIEW 322
/* channel toggles */
#define CMP_CHAN_RGB 1
@@ -975,7 +976,8 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMateria
/* API */
void ntreeCompositExecTree(struct Scene *scene, struct bNodeTree *ntree, struct RenderData *rd, int rendering, int do_previews,
const struct ColorManagedViewSettings *view_settings, const struct ColorManagedDisplaySettings *display_settings);
const struct ColorManagedViewSettings *view_settings, const struct ColorManagedDisplaySettings *display_settings,
const char *view_name);
void ntreeCompositTagRender(struct Scene *sce);
int ntreeCompositTagAnimated(struct bNodeTree *ntree);
void ntreeCompositTagGenerators(struct bNodeTree *ntree);

View File

@@ -70,6 +70,7 @@ void BKE_scene_free(struct Scene *sce);
struct Scene *BKE_scene_add(struct Main *bmain, const char *name);
/* base functions */
struct Base *BKE_scene_base_find_by_name(struct Scene *scene, const char *name);
struct Base *BKE_scene_base_find(struct Scene *scene, struct Object *ob);
struct Base *BKE_scene_base_add(struct Scene *sce, struct Object *ob);
void BKE_scene_base_unlink(struct Scene *sce, struct Base *base);
@@ -122,6 +123,9 @@ void BKE_scene_update_for_newframe_ex(struct EvaluationContext *eval_ctx, struct
struct SceneRenderLayer *BKE_scene_add_render_layer(struct Scene *sce, const char *name);
bool BKE_scene_remove_render_layer(struct Main *main, struct Scene *scene, struct SceneRenderLayer *srl);
struct SceneRenderView *BKE_scene_add_render_view(struct Scene *sce, const char *name);
bool BKE_scene_remove_render_view(struct Scene *scene, struct SceneRenderView *srv);
/* render profile */
int get_render_subsurf_level(const struct RenderData *r, int level);
int get_render_child_particle_number(const struct RenderData *r, int num);
@@ -142,6 +146,23 @@ int BKE_render_num_threads(const struct RenderData *r);
double BKE_scene_unit_scale(const struct UnitSettings *unit, const int unit_type, double value);
/* multiview */
bool BKE_scene_multiview_is_stereo3d(const struct RenderData *rd);
bool BKE_scene_multiview_is_render_view_active(const struct RenderData *rd, const struct SceneRenderView *srv);
bool BKE_scene_multiview_is_render_view_first(const struct RenderData *rd, const char *viewname);
bool BKE_scene_multiview_is_render_view_last(const struct RenderData *rd, const char *viewname);
size_t BKE_scene_multiview_num_views_get(const struct RenderData *rd);
struct SceneRenderView *BKE_scene_multiview_render_view_findindex(const struct RenderData *rd, const int view_id);
const char *BKE_scene_multiview_render_view_name_get(const struct RenderData *rd, const int view_id);
size_t BKE_scene_multiview_view_id_get(const struct RenderData *rd, const char *viewname);
void BKE_scene_multiview_filepath_get(struct SceneRenderView *srv, const char *filepath, char *r_filepath);
void BKE_scene_multiview_view_filepath_get(const struct RenderData *rd, const char *filepath, const char *view, char *r_filepath);
const char *BKE_scene_multiview_view_suffix_get(const struct RenderData *rd, const char *viewname);
const char *BKE_scene_multiview_view_id_suffix_get(const struct RenderData *rd, const size_t view_id);
void BKE_scene_multiview_view_prefix_get(struct Scene *scene, const char *name, char *rprefix, char **rext);
void BKE_scene_multiview_videos_dimensions_get(const struct RenderData *rd, const size_t width, const size_t height, size_t *r_width, size_t *r_height);
size_t BKE_scene_multiview_num_videos_get(const struct RenderData *rd);
#ifdef __cplusplus
}
#endif

View File

@@ -41,6 +41,7 @@ struct Mask;
struct Scene;
struct Sequence;
struct SequenceModifierData;
struct Stereo3dFormat;
struct StripElem;
struct bSound;
@@ -99,6 +100,7 @@ typedef struct SeqRenderData {
float motion_blur_shutter;
bool skip_cache;
bool is_proxy_render;
size_t view_id;
} SeqRenderData;
void BKE_sequencer_new_render_data(
@@ -223,6 +225,7 @@ void BKE_sequencer_base_clipboard_pointers_store(struct ListBase *seqbase);
void BKE_sequencer_base_clipboard_pointers_restore(struct ListBase *seqbase, struct Main *bmain);
void BKE_sequence_free(struct Scene *scene, struct Sequence *seq);
void BKE_sequence_free_anim(struct Sequence *seq);
const char *BKE_sequence_give_name(struct Sequence *seq);
void BKE_sequence_calc(struct Scene *scene, struct Sequence *seq);
void BKE_sequence_calc_disp(struct Scene *scene, struct Sequence *seq);
@@ -235,7 +238,7 @@ struct StripElem *BKE_sequencer_give_stripelem(struct Sequence *seq, int cfra);
void BKE_sequencer_update_changed_seq_and_deps(struct Scene *scene, struct Sequence *changed_seq, int len_change, int ibuf_change);
bool BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context, struct Sequence *seq, float cfra);
struct SeqIndexBuildContext *BKE_sequencer_proxy_rebuild_context(struct Main *bmain, struct Scene *scene, struct Sequence *seq, struct GSet *file_list);
void BKE_sequencer_proxy_rebuild_context(struct Main *bmain, struct Scene *scene, struct Sequence *seq, struct GSet *file_list, ListBase *queue);
void BKE_sequencer_proxy_rebuild(struct SeqIndexBuildContext *context, short *stop, short *do_update, float *progress);
void BKE_sequencer_proxy_rebuild_finish(struct SeqIndexBuildContext *context, bool stop);
@@ -355,6 +358,10 @@ typedef struct SeqLoadInfo {
int len; /* only for image strips */
char path[1024]; /* 1024 = FILE_MAX */
/* multiview */
char views_format;
struct Stereo3dFormat *stereo3d_format;
/* return values */
char name[64];
struct Sequence *seq_sound; /* for movie's */
@@ -399,7 +406,7 @@ struct Sequence *BKE_sequencer_add_sound_strip(struct bContext *C, ListBase *seq
struct Sequence *BKE_sequencer_add_movie_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load);
/* view3d draw callback, run when not in background view */
typedef struct ImBuf *(*SequencerDrawView)(struct Scene *, struct Object *, int, int, unsigned int, int, bool, bool, bool, int, char[256]);
typedef struct ImBuf *(*SequencerDrawView)(struct Scene *, struct Object *, int, int, unsigned int, int, bool, bool, bool, int, const char *, char[256]);
extern SequencerDrawView sequencer_view3d_cb;
/* copy/paste */

View File

@@ -43,16 +43,20 @@ struct ReportList;
struct Scene;
typedef struct bMovieHandle {
int (*start_movie)(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports, bool preview);
int (*append_movie)(struct RenderData *rd, int start_frame, int frame, int *pixels,
int rectx, int recty, struct ReportList *reports);
void (*end_movie)(void);
int (*get_next_frame)(struct RenderData *rd, struct ReportList *reports); /* optional */
void (*get_movie_path)(char *string, struct RenderData *rd, bool preview); /* optional */
int (*start_movie)(void *context_v, struct Scene *scene, struct RenderData *rd, int rectx, int recty,
struct ReportList *reports, bool preview, const char *suffix);
int (*append_movie)(void *context_v, struct RenderData *rd, int start_frame, int frame, int *pixels,
int rectx, int recty, const char *suffix, struct ReportList *reports);
void (*end_movie)(void *context_v);
int (*get_next_frame)(void *context_v, struct RenderData *rd, struct ReportList *reports); /* optional */
void (*get_movie_path)(char *string, struct RenderData *rd, bool preview, const char *suffix); /* optional */
void *(*context_create)(void);
void (*context_free)(void *context_v);
} bMovieHandle;
bMovieHandle *BKE_movie_handle_get(const char imtype);
void BKE_movie_filepath_get(char *string, struct RenderData *rd, bool preview);
void BKE_movie_filepath_get(char *string, struct RenderData *rd, bool preview, const char *suffix);
void BKE_context_create(bMovieHandle *mh);
#ifdef __cplusplus
}

View File

@@ -68,11 +68,11 @@ struct RenderData;
struct ReportList;
struct Scene;
int BKE_ffmpeg_start(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports, bool preview);
void BKE_ffmpeg_end(void);
int BKE_ffmpeg_append(struct RenderData *rd, int start_frame, int frame, int *pixels,
int rectx, int recty, struct ReportList *reports);
void BKE_ffmpeg_filepath_get(char *string, struct RenderData *rd, bool preview);
int BKE_ffmpeg_start(void *context_v, struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports, bool preview, const char *suffix);
void BKE_ffmpeg_end(void *context_v);
int BKE_ffmpeg_append(void *context_v, struct RenderData *rd, int start_frame, int frame, int *pixels,
int rectx, int recty, const char *suffix, struct ReportList *reports);
void BKE_ffmpeg_filepath_get(char *string, struct RenderData *rd, bool preview, const char *suffix);
void BKE_ffmpeg_preset_set(struct RenderData *rd, int preset);
void BKE_ffmpeg_image_type_verify(struct RenderData *rd, struct ImageFormatData *imf);
@@ -82,6 +82,9 @@ bool BKE_ffmpeg_alpha_channel_is_supported(struct RenderData *rd);
int BKE_ffmpeg_property_add_string(struct RenderData *rd, const char *type, const char *str);
void BKE_ffmpeg_property_del(struct RenderData *rd, void *type, void *prop_);
void *BKE_ffmpeg_context_create(void);
void BKE_ffmpeg_context_free(void *context_v);
#ifdef __cplusplus
}
#endif

View File

@@ -40,11 +40,14 @@ struct RenderData;
struct ReportList;
struct Scene;
int BKE_frameserver_start(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports, bool preview);
void BKE_frameserver_end(void);
int BKE_frameserver_append(struct RenderData *rd, int start_frame, int frame, int *pixels,
int rectx, int recty, struct ReportList *reports);
int BKE_frameserver_loop(struct RenderData *rd, struct ReportList *reports);
int BKE_frameserver_start(void *context_v, struct Scene *scene, struct RenderData *rd, int rectx, int recty,
struct ReportList *reports, bool preview, const char *suffix);
void BKE_frameserver_end(void *context_v);
int BKE_frameserver_append(void *context_v, struct RenderData *rd, int start_frame, int frame, int *pixels,
int rectx, int recty, const char*suffix, struct ReportList *reports);
int BKE_frameserver_loop(void *context_v, struct RenderData *rd, struct ReportList *reports);
void *BKE_frameserver_context_create(void);
void BKE_frameserver_context_free(void *context_v);
#ifdef __cplusplus
}

View File

@@ -423,10 +423,10 @@ void BKE_bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int
{
Image *ima;
ima = (Image *)id;
if (ima->packedfile == NULL || (flag & BKE_BPATH_TRAVERSE_SKIP_PACKED) == 0) {
if (BKE_image_has_packedfile(ima) == false || (flag & BKE_BPATH_TRAVERSE_SKIP_PACKED) == 0) {
if (ELEM(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
if (rewrite_path_fixed(ima->name, visit_cb, absbase, bpath_user_data)) {
if (!ima->packedfile) {
if (!BKE_image_has_packedfile(ima)) {
BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD);
BKE_image_walk_all_users(bmain, ima, bpath_traverse_image_user_cb);
}

View File

@@ -30,16 +30,19 @@
*/
#include <stdlib.h>
#include <stddef.h>
#include "DNA_camera_types.h"
#include "DNA_lamp_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_view3d_types.h"
#include "DNA_ID.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLI_rect.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BKE_animsys.h"
#include "BKE_camera.h"
@@ -47,6 +50,7 @@
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "GPU_compositing.h"
@@ -71,6 +75,10 @@ void *BKE_camera_add(Main *bmain, const char *name)
GPU_fx_compositor_init_dof_settings(&cam->gpu_dof);
/* stereoscopy 3d */
cam->stereo.interocular_distance = 0.065f;
cam->stereo.convergence_distance = 30.f * 0.065f;
return cam;
}
@@ -695,6 +703,250 @@ bool BKE_camera_view_frame_fit_to_coords(
return camera_frame_fit_calc_from_data(&params, &data_cb, r_co, r_scale);
}
/******************* multiview matrix functions ***********************/
static void camera_model_matrix(Object *camera, float r_modelmat[4][4])
{
copy_m4_m4(r_modelmat, camera->obmat);
}
static void camera_stereo3d_model_matrix(Object *camera, const bool is_left, float r_modelmat[4][4])
{
Camera *data = (Camera *)camera->data;
float interocular_distance, convergence_distance;
short convergence_mode, pivot;
float sizemat[4][4];
float fac = 1.0f;
float fac_signed;
interocular_distance = data->stereo.interocular_distance;
convergence_distance = data->stereo.convergence_distance;
convergence_mode = data->stereo.convergence_mode;
pivot = data->stereo.pivot;
if (((pivot == CAM_S3D_PIVOT_LEFT) && is_left) ||
((pivot == CAM_S3D_PIVOT_RIGHT) && !is_left))
{
return camera_model_matrix(camera, r_modelmat);
}
else {
float size[3];
mat4_to_size(size, camera->obmat);
size_to_mat4(sizemat, size);
}
if (pivot == CAM_S3D_PIVOT_CENTER)
fac = 0.5f;
fac_signed = is_left ? fac : -fac;
/* rotation */
if (convergence_mode == CAM_S3D_TOE) {
float angle;
float angle_sin, angle_cos;
float toeinmat[4][4];
float rotmat[4][4];
unit_m4(rotmat);
if (pivot == CAM_S3D_PIVOT_CENTER) {
fac = -fac;
fac_signed = -fac_signed;
}
angle = atanf((interocular_distance * 0.5f) / convergence_distance) / fac;
angle_cos = cosf(angle * fac_signed);
angle_sin = sinf(angle * fac_signed);
rotmat[0][0] = angle_cos;
rotmat[2][0] = -angle_sin;
rotmat[0][2] = angle_sin;
rotmat[2][2] = angle_cos;
if (pivot == CAM_S3D_PIVOT_CENTER) {
/* set the rotation */
copy_m4_m4(toeinmat, rotmat);
/* set the translation */
toeinmat[3][0] = interocular_distance * fac_signed;
/* transform */
normalize_m4_m4(r_modelmat, camera->obmat);
mul_m4_m4m4(r_modelmat, r_modelmat, toeinmat);
/* scale back to the original size */
mul_m4_m4m4(r_modelmat, r_modelmat, sizemat);
}
else { /* CAM_S3D_PIVOT_LEFT, CAM_S3D_PIVOT_RIGHT */
/* rotate perpendicular to the interocular line */
normalize_m4_m4(r_modelmat, camera->obmat);
mul_m4_m4m4(r_modelmat, r_modelmat, rotmat);
/* translate along the interocular line */
unit_m4(toeinmat);
toeinmat[3][0] = -interocular_distance * fac_signed;
mul_m4_m4m4(r_modelmat, r_modelmat, toeinmat);
/* rotate to toe-in angle */
mul_m4_m4m4(r_modelmat, r_modelmat, rotmat);
/* scale back to the original size */
mul_m4_m4m4(r_modelmat, r_modelmat, sizemat);
}
}
else {
normalize_m4_m4(r_modelmat, camera->obmat);
/* translate - no rotation in CAM_S3D_OFFAXIS, CAM_S3D_PARALLEL */
translate_m4(r_modelmat, -interocular_distance * fac_signed, 0.0f, 0.0f);
/* scale back to the original size */
mul_m4_m4m4(r_modelmat, r_modelmat, sizemat);
}
}
/* the view matrix is used by the viewport drawing, it is basically the inverted model matrix */
void BKE_camera_multiview_view_matrix(RenderData *rd, Object *camera, const bool is_left, float r_viewmat[4][4])
{
BKE_camera_multiview_model_matrix(rd, camera, is_left ? STEREO_LEFT_NAME : STEREO_RIGHT_NAME, r_viewmat);
invert_m4(r_viewmat);
}
/* left is the default */
static bool camera_is_left(const char *viewname)
{
if (viewname && viewname[0] != '\0') {
return !STREQ(viewname, STEREO_RIGHT_NAME);
}
return true;
}
void BKE_camera_multiview_model_matrix(RenderData *rd, Object *camera, const char *viewname, float r_modelmat[4][4])
{
const bool is_multiview = (rd && rd->scemode & R_MULTIVIEW) != 0;
if (!is_multiview) {
camera_model_matrix(camera, r_modelmat);
}
else if (rd->views_format == SCE_VIEWS_FORMAT_MULTIVIEW) {
camera_model_matrix(camera, r_modelmat);
}
else { /* SCE_VIEWS_SETUP_BASIC */
const bool is_left = camera_is_left(viewname);
camera_stereo3d_model_matrix(camera, is_left, r_modelmat);
}
normalize_m4(r_modelmat);
}
static Object *camera_multiview_advanced(Scene *scene, Object *camera, const char *suffix)
{
SceneRenderView *srv;
char name[MAX_NAME];
const char *camera_name = camera->id.name + 2;
const int len_name = strlen(camera_name);
name[0] = '\0';
for (srv = scene->r.views.first; srv; srv = srv->next) {
const int len_suffix = strlen(srv->suffix);
if (len_name < len_suffix)
continue;
if (STREQ(camera_name + (len_name - len_suffix), srv->suffix)) {
BLI_snprintf(name, sizeof(name), "%.*s%s", (len_name - len_suffix), camera_name, suffix);
break;
}
}
if (name[0] != '\0') {
Base *base = BKE_scene_base_find_by_name(scene, name);
if (base) {
return base->object;
}
}
return camera;
}
/* returns the camera to be used for render */
Object *BKE_camera_multiview_render(Scene *scene, Object *camera, const char *viewname)
{
const bool is_multiview = (scene->r.scemode & R_MULTIVIEW) != 0;
if (!is_multiview) {
return camera;
}
else if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
return camera;
}
else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
const char *suffix = BKE_scene_multiview_view_suffix_get(&scene->r, viewname);
return camera_multiview_advanced(scene, camera, suffix);
}
}
static float camera_stereo3d_shift_x(Object *camera, const char *viewname)
{
Camera *data = camera->data;
float shift = data->shiftx;
float interocular_distance, convergence_distance;
short convergence_mode, pivot;
bool is_left = true;
float fac = 1.0f;
float fac_signed;
if (viewname && viewname[0]) {
is_left = STREQ(viewname, STEREO_LEFT_NAME);
}
interocular_distance = data->stereo.interocular_distance;
convergence_distance = data->stereo.convergence_distance;
convergence_mode = data->stereo.convergence_mode;
pivot = data->stereo.pivot;
if (((pivot == CAM_S3D_PIVOT_LEFT) && is_left) ||
((pivot == CAM_S3D_PIVOT_RIGHT) && !is_left))
{
return shift;
}
if (pivot == CAM_S3D_PIVOT_CENTER)
fac = 0.5f;
fac_signed = is_left ? fac : -fac;
/* Note: in viewport, parallel renders as offaxis, but in render it does parallel */
if (ELEM(convergence_mode, CAM_S3D_OFFAXIS, CAM_S3D_PARALLEL)) {
shift += ((interocular_distance / data->sensor_x) * (data->lens / convergence_distance)) * fac_signed;
}
return shift;
}
float BKE_camera_multiview_shift_x(RenderData *rd, Object *camera, const char *viewname)
{
const bool is_multiview = (rd && rd->scemode & R_MULTIVIEW) != 0;
Camera *data = camera->data;
if (!is_multiview) {
return data->shiftx;
}
else if (rd->views_format == SCE_VIEWS_FORMAT_MULTIVIEW) {
return data->shiftx;
}
else { /* SCE_VIEWS_SETUP_BASIC */
return camera_stereo3d_shift_x(camera, viewname);
}
}
void BKE_camera_multiview_params(RenderData *rd, CameraParams *params, Object *camera, const char *viewname)
{
params->shiftx = BKE_camera_multiview_shift_x(rd, camera, viewname);
}
void BKE_camera_to_gpu_dof(struct Object *camera, struct GPUFXSettings *r_fx_settings)
{
if (camera->type == OB_CAMERA) {

File diff suppressed because it is too large Load Diff

View File

@@ -3475,6 +3475,7 @@ static void registerCompositNodes(void)
register_node_type_cmp_bokehimage();
register_node_type_cmp_bokehblur();
register_node_type_cmp_switch();
register_node_type_cmp_switch_view();
register_node_type_cmp_pixelate();
register_node_type_cmp_mask();

View File

@@ -1002,7 +1002,7 @@ static void cache_filename(char *string, const char *path, const char *relbase,
BLI_join_dirfile(cachepath, sizeof(cachepath), path, fname);
BKE_image_path_from_imtype(string, cachepath, relbase, frame, R_IMF_IMTYPE_OPENEXR, true, true);
BKE_image_path_from_imtype(string, cachepath, relbase, frame, R_IMF_IMTYPE_OPENEXR, true, true, "");
}
/* silly functions but useful to inline when the args do a lot of indirections */

View File

@@ -128,8 +128,8 @@ int countPackedFiles(Main *bmain)
/* let's check if there are packed files... */
for (ima = bmain->image.first; ima; ima = ima->id.next)
if (ima->packedfile)
count++;
if (BKE_image_has_packedfile(ima))
count ++;
for (vf = bmain->vfont.first; vf; vf = vf->id.next)
if (vf->packedfile)
@@ -232,9 +232,9 @@ void packAll(Main *bmain, ReportList *reports)
int tot = 0;
for (ima = bmain->image.first; ima; ima = ima->id.next) {
if (ima->packedfile == NULL && ima->id.lib == NULL) {
if (BKE_image_has_packedfile(ima) == false && ima->id.lib == NULL) {
if (ima->source == IMA_SRC_FILE) {
ima->packedfile = newPackedFile(reports, ima->name, ID_BLEND_PATH(bmain, &ima->id));
BKE_image_packfiles(reports, ima, ID_BLEND_PATH(bmain, &ima->id));
tot ++;
}
else if (BKE_image_is_animated(ima)) {
@@ -564,23 +564,47 @@ int unpackSound(Main *bmain, ReportList *reports, bSound *sound, int how)
int unpackImage(ReportList *reports, Image *ima, int how)
{
char localname[FILE_MAX], absname[FILE_MAX];
char *newname;
int ret_value = RET_ERROR;
if (ima != NULL && ima->name[0]) {
unpack_generate_paths(ima->name, (ID *)ima, absname, localname, sizeof(absname), sizeof(localname));
newname = unpackFile(reports, absname, localname, ima->packedfile, how);
if (newname != NULL) {
ret_value = RET_OK;
freePackedFile(ima->packedfile);
ima->packedfile = NULL;
BLI_strncpy(ima->name, newname, sizeof(ima->name));
MEM_freeN(newname);
BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD);
while (ima->packedfiles.last) {
char localname[FILE_MAX], absname[FILE_MAX];
char *newname;
ImagePackedFile *imapf = ima->packedfiles.last;
unpack_generate_paths(imapf->filepath, (ID *)ima, absname, localname, sizeof(absname), sizeof(localname));
newname = unpackFile(reports, absname, localname, imapf->packedfile, how);
if (newname != NULL) {
ImageView *iv;
ret_value = ret_value == RET_ERROR ? RET_ERROR : RET_OK;
freePackedFile(imapf->packedfile);
imapf->packedfile = NULL;
/* update the new corresponding view filepath */
iv = BLI_findstring(&ima->views, imapf->filepath, offsetof(ImageView, filepath));
if (iv) {
BLI_strncpy(iv->filepath, newname, sizeof(imapf->filepath));
}
/* keep the new name in the image for non-pack specific reasons */
BLI_strncpy(ima->name, newname, sizeof(imapf->filepath));
MEM_freeN(newname);
}
else {
ret_value = RET_ERROR;
}
BLI_remlink(&ima->packedfiles, imapf);
MEM_freeN(imapf);
}
}
if (ret_value == RET_OK) {
BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD);
}
return(ret_value);
}
@@ -636,7 +660,7 @@ void unpackAll(Main *bmain, ReportList *reports, int how)
bSound *sound;
for (ima = bmain->image.first; ima; ima = ima->id.next)
if (ima->packedfile)
if (BKE_image_has_packedfile(ima))
unpackImage(reports, ima, how);
for (vf = bmain->vfont.first; vf; vf = vf->id.next)
@@ -655,7 +679,7 @@ bool BKE_pack_check(ID *id)
case ID_IM:
{
Image *ima = (Image *)id;
return ima->packedfile != NULL;
return BKE_image_has_packedfile(ima);
}
case ID_VF:
{
@@ -683,7 +707,7 @@ void BKE_unpack_id(Main *bmain, ID *id, ReportList *reports, int how)
case ID_IM:
{
Image *ima = (Image *)id;
if (ima->packedfile) {
if (BKE_image_has_packedfile(ima)) {
unpackImage(reports, ima, how);
}
break;

View File

@@ -92,6 +92,7 @@
#include "PIL_time.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
#include "bmesh.h"
@@ -157,14 +158,16 @@ Scene *BKE_scene_copy(Scene *sce, int type)
Base *base, *obase;
if (type == SCE_COPY_EMPTY) {
ListBase lb;
ListBase rl, rv;
/* XXX. main should become an arg */
scen = BKE_scene_add(G.main, sce->id.name + 2);
lb = scen->r.layers;
rl = scen->r.layers;
rv = scen->r.views;
scen->r = sce->r;
scen->r.layers = lb;
scen->r.layers = rl;
scen->r.actlay = 0;
scen->r.views = rv;
scen->unit = sce->unit;
scen->physics_settings = sce->physics_settings;
scen->gm = sce->gm;
@@ -197,6 +200,7 @@ Scene *BKE_scene_copy(Scene *sce, int type)
BLI_duplicatelist(&(scen->markers), &(sce->markers));
BLI_duplicatelist(&(scen->transform_spaces), &(sce->transform_spaces));
BLI_duplicatelist(&(scen->r.layers), &(sce->r.layers));
BLI_duplicatelist(&(scen->r.views), &(sce->r.views));
BKE_keyingsets_copy(&(scen->keyingsets), &(sce->keyingsets));
if (sce->nodetree) {
@@ -390,6 +394,7 @@ void BKE_scene_free(Scene *sce)
BLI_freelistN(&sce->markers);
BLI_freelistN(&sce->transform_spaces);
BLI_freelistN(&sce->r.layers);
BLI_freelistN(&sce->r.views);
if (sce->toolsettings) {
if (sce->toolsettings->vpaint) {
@@ -437,6 +442,7 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
ParticleEditSettings *pset;
int a;
const char *colorspace_name;
SceneRenderView *srv;
sce = BKE_libblock_alloc(bmain, ID_SCE, name);
sce->lay = sce->layact = 1;
@@ -628,7 +634,16 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
/* note; in header_info.c the scene copy happens..., if you add more to renderdata it has to be checked there */
BKE_scene_add_render_layer(sce, NULL);
/* multiview - stereo */
BKE_scene_add_render_view(sce, STEREO_LEFT_NAME);
srv = sce->r.views.first;
BLI_strncpy(srv->suffix, STEREO_LEFT_SUFFIX, sizeof(srv->suffix));
BKE_scene_add_render_view(sce, STEREO_RIGHT_NAME);
srv = sce->r.views.last;
BLI_strncpy(srv->suffix, STEREO_RIGHT_SUFFIX, sizeof(srv->suffix));
/* game data */
sce->gm.stereoflag = STEREO_NOSTEREO;
sce->gm.stereomode = STEREO_ANAGLYPH;
@@ -701,6 +716,19 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
return sce;
}
Base *BKE_scene_base_find_by_name(struct Scene *scene, const char *name)
{
Base *base;
for (base = scene->base.first; base; base = base->next) {
if (STREQ(base->object->id.name + 2, name)) {
break;
}
}
return base;
}
Base *BKE_scene_base_find(Scene *scene, Object *ob)
{
return BLI_findptr(&scene->base, ob, offsetof(Base, object));
@@ -1892,6 +1920,42 @@ bool BKE_scene_remove_render_layer(Main *bmain, Scene *scene, SceneRenderLayer *
return true;
}
/* return default view */
SceneRenderView *BKE_scene_add_render_view(Scene *sce, const char *name)
{
SceneRenderView *srv;
if (!name)
name = DATA_("RenderView");
srv = MEM_callocN(sizeof(SceneRenderView), "new render view");
BLI_strncpy(srv->name, name, sizeof(srv->name));
BLI_uniquename(&sce->r.views, srv, DATA_("RenderView"), '.', offsetof(SceneRenderView, name), sizeof(srv->name));
BLI_addtail(&sce->r.views, srv);
return srv;
}
bool BKE_scene_remove_render_view(Scene *scene, SceneRenderView *srv)
{
const int act = BLI_findindex(&scene->r.views, srv);
if (act == -1) {
return false;
}
else if (scene->r.views.first == scene->r.views.last) {
/* ensure 1 view is kept */
return false;
}
BLI_remlink(&scene->r.views, srv);
MEM_freeN(srv);
scene->r.actview = 0;
return true;
}
/* render simplification */
int get_render_subsurf_level(const RenderData *r, int lvl)
@@ -2062,3 +2126,281 @@ double BKE_scene_unit_scale(const UnitSettings *unit, const int unit_type, doubl
return value;
}
}
/******************** multiview *************************/
size_t BKE_scene_multiview_num_views_get(const RenderData *rd)
{
SceneRenderView *srv;
size_t totviews = 0;
if ((rd->scemode & R_MULTIVIEW) == 0)
return 1;
if (rd->views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
if (BLI_findstring(&rd->views, STEREO_LEFT_NAME, offsetof(SceneRenderView, name))) {
totviews++;
}
if (BLI_findstring(&rd->views, STEREO_RIGHT_NAME, offsetof(SceneRenderView, name))) {
totviews++;
}
}
else {
for (srv = rd->views.first; srv; srv = srv->next) {
if ((srv->viewflag & SCE_VIEW_DISABLE) == 0) {
totviews++;
}
}
}
return totviews;
}
bool BKE_scene_multiview_is_stereo3d(const RenderData *rd)
{
SceneRenderView *srv[2];
if ((rd->scemode & R_MULTIVIEW) == 0)
return false;
srv[0] = (SceneRenderView *)BLI_findstring(&rd->views, STEREO_LEFT_NAME, offsetof(SceneRenderView, name));
srv[1] = (SceneRenderView *)BLI_findstring(&rd->views, STEREO_RIGHT_NAME, offsetof(SceneRenderView, name));
return (srv[0] && ((srv[0]->viewflag & SCE_VIEW_DISABLE) == 0) &&
srv[1] && ((srv[1]->viewflag & SCE_VIEW_DISABLE) == 0));
}
/* return whether to render this SceneRenderView */
bool BKE_scene_multiview_is_render_view_active(const RenderData *rd, const SceneRenderView *srv)
{
if (srv == NULL)
return false;
if ((rd->scemode & R_MULTIVIEW) == 0)
return false;
if ((srv->viewflag & SCE_VIEW_DISABLE))
return false;
if (rd->views_format == SCE_VIEWS_FORMAT_MULTIVIEW)
return true;
/* SCE_VIEWS_SETUP_BASIC */
if (STREQ(srv->name, STEREO_LEFT_NAME) ||
STREQ(srv->name, STEREO_RIGHT_NAME))
{
return true;
}
return false;
}
/* return true if viewname is the first or if the name is NULL or not found */
bool BKE_scene_multiview_is_render_view_first(const RenderData *rd, const char *viewname)
{
SceneRenderView *srv;
if ((rd->scemode & R_MULTIVIEW) == 0)
return true;
if ((!viewname) || (!viewname[0]))
return true;
for (srv = rd->views.first; srv; srv = srv->next) {
if (BKE_scene_multiview_is_render_view_active(rd, srv)) {
return STREQ(viewname, srv->name);
}
}
return true;
}
/* return true if viewname is the last or if the name is NULL or not found */
bool BKE_scene_multiview_is_render_view_last(const RenderData *rd, const char *viewname)
{
SceneRenderView *srv;
if ((rd->scemode & R_MULTIVIEW) == 0)
return true;
if ((!viewname) || (!viewname[0]))
return true;
for (srv = rd->views.last; srv; srv = srv->prev) {
if (BKE_scene_multiview_is_render_view_active(rd, srv)) {
return STREQ(viewname, srv->name);
}
}
return true;
}
SceneRenderView *BKE_scene_multiview_render_view_findindex(const RenderData *rd, const int view_id)
{
SceneRenderView *srv;
size_t nr;
if ((rd->scemode & R_MULTIVIEW) == 0)
return NULL;
nr = 0;
for (srv = rd->views.first, nr = 0; srv; srv = srv->next) {
if (BKE_scene_multiview_is_render_view_active(rd, srv)) {
if (nr++ == view_id)
return srv;
}
}
return srv;
}
const char *BKE_scene_multiview_render_view_name_get(const RenderData *rd, const int view_id)
{
SceneRenderView *srv = BKE_scene_multiview_render_view_findindex(rd, view_id);
if (srv)
return srv->name;
else
return "";
}
size_t BKE_scene_multiview_view_id_get(const RenderData *rd, const char *viewname)
{
SceneRenderView *srv;
size_t nr;
if ((!rd) || ((rd->scemode & R_MULTIVIEW) == 0))
return 0;
if ((!viewname) || (!viewname[0]))
return 0;
nr = 0;
for (srv = rd->views.first, nr = 0; srv; srv = srv->next) {
if (BKE_scene_multiview_is_render_view_active(rd, srv)) {
if (STREQ(viewname, srv->name)) {
return nr;
}
else {
nr += 1;
}
}
}
return 0;
}
void BKE_scene_multiview_filepath_get(
SceneRenderView *srv, const char *filepath,
char *r_filepath)
{
BLI_strncpy(r_filepath, filepath, FILE_MAX);
BLI_path_suffix(r_filepath, FILE_MAX, srv->suffix, "");
}
/**
* When multiview is not used the filepath is as usual (e.g., ``Image.jpg``).
* When multiview is on, even if only one view is enabled the view is incorporated
* into the file name (e.g., ``Image_L.jpg``). That allows for the user to re-render
* individual views.
*/
void BKE_scene_multiview_view_filepath_get(
const RenderData *rd, const char *filepath, const char *viewname,
char *r_filepath)
{
SceneRenderView *srv;
char suffix[FILE_MAX];
srv = BLI_findstring(&rd->views, viewname, offsetof(SceneRenderView, name));
if (srv)
BLI_strncpy(suffix, srv->suffix, sizeof(suffix));
else
BLI_strncpy(suffix, viewname, sizeof(suffix));
BLI_strncpy(r_filepath, filepath, FILE_MAX);
BLI_path_suffix(r_filepath, FILE_MAX, suffix, "");
}
const char *BKE_scene_multiview_view_suffix_get(const RenderData *rd, const char *viewname)
{
SceneRenderView *srv;
if ((viewname == NULL) || (viewname[0] == '\0'))
return viewname;
srv = BLI_findstring(&rd->views, viewname, offsetof(SceneRenderView, name));
if (srv)
return srv->suffix;
else
return viewname;
}
const char *BKE_scene_multiview_view_id_suffix_get(const RenderData *rd, const size_t view_id)
{
if ((rd->scemode & R_MULTIVIEW) == 0) {
return "";
}
else {
const char *viewname = BKE_scene_multiview_render_view_name_get(rd, view_id);
return BKE_scene_multiview_view_suffix_get(rd, viewname);
}
}
void BKE_scene_multiview_view_prefix_get(Scene *scene, const char *name, char *rprefix, char **rext)
{
SceneRenderView *srv;
size_t index_act;
char *suf_act;
const char delims[] = {'.', '\0'};
rprefix[0] = '\0';
/* begin of extension */
index_act = BLI_str_rpartition(name, delims, rext, &suf_act);
BLI_assert(index_act > 0);
for (srv = scene->r.views.first; srv; srv = srv->next) {
if (BKE_scene_multiview_is_render_view_active(&scene->r, srv)) {
size_t len = strlen(srv->suffix);
if (STREQLEN(*rext - len, srv->suffix, len)) {
BLI_strncpy(rprefix, name, strlen(name) - strlen(*rext) - len + 1);
break;
}
}
}
}
void BKE_scene_multiview_videos_dimensions_get(
const RenderData *rd, const size_t width, const size_t height,
size_t *r_width, size_t *r_height)
{
if ((rd->scemode & R_MULTIVIEW) &&
rd->im_format.views_format == R_IMF_VIEWS_STEREO_3D)
{
IMB_stereo3d_write_dimensions(
rd->im_format.stereo3d_format.display_mode,
(rd->im_format.stereo3d_format.flag & S3D_SQUEEZED_FRAME) != 0,
width, height,
r_width, r_height);
}
else {
*r_width = width;
*r_height = height;
}
}
size_t BKE_scene_multiview_num_videos_get(const RenderData *rd)
{
if (BKE_imtype_is_movie(rd->im_format.imtype) == false)
return 0;
if ((rd->scemode & R_MULTIVIEW) == 0)
return 1;
if (rd->im_format.views_format == R_IMF_VIEWS_STEREO_3D) {
return 1;
}
else {
/* R_IMF_VIEWS_INDIVIDUAL */
return BKE_scene_multiview_num_views_get(rd);
}
}

View File

@@ -33,6 +33,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_sequence_types.h"
#include "DNA_scene_types.h"
#include "IMB_moviecache.h"
#include "IMB_imbuf.h"
@@ -41,6 +42,7 @@
#include "BLI_listbase.h"
#include "BKE_sequencer.h"
#include "BKE_scene.h"
typedef struct SeqCacheKey {
struct Sequence *seq;
@@ -77,7 +79,9 @@ static bool seq_cmp_render_data(const SeqRenderData *a, const SeqRenderData *b)
(a->bmain != b->bmain) ||
(a->scene != b->scene) ||
(a->motion_blur_shutter != b->motion_blur_shutter) ||
(a->motion_blur_samples != b->motion_blur_samples));
(a->motion_blur_samples != b->motion_blur_samples) ||
(a->scene->r.views_format != b->scene->r.views_format) ||
(a->view_id != b->view_id));
}
static unsigned int seq_hash_render_data(const SeqRenderData *a)
@@ -89,6 +93,7 @@ static unsigned int seq_hash_render_data(const SeqRenderData *a)
rval ^= ((intptr_t) a->scene) << 6;
rval ^= (int)(a->motion_blur_shutter * 100.0f) << 10;
rval ^= a->motion_blur_samples << 24;
rval ^= ((a->scene->r.views_format * 2) + a->view_id) << 32;
return rval;
}

File diff suppressed because it is too large Load Diff

View File

@@ -50,26 +50,34 @@
/* ********************** general blender movie support ***************************** */
static int start_stub(Scene *UNUSED(scene), RenderData *UNUSED(rd), int UNUSED(rectx), int UNUSED(recty),
ReportList *UNUSED(reports), bool UNUSED(preview))
static int start_stub(void *UNUSED(context_v), Scene *UNUSED(scene), RenderData *UNUSED(rd), int UNUSED(rectx), int UNUSED(recty),
ReportList *UNUSED(reports), bool UNUSED(preview), const char *UNUSED(suffix))
{ return 0; }
static void end_stub(void)
static void end_stub(void *UNUSED(context_v))
{}
static int append_stub(RenderData *UNUSED(rd), int UNUSED(start_frame), int UNUSED(frame), int *UNUSED(pixels),
int UNUSED(rectx), int UNUSED(recty), ReportList *UNUSED(reports))
static int append_stub(void *UNUSED(context_v), RenderData *UNUSED(rd), int UNUSED(start_frame), int UNUSED(frame), int *UNUSED(pixels),
int UNUSED(rectx), int UNUSED(recty), const char *UNUSED(suffix), ReportList *UNUSED(reports))
{ return 0; }
static void *context_create_stub(void)
{ return NULL; }
static void context_free_stub(void *UNUSED(context_v))
{}
#ifdef WITH_AVI
# include "AVI_avi.h"
/* callbacks */
static int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports, bool preview);
static void end_avi(void);
static int append_avi(RenderData *rd, int start_frame, int frame, int *pixels,
int rectx, int recty, ReportList *reports);
static void filepath_avi(char *string, RenderData *rd, bool preview);
static int start_avi(void *context_v, Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports, bool preview, const char *suffix);
static void end_avi(void *context_v);
static int append_avi(void *context_v, RenderData *rd, int start_frame, int frame, int *pixels,
int rectx, int recty, const char *suffix, ReportList *reports);
static void filepath_avi(char *string, RenderData *rd, bool preview, const char *suffix);
static void *context_create_avi(void);
static void context_free_avi(void *context_v);
#endif /* WITH_AVI */
#ifdef WITH_QUICKTIME
@@ -93,13 +101,17 @@ bMovieHandle *BKE_movie_handle_get(const char imtype)
mh.end_movie = end_stub;
mh.get_next_frame = NULL;
mh.get_movie_path = NULL;
mh.context_create = context_create_stub;
mh.context_free = context_free_stub;
/* set the default handle, as builtin */
#ifdef WITH_AVI
mh.start_movie = start_avi;
mh.append_movie = append_avi;
mh.end_movie = end_avi;
mh.get_movie_path = filepath_avi;
mh.context_create = context_create_avi;
mh.context_free = context_free_avi;
#endif
/* do the platform specific handles */
@@ -109,6 +121,8 @@ bMovieHandle *BKE_movie_handle_get(const char imtype)
mh.append_movie = append_qt;
mh.end_movie = end_qt;
mh.get_movie_path = filepath_qt;
mh.context_create = context_create_qt;
mh.context_free = context_free_qt;
}
#endif
#ifdef WITH_FFMPEG
@@ -117,6 +131,8 @@ bMovieHandle *BKE_movie_handle_get(const char imtype)
mh.append_movie = BKE_ffmpeg_append;
mh.end_movie = BKE_ffmpeg_end;
mh.get_movie_path = BKE_ffmpeg_filepath_get;
mh.context_create = BKE_ffmpeg_context_create;
mh.context_free = BKE_ffmpeg_context_free;
}
#endif
#ifdef WITH_FRAMESERVER
@@ -125,6 +141,8 @@ bMovieHandle *BKE_movie_handle_get(const char imtype)
mh.append_movie = BKE_frameserver_append;
mh.end_movie = BKE_frameserver_end;
mh.get_next_frame = BKE_frameserver_loop;
mh.context_create = BKE_frameserver_context_create;
mh.context_free = BKE_frameserver_context_free;
}
#endif
@@ -137,9 +155,7 @@ bMovieHandle *BKE_movie_handle_get(const char imtype)
#ifdef WITH_AVI
static AviMovie *avi = NULL;
static void filepath_avi(char *string, RenderData *rd, bool preview)
static void filepath_avi(char *string, RenderData *rd, bool preview, const char *suffix)
{
int sfra, efra;
@@ -170,27 +186,27 @@ static void filepath_avi(char *string, RenderData *rd, bool preview)
BLI_path_frame_range(string, sfra, efra, 4);
}
}
BLI_path_suffix(string, FILE_MAX, suffix, "");
}
static int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports, bool preview)
static int start_avi(void *context_v, Scene *UNUSED(scene), RenderData *rd, int rectx, int recty,
ReportList *reports, bool preview, const char *suffix)
{
int x, y;
char name[256];
AviFormat format;
int quality;
double framerate;
(void)scene; /* unused */
filepath_avi(name, rd, preview);
AviMovie *avi = context_v;
filepath_avi(name, rd, preview, suffix);
x = rectx;
y = recty;
quality = rd->im_format.quality;
framerate = (double) rd->frs_sec / (double) rd->frs_sec_base;
avi = MEM_mallocN(sizeof(AviMovie), "avimovie");
if (rd->im_format.imtype != R_IMF_IMTYPE_AVIJPEG) format = AVI_FORMAT_AVI_RGB;
else format = AVI_FORMAT_MJPEG;
@@ -216,12 +232,13 @@ static int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportL
return 1;
}
static int append_avi(RenderData *UNUSED(rd), int start_frame, int frame, int *pixels,
int rectx, int recty, ReportList *UNUSED(reports))
static int append_avi(void *context_v, RenderData *UNUSED(rd), int start_frame, int frame, int *pixels,
int rectx, int recty, const char *UNUSED(suffix), ReportList *UNUSED(reports))
{
unsigned int *rt1, *rt2, *rectot;
int x, y;
char *cp, rt;
AviMovie *avi = context_v;
if (avi == NULL)
return 0;
@@ -252,22 +269,37 @@ static int append_avi(RenderData *UNUSED(rd), int start_frame, int frame, int *p
return 1;
}
static void end_avi(void)
static void end_avi(void *context_v)
{
AviMovie *avi = context_v;
if (avi == NULL) return;
AVI_close_compress(avi);
MEM_freeN(avi);
avi = NULL;
}
static void *context_create_avi(void)
{
AviMovie *avi = MEM_mallocN(sizeof(AviMovie), "avimovie");
return avi;
}
static void context_free_avi(void *context_v)
{
AviMovie *avi = context_v;
if (avi) {
MEM_freeN(avi);
}
}
#endif /* WITH_AVI */
/* similar to BKE_image_path_from_imformat() */
void BKE_movie_filepath_get(char *string, RenderData *rd, bool preview)
void BKE_movie_filepath_get(char *string, RenderData *rd, bool preview, const char *suffix)
{
bMovieHandle *mh = BKE_movie_handle_get(rd->im_format.imtype);
if (mh->get_movie_path)
mh->get_movie_path(string, rd, preview);
mh->get_movie_path(string, rd, preview, suffix);
else
string[0] = '\0';
}

View File

@@ -61,36 +61,38 @@
#include "ffmpeg_compat.h"
static int ffmpeg_type = 0;
static int ffmpeg_codec = AV_CODEC_ID_MPEG4;
static int ffmpeg_audio_codec = AV_CODEC_ID_NONE;
static int ffmpeg_video_bitrate = 1150;
static int ffmpeg_audio_bitrate = 128;
static int ffmpeg_gop_size = 12;
static int ffmpeg_autosplit = 0;
static int ffmpeg_autosplit_count = 0;
static bool ffmpeg_preview = false;
typedef struct FFMpegContext {
int ffmpeg_type;
int ffmpeg_codec;
int ffmpeg_audio_codec;
int ffmpeg_video_bitrate;
int ffmpeg_audio_bitrate;
int ffmpeg_gop_size;
int ffmpeg_autosplit;
int ffmpeg_autosplit_count;
bool ffmpeg_preview;
static AVFormatContext *outfile = 0;
static AVStream *video_stream = 0;
static AVStream *audio_stream = 0;
static AVFrame *current_frame = 0;
static struct SwsContext *img_convert_ctx = 0;
AVFormatContext *outfile;
AVStream *video_stream;
AVStream *audio_stream;
AVFrame *current_frame;
struct SwsContext *img_convert_ctx;
static uint8_t *audio_input_buffer = 0;
static uint8_t *audio_deinterleave_buffer = 0;
static int audio_input_samples = 0;
uint8_t *audio_input_buffer;
uint8_t *audio_deinterleave_buffer;
int audio_input_samples;
#ifndef FFMPEG_HAVE_ENCODE_AUDIO2
static uint8_t *audio_output_buffer = 0;
static int audio_outbuf_size = 0;
uint8_t *audio_output_buffer;
int audio_outbuf_size;
#endif
static double audio_time = 0.0f;
static bool audio_deinterleave = false;
static int audio_sample_size = 0;
double audio_time;
bool audio_deinterleave;
int audio_sample_size;
#ifdef WITH_AUDASPACE
static AUD_Device *audio_mixdown_device = 0;
AUD_Device *audio_mixdown_device;
#endif
} FFMpegContext;
#define FFMPEG_AUTOSPLIT_SIZE 2000000000
@@ -99,6 +101,7 @@ static AUD_Device *audio_mixdown_device = 0;
static void ffmpeg_dict_set_int(AVDictionary **dict, const char *key, int value);
static void ffmpeg_dict_set_float(AVDictionary **dict, const char *key, float value);
static void ffmpeg_set_expert_options(RenderData *rd);
static void ffmpeg_filepath_get(FFMpegContext *context, char *string, struct RenderData *rd, bool preview, const char *suffix);
/* Delete a picture buffer */
@@ -117,50 +120,50 @@ static int request_float_audio_buffer(int codec_id)
}
#ifdef WITH_AUDASPACE
static int write_audio_frame(void)
static int write_audio_frame(FFMpegContext *context)
{
AVCodecContext *c = NULL;
AVPacket pkt;
AVFrame *frame = NULL;
int got_output = 0;
c = audio_stream->codec;
c = context->audio_stream->codec;
av_init_packet(&pkt);
pkt.size = 0;
pkt.data = NULL;
AUD_readDevice(audio_mixdown_device, audio_input_buffer, audio_input_samples);
audio_time += (double) audio_input_samples / (double) c->sample_rate;
AUD_readDevice(context->audio_mixdown_device, context->audio_input_buffer, context->audio_input_samples);
context->audio_time += (double) context->audio_input_samples / (double) c->sample_rate;
#ifdef FFMPEG_HAVE_ENCODE_AUDIO2
frame = avcodec_alloc_frame();
avcodec_get_frame_defaults(frame);
frame->pts = audio_time / av_q2d(c->time_base);
frame->nb_samples = audio_input_samples;
frame->pts = context->audio_time / av_q2d(c->time_base);
frame->nb_samples = context->audio_input_samples;
frame->format = c->sample_fmt;
#ifdef FFMPEG_HAVE_FRAME_CHANNEL_LAYOUT
frame->channel_layout = c->channel_layout;
#endif
if (audio_deinterleave) {
if (context->audio_deinterleave) {
int channel, i;
uint8_t *temp;
for (channel = 0; channel < c->channels; channel++) {
for (i = 0; i < frame->nb_samples; i++) {
memcpy(audio_deinterleave_buffer + (i + channel * frame->nb_samples) * audio_sample_size,
audio_input_buffer + (c->channels * i + channel) * audio_sample_size, audio_sample_size);
memcpy(context->audio_deinterleave_buffer + (i + channel * frame->nb_samples) * context->audio_sample_size,
context->audio_input_buffer + (c->channels * i + channel) * context->audio_sample_size, context->audio_sample_size);
}
}
temp = audio_deinterleave_buffer;
audio_deinterleave_buffer = audio_input_buffer;
audio_input_buffer = temp;
temp = context->audio_deinterleave_buffer;
context->audio_deinterleave_buffer = context->audio_input_buffer;
context->audio_input_buffer = temp;
}
avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt, audio_input_buffer,
audio_input_samples * c->channels * audio_sample_size, 1);
avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt, context->audio_input_buffer,
context->audio_input_samples * c->channels * context->audio_sample_size, 1);
if (avcodec_encode_audio2(c, &pkt, frame, &got_output) < 0) {
// XXX error("Error writing audio packet");
@@ -172,30 +175,30 @@ static int write_audio_frame(void)
return 0;
}
#else
pkt.size = avcodec_encode_audio(c, audio_output_buffer, audio_outbuf_size, (short *) audio_input_buffer);
pkt.size = avcodec_encode_audio(c, context->audio_output_buffer, context->audio_outbuf_size, (short *) context->audio_input_buffer);
if (pkt.size < 0) {
// XXX error("Error writing audio packet");
return -1;
}
pkt.data = audio_output_buffer;
pkt.data = context->audio_output_buffer;
got_output = 1;
#endif
if (got_output) {
if (pkt.pts != AV_NOPTS_VALUE)
pkt.pts = av_rescale_q(pkt.pts, c->time_base, audio_stream->time_base);
pkt.pts = av_rescale_q(pkt.pts, c->time_base, context->audio_stream->time_base);
if (pkt.dts != AV_NOPTS_VALUE)
pkt.dts = av_rescale_q(pkt.dts, c->time_base, audio_stream->time_base);
pkt.dts = av_rescale_q(pkt.dts, c->time_base, context->audio_stream->time_base);
if (pkt.duration > 0)
pkt.duration = av_rescale_q(pkt.duration, c->time_base, audio_stream->time_base);
pkt.duration = av_rescale_q(pkt.duration, c->time_base, context->audio_stream->time_base);
pkt.stream_index = audio_stream->index;
pkt.stream_index = context->audio_stream->index;
pkt.flags |= AV_PKT_FLAG_KEY;
if (av_interleaved_write_frame(outfile, &pkt) != 0) {
if (av_interleaved_write_frame(context->outfile, &pkt) != 0) {
fprintf(stderr, "Error writing audio packet!\n");
if (frame)
avcodec_free_frame(&frame);
@@ -302,11 +305,11 @@ static const char **get_file_extensions(int format)
}
/* Write a frame to the output file */
static int write_video_frame(RenderData *rd, int cfra, AVFrame *frame, ReportList *reports)
static int write_video_frame(FFMpegContext *context, RenderData *rd, int cfra, AVFrame *frame, ReportList *reports)
{
int got_output;
int ret, success = 1;
AVCodecContext *c = video_stream->codec;
AVCodecContext *c = context->video_stream->codec;
AVPacket packet = { 0 };
av_init_packet(&packet);
@@ -321,22 +324,22 @@ static int write_video_frame(RenderData *rd, int cfra, AVFrame *frame, ReportLis
if (ret >= 0 && got_output) {
if (packet.pts != AV_NOPTS_VALUE) {
packet.pts = av_rescale_q(packet.pts, c->time_base, video_stream->time_base);
packet.pts = av_rescale_q(packet.pts, c->time_base, context->video_stream->time_base);
PRINT("Video Frame PTS: %d\n", (int)packet.pts);
}
else {
PRINT("Video Frame PTS: not set\n");
}
if (packet.dts != AV_NOPTS_VALUE) {
packet.dts = av_rescale_q(packet.dts, c->time_base, video_stream->time_base);
packet.dts = av_rescale_q(packet.dts, c->time_base, context->video_stream->time_base);
PRINT("Video Frame DTS: %d\n", (int)packet.dts);
}
else {
PRINT("Video Frame DTS: not set\n");
}
packet.stream_index = video_stream->index;
ret = av_interleaved_write_frame(outfile, &packet);
packet.stream_index = context->video_stream->index;
ret = av_interleaved_write_frame(context->outfile, &packet);
success = (ret == 0);
}
else if (ret < 0) {
@@ -350,11 +353,11 @@ static int write_video_frame(RenderData *rd, int cfra, AVFrame *frame, ReportLis
}
/* read and encode a frame of audio from the buffer */
static AVFrame *generate_video_frame(uint8_t *pixels, ReportList *reports)
static AVFrame *generate_video_frame(FFMpegContext *context, uint8_t *pixels, ReportList *reports)
{
uint8_t *rendered_frame;
AVCodecContext *c = video_stream->codec;
AVCodecContext *c = context->video_stream->codec;
int width = c->width;
int height = c->height;
AVFrame *rgb_frame;
@@ -367,7 +370,7 @@ static AVFrame *generate_video_frame(uint8_t *pixels, ReportList *reports)
}
}
else {
rgb_frame = current_frame;
rgb_frame = context->current_frame;
}
rendered_frame = pixels;
@@ -411,17 +414,17 @@ static AVFrame *generate_video_frame(uint8_t *pixels, ReportList *reports)
}
if (c->pix_fmt != PIX_FMT_BGR32) {
sws_scale(img_convert_ctx, (const uint8_t *const *) rgb_frame->data,
sws_scale(context->img_convert_ctx, (const uint8_t *const *) rgb_frame->data,
rgb_frame->linesize, 0, c->height,
current_frame->data, current_frame->linesize);
context->current_frame->data, context->current_frame->linesize);
delete_picture(rgb_frame);
}
current_frame->format = PIX_FMT_BGR32;
current_frame->width = width;
current_frame->height = height;
context->current_frame->format = PIX_FMT_BGR32;
context->current_frame->width = width;
context->current_frame->height = height;
return current_frame;
return context->current_frame;
}
static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop, AVDictionary **dictionary)
@@ -516,7 +519,7 @@ static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char
/* prepare a video stream for the output file */
static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContext *of,
static AVStream *alloc_video_stream(FFMpegContext *context, RenderData *rd, int codec_id, AVFormatContext *of,
int rectx, int recty, char *error, int error_size)
{
AVStream *st;
@@ -542,7 +545,7 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
c->height = recty;
/* FIXME: Really bad hack (tm) for NTSC support */
if (ffmpeg_type == FFMPEG_DV && rd->frs_sec != 25) {
if (context->ffmpeg_type == FFMPEG_DV && rd->frs_sec != 25) {
c->time_base.den = 2997;
c->time_base.num = 100;
}
@@ -555,8 +558,8 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
c->time_base.num = ((double) rd->frs_sec_base) * 100000;
}
c->gop_size = ffmpeg_gop_size;
c->bit_rate = ffmpeg_video_bitrate * 1000;
c->gop_size = context->ffmpeg_gop_size;
c->bit_rate = context->ffmpeg_video_bitrate * 1000;
c->rc_max_rate = rd->ffcodecdata.rc_max_rate * 1000;
c->rc_min_rate = rd->ffcodecdata.rc_min_rate * 1000;
c->rc_buffer_size = rd->ffcodecdata.rc_buffer_size * 1024;
@@ -585,7 +588,7 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
c->pix_fmt = PIX_FMT_YUV422P;
}
if (ffmpeg_type == FFMPEG_XVID) {
if (context->ffmpeg_type == FFMPEG_XVID) {
/* arghhhh ... */
c->pix_fmt = PIX_FMT_YUV420P;
c->codec_tag = (('D' << 24) + ('I' << 16) + ('V' << 8) + 'X');
@@ -655,14 +658,14 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
}
av_dict_free(&opts);
current_frame = alloc_picture(c->pix_fmt, c->width, c->height);
context->current_frame = alloc_picture(c->pix_fmt, c->width, c->height);
img_convert_ctx = sws_getContext(c->width, c->height, PIX_FMT_BGR32, c->width, c->height, c->pix_fmt, SWS_BICUBIC,
context->img_convert_ctx = sws_getContext(c->width, c->height, PIX_FMT_BGR32, c->width, c->height, c->pix_fmt, SWS_BICUBIC,
NULL, NULL, NULL);
return st;
}
static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContext *of, char *error, int error_size)
static AVStream *alloc_audio_stream(FFMpegContext *context, RenderData *rd, int codec_id, AVFormatContext *of, char *error, int error_size)
{
AVStream *st;
AVCodecContext *c;
@@ -680,7 +683,7 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
c->codec_type = AVMEDIA_TYPE_AUDIO;
c->sample_rate = rd->ffcodecdata.audio_mixrate;
c->bit_rate = ffmpeg_audio_bitrate * 1000;
c->bit_rate = context->ffmpeg_audio_bitrate * 1000;
c->sample_fmt = AV_SAMPLE_FMT_S16;
c->channels = rd->ffcodecdata.audio_channels;
@@ -747,35 +750,35 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
st->codec->time_base.den = st->codec->sample_rate;
#ifndef FFMPEG_HAVE_ENCODE_AUDIO2
audio_outbuf_size = FF_MIN_BUFFER_SIZE;
context->audio_outbuf_size = FF_MIN_BUFFER_SIZE;
#endif
if (c->frame_size == 0)
// used to be if ((c->codec_id >= CODEC_ID_PCM_S16LE) && (c->codec_id <= CODEC_ID_PCM_DVD))
// not sure if that is needed anymore, so let's try out if there are any
// complaints regarding some ffmpeg versions users might have
audio_input_samples = FF_MIN_BUFFER_SIZE * 8 / c->bits_per_coded_sample / c->channels;
context->audio_input_samples = FF_MIN_BUFFER_SIZE * 8 / c->bits_per_coded_sample / c->channels;
else {
audio_input_samples = c->frame_size;
context->audio_input_samples = c->frame_size;
#ifndef FFMPEG_HAVE_ENCODE_AUDIO2
if (c->frame_size * c->channels * sizeof(int16_t) * 4 > audio_outbuf_size)
audio_outbuf_size = c->frame_size * c->channels * sizeof(int16_t) * 4;
if (c->frame_size * c->channels * sizeof(int16_t) * 4 > context->audio_outbuf_size)
context->audio_outbuf_size = c->frame_size * c->channels * sizeof(int16_t) * 4;
#endif
}
audio_deinterleave = av_sample_fmt_is_planar(c->sample_fmt);
context->audio_deinterleave = av_sample_fmt_is_planar(c->sample_fmt);
audio_sample_size = av_get_bytes_per_sample(c->sample_fmt);
context->audio_sample_size = av_get_bytes_per_sample(c->sample_fmt);
audio_input_buffer = (uint8_t *) av_malloc(audio_input_samples * c->channels * audio_sample_size);
context->audio_input_buffer = (uint8_t *) av_malloc(context->audio_input_samples * c->channels * context->audio_sample_size);
#ifndef FFMPEG_HAVE_ENCODE_AUDIO2
audio_output_buffer = (uint8_t *) av_malloc(audio_outbuf_size);
context->audio_output_buffer = (uint8_t *) av_malloc(context->audio_outbuf_size);
#endif
if (audio_deinterleave)
audio_deinterleave_buffer = (uint8_t *) av_malloc(audio_input_samples * c->channels * audio_sample_size);
if (context->audio_deinterleave)
context->audio_deinterleave_buffer = (uint8_t *) av_malloc(context->audio_input_samples * c->channels * context->audio_sample_size);
audio_time = 0.0f;
context->audio_time = 0.0f;
return st;
}
@@ -799,7 +802,7 @@ static void ffmpeg_dict_set_float(AVDictionary **dict, const char *key, float va
av_dict_set(dict, key, buffer, 0);
}
static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, ReportList *reports)
static int start_ffmpeg_impl(FFMpegContext *context, struct RenderData *rd, int rectx, int recty, const char *suffix, ReportList *reports)
{
/* Handle to the output file */
AVFormatContext *of;
@@ -808,26 +811,26 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
char name[256], error[1024];
const char **exts;
ffmpeg_type = rd->ffcodecdata.type;
ffmpeg_codec = rd->ffcodecdata.codec;
ffmpeg_audio_codec = rd->ffcodecdata.audio_codec;
ffmpeg_video_bitrate = rd->ffcodecdata.video_bitrate;
ffmpeg_audio_bitrate = rd->ffcodecdata.audio_bitrate;
ffmpeg_gop_size = rd->ffcodecdata.gop_size;
ffmpeg_autosplit = rd->ffcodecdata.flags & FFMPEG_AUTOSPLIT_OUTPUT;
context->ffmpeg_type = rd->ffcodecdata.type;
context->ffmpeg_codec = rd->ffcodecdata.codec;
context->ffmpeg_audio_codec = rd->ffcodecdata.audio_codec;
context->ffmpeg_video_bitrate = rd->ffcodecdata.video_bitrate;
context->ffmpeg_audio_bitrate = rd->ffcodecdata.audio_bitrate;
context->ffmpeg_gop_size = rd->ffcodecdata.gop_size;
context->ffmpeg_autosplit = rd->ffcodecdata.flags & FFMPEG_AUTOSPLIT_OUTPUT;
/* Determine the correct filename */
BKE_ffmpeg_filepath_get(name, rd, ffmpeg_preview);
ffmpeg_filepath_get(context, name, rd, context->ffmpeg_preview, suffix);
PRINT("Starting output to %s(ffmpeg)...\n"
" Using type=%d, codec=%d, audio_codec=%d,\n"
" video_bitrate=%d, audio_bitrate=%d,\n"
" gop_size=%d, autosplit=%d\n"
" render width=%d, render height=%d\n",
name, ffmpeg_type, ffmpeg_codec, ffmpeg_audio_codec,
ffmpeg_video_bitrate, ffmpeg_audio_bitrate,
ffmpeg_gop_size, ffmpeg_autosplit, rectx, recty);
name, context->ffmpeg_type, context->ffmpeg_codec, context->ffmpeg_audio_codec,
context->ffmpeg_video_bitrate, context->ffmpeg_audio_bitrate,
context->ffmpeg_gop_size, context->ffmpeg_autosplit, rectx, recty);
exts = get_file_extensions(ffmpeg_type);
exts = get_file_extensions(context->ffmpeg_type);
if (!exts) {
BKE_report(reports, RPT_ERROR, "No valid formats found");
return 0;
@@ -846,7 +849,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
of->oformat = fmt;
of->packet_size = rd->ffcodecdata.mux_packet_size;
if (ffmpeg_audio_codec != AV_CODEC_ID_NONE) {
if (context->ffmpeg_audio_codec != AV_CODEC_ID_NONE) {
ffmpeg_dict_set_int(&opts, "muxrate", rd->ffcodecdata.mux_rate);
}
else {
@@ -857,15 +860,15 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
of->max_delay = (int)(0.7 * AV_TIME_BASE);
fmt->audio_codec = ffmpeg_audio_codec;
fmt->audio_codec = context->ffmpeg_audio_codec;
BLI_strncpy(of->filename, name, sizeof(of->filename));
/* set the codec to the user's selection */
switch (ffmpeg_type) {
switch (context->ffmpeg_type) {
case FFMPEG_AVI:
case FFMPEG_MOV:
case FFMPEG_MKV:
fmt->video_codec = ffmpeg_codec;
fmt->video_codec = context->ffmpeg_codec;
break;
case FFMPEG_OGG:
fmt->video_codec = AV_CODEC_ID_THEORA;
@@ -908,9 +911,9 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
}
}
if (ffmpeg_type == FFMPEG_DV) {
if (context->ffmpeg_type == FFMPEG_DV) {
fmt->audio_codec = AV_CODEC_ID_PCM_S16LE;
if (ffmpeg_audio_codec != AV_CODEC_ID_NONE && rd->ffcodecdata.audio_mixrate != 48000 && rd->ffcodecdata.audio_channels != 2) {
if (context->ffmpeg_audio_codec != AV_CODEC_ID_NONE && rd->ffcodecdata.audio_mixrate != 48000 && rd->ffcodecdata.audio_channels != 2) {
BKE_report(reports, RPT_ERROR, "FFMPEG only supports 48khz / stereo audio for DV!");
av_dict_free(&opts);
return 0;
@@ -918,9 +921,9 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
}
if (fmt->video_codec != AV_CODEC_ID_NONE) {
video_stream = alloc_video_stream(rd, fmt->video_codec, of, rectx, recty, error, sizeof(error));
PRINT("alloc video stream %p\n", video_stream);
if (!video_stream) {
context->video_stream = alloc_video_stream(context, rd, fmt->video_codec, of, rectx, recty, error, sizeof(error));
PRINT("alloc video stream %p\n", context->video_stream);
if (!context->video_stream) {
if (error[0])
BKE_report(reports, RPT_ERROR, error);
else
@@ -931,9 +934,9 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
}
}
if (ffmpeg_audio_codec != AV_CODEC_ID_NONE) {
audio_stream = alloc_audio_stream(rd, fmt->audio_codec, of, error, sizeof(error));
if (!audio_stream) {
if (context->ffmpeg_audio_codec != AV_CODEC_ID_NONE) {
context->audio_stream = alloc_audio_stream(context, rd, fmt->audio_codec, of, error, sizeof(error));
if (!context->audio_stream) {
if (error[0])
BKE_report(reports, RPT_ERROR, error);
else
@@ -956,7 +959,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
return 0;
}
outfile = of;
context->outfile = of;
av_dump_format(of, 0, name, 1);
av_dict_free(&opts);
@@ -980,11 +983,11 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
* parameter.
* </p>
*/
static void flush_ffmpeg(void)
static void flush_ffmpeg(FFMpegContext *context)
{
int ret = 0;
AVCodecContext *c = video_stream->codec;
AVCodecContext *c = context->video_stream->codec;
/* get the delayed frames */
while (1) {
int got_output;
@@ -1000,28 +1003,28 @@ static void flush_ffmpeg(void)
break;
}
if (packet.pts != AV_NOPTS_VALUE) {
packet.pts = av_rescale_q(packet.pts, c->time_base, video_stream->time_base);
packet.pts = av_rescale_q(packet.pts, c->time_base, context->video_stream->time_base);
PRINT("Video Frame PTS: %d\n", (int) packet.pts);
}
else {
PRINT("Video Frame PTS: not set\n");
}
if (packet.dts != AV_NOPTS_VALUE) {
packet.dts = av_rescale_q(packet.dts, c->time_base, video_stream->time_base);
packet.dts = av_rescale_q(packet.dts, c->time_base, context->video_stream->time_base);
PRINT("Video Frame DTS: %d\n", (int) packet.dts);
}
else {
PRINT("Video Frame DTS: not set\n");
}
packet.stream_index = video_stream->index;
ret = av_interleaved_write_frame(outfile, &packet);
packet.stream_index = context->video_stream->index;
ret = av_interleaved_write_frame(context->outfile, &packet);
if (ret != 0) {
fprintf(stderr, "Error writing delayed frame %d\n", ret);
break;
}
}
avcodec_flush_buffers(video_stream->codec);
avcodec_flush_buffers(context->video_stream->codec);
}
/* **********************************************************************
@@ -1029,7 +1032,7 @@ static void flush_ffmpeg(void)
* ********************************************************************** */
/* Get the output filename-- similar to the other output formats */
void BKE_ffmpeg_filepath_get(char *string, RenderData *rd, bool preview)
static void ffmpeg_filepath_get(FFMpegContext *context, char *string, RenderData *rd, bool preview, const char *suffix)
{
char autosplit[20];
@@ -1056,7 +1059,9 @@ void BKE_ffmpeg_filepath_get(char *string, RenderData *rd, bool preview)
autosplit[0] = 0;
if ((rd->ffcodecdata.flags & FFMPEG_AUTOSPLIT_OUTPUT) != 0) {
sprintf(autosplit, "_%03d", ffmpeg_autosplit_count);
if (context) {
sprintf(autosplit, "_%03d", context->ffmpeg_autosplit_count);
}
}
if (rd->scemode & R_EXTENSION) {
@@ -1086,19 +1091,28 @@ void BKE_ffmpeg_filepath_get(char *string, RenderData *rd, bool preview)
strcat(string, autosplit);
}
BLI_path_suffix(string, FILE_MAX, suffix, "");
}
int BKE_ffmpeg_start(struct Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports, bool preview)
void BKE_ffmpeg_filepath_get(char *string, RenderData *rd, bool preview, const char *suffix)
{
ffmpeg_filepath_get(NULL, string, rd, preview, suffix);
}
int BKE_ffmpeg_start(void *context_v, struct Scene *scene, RenderData *rd, int rectx, int recty,
ReportList *reports, bool preview, const char *suffix)
{
int success;
FFMpegContext *context = context_v;
ffmpeg_autosplit_count = 0;
ffmpeg_preview = preview;
context->ffmpeg_autosplit_count = 0;
context->ffmpeg_preview = preview;
success = start_ffmpeg_impl(rd, rectx, recty, reports);
success = start_ffmpeg_impl(context, rd, rectx, recty, suffix, reports);
#ifdef WITH_AUDASPACE
if (audio_stream) {
AVCodecContext *c = audio_stream->codec;
if (context->audio_stream) {
AVCodecContext *c = context->audio_stream->codec;
AUD_DeviceSpecs specs;
specs.channels = c->channels;
@@ -1123,7 +1137,7 @@ int BKE_ffmpeg_start(struct Scene *scene, RenderData *rd, int rectx, int recty,
}
specs.rate = rd->ffcodecdata.audio_mixrate;
audio_mixdown_device = BKE_sound_mixdown(scene, specs, preview ? rd->psfra : rd->sfra, rd->ffcodecdata.audio_volume);
context->audio_mixdown_device = BKE_sound_mixdown(scene, specs, preview ? rd->psfra : rd->sfra, rd->ffcodecdata.audio_volume);
#ifdef FFMPEG_CODEC_TIME_BASE
c->time_base.den = specs.rate;
c->time_base.num = 1;
@@ -1133,16 +1147,16 @@ int BKE_ffmpeg_start(struct Scene *scene, RenderData *rd, int rectx, int recty,
return success;
}
static void end_ffmpeg_impl(int is_autosplit);
static void end_ffmpeg_impl(FFMpegContext *context, int is_autosplit);
#ifdef WITH_AUDASPACE
static void write_audio_frames(double to_pts)
static void write_audio_frames(FFMpegContext *context, double to_pts)
{
int finished = 0;
while (audio_stream && !finished) {
if ((audio_time >= to_pts) ||
(write_audio_frame()))
while (context->audio_stream && !finished) {
if ((context->audio_time >= to_pts) ||
(write_audio_frame(context)))
{
finished = 1;
}
@@ -1150,8 +1164,10 @@ static void write_audio_frames(double to_pts)
}
#endif
int BKE_ffmpeg_append(RenderData *rd, int start_frame, int frame, int *pixels, int rectx, int recty, ReportList *reports)
int BKE_ffmpeg_append(void *context_v, RenderData *rd, int start_frame, int frame, int *pixels,
int rectx, int recty, const char *suffix, ReportList *reports)
{
FFMpegContext *context = context_v;
AVFrame *avframe;
int success = 1;
@@ -1160,111 +1176,112 @@ int BKE_ffmpeg_append(RenderData *rd, int start_frame, int frame, int *pixels, i
/* why is this done before writing the video frame and again at end_ffmpeg? */
// write_audio_frames(frame / (((double)rd->frs_sec) / rd->frs_sec_base));
if (video_stream) {
avframe = generate_video_frame((unsigned char *) pixels, reports);
success = (avframe && write_video_frame(rd, frame - start_frame, avframe, reports));
if (context->video_stream) {
avframe = generate_video_frame(context, (unsigned char *) pixels, reports);
success = (avframe && write_video_frame(context, rd, frame - start_frame, avframe, reports));
if (ffmpeg_autosplit) {
if (avio_tell(outfile->pb) > FFMPEG_AUTOSPLIT_SIZE) {
end_ffmpeg_impl(true);
ffmpeg_autosplit_count++;
success &= start_ffmpeg_impl(rd, rectx, recty, reports);
if (context->ffmpeg_autosplit) {
if (avio_tell(context->outfile->pb) > FFMPEG_AUTOSPLIT_SIZE) {
end_ffmpeg_impl(context, true);
context->ffmpeg_autosplit_count++;
success &= start_ffmpeg_impl(context, rd, rectx, recty, suffix, reports);
}
}
}
#ifdef WITH_AUDASPACE
write_audio_frames((frame - start_frame) / (((double)rd->frs_sec) / (double)rd->frs_sec_base));
write_audio_frames(context, (frame - start_frame) / (((double)rd->frs_sec) / (double)rd->frs_sec_base));
#endif
return success;
}
static void end_ffmpeg_impl(int is_autosplit)
static void end_ffmpeg_impl(FFMpegContext *context, int is_autosplit)
{
unsigned int i;
PRINT("Closing ffmpeg...\n");
#if 0
if (audio_stream) { /* SEE UPPER */
write_audio_frames();
if (context->audio_stream) { /* SEE UPPER */
write_audio_frames(context);
}
#endif
#ifdef WITH_AUDASPACE
if (is_autosplit == false) {
if (audio_mixdown_device) {
AUD_closeReadDevice(audio_mixdown_device);
audio_mixdown_device = 0;
if (context->audio_mixdown_device) {
AUD_closeReadDevice(context->audio_mixdown_device);
context->audio_mixdown_device = 0;
}
}
#endif
if (video_stream && video_stream->codec) {
if (context->video_stream && context->video_stream->codec) {
PRINT("Flushing delayed frames...\n");
flush_ffmpeg();
flush_ffmpeg(context);
}
if (outfile) {
av_write_trailer(outfile);
if (context->outfile) {
av_write_trailer(context->outfile);
}
/* Close the video codec */
if (video_stream && video_stream->codec) {
avcodec_close(video_stream->codec);
PRINT("zero video stream %p\n", video_stream);
video_stream = 0;
if (context->video_stream && context->video_stream->codec) {
avcodec_close(context->video_stream->codec);
PRINT("zero video stream %p\n", context->video_stream);
context->video_stream = 0;
}
/* Close the output file */
if (outfile) {
for (i = 0; i < outfile->nb_streams; i++) {
if (&outfile->streams[i]) {
av_freep(&outfile->streams[i]);
if (context->outfile) {
for (i = 0; i < context->outfile->nb_streams; i++) {
if (&context->outfile->streams[i]) {
av_freep(&context->outfile->streams[i]);
}
}
}
/* free the temp buffer */
if (current_frame) {
delete_picture(current_frame);
current_frame = 0;
if (context->current_frame) {
delete_picture(context->current_frame);
context->current_frame = 0;
}
if (outfile && outfile->oformat) {
if (!(outfile->oformat->flags & AVFMT_NOFILE)) {
avio_close(outfile->pb);
if (context->outfile && context->outfile->oformat) {
if (!(context->outfile->oformat->flags & AVFMT_NOFILE)) {
avio_close(context->outfile->pb);
}
}
if (outfile) {
av_free(outfile);
outfile = 0;
if (context->outfile) {
av_free(context->outfile);
context->outfile = 0;
}
if (audio_input_buffer) {
av_free(audio_input_buffer);
audio_input_buffer = 0;
if (context->audio_input_buffer) {
av_free(context->audio_input_buffer);
context->audio_input_buffer = 0;
}
#ifndef FFMPEG_HAVE_ENCODE_AUDIO2
if (audio_output_buffer) {
av_free(audio_output_buffer);
audio_output_buffer = 0;
if (context->audio_output_buffer) {
av_free(context->audio_output_buffer);
context->audio_output_buffer = 0;
}
#endif
if (audio_deinterleave_buffer) {
av_free(audio_deinterleave_buffer);
audio_deinterleave_buffer = 0;
if (context->audio_deinterleave_buffer) {
av_free(context->audio_deinterleave_buffer);
context->audio_deinterleave_buffer = 0;
}
if (img_convert_ctx) {
sws_freeContext(img_convert_ctx);
img_convert_ctx = 0;
if (context->img_convert_ctx) {
sws_freeContext(context->img_convert_ctx);
context->img_convert_ctx = 0;
}
}
void BKE_ffmpeg_end(void)
void BKE_ffmpeg_end(void *context_v)
{
end_ffmpeg_impl(false);
FFMpegContext *context = context_v;
end_ffmpeg_impl(context, false);
}
/* properties */
@@ -1658,4 +1675,31 @@ bool BKE_ffmpeg_alpha_channel_is_supported(RenderData *rd)
return false;
}
#endif
void *BKE_ffmpeg_context_create(void)
{
FFMpegContext *context;
/* new ffmpeg data struct */
context = MEM_callocN(sizeof(FFMpegContext), "new ffmpeg context");
context->ffmpeg_codec = AV_CODEC_ID_MPEG4;
context->ffmpeg_audio_codec = AV_CODEC_ID_NONE;
context->ffmpeg_video_bitrate = 1150;
context->ffmpeg_audio_bitrate = 128;
context->ffmpeg_gop_size = 12;
context->ffmpeg_autosplit = 0;
context->ffmpeg_autosplit_count = 0;
context->ffmpeg_preview = false;
return context;
}
void BKE_ffmpeg_context_free(void *context_v)
{
FFMpegContext *context = context_v;
if (context) {
MEM_freeN(context);
}
}
#endif /* WITH_FFMPEG */

View File

@@ -66,12 +66,15 @@
#include "BKE_report.h"
#include "DNA_scene_types.h"
#include "MEM_guardedalloc.h"
static int sock;
static int connsock;
static int write_ppm;
static int render_width;
static int render_height;
typedef struct FrameserverContext {
int sock;
int connsock;
int write_ppm;
int render_width;
int render_height;
} FrameserverContext;
#if defined(_WIN32)
@@ -110,10 +113,11 @@ static int closesocket(int fd)
}
#endif
int BKE_frameserver_start(struct Scene *scene, RenderData *UNUSED(rd), int rectx, int recty, ReportList *reports, bool UNUSED(preview))
int BKE_frameserver_start(void *context_v, struct Scene *scene, RenderData *UNUSED(rd), int rectx, int recty, ReportList *reports, bool UNUSED(preview), const char *UNUSED(suffix))
{
struct sockaddr_in addr;
int arg = 1;
FrameserverContext *context = context_v;
(void)scene; /* unused */
@@ -122,33 +126,33 @@ int BKE_frameserver_start(struct Scene *scene, RenderData *UNUSED(rd), int rectx
return 0;
}
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
if ((context->sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
shutdown_socket_system();
BKE_report(reports, RPT_ERROR, "Cannot open socket");
return 0;
}
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &arg, sizeof(arg));
setsockopt(context->sock, SOL_SOCKET, SO_REUSEADDR, (char *) &arg, sizeof(arg));
addr.sin_family = AF_INET;
addr.sin_port = htons(U.frameserverport);
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
if (bind(context->sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
shutdown_socket_system();
BKE_report(reports, RPT_ERROR, "Cannot bind to socket");
return 0;
}
if (listen(sock, SOMAXCONN) < 0) {
if (listen(context->sock, SOMAXCONN) < 0) {
shutdown_socket_system();
BKE_report(reports, RPT_ERROR, "Cannot establish listen backlog");
return 0;
}
connsock = -1;
context->connsock = -1;
render_width = rectx;
render_height = recty;
context->render_width = rectx;
context->render_height = recty;
return 1;
}
@@ -177,7 +181,7 @@ static char good_bye[] =
"<body><pre>\n"
"Render stopped. Goodbye</pre></body></html>";
static int safe_write(char *s, int tosend)
static int safe_write(const int connsock, char *s, int tosend)
{
int total = tosend;
do {
@@ -192,12 +196,12 @@ static int safe_write(char *s, int tosend)
return total;
}
static int safe_puts(char *s)
static int safe_puts(const int connsock, char *s)
{
return safe_write(s, strlen(s));
return safe_write(connsock, s, strlen(s));
}
static int handle_request(RenderData *rd, char *req)
static int handle_request(FrameserverContext *context, RenderData *rd, char *req)
{
char *p;
char *path;
@@ -214,16 +218,16 @@ static int handle_request(RenderData *rd, char *req)
*p = 0;
if (STREQ(path, "/index.html") || STREQ(path, "/")) {
safe_puts(index_page);
if (STREQ(path, "/index.html") || strcmp(path, "/")) {
safe_puts(context->connsock, index_page);
return -1;
}
write_ppm = 0;
context->write_ppm = 0;
pathlen = strlen(path);
if (pathlen > 12 && memcmp(path, "/images/ppm/", 12) == 0) {
write_ppm = 1;
context->write_ppm = 1;
return atoi(path + 12);
}
if (STREQ(path, "/info.txt")) {
@@ -241,24 +245,24 @@ static int handle_request(RenderData *rd, char *req)
"ratescale %d\n",
rd->sfra,
rd->efra,
render_width,
render_height,
context->render_width,
context->render_height,
rd->frs_sec,
1
);
safe_puts(buf);
safe_puts(context->connsock, buf);
return -1;
}
if (STREQ(path, "/close.txt")) {
safe_puts(good_bye);
safe_puts(context->connsock, good_bye);
G.is_break = true; /* Abort render */
return -1;
}
return -1;
}
int BKE_frameserver_loop(RenderData *rd, ReportList *UNUSED(reports))
int BKE_frameserver_loop(void *context_v, RenderData *rd, ReportList *UNUSED(reports))
{
fd_set readfds;
struct timeval tv;
@@ -271,18 +275,20 @@ int BKE_frameserver_loop(RenderData *rd, ReportList *UNUSED(reports))
#endif
char buf[4096];
if (connsock != -1) {
closesocket(connsock);
connsock = -1;
FrameserverContext *context = context_v;
if (context->connsock != -1) {
closesocket(context->connsock);
context->connsock = -1;
}
tv.tv_sec = 1;
tv.tv_usec = 0;
FD_ZERO(&readfds);
FD_SET(sock, &readfds);
FD_SET(context->sock, &readfds);
rval = select(sock + 1, &readfds, NULL, NULL, &tv);
rval = select(context->sock + 1, &readfds, NULL, NULL, &tv);
if (rval < 0) {
return -1;
}
@@ -293,19 +299,19 @@ int BKE_frameserver_loop(RenderData *rd, ReportList *UNUSED(reports))
socklen = sizeof(addr);
if ((connsock = accept(sock, (struct sockaddr *)&addr, &socklen)) < 0) {
if ((context->connsock = accept(context->sock, (struct sockaddr *)&addr, &socklen)) < 0) {
return -1;
}
FD_ZERO(&readfds);
FD_SET(connsock, &readfds);
FD_SET(context->connsock, &readfds);
for (;;) {
/* give 10 seconds for telnet testing... */
tv.tv_sec = 10;
tv.tv_usec = 0;
rval = select(connsock + 1, &readfds, NULL, NULL, &tv);
rval = select(context->connsock + 1, &readfds, NULL, NULL, &tv);
if (rval > 0) {
break;
}
@@ -319,7 +325,7 @@ int BKE_frameserver_loop(RenderData *rd, ReportList *UNUSED(reports))
}
}
len = recv(connsock, buf, sizeof(buf) - 1, 0);
len = recv(context->connsock, buf, sizeof(buf) - 1, 0);
if (len < 0) {
return -1;
@@ -327,13 +333,13 @@ int BKE_frameserver_loop(RenderData *rd, ReportList *UNUSED(reports))
buf[len] = 0;
return handle_request(rd, buf);
return handle_request(context, rd, buf);
}
static void serve_ppm(int *pixels, int rectx, int recty)
static void serve_ppm(FrameserverContext *context, int *pixels, int rectx, int recty)
{
unsigned char *rendered_frame;
unsigned char *row = (unsigned char *) malloc(render_width * 3);
unsigned char *row = (unsigned char *) malloc(context->render_width * 3);
int y;
char header[1024];
@@ -348,7 +354,7 @@ static void serve_ppm(int *pixels, int rectx, int recty)
"255\n",
rectx, recty);
safe_puts(header);
safe_puts(context->connsock, header);
rendered_frame = (unsigned char *)pixels;
@@ -364,36 +370,54 @@ static void serve_ppm(int *pixels, int rectx, int recty)
target += 3;
src += 4;
}
safe_write((char *)row, 3 * rectx);
safe_write(context->connsock, (char *)row, 3 * rectx);
}
free(row);
closesocket(connsock);
connsock = -1;
closesocket(context->connsock);
context->connsock = -1;
}
int BKE_frameserver_append(RenderData *UNUSED(rd), int UNUSED(start_frame), int frame, int *pixels,
int rectx, int recty, ReportList *UNUSED(reports))
int BKE_frameserver_append(void *context_v, RenderData *UNUSED(rd), int UNUSED(start_frame), int frame, int *pixels,
int rectx, int recty, const char *UNUSED(suffix), ReportList *UNUSED(reports))
{
FrameserverContext *context = context_v;
fprintf(stderr, "Serving frame: %d\n", frame);
if (write_ppm) {
serve_ppm(pixels, rectx, recty);
if (context->write_ppm) {
serve_ppm(context, pixels, rectx, recty);
}
if (connsock != -1) {
closesocket(connsock);
connsock = -1;
if (context->connsock != -1) {
closesocket(context->connsock);
context->connsock = -1;
}
return 1;
}
void BKE_frameserver_end(void)
void BKE_frameserver_end(void *context_v)
{
if (connsock != -1) {
closesocket(connsock);
connsock = -1;
FrameserverContext *context = context_v;
if (context->connsock != -1) {
closesocket(context->connsock);
context->connsock = -1;
}
closesocket(sock);
closesocket(context->sock);
shutdown_socket_system();
}
void *BKE_frameserver_context_create(void)
{
FrameserverContext *context = MEM_mallocN(sizeof(FrameserverContext), "Frameserver Context");
return context;
}
void BKE_frameserver_context_free(void *context_v)
{
FrameserverContext *context = context_v;
if (context) {
MEM_freeN(context);
}
}
#endif /* WITH_FRAMESERVER */

View File

@@ -89,6 +89,7 @@ int BLI_system_num_threads_override_get(void);
#define LOCK_MOVIECLIP 7
#define LOCK_COLORMANAGE 8
#define LOCK_FFTW 9
#define LOCK_VIEW3D 10
void BLI_lock_thread(int type);
void BLI_unlock_thread(int type);

View File

@@ -122,6 +122,7 @@ static pthread_mutex_t _nodes_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _movieclip_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _colormanage_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _fftw_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _view3d_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_t mainid;
static int thread_levels = 0; /* threads can be invoked inside threads */
static int num_threads_override = 0;
@@ -402,6 +403,8 @@ void BLI_lock_thread(int type)
pthread_mutex_lock(&_colormanage_lock);
else if (type == LOCK_FFTW)
pthread_mutex_lock(&_fftw_lock);
else if (type == LOCK_VIEW3D)
pthread_mutex_lock(&_view3d_lock);
}
void BLI_unlock_thread(int type)
@@ -426,6 +429,8 @@ void BLI_unlock_thread(int type)
pthread_mutex_unlock(&_colormanage_lock);
else if (type == LOCK_FFTW)
pthread_mutex_unlock(&_fftw_lock);
else if (type == LOCK_VIEW3D)
pthread_mutex_unlock(&_view3d_lock);
}
/* Mutex Locks */

View File

@@ -1533,9 +1533,15 @@ void blo_make_packed_pointer_map(FileData *fd, Main *oldmain)
fd->packedmap = oldnewmap_new();
for (ima = oldmain->image.first; ima; ima = ima->id.next)
for (ima = oldmain->image.first; ima; ima = ima->id.next) {
ImagePackedFile *imapf;
if (ima->packedfile)
insert_packedmap(fd, ima->packedfile);
for (imapf = ima->packedfiles.first; imapf; imapf = imapf->next)
if (imapf->packedfile)
insert_packedmap(fd, imapf->packedfile);
}
for (vfont = oldmain->vfont.first; vfont; vfont = vfont->id.next)
if (vfont->packedfile)
@@ -1568,8 +1574,13 @@ void blo_end_packed_pointer_map(FileData *fd, Main *oldmain)
entry->newp = NULL;
}
for (ima = oldmain->image.first; ima; ima = ima->id.next)
for (ima = oldmain->image.first; ima; ima = ima->id.next) {
ImagePackedFile *imapf;
ima->packedfile = newpackedadr(fd, ima->packedfile);
for (imapf = ima->packedfiles.first; imapf; imapf = imapf->next)
imapf->packedfile = newpackedadr(fd, imapf->packedfile);
}
for (vfont = oldmain->vfont.first; vfont; vfont = vfont->id.next)
vfont->packedfile = newpackedadr(fd, vfont->packedfile);
@@ -3391,6 +3402,8 @@ static void lib_link_image(FileData *fd, Main *main)
static void direct_link_image(FileData *fd, Image *ima)
{
ImagePackedFile *imapf;
/* for undo system, pointers could be restored */
if (fd->imamap)
ima->cache = newimaadr(fd, ima->cache);
@@ -3404,8 +3417,7 @@ static void direct_link_image(FileData *fd, Image *ima)
ima->gputexture = NULL;
ima->rr = NULL;
}
ima->anim = NULL;
ima->repbind = NULL;
/* undo system, try to restore render buffers */
@@ -3419,9 +3431,18 @@ static void direct_link_image(FileData *fd, Image *ima)
memset(ima->renders, 0, sizeof(ima->renders));
ima->last_render_slot = ima->render_slot;
}
link_list(fd, &(ima->views));
link_list(fd, &(ima->packedfiles));
for (imapf = ima->packedfiles.first; imapf; imapf = imapf->next) {
imapf->packedfile = direct_link_packedfile(fd, imapf->packedfile);
}
ima->anims.first = ima->anims.last = NULL;
ima->packedfile = direct_link_packedfile(fd, ima->packedfile);
ima->preview = direct_link_preview_image(fd, ima->preview);
ima->stereo3d_format = newdataadr(fd, ima->stereo3d_format);
ima->ok = 1;
}
@@ -5378,7 +5399,7 @@ static void lib_link_scene(FileData *fd, Main *main)
seq->scene_sound = BKE_sound_add_scene_sound_defaults(sce, seq);
}
}
seq->anim = NULL;
seq->anims.first = seq->anims.last = NULL;
lib_link_sequence_modifiers(fd, sce, &seq->modifiers);
}
@@ -5610,6 +5631,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
if (seq->seq3 == NULL) seq->seq3 = seq->seq2;
seq->effectdata = newdataadr(fd, seq->effectdata);
seq->stereo3d_format = newdataadr(fd, seq->stereo3d_format);
if (seq->type & SEQ_TYPE_EFFECT)
seq->flag |= SEQ_EFFECT_NOT_LOADED;
@@ -5722,6 +5744,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
link_list(fd, &(sce->markers));
link_list(fd, &(sce->transform_spaces));
link_list(fd, &(sce->r.layers));
link_list(fd, &(sce->r.views));
for (srl = sce->r.layers.first; srl; srl = srl->next) {
link_list(fd, &(srl->freestyleConfig.modules));
@@ -5785,8 +5808,8 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
BLI_listbase_clear(&win->modalhandlers);
BLI_listbase_clear(&win->subwindows);
BLI_listbase_clear(&win->gesture);
BLI_listbase_clear(&win->drawdata);
win->drawdata = NULL;
win->drawmethod = -1;
win->drawfail = 0;
win->active = 0;
@@ -5794,6 +5817,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
win->cursor = 0;
win->lastcursor = 0;
win->modalcursor = 0;
win->stereo3d_format = newdataadr(fd, win->stereo3d_format);
}
BLI_listbase_clear(&wm->timers);
@@ -7765,7 +7789,6 @@ static void do_versions_userdef(FileData *fd, BlendFileData *bfd)
user->walk_navigation.jump_height = 0.4f; /* m */
user->walk_navigation.teleport_time = 0.2f; /* s */
}
}
static void do_versions(FileData *fd, Library *lib, Main *main)
@@ -7888,7 +7911,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
link_list(fd, &user->user_keymaps);
link_list(fd, &user->addons);
link_list(fd, &user->autoexec_paths);
for (keymap=user->user_keymaps.first; keymap; keymap=keymap->next) {
keymap->modal_items= NULL;
keymap->poll = NULL;

View File

@@ -27,6 +27,7 @@
#include "BLI_utildefines.h"
#include "BLI_compiler_attrs.h"
#include "BLI_string.h"
/* for MinGW32 definition of NULL, could use BLI_blenlib.h instead too */
#include <stddef.h>
@@ -48,14 +49,18 @@
#include "DNA_particle_types.h"
#include "DNA_linestyle_types.h"
#include "DNA_actuator_types.h"
#include "DNA_camera_types.h"
#include "DNA_view3d_types.h"
#include "DNA_genfile.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
#include "BKE_node.h"
#include "BKE_scene.h"
#include "BKE_sequencer.h"
#include "BKE_screen.h"
#include "BKE_sequencer.h"
#include "BLI_math.h"
#include "BLI_listbase.h"
@@ -460,10 +465,10 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
br->mtex.random_angle = 2.0 * M_PI;
br->mask_mtex.random_angle = 2.0 * M_PI;
}
}
#undef BRUSH_RAKE
#undef BRUSH_RANDOM_ROTATION
}
/* Customizable Safe Areas */
if (!MAIN_VERSION_ATLEAST(main, 273, 2)) {
@@ -724,4 +729,85 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
#undef SEQ_USE_PROXY_CUSTOM_DIR
#undef SEQ_USE_PROXY_CUSTOM_FILE
}
if (!MAIN_VERSION_ATLEAST(main, 274, 3))
{
SceneRenderView *srv;
wmWindowManager *wm;
bScreen *screen;
wmWindow *win;
Scene *scene;
Camera *cam;
Image *ima;
for (scene = main->scene.first; scene; scene = scene->id.next) {
Sequence *seq;
BKE_scene_add_render_view(scene, STEREO_LEFT_NAME);
srv = scene->r.views.first;
BLI_strncpy(srv->suffix, STEREO_LEFT_SUFFIX, sizeof(srv->suffix));
BKE_scene_add_render_view(scene, STEREO_RIGHT_NAME);
srv = scene->r.views.last;
BLI_strncpy(srv->suffix, STEREO_RIGHT_SUFFIX, sizeof(srv->suffix));
SEQ_BEGIN (scene->ed, seq)
{
seq->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Stereo Display 3d Format");
}
SEQ_END
}
for (screen = main->screen.first; screen; screen = screen->id.next) {
ScrArea *sa;
for (sa = screen->areabase.first; sa; sa = sa->next) {
SpaceLink *sl;
for (sl = sa->spacedata.first; sl; sl = sl->next) {
switch (sl->spacetype) {
case SPACE_VIEW3D:
{
View3D *v3d = (View3D *)sl;
v3d->stereo3d_camera = STEREO_3D_ID;
v3d->stereo3d_flag |= V3D_S3D_DISPPLANE;
v3d->stereo3d_convergence_alpha = 0.15f;
v3d->stereo3d_volume_alpha = 0.05f;
break;
}
case SPACE_IMAGE:
{
SpaceImage *sima = (SpaceImage *) sl;
sima->iuser.flag |= IMA_SHOW_STEREO;
sima->iuser.passtype = SCE_PASS_COMBINED;
break;
}
}
}
}
}
for (cam = main->camera.first; cam; cam = cam->id.next) {
cam->stereo.interocular_distance = 0.065;
cam->stereo.convergence_distance = 30.f * 0.065;
}
for (ima = main->image.first; ima; ima = ima->id.next) {
ima->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Image Stereo 3d Format");
if (ima->packedfile) {
ImagePackedFile *imapf = MEM_mallocN(sizeof(ImagePackedFile), "Image Packed File");
BLI_addtail(&ima->packedfiles, imapf);
imapf->packedfile = ima->packedfile;
BLI_strncpy(imapf->filepath, ima->name, FILE_MAX);
ima->packedfile = NULL;
}
}
for (wm = main->wm.first; wm; wm = wm->id.next) {
for (win = wm->windows.first; win; win = win->next) {
win->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Stereo Display 3d Format");
}
}
}
}

View File

@@ -2124,7 +2124,8 @@ static void write_images(WriteData *wd, ListBase *idbase)
{
Image *ima;
PackedFile * pf;
ImageView *iv;
ImagePackedFile *imapf;
ima= idbase->first;
while (ima) {
@@ -2133,13 +2134,20 @@ static void write_images(WriteData *wd, ListBase *idbase)
writestruct(wd, ID_IM, "Image", 1, ima);
if (ima->id.properties) IDP_WriteProperty(ima->id.properties, wd);
if (ima->packedfile) {
pf = ima->packedfile;
writestruct(wd, DATA, "PackedFile", 1, pf);
writedata(wd, DATA, pf->size, pf->data);
for (imapf = ima->packedfiles.first; imapf; imapf = imapf->next) {
writestruct(wd, DATA, "ImagePackedFile", 1, imapf);
if (imapf->packedfile) {
pf = imapf->packedfile;
writestruct(wd, DATA, "PackedFile", 1, pf);
writedata(wd, DATA, pf->size, pf->data);
}
}
write_previews(wd, ima->preview);
for (iv = ima->views.first; iv; iv = iv->next)
writestruct(wd, DATA, "ImageView", 1, iv);
writestruct(wd, DATA, "Stereo3dFormat", 1, ima->stereo3d_format);
}
ima= ima->id.next;
}
@@ -2340,6 +2348,7 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
TimeMarker *marker;
TransformOrientation *ts;
SceneRenderLayer *srl;
SceneRenderView *srv;
ToolSettings *tos;
FreestyleModuleConfig *fmc;
FreestyleLineSet *fls;
@@ -2421,7 +2430,9 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
break;
}
}
writestruct(wd, DATA, "Stereo3dFormat", 1, seq->stereo3d_format);
strip= seq->strip;
writestruct(wd, DATA, "Strip", 1, strip);
if (seq->flag & SEQ_USE_CROP && strip->crop) {
@@ -2486,6 +2497,10 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
writestruct(wd, DATA, "FreestyleLineSet", 1, fls);
}
}
/* writing MultiView to the blend file */
for (srv = sce->r.views.first; srv; srv = srv->next)
writestruct(wd, DATA, "SceneRenderView", 1, srv);
if (sce->nodetree) {
writestruct(wd, DATA, "bNodeTree", 1, sce->nodetree);
@@ -2548,8 +2563,10 @@ static void write_windowmanagers(WriteData *wd, ListBase *lb)
for (wm= lb->first; wm; wm= wm->id.next) {
writestruct(wd, ID_WM, "wmWindowManager", 1, wm);
for (win= wm->windows.first; win; win= win->next)
for (win= wm->windows.first; win; win= win->next) {
writestruct(wd, DATA, "wmWindow", 1, win);
writestruct(wd, DATA, "Stereo3dFormat", 1, win->stereo3d_format);
}
}
}

View File

@@ -74,7 +74,7 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
short image_source = image->source;
bool is_generated = image_source == IMA_SRC_GENERATED;
bool is_packed = image->packedfile != NULL;
bool is_packed = BKE_image_has_packedfile(image);
char export_path[FILE_MAX];
char source_path[FILE_MAX];

View File

@@ -119,6 +119,8 @@ set(SRC
nodes/COM_TimeNode.h
nodes/COM_SwitchNode.cpp
nodes/COM_SwitchNode.h
nodes/COM_SwitchViewNode.cpp
nodes/COM_SwitchViewNode.h
nodes/COM_MovieClipNode.cpp
nodes/COM_MovieClipNode.h
nodes/COM_OutputFileNode.cpp
@@ -370,6 +372,8 @@ set(SRC
operations/COM_CompositorOperation.cpp
operations/COM_OutputFileOperation.h
operations/COM_OutputFileOperation.cpp
operations/COM_OutputFileMultiViewOperation.h
operations/COM_OutputFileMultiViewOperation.cpp
operations/COM_ViewerOperation.h
operations/COM_ViewerOperation.cpp
operations/COM_PreviewOperation.h

View File

@@ -316,7 +316,8 @@ extern "C" {
* generation in display space
*/
void COM_execute(RenderData *rd, Scene *scene, bNodeTree *editingtree, int rendering,
const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings);
const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings,
const char *viewName);
/**
* @brief Deinitialize the compositor caches and allocated memory.

View File

@@ -87,6 +87,11 @@ private:
const ColorManagedViewSettings *m_viewSettings;
const ColorManagedDisplaySettings *m_displaySettings;
/**
* @brief active rendering view name
*/
const char *m_viewName;
public:
/**
* @brief constructor initializes the context with default values.
@@ -180,7 +185,17 @@ public:
* @brief set has this system active openclDevices?
*/
void setHasActiveOpenCLDevices(bool hasAvtiveOpenCLDevices) { this->m_hasActiveOpenCLDevices = hasAvtiveOpenCLDevices; }
/**
* @brief get the active rendering view
*/
const char *getViewName() const { return this->m_viewName; }
/**
* @brief set the active rendering view
*/
void setViewName(const char *viewName) { this->m_viewName = viewName; }
int getChunksize() const { return this->getbNodeTree()->chunksize; }
void setFastCalculation(bool fastCalculation) {this->m_fastCalculation = fastCalculation;}

View File

@@ -101,6 +101,7 @@ extern "C" {
#include "COM_Stabilize2dNode.h"
#include "COM_SunBeamsNode.h"
#include "COM_SwitchNode.h"
#include "COM_SwitchViewNode.h"
#include "COM_TextureNode.h"
#include "COM_TimeNode.h"
#include "COM_TonemapNode.h"
@@ -328,6 +329,9 @@ Node *Converter::convert(bNode *b_node)
case CMP_NODE_SWITCH:
node = new SwitchNode(b_node);
break;
case CMP_NODE_SWITCH_VIEW:
node = new SwitchViewNode(b_node);
break;
case CMP_NODE_GLARE:
node = new GlareNode(b_node);
break;

View File

@@ -43,8 +43,10 @@ extern "C" {
#endif
ExecutionSystem::ExecutionSystem(RenderData *rd, Scene *scene, bNodeTree *editingtree, bool rendering, bool fastcalculation,
const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings)
const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings,
const char *viewName)
{
this->m_context.setViewName(viewName);
this->m_context.setScene(scene);
this->m_context.setbNodeTree(editingtree);
this->m_context.setPreviewHash(editingtree->previews);

View File

@@ -151,7 +151,8 @@ public:
* @param rendering [true false]
*/
ExecutionSystem(RenderData *rd, Scene *scene, bNodeTree *editingtree, bool rendering, bool fastcalculation,
const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings);
const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings,
const char *viewName);
/**
* Destructor

View File

@@ -45,7 +45,8 @@ static void intern_freeCompositorCaches()
void COM_execute(RenderData *rd, Scene *scene, bNodeTree *editingtree, int rendering,
const ColorManagedViewSettings *viewSettings,
const ColorManagedDisplaySettings *displaySettings)
const ColorManagedDisplaySettings *displaySettings,
const char *viewName)
{
/* initialize mutex, TODO this mutex init is actually not thread safe and
* should be done somewhere as part of blender startup, all the other
@@ -82,7 +83,7 @@ void COM_execute(RenderData *rd, Scene *scene, bNodeTree *editingtree, int rende
bool twopass = (editingtree->flag & NTREE_TWO_PASS) > 0 && !rendering;
/* initialize execution system */
if (twopass) {
ExecutionSystem *system = new ExecutionSystem(rd, scene, editingtree, rendering, twopass, viewSettings, displaySettings);
ExecutionSystem *system = new ExecutionSystem(rd, scene, editingtree, rendering, twopass, viewSettings, displaySettings, viewName);
system->execute();
delete system;
@@ -95,7 +96,7 @@ void COM_execute(RenderData *rd, Scene *scene, bNodeTree *editingtree, int rende
}
ExecutionSystem *system = new ExecutionSystem(rd, scene, editingtree, rendering, false,
viewSettings, displaySettings);
viewSettings, displaySettings, viewName);
system->execute();
delete system;

View File

@@ -43,6 +43,7 @@ void CompositorNode::convertToOperations(NodeConverter &converter, const Composi
CompositorOperation *compositorOperation = new CompositorOperation();
compositorOperation->setSceneName(context.getScene()->id.name);
compositorOperation->setRenderData(context.getRenderData());
compositorOperation->setViewName(context.getViewName());
compositorOperation->setbNodeTree(context.getbNodeTree());
/* alpha socket gives either 1 or a custom alpha value if "use alpha" is enabled */
compositorOperation->setUseAlphaInput(ignore_alpha || alphaSocket->isLinked());

View File

@@ -40,19 +40,19 @@ ImageNode::ImageNode(bNode *editorNode) : Node(editorNode)
}
NodeOperation *ImageNode::doMultilayerCheck(NodeConverter &converter, RenderLayer *rl, Image *image, ImageUser *user,
int framenumber, int outputsocketIndex, int passindex, DataType datatype) const
int framenumber, int outputsocketIndex, int passtype, int view, DataType datatype) const
{
NodeOutput *outputSocket = this->getOutputSocket(outputsocketIndex);
MultilayerBaseOperation *operation = NULL;
switch (datatype) {
case COM_DT_VALUE:
operation = new MultilayerValueOperation(passindex);
operation = new MultilayerValueOperation(passtype, view);
break;
case COM_DT_VECTOR:
operation = new MultilayerVectorOperation(passindex);
operation = new MultilayerVectorOperation(passtype, view);
break;
case COM_DT_COLOR:
operation = new MultilayerColorOperation(passindex);
operation = new MultilayerColorOperation(passtype, view);
break;
default:
break;
@@ -96,6 +96,10 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo
NodeOperation *operation = NULL;
socket = this->getOutputSocket(index);
bNodeSocket *bnodeSocket = socket->getbNodeSocket();
RenderPass *rpass = (RenderPass *)BLI_findstring(&rl->passes, bnodeSocket->identifier, offsetof(RenderPass, internal_name));
int view = (rpass ? rpass->view_id : 0);
/* Passes in the file can differ from passes stored in sockets (#36755).
* Look up the correct file pass using the socket identifier instead.
*/
@@ -104,8 +108,22 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo
int passindex = storage->pass_index;*/
RenderPass *rpass = (RenderPass *)BLI_findlink(&rl->passes, passindex);
#endif
int passindex;
RenderPass *rpass;
/* returns the image view to use for the current active view */
if (BLI_listbase_count_ex(&image->rr->views, 2) > 1) {
const int view_image = imageuser->view;
const bool is_allview = (view_image == 0); /* if view selected == All (0) */
if (is_allview) {
/* heuristic to match image name with scene names
* check if the view name exists in the image */
view = BLI_findstringindex(&image->rr->views, context.getViewName(), offsetof(RenderView, name));
}
else {
view = view_image - 1;
}
}
if (STREQ(bnodeSocket->identifier, "Alpha")) {
BLI_assert(combined_operation != NULL);
NodeOutput *outputSocket = this->getOutputSocket(index);
@@ -118,22 +136,21 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo
operation = separate_operation;
}
else {
for (rpass = (RenderPass *)rl->passes.first, passindex = 0; rpass; rpass = rpass->next, ++passindex)
if (STREQ(rpass->name, bnodeSocket->identifier))
break;
if (rpass) {
imageuser->pass = passindex;
switch (rpass->channels) {
case 1:
operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, passindex, COM_DT_VALUE);
operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index,
rpass->passtype, view, COM_DT_VALUE);
break;
/* using image operations for both 3 and 4 channels (RGB and RGBA respectively) */
/* XXX any way to detect actual vector images? */
case 3:
operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, passindex, COM_DT_VECTOR);
operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index,
rpass->passtype, view, COM_DT_VECTOR);
break;
case 4:
operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index, passindex, COM_DT_COLOR);
operation = doMultilayerCheck(converter, rl, image, imageuser, framenumber, index,
rpass->passtype, view, COM_DT_COLOR);
break;
default:
/* dummy operation is added below */
@@ -168,6 +185,8 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo
operation->setImage(image);
operation->setImageUser(imageuser);
operation->setFramenumber(framenumber);
operation->setRenderData(context.getRenderData());
operation->setViewName(context.getViewName());
converter.addOperation(operation);
if (outputStraightAlpha) {
@@ -190,6 +209,8 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo
alphaOperation->setImage(image);
alphaOperation->setImageUser(imageuser);
alphaOperation->setFramenumber(framenumber);
alphaOperation->setRenderData(context.getRenderData());
alphaOperation->setViewName(context.getViewName());
converter.addOperation(alphaOperation);
converter.mapOutputSocket(alphaImage, alphaOperation->getOutputSocket());
@@ -200,6 +221,8 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo
depthOperation->setImage(image);
depthOperation->setImageUser(imageuser);
depthOperation->setFramenumber(framenumber);
depthOperation->setRenderData(context.getRenderData());
depthOperation->setViewName(context.getViewName());
converter.addOperation(depthOperation);
converter.mapOutputSocket(depthImage, depthOperation->getOutputSocket());
@@ -239,6 +262,7 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo
}
if (operation) {
/* not supporting multiview for this generic case */
converter.addOperation(operation);
converter.mapOutputSocket(output, operation->getOutputSocket());
}

View File

@@ -36,7 +36,7 @@ extern "C" {
class ImageNode : public Node {
private:
NodeOperation *doMultilayerCheck(NodeConverter &converter, RenderLayer *rl, Image *image, ImageUser *user,
int framenumber, int outputsocketIndex, int passindex, DataType datatype) const;
int framenumber, int outputsocketIndex, int passtype, int view, DataType datatype) const;
public:
ImageNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;

View File

@@ -23,8 +23,11 @@
#include "COM_OutputFileNode.h"
#include "COM_OutputFileOperation.h"
#include "COM_OutputFileMultiViewOperation.h"
#include "COM_ExecutionSystem.h"
#include "BKE_scene.h"
#include "BLI_path_util.h"
OutputFileNode::OutputFileNode(bNode *editorNode) : Node(editorNode)
@@ -35,6 +38,7 @@ OutputFileNode::OutputFileNode(bNode *editorNode) : Node(editorNode)
void OutputFileNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
NodeImageMultiFile *storage = (NodeImageMultiFile *)this->getbNode()->storage;
const bool is_multiview = (context.getRenderData()->scemode & R_MULTIVIEW) != 0;
if (!context.isRendering()) {
/* only output files when rendering a sequence -
@@ -46,10 +50,18 @@ void OutputFileNode::convertToOperations(NodeConverter &converter, const Composi
if (storage->format.imtype == R_IMF_IMTYPE_MULTILAYER) {
/* single output operation for the multilayer file */
OutputOpenExrMultiLayerOperation *outputOperation = new OutputOpenExrMultiLayerOperation(
context.getRenderData(), context.getbNodeTree(), storage->base_path, storage->format.exr_codec);
OutputOpenExrMultiLayerOperation *outputOperation;
if (is_multiview && storage->format.views_format == R_IMF_VIEWS_MULTIVIEW) {
outputOperation = new OutputOpenExrMultiLayerMultiViewOperation(
context.getRenderData(), context.getbNodeTree(), storage->base_path, storage->format.exr_codec, context.getViewName());
}
else {
outputOperation = new OutputOpenExrMultiLayerOperation(
context.getRenderData(), context.getbNodeTree(), storage->base_path, storage->format.exr_codec, context.getViewName());
}
converter.addOperation(outputOperation);
int num_inputs = getNumberOfInputSockets();
bool previewAdded = false;
for (int i = 0; i < num_inputs; ++i) {
@@ -76,17 +88,31 @@ void OutputFileNode::convertToOperations(NodeConverter &converter, const Composi
NodeImageMultiFileSocket *sockdata = (NodeImageMultiFileSocket *)input->getbNodeSocket()->storage;
ImageFormatData *format = (sockdata->use_node_format ? &storage->format : &sockdata->format);
char path[FILE_MAX];
/* combine file path for the input */
BLI_join_dirfile(path, FILE_MAX, storage->base_path, sockdata->path);
OutputSingleLayerOperation *outputOperation = new OutputSingleLayerOperation(
context.getRenderData(), context.getbNodeTree(), input->getDataType(), format, path,
context.getViewSettings(), context.getDisplaySettings());
NodeOperation *outputOperation = NULL;
if (is_multiview && format->views_format == R_IMF_VIEWS_MULTIVIEW) {
outputOperation = new OutputOpenExrSingleLayerMultiViewOperation(
context.getRenderData(), context.getbNodeTree(), input->getDataType(), format, path,
context.getViewSettings(), context.getDisplaySettings(), context.getViewName());
}
else if ((!is_multiview) || (format->views_format == R_IMF_VIEWS_INDIVIDUAL)) {
outputOperation = new OutputSingleLayerOperation(
context.getRenderData(), context.getbNodeTree(), input->getDataType(), format, path,
context.getViewSettings(), context.getDisplaySettings(), context.getViewName());
}
else { /* R_IMF_VIEWS_STEREO_3D */
outputOperation = new OutputStereoOperation(
context.getRenderData(), context.getbNodeTree(), input->getDataType(), format, path,
sockdata->layer, context.getViewSettings(), context.getDisplaySettings(), context.getViewName());
}
converter.addOperation(outputOperation);
converter.mapInputSocket(input, outputOperation->getInputSocket(0));
if (!previewAdded) {
converter.addNodeInputPreview(input);
previewAdded = true;

View File

@@ -42,7 +42,8 @@ void RenderLayersNode::testSocketLink(NodeConverter &converter, const Compositor
operation->setScene(scene);
operation->setLayerId(layerId);
operation->setRenderData(context.getRenderData());
operation->setViewName(context.getViewName());
converter.mapOutputSocket(outputSocket, operation->getOutputSocket());
converter.addOperation(operation);

View File

@@ -22,6 +22,8 @@
#include "COM_SplitViewerNode.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_scene.h"
#include "COM_SplitOperation.h"
#include "COM_ViewerOperation.h"
@@ -55,6 +57,8 @@ void SplitViewerNode::convertToOperations(NodeConverter &converter, const Compos
viewerOperation->setImageUser(imageUser);
viewerOperation->setViewSettings(context.getViewSettings());
viewerOperation->setDisplaySettings(context.getDisplaySettings());
viewerOperation->setRenderData(context.getRenderData());
viewerOperation->setViewName(context.getViewName());
/* defaults - the viewer node has these options but not exposed for split view
* we could use the split to define an area of interest on one axis at least */

View File

@@ -0,0 +1,42 @@
/*
* Copyright 2015, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor:
* Dalai Felinto
*/
#include "COM_SwitchViewNode.h"
#include "BLI_listbase.h"
SwitchViewNode::SwitchViewNode(bNode *editorNode) : Node(editorNode)
{
/* pass */
}
void SwitchViewNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
NodeOperationOutput *result;
const char *viewName = context.getViewName();
bNode *bnode = this->getbNode();
/* get the internal index of the socket with a matching name */
int nr = BLI_findstringindex(&bnode->inputs, viewName, offsetof(bNodeSocket, name));
nr = max(nr, 0);
result = converter.addInputProxy(getInputSocket(nr), false);
converter.mapOutputSocket(getOutputSocket(0), result);
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2015, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor:
* Dalai Felinto
*/
#ifndef _COM_SwitchViewNode_h_
#define _COM_SwitchViewNode_h_
#include "COM_Node.h"
#include "COM_NodeOperation.h"
#include "DNA_node_types.h"
/**
* @brief SwitchViewNode
* @ingroup Node
*/
class SwitchViewNode : public Node {
public:
SwitchViewNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
};
#endif

View File

@@ -22,6 +22,9 @@
#include "COM_ViewerNode.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BLI_listbase.h"
#include "BKE_scene.h"
#include "COM_ViewerOperation.h"
#include "COM_ExecutionSystem.h"
@@ -51,6 +54,8 @@ void ViewerNode::convertToOperations(NodeConverter &converter, const CompositorC
viewerOperation->setCenterY(editorNode->custom4);
/* alpha socket gives either 1 or a custom alpha value if "use alpha" is enabled */
viewerOperation->setUseAlphaInput(ignore_alpha || alphaSocket->isLinked());
viewerOperation->setRenderData(context.getRenderData());
viewerOperation->setViewName(context.getViewName());
viewerOperation->setViewSettings(context.getViewSettings());
viewerOperation->setDisplaySettings(context.getDisplaySettings());

View File

@@ -52,6 +52,7 @@ CompositorOperation::CompositorOperation() : NodeOperation()
this->m_active = false;
this->m_sceneName[0] = '\0';
this->m_viewName = NULL;
}
void CompositorOperation::initExecution()
@@ -81,14 +82,16 @@ void CompositorOperation::deinitExecution()
RenderResult *rr = RE_AcquireResultWrite(re);
if (rr) {
if (rr->rectf != NULL) {
MEM_freeN(rr->rectf);
RenderView *rv = (RenderView *)BLI_findstring(&rr->views, this->m_viewName, offsetof(RenderView, name));
if (rv->rectf != NULL) {
MEM_freeN(rv->rectf);
}
rr->rectf = this->m_outputBuffer;
if (rr->rectz != NULL) {
MEM_freeN(rr->rectz);
rv->rectf = this->m_outputBuffer;
if (rv->rectz != NULL) {
MEM_freeN(rv->rectz);
}
rr->rectz = this->m_depthBuffer;
rv->rectz = this->m_depthBuffer;
}
else {
if (this->m_outputBuffer) {

View File

@@ -75,11 +75,17 @@ private:
* @brief operation is active for calculating final compo result
*/
bool m_active;
/**
* @brief View name, used for multiview
*/
const char *m_viewName;
public:
CompositorOperation();
const bool isActiveCompositorOutput() const { return this->m_active; }
void executeRegion(rcti *rect, unsigned int tileNumber);
void setSceneName(const char *sceneName) { BLI_strncpy(this->m_sceneName, sceneName, sizeof(this->m_sceneName)); }
void setViewName(const char *viewName) { this->m_viewName = viewName; }
void setRenderData(const RenderData *rd) { this->m_rd = rd; }
bool isOutputOperation(bool /*rendering*/) const { return this->isActiveCompositorOutput(); }
void initExecution();

View File

@@ -25,6 +25,7 @@
#include "BLI_listbase.h"
#include "DNA_image_types.h"
#include "BKE_image.h"
#include "BKE_scene.h"
#include "BLI_math.h"
extern "C" {
@@ -48,6 +49,8 @@ BaseImageOperation::BaseImageOperation() : NodeOperation()
this->m_framenumber = 0;
this->m_depthBuffer = NULL;
this->m_numberOfChannels = 0;
this->m_rd = NULL;
this->m_viewName = NULL;
}
ImageOperation::ImageOperation() : BaseImageOperation()
{
@@ -65,8 +68,12 @@ ImageDepthOperation::ImageDepthOperation() : BaseImageOperation()
ImBuf *BaseImageOperation::getImBuf()
{
ImBuf *ibuf;
ibuf = BKE_image_acquire_ibuf(this->m_image, this->m_imageUser, NULL);
ImageUser iuser = *this->m_imageUser;
/* local changes to the original ImageUser */
iuser.multi_index = BKE_scene_multiview_view_id_get(this->m_rd, this->m_viewName);
ibuf = BKE_image_acquire_ibuf(this->m_image, &iuser, NULL);
if (ibuf == NULL || (ibuf->rect == NULL && ibuf->rect_float == NULL)) {
BKE_image_release_ibuf(this->m_image, ibuf, NULL);
return NULL;

View File

@@ -49,7 +49,9 @@ protected:
int m_imagewidth;
int m_framenumber;
int m_numberOfChannels;
const RenderData *m_rd;
const char *m_viewName;
BaseImageOperation();
/**
* Determine the output resolution. The resolution is retrieved from the Renderer
@@ -64,7 +66,8 @@ public:
void deinitExecution();
void setImage(Image *image) { this->m_image = image; }
void setImageUser(ImageUser *imageuser) { this->m_imageUser = imageuser; }
void setRenderData(const RenderData *rd) { this->m_rd = rd; }
void setViewName(const char *viewName) { this->m_viewName = viewName; }
void setFramenumber(int framenumber) { this->m_framenumber = framenumber; }
};
class ImageOperation : public BaseImageOperation {

View File

@@ -27,18 +27,27 @@ extern "C" {
# include "IMB_imbuf_types.h"
}
MultilayerBaseOperation::MultilayerBaseOperation(int passindex) : BaseImageOperation()
MultilayerBaseOperation::MultilayerBaseOperation(int passtype, int view) : BaseImageOperation()
{
this->m_passId = passindex;
this->m_passtype = passtype;
this->m_view = view;
}
ImBuf *MultilayerBaseOperation::getImBuf()
{
RenderPass *rpass = (RenderPass *)BLI_findlink(&this->m_renderlayer->passes, this->m_passId);
if (rpass) {
this->m_imageUser->pass = m_passId;
BKE_image_multilayer_index(this->m_image->rr, this->m_imageUser);
return BaseImageOperation::getImBuf();
/* temporarily changes the view to get the right ImBuf */
int view = this->m_imageUser->view;
this->m_imageUser->view = this->m_view;
this->m_imageUser->passtype = this->m_passtype;
if (BKE_image_multilayer_index(this->m_image->rr, this->m_imageUser)) {
ImBuf *ibuf = BaseImageOperation::getImBuf();
this->m_imageUser->view = view;
return ibuf;
}
this->m_imageUser->view = view;
return NULL;
}

View File

@@ -29,7 +29,8 @@
class MultilayerBaseOperation : public BaseImageOperation {
private:
int m_passId;
int m_passtype;
int m_view;
RenderLayer *m_renderlayer;
protected:
ImBuf *getImBuf();
@@ -37,13 +38,13 @@ public:
/**
* Constructor
*/
MultilayerBaseOperation(int passindex);
MultilayerBaseOperation(int passtype, int view);
void setRenderLayer(RenderLayer *renderlayer) { this->m_renderlayer = renderlayer; }
};
class MultilayerColorOperation : public MultilayerBaseOperation {
public:
MultilayerColorOperation(int passindex) : MultilayerBaseOperation(passindex) {
MultilayerColorOperation(int passtype, int view) : MultilayerBaseOperation(passtype, view) {
this->addOutputSocket(COM_DT_COLOR);
}
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
@@ -51,7 +52,7 @@ public:
class MultilayerValueOperation : public MultilayerBaseOperation {
public:
MultilayerValueOperation(int passindex) : MultilayerBaseOperation(passindex) {
MultilayerValueOperation(int passtype, int view) : MultilayerBaseOperation(passtype, view) {
this->addOutputSocket(COM_DT_VALUE);
}
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
@@ -59,7 +60,7 @@ public:
class MultilayerVectorOperation : public MultilayerBaseOperation {
public:
MultilayerVectorOperation(int passindex) : MultilayerBaseOperation(passindex) {
MultilayerVectorOperation(int passtype, int view) : MultilayerBaseOperation(passtype, view) {
this->addOutputSocket(COM_DT_VECTOR);
}
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);

View File

@@ -0,0 +1,317 @@
/*
* Copyright 2015, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
* Lukas Tönne
* Dalai Felinto
*/
#include "COM_OutputFileOperation.h"
#include "COM_OutputFileMultiViewOperation.h"
#include <string.h>
#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BKE_image.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_scene.h"
#include "DNA_color_types.h"
#include "MEM_guardedalloc.h"
extern "C" {
#include "IMB_imbuf.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf_types.h"
}
/************************************ OpenEXR Singlelayer Multiview *****************************************/
OutputOpenExrSingleLayerMultiViewOperation::OutputOpenExrSingleLayerMultiViewOperation(
const RenderData *rd, const bNodeTree *tree, DataType datatype, ImageFormatData *format, const char *path,
const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings,
const char *viewName)
: OutputSingleLayerOperation(rd, tree, datatype, format, path, viewSettings, displaySettings, viewName)
{
}
void *OutputOpenExrSingleLayerMultiViewOperation::get_handle(const char *filename)
{
size_t width = this->getWidth();
size_t height = this->getHeight();
SceneRenderView *srv;
if (width != 0 && height != 0) {
void *exrhandle;
exrhandle = IMB_exr_get_handle_name(filename);
if (!BKE_scene_multiview_is_render_view_first(this->m_rd, this->m_viewName))
return exrhandle;
IMB_exr_clear_channels(exrhandle);
for (srv = (SceneRenderView *)this->m_rd->views.first; srv; srv = srv->next) {
if (BKE_scene_multiview_is_render_view_active(this->m_rd, srv) == false)
continue;
IMB_exr_add_view(exrhandle, srv->name);
add_exr_channels(exrhandle, NULL, this->m_datatype, srv->name, width, NULL);
}
BLI_make_existing_file(filename);
/* prepare the file with all the channels */
if (IMB_exr_begin_write(exrhandle, filename, width, height, this->m_format->exr_codec) == 0) {
printf("Error Writing Singlelayer Multiview Openexr\n");
IMB_exr_close(exrhandle);
}
else {
IMB_exr_clear_channels(exrhandle);
return exrhandle;
}
}
return NULL;
}
void OutputOpenExrSingleLayerMultiViewOperation::deinitExecution()
{
unsigned int width = this->getWidth();
unsigned int height = this->getHeight();
if (width != 0 && height != 0) {
void *exrhandle;
Main *bmain = G.main; /* TODO, have this passed along */
char filename[FILE_MAX];
BKE_image_path_from_imtype(
filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_OPENEXR,
(this->m_rd->scemode & R_EXTENSION) != 0, true, NULL);
exrhandle = this->get_handle(filename);
add_exr_channels(exrhandle, NULL, this->m_datatype, this->m_viewName, width, this->m_outputBuffer);
/* memory can only be freed after we write all views to the file */
this->m_outputBuffer = NULL;
this->m_imageInput = NULL;
/* ready to close the file */
if (BKE_scene_multiview_is_render_view_last(this->m_rd, this->m_viewName)) {
IMB_exr_write_channels(exrhandle);
/* free buffer memory for all the views */
free_exr_channels(exrhandle, this->m_rd, NULL, this->m_datatype);
/* remove exr handle and data */
IMB_exr_close(exrhandle);
}
}
}
/************************************ OpenEXR Multilayer Multiview *****************************************/
OutputOpenExrMultiLayerMultiViewOperation::OutputOpenExrMultiLayerMultiViewOperation(
const RenderData *rd, const bNodeTree *tree, const char *path, char exr_codec, const char *viewName)
: OutputOpenExrMultiLayerOperation(rd, tree, path, exr_codec, viewName)
{
}
void *OutputOpenExrMultiLayerMultiViewOperation::get_handle(const char *filename)
{
unsigned int width = this->getWidth();
unsigned int height = this->getHeight();
if (width != 0 && height != 0) {
void *exrhandle;
SceneRenderView *srv;
/* get a new global handle */
exrhandle = IMB_exr_get_handle_name(filename);
if (!BKE_scene_multiview_is_render_view_first(this->m_rd, this->m_viewName))
return exrhandle;
IMB_exr_clear_channels(exrhandle);
/* check renderdata for amount of views */
for (srv = (SceneRenderView *) this->m_rd->views.first; srv; srv = srv->next) {
if (BKE_scene_multiview_is_render_view_active(this->m_rd, srv) == false)
continue;
IMB_exr_add_view(exrhandle, srv->name);
for (unsigned int i = 0; i < this->m_layers.size(); ++i)
add_exr_channels(exrhandle, this->m_layers[i].name, this->m_layers[i].datatype, srv->name, width, NULL);
}
BLI_make_existing_file(filename);
/* prepare the file with all the channels for the header */
if (IMB_exr_begin_write(exrhandle, filename, width, height, this->m_exr_codec) == 0) {
printf("Error Writing Multilayer Multiview Openexr\n");
IMB_exr_close(exrhandle);
}
else {
IMB_exr_clear_channels(exrhandle);
return exrhandle;
}
}
return NULL;
}
void OutputOpenExrMultiLayerMultiViewOperation::deinitExecution()
{
unsigned int width = this->getWidth();
unsigned int height = this->getHeight();
if (width != 0 && height != 0) {
void *exrhandle;
Main *bmain = G.main; /* TODO, have this passed along */
char filename[FILE_MAX];
BKE_image_path_from_imtype(
filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_MULTILAYER,
(this->m_rd->scemode & R_EXTENSION) != 0, true, NULL);
exrhandle = this->get_handle(filename);
for (unsigned int i = 0; i < this->m_layers.size(); ++i)
add_exr_channels(exrhandle, this->m_layers[i].name, this->m_layers[i].datatype, this->m_viewName, width, this->m_layers[i].outputBuffer);
for (unsigned int i = 0; i < this->m_layers.size(); ++i) {
/* memory can only be freed after we write all views to the file */
this->m_layers[i].outputBuffer = NULL;
this->m_layers[i].imageInput = NULL;
}
/* ready to close the file */
if (BKE_scene_multiview_is_render_view_last(this->m_rd, this->m_viewName)) {
IMB_exr_write_channels(exrhandle);
/* free buffer memory for all the views */
for (unsigned int i = 0; i < this->m_layers.size(); ++i) {
free_exr_channels(exrhandle, this->m_rd, this->m_layers[i].name, this->m_layers[i].datatype);
}
IMB_exr_close(exrhandle);
}
}
}
/******************************** Stereo3D ******************************/
OutputStereoOperation::OutputStereoOperation(
const RenderData *rd, const bNodeTree *tree, DataType datatype, ImageFormatData *format, const char *path,
const char *name, const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings,
const char *viewName)
: OutputSingleLayerOperation(rd, tree, datatype, format, path, viewSettings, displaySettings, viewName)
{
BLI_strncpy(this->m_name, name, sizeof(this->m_name));
this->m_channels = get_datatype_size(datatype);
}
void *OutputStereoOperation::get_handle(const char *filename)
{
size_t width = this->getWidth();
size_t height = this->getHeight();
const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
size_t i;
if (width != 0 && height != 0) {
void *exrhandle;
exrhandle = IMB_exr_get_handle_name(filename);
if (!BKE_scene_multiview_is_render_view_first(this->m_rd, this->m_viewName))
return exrhandle;
IMB_exr_clear_channels(exrhandle);
for (i = 0; i < 2; i++)
IMB_exr_add_view(exrhandle, names[i]);
return exrhandle;
}
return NULL;
}
void OutputStereoOperation::deinitExecution()
{
unsigned int width = this->getWidth();
unsigned int height = this->getHeight();
if (width != 0 && height != 0) {
void *exrhandle;
exrhandle = this->get_handle(this->m_path);
float *buf = this->m_outputBuffer;
/* populate single EXR channel with view data */
IMB_exr_add_channel(exrhandle, NULL, this->m_name, this->m_viewName, 1, this->m_channels * width * height, buf);
this->m_imageInput = NULL;
this->m_outputBuffer = NULL;
/* create stereo ibuf */
if (BKE_scene_multiview_is_render_view_last(this->m_rd, this->m_viewName)) {
ImBuf *ibuf[3] = {NULL};
const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
Main *bmain = G.main; /* TODO, have this passed along */
char filename[FILE_MAX];
int i;
/* get rectf from EXR */
for (i = 0; i < 2; i++) {
float *rectf = IMB_exr_channel_rect(exrhandle, NULL, this->m_name, names[i]);
ibuf[i] = IMB_allocImBuf(width, height, this->m_format->planes, 0);
ibuf[i]->channels = this->m_channels;
ibuf[i]->rect_float = rectf;
ibuf[i]->mall |= IB_rectfloat;
ibuf[i]->dither = this->m_rd->dither_intensity;
/* do colormanagement in the individual views, so it doesn't need to do in the stereo */
IMB_colormanagement_imbuf_for_write(ibuf[i], true, false, this->m_viewSettings,
this->m_displaySettings, this->m_format);
IMB_prepare_write_ImBuf(IMB_isfloat(ibuf[i]), ibuf[i]);
}
/* create stereo buffer */
ibuf[2] = IMB_stereo3d_ImBuf(this->m_format, ibuf[0], ibuf[1]);
BKE_image_path_from_imformat(
filename, this->m_path, bmain->name, this->m_rd->cfra, this->m_format,
(this->m_rd->scemode & R_EXTENSION) != 0, true, NULL);
BKE_imbuf_write(ibuf[2], filename, this->m_format);
/* imbuf knows which rects are not part of ibuf */
for (i = 0; i < 3; i++)
IMB_freeImBuf(ibuf[i]);
IMB_exr_close(exrhandle);
}
}
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright 2015, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
* Lukas Tönne
* Dalai Felinto
*/
#ifndef _COM_OutputFileMultiViewOperation_h
#define _COM_OutputFileMultiViewOperation_h
#include "COM_NodeOperation.h"
#include "BLI_rect.h"
#include "BLI_path_util.h"
#include "DNA_color_types.h"
#include "DNA_userdef_types.h"
#include "intern/openexr/openexr_multi.h"
class OutputOpenExrSingleLayerMultiViewOperation : public OutputSingleLayerOperation {
private:
public:
OutputOpenExrSingleLayerMultiViewOperation(const RenderData *rd, const bNodeTree *tree, DataType datatype,
ImageFormatData *format, const char *path,
const ColorManagedViewSettings *viewSettings,
const ColorManagedDisplaySettings *displaySettings,
const char *viewName);
void *get_handle(const char *filename);
void deinitExecution();
};
/* Writes inputs into OpenEXR multilayer channels. */
class OutputOpenExrMultiLayerMultiViewOperation : public OutputOpenExrMultiLayerOperation {
private:
public:
OutputOpenExrMultiLayerMultiViewOperation(const RenderData *rd, const bNodeTree *tree, const char *path, char exr_codec, const char *viewName);
void *get_handle(const char *filename);
void deinitExecution();
};
/**/
class OutputStereoOperation : public OutputSingleLayerOperation {
private:
char m_name[FILE_MAX];
size_t m_channels;
public:
OutputStereoOperation(const RenderData *rd, const bNodeTree *tree, DataType datatype,
struct ImageFormatData *format, const char *path, const char *name,
const ColorManagedViewSettings *viewSettings,
const ColorManagedDisplaySettings *displaySettings, const char *viewName);
void *get_handle(const char *filename);
void deinitExecution();
};
#endif

View File

@@ -29,6 +29,7 @@
#include "BKE_image.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_scene.h"
#include "DNA_color_types.h"
@@ -39,7 +40,60 @@ extern "C" {
# include "IMB_imbuf_types.h"
}
static int get_datatype_size(DataType datatype)
void add_exr_channels(void *exrhandle, const char *layerName, const DataType datatype, const char *viewName, const size_t width, float *buf)
{
/* create channels */
switch (datatype) {
case COM_DT_VALUE:
IMB_exr_add_channel(exrhandle, layerName, "V", viewName, 1, width, buf ? buf : NULL);
break;
case COM_DT_VECTOR:
IMB_exr_add_channel(exrhandle, layerName, "X", viewName, 3, 3 * width, buf ? buf : NULL);
IMB_exr_add_channel(exrhandle, layerName, "Y", viewName, 3, 3 * width, buf ? buf + 1 : NULL);
IMB_exr_add_channel(exrhandle, layerName, "Z", viewName, 3, 3 * width, buf ? buf + 2 : NULL);
break;
case COM_DT_COLOR:
IMB_exr_add_channel(exrhandle, layerName, "R", viewName, 4, 4 * width, buf ? buf : NULL);
IMB_exr_add_channel(exrhandle, layerName, "G", viewName, 4, 4 * width, buf ? buf + 1 : NULL);
IMB_exr_add_channel(exrhandle, layerName, "B", viewName, 4, 4 * width, buf ? buf + 2 : NULL);
IMB_exr_add_channel(exrhandle, layerName, "A", viewName, 4, 4 * width, buf ? buf + 3 : NULL);
break;
default:
break;
}
}
void free_exr_channels(void *exrhandle, const RenderData *rd, const char *layerName, const DataType datatype)
{
SceneRenderView *srv;
/* check renderdata for amount of views */
for (srv = (SceneRenderView *) rd->views.first; srv; srv = srv->next) {
float *rect = NULL;
if (BKE_scene_multiview_is_render_view_active(rd, srv) == false)
continue;
/* the pointer is stored in the first channel of each datatype */
switch (datatype) {
case COM_DT_VALUE:
rect = IMB_exr_channel_rect(exrhandle, layerName, "V", srv->name);
break;
case COM_DT_VECTOR:
rect = IMB_exr_channel_rect(exrhandle, layerName, "X", srv->name);
break;
case COM_DT_COLOR:
rect = IMB_exr_channel_rect(exrhandle, layerName, "R", srv->name);
break;
default:
break;
}
if (rect)
MEM_freeN(rect);
}
}
int get_datatype_size(DataType datatype)
{
switch (datatype) {
case COM_DT_VALUE: return 1;
@@ -94,7 +148,7 @@ static void write_buffer_rect(rcti *rect, const bNodeTree *tree,
OutputSingleLayerOperation::OutputSingleLayerOperation(
const RenderData *rd, const bNodeTree *tree, DataType datatype, ImageFormatData *format, const char *path,
const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings)
const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings, const char *viewName)
{
this->m_rd = rd;
this->m_tree = tree;
@@ -110,6 +164,7 @@ OutputSingleLayerOperation::OutputSingleLayerOperation(
this->m_viewSettings = viewSettings;
this->m_displaySettings = displaySettings;
this->m_viewName = viewName;
}
void OutputSingleLayerOperation::initExecution()
@@ -131,6 +186,7 @@ void OutputSingleLayerOperation::deinitExecution()
ImBuf *ibuf = IMB_allocImBuf(this->getWidth(), this->getHeight(), this->m_format->planes, 0);
Main *bmain = G.main; /* TODO, have this passed along */
char filename[FILE_MAX];
const char *suffix;
ibuf->channels = size;
ibuf->rect_float = this->m_outputBuffer;
@@ -140,10 +196,12 @@ void OutputSingleLayerOperation::deinitExecution()
IMB_colormanagement_imbuf_for_write(ibuf, true, false, m_viewSettings, m_displaySettings,
this->m_format);
suffix = BKE_scene_multiview_view_suffix_get(this->m_rd, this->m_viewName);
BKE_image_path_from_imformat(
filename, this->m_path, bmain->name, this->m_rd->cfra,
this->m_format, (this->m_rd->scemode & R_EXTENSION) != 0, true);
filename, this->m_path, bmain->name, this->m_rd->cfra, this->m_format,
(this->m_rd->scemode & R_EXTENSION) != 0, true, suffix);
if (0 == BKE_imbuf_write(ibuf, filename, this->m_format))
printf("Cannot save Node File Output to %s\n", filename);
else
@@ -155,6 +213,7 @@ void OutputSingleLayerOperation::deinitExecution()
this->m_imageInput = NULL;
}
/******************************* MultiLayer *******************************/
OutputOpenExrLayer::OutputOpenExrLayer(const char *name_, DataType datatype_, bool use_layer_)
{
@@ -168,13 +227,14 @@ OutputOpenExrLayer::OutputOpenExrLayer(const char *name_, DataType datatype_, bo
}
OutputOpenExrMultiLayerOperation::OutputOpenExrMultiLayerOperation(
const RenderData *rd, const bNodeTree *tree, const char *path, char exr_codec)
const RenderData *rd, const bNodeTree *tree, const char *path, char exr_codec, const char *viewName)
{
this->m_rd = rd;
this->m_tree = tree;
BLI_strncpy(this->m_path, path, sizeof(this->m_path));
this->m_exr_codec = exr_codec;
this->m_viewName = viewName;
}
void OutputOpenExrMultiLayerOperation::add_layer(const char *name, DataType datatype, bool use_layer)
@@ -210,52 +270,21 @@ void OutputOpenExrMultiLayerOperation::deinitExecution()
if (width != 0 && height != 0) {
Main *bmain = G.main; /* TODO, have this passed along */
char filename[FILE_MAX];
const char *suffix;
void *exrhandle = IMB_exr_get_handle();
suffix = BKE_scene_multiview_view_suffix_get(this->m_rd, this->m_viewName);
BKE_image_path_from_imtype(
filename, this->m_path, bmain->name, this->m_rd->cfra, R_IMF_IMTYPE_MULTILAYER,
(this->m_rd->scemode & R_EXTENSION) != 0, true);
(this->m_rd->scemode & R_EXTENSION) != 0, true, suffix);
BLI_make_existing_file(filename);
for (unsigned int i = 0; i < this->m_layers.size(); ++i) {
OutputOpenExrLayer &layer = this->m_layers[i];
if (!layer.imageInput)
continue; /* skip unconnected sockets */
char channelname[EXR_TOT_MAXNAME];
BLI_strncpy(channelname, this->m_layers[i].name, sizeof(channelname) - 2);
char *channelname_ext = channelname + strlen(channelname);
float *buf = this->m_layers[i].outputBuffer;
/* create channels */
switch (this->m_layers[i].datatype) {
case COM_DT_VALUE:
strcpy(channelname_ext, ".V");
IMB_exr_add_channel(exrhandle, 0, channelname, 1, width, buf);
break;
case COM_DT_VECTOR:
strcpy(channelname_ext, ".X");
IMB_exr_add_channel(exrhandle, 0, channelname, 3, 3 * width, buf);
strcpy(channelname_ext, ".Y");
IMB_exr_add_channel(exrhandle, 0, channelname, 3, 3 * width, buf + 1);
strcpy(channelname_ext, ".Z");
IMB_exr_add_channel(exrhandle, 0, channelname, 3, 3 * width, buf + 2);
break;
case COM_DT_COLOR:
strcpy(channelname_ext, ".R");
IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4 * width, buf);
strcpy(channelname_ext, ".G");
IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4 * width, buf + 1);
strcpy(channelname_ext, ".B");
IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4 * width, buf + 2);
strcpy(channelname_ext, ".A");
IMB_exr_add_channel(exrhandle, 0, channelname, 4, 4 * width, buf + 3);
break;
default:
break;
}
add_exr_channels(exrhandle, this->m_layers[i].name, this->m_layers[i].datatype, "", width, this->m_layers[i].outputBuffer);
}
/* when the filename has no permissions, this can fail */
@@ -279,3 +308,4 @@ void OutputOpenExrMultiLayerOperation::deinitExecution()
}
}
}

View File

@@ -34,7 +34,7 @@
/* Writes the image to a single-layer file. */
class OutputSingleLayerOperation : public NodeOperation {
private:
protected:
const RenderData *m_rd;
const bNodeTree *m_tree;
@@ -47,9 +47,11 @@ private:
const ColorManagedViewSettings *m_viewSettings;
const ColorManagedDisplaySettings *m_displaySettings;
const char *m_viewName;
public:
OutputSingleLayerOperation(const RenderData *rd, const bNodeTree *tree, DataType datatype, ImageFormatData *format, const char *path,
const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings);
const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings, const char *viewName);
void executeRegion(rcti *rect, unsigned int tileNumber);
bool isOutputOperation(bool /*rendering*/) const { return true; }
@@ -75,7 +77,7 @@ struct OutputOpenExrLayer {
/* Writes inputs into OpenEXR multilayer channels. */
class OutputOpenExrMultiLayerOperation : public NodeOperation {
private:
protected:
typedef std::vector<OutputOpenExrLayer> LayerList;
const RenderData *m_rd;
@@ -84,9 +86,10 @@ private:
char m_path[FILE_MAX];
char m_exr_codec;
LayerList m_layers;
const char *m_viewName;
public:
OutputOpenExrMultiLayerOperation(const RenderData *rd, const bNodeTree *tree, const char *path, char exr_codec);
OutputOpenExrMultiLayerOperation(const RenderData *rd, const bNodeTree *tree, const char *path, char exr_codec, const char *viewName);
void add_layer(const char *name, DataType datatype, bool use_layer);
@@ -99,4 +102,8 @@ public:
bool isFileOutputOperation() const { return true; }
};
void add_exr_channels(void *exrhandle, const char *layerName, const DataType datatype, const char *viewName, const size_t width, float *buf);
void free_exr_channels(void *exrhandle, const RenderData *rd, const char *layerName, const DataType datatype);
int get_datatype_size(DataType datatype);
#endif

View File

@@ -23,6 +23,7 @@
#include "COM_RenderLayersProg.h"
#include "BLI_listbase.h"
#include "BKE_scene.h"
#include "DNA_scene_types.h"
extern "C" {
@@ -57,11 +58,10 @@ void RenderLayersBaseProg::initExecution()
if (srl) {
RenderLayer *rl = RE_GetRenderLayer(rr, srl->name);
if (rl && rl->rectf) {
this->m_inputBuffer = RE_RenderLayerGetPass(rl, this->m_renderpass);
if (rl) {
this->m_inputBuffer = RE_RenderLayerGetPass(rl, this->m_renderpass, this->m_viewName);
if (this->m_inputBuffer == NULL && this->m_renderpass == SCE_PASS_COMBINED) {
this->m_inputBuffer = rl->rectf;
this->m_inputBuffer = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, this->m_viewName);
}
}
}
@@ -195,7 +195,7 @@ void RenderLayersBaseProg::determineResolution(unsigned int resolution[2], unsig
SceneRenderLayer *srl = (SceneRenderLayer *)BLI_findlink(&sce->r.layers, getLayerId());
if (srl) {
RenderLayer *rl = RE_GetRenderLayer(rr, srl->name);
if (rl && rl->rectf) {
if (rl) {
resolution[0] = rl->rectx;
resolution[1] = rl->recty;
}

View File

@@ -51,7 +51,12 @@ private:
* layerId of the layer where this operation needs to get its data from
*/
short m_layerId;
/**
* viewName of the view to use (unless another view is specified by the node
*/
const char *m_viewName;
/**
* cached instance to the float buffer inside the layer
*/
@@ -97,6 +102,8 @@ public:
void setRenderData(const RenderData *rd) { this->m_rd = rd; }
void setLayerId(short layerId) { this->m_layerId = layerId; }
short getLayerId() { return this->m_layerId; }
void setViewName(const char *viewName) { this->m_viewName = viewName; }
const char *getViewName() { return this->m_viewName; }
void initExecution();
void deinitExecution();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);

View File

@@ -23,6 +23,7 @@
#include "COM_ViewerOperation.h"
#include "BLI_listbase.h"
#include "BKE_image.h"
#include "BKE_scene.h"
#include "WM_api.h"
#include "WM_types.h"
#include "PIL_time.h"
@@ -57,6 +58,8 @@ ViewerOperation::ViewerOperation() : NodeOperation()
this->m_imageInput = NULL;
this->m_alphaInput = NULL;
this->m_depthInput = NULL;
this->m_rd = NULL;
this->m_viewName = NULL;
}
void ViewerOperation::initExecution()
@@ -123,8 +126,18 @@ void ViewerOperation::executeRegion(rcti *rect, unsigned int /*tileNumber*/)
void ViewerOperation::initImage()
{
Image *ima = this->m_image;
ImageUser iuser = *this->m_imageUser;
void *lock;
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, this->m_imageUser, &lock);
ImBuf *ibuf;
/* make sure the image has the correct number of views */
if (ima && BKE_scene_multiview_is_render_view_first(this->m_rd, this->m_viewName)) {
BKE_image_verify_viewer_views(this->m_rd, ima, this->m_imageUser);
}
/* local changes to the original ImageUser */
iuser.multi_index = BKE_scene_multiview_view_id_get(this->m_rd, this->m_viewName);
ibuf = BKE_image_acquire_ibuf(ima, &iuser, &lock);
if (!ibuf) return;
BLI_lock_thread(LOCK_DRAW_IMAGE);

View File

@@ -40,7 +40,9 @@ private:
bool m_doDepthBuffer;
ImBuf *m_ibuf;
bool m_useAlphaInput;
const RenderData *m_rd;
const char *m_viewName;
const ColorManagedViewSettings *m_viewSettings;
const ColorManagedDisplaySettings *m_displaySettings;
@@ -67,6 +69,8 @@ public:
const CompositorPriority getRenderPriority() const;
bool isViewerOperation() const { return true; }
void setUseAlphaInput(bool value) { this->m_useAlphaInput = value; }
void setRenderData(const RenderData *rd) { this->m_rd = rd; }
void setViewName(const char *viewName) { this->m_viewName = viewName; }
void setViewSettings(const ColorManagedViewSettings *viewSettings) { this->m_viewSettings = viewSettings; }
void setDisplaySettings(const ColorManagedDisplaySettings *displaySettings) { this->m_displaySettings = displaySettings; }

View File

@@ -112,6 +112,7 @@ void ED_screen_full_prevspace(struct bContext *C, ScrArea *sa);
void ED_screen_full_restore(struct bContext *C, ScrArea *sa);
struct ScrArea *ED_screen_state_toggle(struct bContext *C, struct wmWindow *win, struct ScrArea *sa, const short state);
void ED_screens_header_tools_menu_create(struct bContext *C, struct uiLayout *layout, void *arg);
bool ED_screen_stereo3d_required(struct bScreen *screen);
/* anim */
void ED_update_for_newframe(struct Main *bmain, struct Scene *scene, int mute);

View File

@@ -323,12 +323,13 @@ void ED_view3d_draw_offscreen(
struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int winx, int winy, float viewmat[4][4],
float winmat[4][4], bool do_bgpic, bool do_sky, bool is_persp,
struct GPUOffScreen *ofs,
struct GPUFX *fx, struct GPUFXSettings *fx_settings);
struct GPUFX *fx, struct GPUFXSettings *fx_settings,
const char *viewname);
struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag,
bool draw_background, int alpha_mode, char err_out[256]);
bool draw_background, int alpha_mode, const char *viewname, char err_out[256]);
struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(struct Scene *scene, struct Object *camera, int width, int height, unsigned int flag, int drawtype,
bool use_solid_tex, bool use_gpencil, bool draw_background, int alpha_mode, char err_out[256]);
bool use_solid_tex, bool use_gpencil, bool draw_background, int alpha_mode, const char *viewname, char err_out[256]);
struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]);
void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, bool do_clip);

View File

@@ -889,6 +889,9 @@ void uiTemplateGameStates(uiLayout *layout, struct PointerRNA *ptr, const char *
PointerRNA *used_ptr, const char *used_propname, int active_state);
void uiTemplateImage(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, struct PointerRNA *userptr, int compact);
void uiTemplateImageSettings(uiLayout *layout, struct PointerRNA *imfptr, int color_management);
void uiTemplateImageStereo3d(uiLayout *layout, struct PointerRNA *stereo3d_format_ptr);
void uiTemplateImageViews(uiLayout *layout, struct PointerRNA *imaptr);
void uiTemplateImageFormatViews(uiLayout *layout, PointerRNA *imfptr, PointerRNA *ptr);
void uiTemplateImageLayers(uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser);
void uiTemplateImageInfo(uiLayout *layout, struct bContext *C, Image *ima, ImageUser *iuser);
void uiTemplateRunningJobs(uiLayout *layout, struct bContext *C);

View File

@@ -613,6 +613,7 @@ static int editsource_exec(bContext *C, wmOperator *op)
/* redraw and get active button python info */
ED_region_do_draw(C, ar);
ar->do_draw = false;
for (BLI_ghashIterator_init(&ghi, ui_editsource_info->hash);
BLI_ghashIterator_done(&ghi) == false;

View File

@@ -929,7 +929,7 @@ cage_cleanup:
BakeData *bake = &scene->r.bake;
char name[FILE_MAX];
BKE_image_path_from_imtype(name, filepath, bmain->name, 0, bake->im_format.imtype, true, false);
BKE_image_path_from_imtype(name, filepath, bmain->name, 0, bake->im_format.imtype, true, false, NULL);
if (is_automatic_name) {
BLI_path_suffix(name, FILE_MAX, ob_low->id.name + 2, "_");

View File

@@ -55,6 +55,9 @@ void MATERIAL_OT_paste(struct wmOperatorType *ot);
void SCENE_OT_render_layer_add(struct wmOperatorType *ot);
void SCENE_OT_render_layer_remove(struct wmOperatorType *ot);
void SCENE_OT_render_view_add(struct wmOperatorType *ot);
void SCENE_OT_render_view_remove(struct wmOperatorType *ot);
#ifdef WITH_FREESTYLE
void SCENE_OT_freestyle_module_add(struct wmOperatorType *ot);
void SCENE_OT_freestyle_module_remove(struct wmOperatorType *ot);

View File

@@ -48,6 +48,7 @@
#include "DNA_userdef_types.h"
#include "BKE_blender.h"
#include "BKE_camera.h"
#include "BKE_context.h"
#include "BKE_colortools.h"
#include "BKE_depsgraph.h"
@@ -116,7 +117,7 @@ typedef struct RenderJob {
} RenderJob;
/* called inside thread! */
static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibuf, ImageUser *iuser, volatile rcti *renrect)
static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibuf, ImageUser *iuser, volatile rcti *renrect, const char *viewname)
{
Scene *scene = rj->scene;
const float *rectf = NULL;
@@ -188,11 +189,11 @@ static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibu
*/
/* TODO(sergey): Need to check has_combined here? */
if (iuser->pass == 0) {
size_t view_id = BKE_scene_multiview_view_id_get(&scene->r, viewname);
/* find current float rect for display, first case is after composite... still weak */
if (rr->rectf)
rectf = rr->rectf;
else {
if (rr->rect32) {
rectf = RE_RenderViewGetRectf(rr, view_id);
if (rectf == NULL) {
if (RE_RenderViewGetRect32(rr, view_id)) {
/* special case, currently only happens with sequencer rendering,
* which updates the whole frame, so we can only mark display buffer
* as invalid here (sergey)
@@ -201,8 +202,8 @@ static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibu
return;
}
else {
if (rr->renlay == NULL || rr->renlay->rectf == NULL) return;
rectf = rr->renlay->rectf;
if (rr->renlay == NULL) return;
rectf = RE_RenderLayerGetPass(rr->renlay, SCE_PASS_COMBINED, viewname);
}
}
if (rectf == NULL) return;
@@ -531,6 +532,7 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec
Image *ima = rj->image;
ImBuf *ibuf;
void *lock;
const char *viewname = RE_GetActiveRenderView(rj->re);
/* only update if we are displaying the slot being rendered */
if (ima->render_slot != ima->last_render_slot) {
@@ -563,7 +565,7 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec
ibuf->channels == 1 ||
U.image_draw_method != IMAGE_DRAW_METHOD_GLSL)
{
image_buffer_rect_update(rj, rr, ibuf, &rj->iuser, renrect);
image_buffer_rect_update(rj, rr, ibuf, &rj->iuser, renrect, viewname);
}
/* make jobs timer to send notifier */
@@ -1487,7 +1489,8 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C)
if (re == NULL) return;
}
RE_AcquireResultImage(re, &rres);
/* Viewport render preview doesn't support multiview, view hardcoded to 0 */
RE_AcquireResultImage(re, &rres, 0);
if (rres.rectf) {
RegionView3D *rv3d = CTX_wm_region_view3d(C);

View File

@@ -39,6 +39,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_jitter.h"
#include "BLI_threads.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
@@ -103,11 +104,17 @@ typedef struct OGLRender {
bMovieHandle *mh;
int cfrao, nfra;
size_t totvideos;
/* quick lookup */
int view_id;
/* wm vars for timer and progress cursor */
wmWindowManager *wm;
wmWindow *win;
wmTimer *timer; /* use to check if running modal or not (invoke'd or exec'd)*/
void **movie_ctx_arr;
} OGLRender;
/* added because v3d is not always valid */
@@ -121,16 +128,125 @@ static unsigned int screen_opengl_layers(OGLRender *oglrender)
}
}
static void screen_opengl_render_apply(OGLRender *oglrender)
static bool screen_opengl_is_multiview(OGLRender *oglrender)
{
View3D *v3d = oglrender->v3d;
RegionView3D *rv3d = oglrender->rv3d;
RenderData *rd = &oglrender->scene->r;
if ((rd == NULL) || ((!oglrender->is_sequencer) && ((rv3d == NULL) || (v3d == NULL))))
return false;
return (rd->scemode & R_MULTIVIEW) && ((oglrender->is_sequencer) || (rv3d->persp == RV3D_CAMOB && v3d->camera));
}
static void screen_opengl_views_setup(OGLRender *oglrender)
{
RenderResult *rr;
RenderView *rv;
SceneRenderView *srv;
bool is_multiview;
View3D *v3d = oglrender->v3d;
RenderData *rd = &oglrender->scene->r;
rr = RE_AcquireResultWrite(oglrender->re);
is_multiview = screen_opengl_is_multiview(oglrender);
if (!is_multiview) {
/* we only have one view when multiview is off */
rv = rr->views.first;
if (rv == NULL) {
rv = MEM_callocN(sizeof(RenderView), "new opengl render view");
BLI_addtail(&rr->views, rv);
}
while (rv->next) {
RenderView *rv_del = rv->next;
BLI_remlink(&rr->views, rv_del);
if (rv_del->rectf)
MEM_freeN(rv_del->rectf);
if (rv_del->rectz)
MEM_freeN(rv_del->rectz);
MEM_freeN(rv_del);
}
}
else {
if (!oglrender->is_sequencer)
RE_SetOverrideCamera(oglrender->re, V3D_CAMERA_SCENE(oglrender->scene, v3d));
/* remove all the views that are not needed */
rv = rr->views.last;
while (rv) {
srv = BLI_findstring(&rd->views, rv->name, offsetof(SceneRenderView, name));
if (BKE_scene_multiview_is_render_view_active(rd, srv)) {
if (rv->rectf == NULL)
rv->rectf = MEM_callocN(sizeof(float) * 4 * oglrender->sizex * oglrender->sizey, "screen_opengl_render_init rect");
rv = rv->prev;
}
else {
RenderView *rv_del = rv;
rv = rv_del->prev;
BLI_remlink(&rr->views, rv_del);
if (rv_del->rectf)
MEM_freeN(rv_del->rectf);
if (rv_del->rectz)
MEM_freeN(rv_del->rectz);
MEM_freeN(rv_del);
}
}
/* create all the views that are needed */
for (srv = rd->views.first; srv; srv = srv->next) {
if (BKE_scene_multiview_is_render_view_active(rd, srv) == false)
continue;
rv = BLI_findstring(&rr->views, srv->name, offsetof(SceneRenderView, name));
if (rv == NULL) {
rv = MEM_callocN(sizeof(RenderView), "new opengl render view");
BLI_strncpy(rv->name, srv->name, sizeof(rv->name));
BLI_addtail(&rr->views, rv);
}
}
}
for (rv = rr->views.first; rv; rv = rv->next) {
if (rv->rectf == NULL) {
rv->rectf = MEM_callocN(sizeof(float) * 4 * oglrender->sizex * oglrender->sizey, "screen_opengl_render_init rect");
}
}
BLI_lock_thread(LOCK_DRAW_IMAGE);
if (is_multiview && BKE_scene_multiview_is_stereo3d(rd)) {
oglrender->ima->flag |= IMA_IS_STEREO;
}
else {
oglrender->ima->flag &= ~IMA_IS_STEREO;
oglrender->iuser.flag &= ~IMA_SHOW_STEREO;
}
BLI_unlock_thread(LOCK_DRAW_IMAGE);
RE_ReleaseResult(oglrender->re);
}
static void screen_opengl_render_doit(OGLRender *oglrender, RenderResult *rr)
{
Scene *scene = oglrender->scene;
ARegion *ar = oglrender->ar;
View3D *v3d = oglrender->v3d;
RegionView3D *rv3d = oglrender->rv3d;
RenderResult *rr;
Object *camera = NULL;
ImBuf *ibuf;
void *lock;
float winmat[4][4];
int sizex = oglrender->sizex;
int sizey = oglrender->sizey;
@@ -138,8 +254,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
bool draw_bgpic = true;
bool draw_sky = (scene->r.alphamode == R_ADDSKY);
unsigned char *rect = NULL;
rr = RE_AcquireResultRead(oglrender->re);
const char *viewname = RE_GetActiveRenderView(oglrender->re);
if (oglrender->is_sequencer) {
SeqRenderData context;
@@ -152,9 +267,11 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
oglrender->sizex, oglrender->sizey, 100.0f,
&context);
context.view_id = BKE_scene_multiview_view_id_get(&scene->r, viewname);
ibuf = BKE_sequencer_give_ibuf(&context, CFRA, chanshown);
if (ibuf) {
float *rectf;
ImBuf *linear_ibuf;
BLI_assert((oglrender->sizex == ibuf->x) && (oglrender->sizey == ibuf->y));
@@ -175,7 +292,8 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
BKE_sequencer_imbuf_from_sequencer_space(scene, linear_ibuf);
}
memcpy(rr->rectf, linear_ibuf->rect_float, sizeof(float) * 4 * oglrender->sizex * oglrender->sizey);
rectf = RE_RenderViewGetRectf(rr, oglrender->view_id);
memcpy(rectf, linear_ibuf->rect_float, sizeof(float) * 4 * oglrender->sizex * oglrender->sizey);
IMB_freeImBuf(linear_ibuf);
}
@@ -221,7 +339,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
/* render 3d view */
if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
/*int is_ortho = scene->r.mode & R_ORTHO;*/
camera = v3d->camera;
camera = BKE_camera_multiview_render(oglrender->scene, v3d->camera, viewname);
RE_GetCameraWindow(oglrender->re, camera, scene->r.cfra, winmat);
if (camera->type == OB_CAMERA) {
Camera *cam = camera->data;
@@ -248,7 +366,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
ED_view3d_draw_offscreen(
scene, v3d, ar, sizex, sizey, NULL, winmat,
draw_bgpic, draw_sky, is_persp,
oglrender->ofs, oglrender->fx, &fx_settings);
oglrender->ofs, oglrender->fx, &fx_settings, viewname);
GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, rect);
}
else {
@@ -264,7 +382,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
ED_view3d_draw_offscreen(
scene, v3d, ar, sizex, sizey, NULL, winmat,
draw_bgpic, draw_sky, is_persp,
oglrender->ofs, oglrender->fx, &fx_settings);
oglrender->ofs, oglrender->fx, &fx_settings, viewname);
GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, rect);
for (i = 0; i < sizex * sizey * 4; i++)
@@ -280,7 +398,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
ED_view3d_draw_offscreen(
scene, v3d, ar, sizex, sizey, NULL, winmat_jitter,
draw_bgpic, draw_sky, is_persp,
oglrender->ofs, oglrender->fx, &fx_settings);
oglrender->ofs, oglrender->fx, &fx_settings, viewname);
GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, rect);
for (i = 0; i < sizex * sizey * 4; i++)
@@ -300,7 +418,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
char err_out[256] = "unknown";
ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey,
IB_rect, OB_SOLID, false, true, true,
(draw_sky) ? R_ADDSKY : R_ALPHAPREMUL, err_out);
(draw_sky) ? R_ADDSKY : R_ALPHAPREMUL, viewname, err_out);
camera = scene->camera;
if (ibuf_view) {
@@ -325,6 +443,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
if (rect) {
int profile_to;
float *rectf = RE_RenderViewGetRectf(rr, oglrender->view_id);
if (BKE_scene_check_color_management_enabled(scene))
profile_to = IB_PROFILE_LINEAR_RGB;
@@ -333,47 +452,60 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
/* sequencer has got trickier conversion happened above
* also assume opengl's space matches byte buffer color space */
IMB_buffer_float_from_byte(rr->rectf, rect,
IMB_buffer_float_from_byte(rectf, rect,
profile_to, IB_PROFILE_SRGB, true,
oglrender->sizex, oglrender->sizey, oglrender->sizex, oglrender->sizex);
/* rr->rectf is now filled with image data */
if ((scene->r.stamp & R_STAMP_ALL) && (scene->r.stamp & R_STAMP_DRAW))
BKE_image_stamp_buf(scene, camera, rect, rectf, rr->rectx, rr->recty, 4);
MEM_freeN(rect);
}
}
/* rr->rectf is now filled with image data */
static void screen_opengl_render_write(OGLRender *oglrender)
{
Scene *scene = oglrender->scene;
RenderResult *rr;
bool ok;
char name[FILE_MAX];
Object *camera = RE_GetCamera(oglrender->re);
if ((scene->r.stamp & R_STAMP_ALL) && (scene->r.stamp & R_STAMP_DRAW)) {
BKE_image_stamp_buf(scene, camera, rect, rr->rectf, rr->rectx, rr->recty, 4);
rr = RE_AcquireResultRead(oglrender->re);
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, false, NULL);
/* write images as individual images or stereo */
ok = RE_WriteRenderViewsImage(oglrender->reports, rr, scene, camera, false, name);
RE_ReleaseResultImage(oglrender->re);
if (ok) printf("OpenGL Render written to '%s'\n", name);
else printf("OpenGL Render failed to write '%s'\n", name);
}
static void screen_opengl_render_apply(OGLRender *oglrender)
{
RenderResult *rr;
RenderView *rv;
int view_id;
rr = RE_AcquireResultRead(oglrender->re);
for (rv = rr->views.first, view_id = 0; rv; rv = rv->next, view_id++) {
RE_SetActiveRenderView(oglrender->re, rv->name);
oglrender->view_id = view_id;
screen_opengl_render_doit(oglrender, rr);
}
RE_ReleaseResult(oglrender->re);
/* update byte from float buffer */
ibuf = BKE_image_acquire_ibuf(oglrender->ima, &oglrender->iuser, &lock);
if (ibuf) {
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
/* write file for animation */
if (oglrender->write_still) {
char name[FILE_MAX];
int ok;
if (scene->r.im_format.planes == R_IMF_CHAN_DEPTH_8) {
IMB_color_to_bw(ibuf);
}
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, false);
ok = BKE_imbuf_write_as(ibuf, name, &scene->r.im_format, true); /* no need to stamp here */
if (ok) printf("OpenGL Render written to '%s'\n", name);
else printf("OpenGL Render failed to write '%s'\n", name);
}
if (oglrender->write_still) {
screen_opengl_render_write(oglrender);
}
BKE_image_release_ibuf(oglrender->ima, ibuf, lock);
if (rect)
MEM_freeN(rect);
}
static bool screen_opengl_render_init(bContext *C, wmOperator *op)
@@ -385,7 +517,6 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
ScrArea *prevsa = CTX_wm_area(C);
ARegion *prevar = CTX_wm_region(C);
RenderResult *rr;
GPUOffScreen *ofs;
OGLRender *oglrender;
int sizex, sizey;
@@ -458,7 +589,6 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
oglrender->sseq = CTX_wm_space_seq(C);
}
oglrender->prevsa = prevsa;
oglrender->prevar = prevar;
@@ -492,15 +622,17 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
/* create render result */
RE_InitState(oglrender->re, NULL, &scene->r, NULL, sizex, sizey, NULL);
rr = RE_AcquireResultWrite(oglrender->re);
if (rr->rectf == NULL)
rr->rectf = MEM_callocN(sizeof(float) * 4 * sizex * sizey, "screen_opengl_render_init rect");
RE_ReleaseResult(oglrender->re);
/* create render views */
screen_opengl_views_setup(oglrender);
/* wm vars */
oglrender->wm = wm;
oglrender->win = win;
oglrender->totvideos = 0;
oglrender->mh = NULL;
oglrender->movie_ctx_arr = NULL;
return true;
}
@@ -508,10 +640,19 @@ 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))
oglrender->mh->end_movie();
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 */
@@ -552,13 +693,27 @@ static int screen_opengl_render_anim_initialize(bContext *C, wmOperator *op)
oglrender = op->customdata;
scene = oglrender->scene;
oglrender->totvideos = BKE_scene_multiview_num_videos_get(&scene->r);
oglrender->reports = op->reports;
oglrender->mh = BKE_movie_handle_get(scene->r.im_format.imtype);
if (BKE_imtype_is_movie(scene->r.im_format.imtype)) {
if (!oglrender->mh->start_movie(scene, &scene->r, oglrender->sizex, oglrender->sizey, oglrender->reports, PRVRANGEON != 0)) {
screen_opengl_render_end(C, oglrender);
return 0;
size_t i, width, height;
BKE_scene_multiview_videos_dimensions_get(&scene->r, oglrender->sizex, oglrender->sizey, &width, &height);
oglrender->movie_ctx_arr = MEM_mallocN(sizeof(void *) * oglrender->totvideos, "Movies");
oglrender->mh = BKE_movie_handle_get(scene->r.im_format.imtype);
for (i = 0; i < oglrender->totvideos; i++) {
const char *suffix = BKE_scene_multiview_view_id_suffix_get(&scene->r, i);
oglrender->movie_ctx_arr[i] = oglrender->mh->context_create();
if (!oglrender->mh->start_movie(oglrender->movie_ctx_arr[i], scene, &scene->r, oglrender->sizex,
oglrender->sizey, oglrender->reports, PRVRANGEON != 0, suffix))
{
screen_opengl_render_end(C, oglrender);
return 0;
}
}
}
@@ -568,18 +723,17 @@ static int screen_opengl_render_anim_initialize(bContext *C, wmOperator *op)
return 1;
}
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];
bool ok = false;
const bool view_context = (oglrender->v3d != NULL);
Object *camera = NULL;
bool is_movie;
RenderResult *rr;
/* go to next frame */
if (CFRA < oglrender->nfra)
@@ -599,7 +753,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
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);
&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);
@@ -619,89 +773,40 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op)
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);
rr = RE_AcquireResultRead(oglrender->re);
if (ibuf) {
bool 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;
if (is_movie) {
ok = RE_WriteRenderViewsMovie(oglrender->reports, rr, scene, &scene->r, oglrender->mh, oglrender->sizex,
oglrender->sizey, oglrender->movie_ctx_arr, oglrender->totvideos);
if (ok) {
printf("Append frame %d", scene->r.cfra);
BKE_reportf(op->reports, RPT_INFO, "Appended frame: %d", scene->r.cfra);
}
/* 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 {
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 {
/* 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;
printf("Write error: cannot save %s\n", name);
BKE_reportf(op->reports, RPT_ERROR, "Write error: cannot save %s", name);
}
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);
RE_ReleaseResult(oglrender->re);
/* movie stats prints have no line break */
printf("\n");

View File

@@ -58,6 +58,9 @@ void ED_operatortypes_render(void)
WM_operatortype_append(SCENE_OT_render_layer_add);
WM_operatortype_append(SCENE_OT_render_layer_remove);
WM_operatortype_append(SCENE_OT_render_view_add);
WM_operatortype_append(SCENE_OT_render_view_remove);
#ifdef WITH_FREESTYLE
WM_operatortype_append(SCENE_OT_freestyle_module_add);
WM_operatortype_append(SCENE_OT_freestyle_module_remove);

View File

@@ -548,7 +548,9 @@ static bool ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect,
/* test if something rendered ok */
re = RE_GetRender(name);
RE_AcquireResultImage(re, &rres);
/* material preview only needs monoscopy (view 0) */
RE_AcquireResultImage(re, &rres, 0);
if (rres.rectf) {
@@ -561,9 +563,11 @@ static bool ed_preview_draw_rect(ScrArea *sa, int split, int first, rcti *rect,
unsigned char *rect_byte = MEM_mallocN(rres.rectx * rres.recty * sizeof(int), "ed_preview_draw_rect");
float fx = rect->xmin + offx;
float fy = rect->ymin;
/* material preview only needs monoscopy (view 0) */
if (re)
RE_AcquiredResultGet32(re, &rres, (unsigned int *)rect_byte);
RE_AcquiredResultGet32(re, &rres, (unsigned int *)rect_byte, 0);
glaDrawPixelsSafe(fx, fy, rres.rectx, rres.recty, rres.rectx, GL_RGBA, GL_UNSIGNED_BYTE, rect_byte);
MEM_freeN(rect_byte);

View File

@@ -605,6 +605,70 @@ void SCENE_OT_render_layer_remove(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
}
/********************** render view operators *********************/
static int render_view_remove_poll(bContext *C)
{
Scene *scene = CTX_data_scene(C);
/* don't allow user to remove "left" and "right" views */
return scene->r.actview > 1;
}
static int render_view_add_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
BKE_scene_add_render_view(scene, NULL);
scene->r.actview = BLI_listbase_count(&scene->r.views) - 1;
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
return OPERATOR_FINISHED;
}
void SCENE_OT_render_view_add(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Add Render View";
ot->idname = "SCENE_OT_render_view_add";
ot->description = "Add a render view";
/* api callbacks */
ot->exec = render_view_add_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int render_view_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
SceneRenderView *rv = BLI_findlink(&scene->r.views, scene->r.actview);
if (!BKE_scene_remove_render_view(scene, rv))
return OPERATOR_CANCELLED;
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
return OPERATOR_FINISHED;
}
void SCENE_OT_render_view_remove(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Remove Render View";
ot->idname = "SCENE_OT_render_view_remove";
ot->description = "Remove the selected render view";
/* api callbacks */
ot->exec = render_view_remove_exec;
ot->poll = render_view_remove_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
#ifdef WITH_FREESTYLE
static bool freestyle_linestyle_check_report(FreestyleLineSet *lineset, ReportList *reports)

View File

@@ -493,7 +493,6 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
glDisable(GL_BLEND);
#endif
ar->do_draw = 0;
memset(&ar->drawrct, 0, sizeof(ar->drawrct));
UI_blocklist_free_inactive(C, &ar->uiblocks);

View File

@@ -59,6 +59,7 @@
#include "ED_screen.h"
#include "ED_screen_types.h"
#include "ED_clip.h"
#include "ED_node.h"
#include "ED_render.h"
#include "UI_interface.h"
@@ -2122,4 +2123,85 @@ void ED_update_for_newframe(Main *bmain, Scene *scene, int UNUSED(mute))
}
/*
* return true if any active area requires to see in 3D
*/
bool ED_screen_stereo3d_required(bScreen *screen)
{
ScrArea *sa;
Scene *sce = screen->scene;
const bool is_multiview = (sce->r.scemode & R_MULTIVIEW) != 0;
for (sa = screen->areabase.first; sa; sa = sa->next) {
switch (sa->spacetype) {
case SPACE_VIEW3D:
{
View3D *v3d;
if (!is_multiview)
continue;
v3d = sa->spacedata.first;
if (v3d->camera && v3d->stereo3d_camera == STEREO_3D_ID) {
ARegion *ar;
for (ar = sa->regionbase.first; ar; ar = ar->next) {
if (ar->regiondata && ar->regiontype == RGN_TYPE_WINDOW) {
RegionView3D *rv3d = ar->regiondata;
if (rv3d->persp == RV3D_CAMOB) {
return true;
}
}
}
}
break;
}
case SPACE_IMAGE:
{
SpaceImage *sima;
/* images should always show in stereo, even if
* the file doesn't have views enabled */
sima = sa->spacedata.first;
if (sima->image && (sima->image->flag & IMA_IS_STEREO) &&
(sima->iuser.flag & IMA_SHOW_STEREO))
{
return true;
}
break;
}
case SPACE_NODE:
{
SpaceNode *snode;
if (!is_multiview)
continue;
snode = sa->spacedata.first;
if ((snode->flag & SNODE_BACKDRAW) && ED_node_is_compositor(snode)) {
return true;
}
break;
}
case SPACE_SEQ:
{
SpaceSeq *sseq;
if (!is_multiview)
continue;
sseq = sa->spacedata.first;
if (ELEM(sseq->view, SEQ_VIEW_PREVIEW, SEQ_VIEW_SEQUENCE_PREVIEW)) {
return true;
}
if (sseq->draw_flag & SEQ_DRAW_BACKDROP) {
return true;
}
break;
}
}
}
return false;
}

View File

@@ -990,6 +990,7 @@ static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
rect.ymax = rect.ymin + BLI_rcti_size_y(&rect) / U.pixelsize;
newwin = WM_window_open(C, &rect);
*newwin->stereo3d_format = *win->stereo3d_format;
/* allocs new screen and adds to newly created window, using window size */
newsc = ED_screen_add(newwin, CTX_data_scene(C), sc->id.name + 2);

View File

@@ -303,6 +303,7 @@ typedef struct ScreenshotJob {
const short *stop;
const short *do_update;
ReportList reports;
void *movie_ctx;
} ScreenshotJob;
@@ -312,7 +313,10 @@ static void screenshot_freejob(void *sjv)
if (sj->dumprect)
MEM_freeN(sj->dumprect);
if (sj->movie_ctx)
MEM_freeN(sj->movie_ctx);
MEM_freeN(sj);
}
@@ -337,20 +341,21 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float
{
ScreenshotJob *sj = sjv;
RenderData rd = sj->scene->r;
bMovieHandle *mh = BKE_movie_handle_get(sj->scene->r.im_format.imtype);
bMovieHandle *mh = NULL;
/* we need this as local variables for renderdata */
rd.frs_sec = U.scrcastfps;
rd.frs_sec_base = 1.0f;
if (BKE_imtype_is_movie(rd.im_format.imtype)) {
if (!mh->start_movie(sj->scene, &rd, sj->dumpsx, sj->dumpsy, &sj->reports, false)) {
mh = BKE_movie_handle_get(sj->scene->r.im_format.imtype);
sj->movie_ctx = mh->context_create();
if (!mh->start_movie(sj->movie_ctx, sj->scene, &rd, sj->dumpsx, sj->dumpsy, &sj->reports, false, "")) {
printf("screencast job stopped\n");
return;
}
}
else
mh = NULL;
sj->stop = stop;
sj->do_update = do_update;
@@ -362,8 +367,8 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float
if (sj->dumprect) {
if (mh) {
if (mh->append_movie(&rd, rd.sfra, rd.cfra, (int *)sj->dumprect,
sj->dumpsx, sj->dumpsy, &sj->reports))
if (mh->append_movie(sj->movie_ctx, &rd, rd.sfra, rd.cfra, (int *)sj->dumprect,
sj->dumpsx, sj->dumpsy, "", &sj->reports))
{
BKE_reportf(&sj->reports, RPT_INFO, "Appended frame: %d", rd.cfra);
printf("Appended frame %d\n", rd.cfra);
@@ -379,7 +384,7 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float
BKE_image_path_from_imformat(
name, rd.pic, sj->bmain->name, rd.cfra,
&rd.im_format, (rd.scemode & R_EXTENSION) != 0, true);
&rd.im_format, (rd.scemode & R_EXTENSION) != 0, true, NULL);
ibuf->rect = sj->dumprect;
ok = BKE_imbuf_write(ibuf, name, &rd.im_format);
@@ -410,8 +415,10 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float
PIL_sleep_ms(U.scrcastwait);
}
if (mh)
mh->end_movie();
if (mh) {
mh->end_movie(sj->movie_ctx);
mh->context_free(sj->movie_ctx);
}
BKE_report(&sj->reports, RPT_INFO, "Screencast job stopped");
}

View File

@@ -499,7 +499,7 @@ void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short te
int w = imapaintpartial.x2 - imapaintpartial.x1;
int h = imapaintpartial.y2 - imapaintpartial.y1;
/* Testing with partial update in uv editor too */
GPU_paint_update_image(image, imapaintpartial.x1, imapaintpartial.y1, w, h); //!texpaint);
GPU_paint_update_image(image, (sima ? &sima->iuser : NULL), imapaintpartial.x1, imapaintpartial.y1, w, h); //!texpaint);
}
}

View File

@@ -1109,7 +1109,7 @@ static int paint_2d_canvas_set(ImagePaintState *s, Image *ima)
if (ima == NULL) {
return 0;
}
else if (ima->packedfile && ima->rr) {
else if (BKE_image_has_packedfile(ima) && ima->rr) {
s->warnpackedfile = ima->id.name + 2;
return 0;
}

View File

@@ -5233,7 +5233,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
if (w > maxsize) w = maxsize;
if (h > maxsize) h = maxsize;
ibuf = ED_view3d_draw_offscreen_imbuf(scene, CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, false, R_ALPHAPREMUL, err_out);
ibuf = ED_view3d_draw_offscreen_imbuf(scene, CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, false, R_ALPHAPREMUL, NULL, err_out);
if (!ibuf) {
/* Mostly happens when OpenGL offscreen buffer was failed to create, */
/* but could be other reasons. Should be handled in the future. nazgul */
@@ -5444,7 +5444,7 @@ static Image *proj_paint_image_create(wmOperator *op, Main *bmain)
RNA_string_get(op->ptr, "name", imagename);
}
ima = BKE_image_add_generated(bmain, width, height, imagename, alpha ? 32 : 24, use_float,
gen_type, color);
gen_type, color, false);
return ima;
}

View File

@@ -44,6 +44,7 @@
#include "BKE_image.h"
#include "BKE_node.h"
#include "BKE_screen.h"
#include "BKE_scene.h"
#include "RE_pipeline.h"
@@ -82,9 +83,9 @@ static void image_info(Scene *scene, ImageUser *iuser, Image *ima, ImBuf *ibuf,
else {
if (ima->source == IMA_SRC_MOVIE) {
ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Movie"), len - ofs);
if (ima->anim)
if (BKE_image_has_anim(ima))
ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_(" %d frs"),
IMB_anim_get_duration(ima->anim, IMB_TC_RECORD_RUN));
IMB_anim_get_duration(((ImageAnim *)ima->anims.first)->anim, IMB_TC_RECORD_RUN));
}
else {
ofs += BLI_strncpy_rlen(str, IFACE_("Image"), len - ofs);
@@ -311,10 +312,10 @@ static void ui_imageuser_slot_menu(bContext *UNUSED(C), uiLayout *layout, void *
static const char *ui_imageuser_layer_fake_name(RenderResult *rr)
{
if (rr->rectf) {
if (RE_RenderViewGetRectf(rr, 0)) {
return IFACE_("Composite");
}
else if (rr->rect32) {
else if (RE_RenderViewGetRect32(rr, 0)) {
return IFACE_("Sequence");
}
else {
@@ -375,7 +376,7 @@ final:
static const char *ui_imageuser_pass_fake_name(RenderLayer *rl)
{
if (rl == NULL || rl->rectf) {
if (rl == NULL) {
return IFACE_("Combined");
}
else {
@@ -383,9 +384,9 @@ static const char *ui_imageuser_pass_fake_name(RenderLayer *rl)
}
}
static void ui_imageuser_pass_menu(bContext *UNUSED(C), uiLayout *layout, void *ptrpair_p)
static void ui_imageuser_pass_menu(bContext *UNUSED(C), uiLayout *layout, void *rnd_pt)
{
void **rnd_data = ptrpair_p;
void **rnd_data = rnd_pt;
uiBlock *block = uiLayoutGetBlock(layout);
Image *image = rnd_data[0];
ImageUser *iuser = rnd_data[1];
@@ -398,6 +399,7 @@ static void ui_imageuser_pass_menu(bContext *UNUSED(C), uiLayout *layout, void *
RenderPass *rpass;
const char *fake_name;
int nr;
int passflag = 0;
/* may have been freed since drawing */
rr = BKE_image_acquire_renderresult(scene, image);
@@ -419,15 +421,22 @@ static void ui_imageuser_pass_menu(bContext *UNUSED(C), uiLayout *layout, void *
fake_name = ui_imageuser_pass_fake_name(rl);
if (fake_name) {
BLI_strncpy(rpass_fake.name, fake_name, sizeof(rpass_fake.name));
BLI_strncpy(rpass_fake.internal_name, fake_name, sizeof(rpass_fake.internal_name));
nr += 1;
}
/* rendered results don't have a Combined pass */
for (rpass = rl ? rl->passes.last : NULL; rpass; rpass = rpass->prev, nr--) {
/* just show one pass of each kind */
if (passflag & rpass->passtype)
continue;
passflag |= rpass->passtype;
final:
uiDefButS(block, UI_BTYPE_BUT_MENU, B_NOP, IFACE_(rpass->name), 0, 0,
UI_UNIT_X * 5, UI_UNIT_X, &iuser->pass, (float) nr, 0.0, 0, -1, "");
uiDefButS(block, UI_BTYPE_BUT_MENU, B_NOP, IFACE_(rpass->internal_name), 0, 0,
UI_UNIT_X * 5, UI_UNIT_X, &iuser->passtype, (float) rpass->passtype, 0.0, 0, -1, "");
}
if (fake_name) {
@@ -441,21 +450,81 @@ final:
BKE_image_release_renderresult(scene, image);
}
/**************************** view menus *****************************/
static void ui_imageuser_view_menu_rr(bContext *UNUSED(C), uiLayout *layout, void *rnd_pt)
{
void **rnd_data = rnd_pt;
uiBlock *block = uiLayoutGetBlock(layout);
Image *image = rnd_data[0];
ImageUser *iuser = rnd_data[1];
RenderResult *rr;
RenderView *rview;
int nr;
Scene *scene = iuser->scene;
/* may have been freed since drawing */
rr = BKE_image_acquire_renderresult(scene, image);
if (UNLIKELY(rr == NULL)) {
return;
}
UI_block_layout_set_current(block, layout);
uiLayoutColumn(layout, false);
uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("View"),
0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
uiItemS(layout);
nr = (rr ? BLI_listbase_count(&rr->views) : 0) - 1;
for (rview = rr ? rr->views.last : NULL; rview; rview = rview->prev, nr--) {
uiDefButS(block, UI_BTYPE_BUT_MENU, B_NOP, IFACE_(rview->name), 0, 0,
UI_UNIT_X * 5, UI_UNIT_X, &iuser->view, (float) nr, 0.0, 0, -1, "");
}
BKE_image_release_renderresult(scene, image);
}
static void ui_imageuser_view_menu_multiview(bContext *UNUSED(C), uiLayout *layout, void *rnd_pt)
{
void **rnd_data = rnd_pt;
uiBlock *block = uiLayoutGetBlock(layout);
Image *image = rnd_data[0];
ImageUser *iuser = rnd_data[1];
int nr;
ImageView *iv;
UI_block_layout_set_current(block, layout);
uiLayoutColumn(layout, false);
uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_("View"),
0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
uiItemS(layout);
nr = BLI_listbase_count(&image->views) - 1;
for (iv = image->views.last; iv; iv = iv->prev, nr--) {
uiDefButS(block, UI_BTYPE_BUT_MENU, B_NOP, IFACE_(iv->name), 0, 0,
UI_UNIT_X * 5, UI_UNIT_X, &iuser->view, (float) nr, 0.0, 0, -1, "");
}
}
/* 5 layer button callbacks... */
static void image_multi_cb(bContext *C, void *rr_v, void *iuser_v)
{
ImageUser *iuser = iuser_v;
BKE_image_multilayer_index(rr_v, iuser);
BKE_image_multilayer_index(rr_v, iuser);
WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL);
}
static void image_multi_inclay_cb(bContext *C, void *rr_v, void *iuser_v)
{
RenderResult *rr = rr_v;
ImageUser *iuser = iuser_v;
int tot = BLI_listbase_count(&rr->layers);
if (rr->rectf || rr->rect32)
if (RE_HasFakeLayer(rr))
tot++; /* fake compo/sequencer layer */
if (iuser->layer < tot - 1) {
@@ -483,7 +552,7 @@ static void image_multi_incpass_cb(bContext *C, void *rr_v, void *iuser_v)
if (rl) {
int tot = BLI_listbase_count(&rl->passes);
if (rr->rectf || rr->rect32)
if (RE_HasFakeLayer(rr))
tot++; /* fake compo/sequencer layer */
if (iuser->pass < tot - 1) {
@@ -504,6 +573,16 @@ static void image_multi_decpass_cb(bContext *C, void *rr_v, void *iuser_v)
}
}
/* 5 view button callbacks... */
static void image_multiview_cb(bContext *C, void *ima_v, void *iuser_v)
{
Image *ima = ima_v;
ImageUser *iuser = iuser_v;
BKE_image_multiview_index(ima, iuser);
WM_event_add_notifier(C, NC_IMAGE | ND_DRAW, NULL);
}
#if 0
static void image_freecache_cb(bContext *C, void *ima_v, void *unused)
{
@@ -523,13 +602,14 @@ static void image_user_change(bContext *C, void *iuser_v, void *unused)
static void uiblock_layer_pass_buttons(uiLayout *layout, Image *image, RenderResult *rr, ImageUser *iuser, int w, short *render_slot)
{
static void *rnd_pt[3]; /* XXX, workaround */
static void *rnd_pt[4]; /* XXX, workaround */
uiBlock *block = uiLayoutGetBlock(layout);
uiBut *but;
RenderLayer *rl = NULL;
int wmenu1, wmenu2, wmenu3;
int wmenu1, wmenu2, wmenu3, wmenu4;
const char *fake_name;
const char *display_name;
const char *display_name = "";
const bool show_stereo = (iuser->flag & IMA_SHOW_STEREO);
uiLayoutRow(layout, true);
@@ -537,6 +617,7 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, Image *image, RenderRes
wmenu1 = (2 * w) / 5;
wmenu2 = (3 * w) / 5;
wmenu3 = (3 * w) / 6;
wmenu4 = (3 * w) / 6;
rnd_pt[0] = image;
rnd_pt[1] = iuser;
@@ -558,6 +639,7 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, Image *image, RenderRes
if (rr) {
RenderPass *rpass;
RenderView *rview;
int rpass_index;
/* layer */
@@ -566,20 +648,50 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, Image *image, RenderRes
rl = BLI_findlink(&rr->layers, rpass_index);
rnd_pt[2] = SET_INT_IN_POINTER(rpass_index);
display_name = rl ? rl->name : (fake_name ? fake_name : "");
but = uiDefMenuBut(block, ui_imageuser_layer_menu, rnd_pt, display_name, 0, 0, wmenu2, UI_UNIT_Y, TIP_("Select Layer"));
UI_but_func_set(but, image_multi_cb, rr, iuser);
UI_but_type_set_menu_from_pulldown(but);
if (RE_layers_have_name(rr)) {
display_name = rl ? rl->name : (fake_name ? fake_name : "");
but = uiDefMenuBut(block, ui_imageuser_layer_menu, rnd_pt, display_name, 0, 0, wmenu2, UI_UNIT_Y, TIP_("Select Layer"));
UI_but_func_set(but, image_multi_cb, rr, iuser);
UI_but_type_set_menu_from_pulldown(but);
}
/* pass */
fake_name = ui_imageuser_pass_fake_name(rl);
rpass = (rl ? BLI_findlink(&rl->passes, iuser->pass - (fake_name ? 1 : 0)) : NULL);
display_name = rpass ? rpass->name : (fake_name ? fake_name : "");
display_name = rpass ? rpass->internal_name : (fake_name ? fake_name : "");
but = uiDefMenuBut(block, ui_imageuser_pass_menu, rnd_pt, display_name, 0, 0, wmenu3, UI_UNIT_Y, TIP_("Select Pass"));
UI_but_func_set(but, image_multi_cb, rr, iuser);
UI_but_type_set_menu_from_pulldown(but);
/* view */
if (BLI_listbase_count_ex(&rr->views, 2) > 1 && !show_stereo) {
rview = BLI_findlink(&rr->views, iuser->view);
display_name = rview ? rview->name : "";
but = uiDefMenuBut(block, ui_imageuser_view_menu_rr, rnd_pt, display_name, 0, 0, wmenu4, UI_UNIT_Y, TIP_("Select View"));
UI_but_func_set(but, image_multi_cb, rr, iuser);
UI_but_type_set_menu_from_pulldown(but);
}
}
/* stereo image */
else if (((image->flag & IMA_IS_STEREO) && (!show_stereo)) ||
((image->flag & IMA_IS_MULTIVIEW) && ((image->flag & IMA_IS_STEREO) == 0)))
{
ImageView *iv;
int nr = 0;
for (iv = image->views.first; iv; iv = iv->next) {
if (nr++ == iuser->view) {
display_name = iv->name;
break;
}
}
but = uiDefMenuBut(block, ui_imageuser_view_menu_multiview, rnd_pt, display_name, 0, 0, wmenu1, UI_UNIT_Y, TIP_("Select View"));
UI_but_func_set(but, image_multiview_cb, image, iuser);
UI_but_type_set_menu_from_pulldown(but);
}
}
@@ -734,13 +846,13 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
if (ima->source != IMA_SRC_GENERATED) {
row = uiLayoutRow(layout, true);
if (ima->packedfile)
if (BKE_image_has_packedfile(ima))
uiItemO(row, "", ICON_PACKAGE, "image.unpack");
else
uiItemO(row, "", ICON_UGLYPACKAGE, "image.pack");
row = uiLayoutRow(row, true);
uiLayoutSetEnabled(row, ima->packedfile == NULL);
uiLayoutSetEnabled(row, BKE_image_has_packedfile(ima) == false);
uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE);
uiItemO(row, "", ICON_FILE_REFRESH, "image.reload");
}
@@ -792,6 +904,17 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
uiItemR(row, &imaptr, "alpha_mode", 0, IFACE_("Alpha"), ICON_NONE);
}
if ((scene->r.scemode & R_MULTIVIEW) != 0) {
uiItemS(layout);
col = uiLayoutColumn(layout, false);
uiItemR(col, &imaptr, "use_multiview", 0, NULL, ICON_NONE);
col = uiLayoutColumn(layout, false);
uiLayoutSetActive(col, RNA_boolean_get(&imaptr, "use_multiview"));
uiTemplateImageViews(col, &imaptr);
}
if (ima->source == IMA_SRC_MOVIE) {
col = uiLayoutColumn(layout, false);
uiItemR(col, &imaptr, "use_deinterlace", 0, IFACE_("Deinterlace"), ICON_NONE);
@@ -962,6 +1085,101 @@ void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, int color_man
}
}
void uiTemplateImageStereo3d(uiLayout *layout, PointerRNA *stereo3d_format_ptr)
{
Stereo3dFormat *stereo3d_format = stereo3d_format_ptr->data;
uiLayout *col;
col = uiLayoutColumn(layout, false);
uiItemR(col, stereo3d_format_ptr, "display_mode", 0, NULL, ICON_NONE);
switch (stereo3d_format->display_mode) {
case S3D_DISPLAY_ANAGLYPH:
{
uiItemR(col, stereo3d_format_ptr, "anaglyph_type", 0, NULL, ICON_NONE);
break;
}
case S3D_DISPLAY_INTERLACE:
{
uiItemR(col, stereo3d_format_ptr, "interlace_type", 0, NULL, ICON_NONE);
uiItemR(col, stereo3d_format_ptr, "use_interlace_swap", 0, NULL, ICON_NONE);
break;
}
case S3D_DISPLAY_SIDEBYSIDE:
{
uiItemR(col, stereo3d_format_ptr, "use_sidebyside_crosseyed", 0, NULL, ICON_NONE);
/* fall-through */
}
case S3D_DISPLAY_TOPBOTTOM:
{
uiItemR(col, stereo3d_format_ptr, "use_squeezed_frame", 0, NULL, ICON_NONE);
break;
}
}
}
static void uiTemplateViewsFormat(uiLayout *layout, PointerRNA *ptr, PointerRNA *stereo3d_format_ptr)
{
uiLayout *col, *box;
col = uiLayoutColumn(layout, false);
uiItemL(col, IFACE_("Views Format:"), ICON_NONE);
uiItemR(uiLayoutRow(col, false), ptr, "views_format", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
if (stereo3d_format_ptr) {
box = uiLayoutBox(col);
uiLayoutSetActive(box, RNA_enum_get(ptr, "views_format") == R_IMF_VIEWS_STEREO_3D);
uiTemplateImageStereo3d(box, stereo3d_format_ptr);
}
}
void uiTemplateImageViews(uiLayout *layout, PointerRNA *imaptr)
{
Image *ima = imaptr->data;
if (ima->type != IMA_TYPE_MULTILAYER) {
PropertyRNA *prop;
PointerRNA stereo3d_format_ptr;
prop = RNA_struct_find_property(imaptr, "stereo_3d_format");
stereo3d_format_ptr = RNA_property_pointer_get(imaptr, prop);
uiTemplateViewsFormat(layout, imaptr, &stereo3d_format_ptr);
}
else {
uiTemplateViewsFormat(layout, imaptr, NULL);
}
}
void uiTemplateImageFormatViews(uiLayout *layout, PointerRNA *imfptr, PointerRNA *ptr)
{
ImageFormatData *imf = imfptr->data;
uiLayout *col;
if (ptr) {
uiItemR(layout, ptr, "use_multiview", 0, NULL, ICON_NONE);
col = uiLayoutColumn(layout, false);
uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_multiview"));
}
else {
col = uiLayoutColumn(layout, false);
}
if (imf->imtype != R_IMF_IMTYPE_MULTILAYER) {
PropertyRNA *prop;
PointerRNA stereo3d_format_ptr;
prop = RNA_struct_find_property(imfptr, "stereo_3d_format");
stereo3d_format_ptr = RNA_property_pointer_get(imfptr, prop);
uiTemplateViewsFormat(col, imfptr, &stereo3d_format_ptr);
}
else {
uiTemplateViewsFormat(col, imfptr, NULL);
}
}
void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser *iuser)
{
Scene *scene = CTX_data_scene(C);

View File

@@ -783,7 +783,7 @@ void draw_image_main(const bContext *C, ARegion *ar)
Image *ima;
ImBuf *ibuf;
float zoomx, zoomy;
bool show_viewer, show_render, show_paint;
bool show_viewer, show_render, show_paint, show_stereo3d, show_multilayer;
void *lock;
/* XXX can we do this in refresh? */
@@ -813,6 +813,8 @@ void draw_image_main(const bContext *C, ARegion *ar)
show_viewer = (ima && ima->source == IMA_SRC_VIEWER) != 0;
show_render = (show_viewer && ima->type == IMA_TYPE_R_RESULT) != 0;
show_paint = (ima && (sima->mode == SI_MODE_PAINT) && (show_viewer == false) && (show_render == false));
show_stereo3d = (ima && (ima->flag & IMA_IS_STEREO) && (sima->iuser.flag & IMA_SHOW_STEREO));
show_multilayer = ima && BKE_image_is_multilayer(ima);
if (show_viewer) {
/* use locked draw for drawing viewer image buffer since the compositor
@@ -823,6 +825,14 @@ void draw_image_main(const bContext *C, ARegion *ar)
BLI_lock_thread(LOCK_DRAW_IMAGE);
}
if (show_stereo3d) {
if (show_multilayer)
/* update multiindex and pass for the current eye */
BKE_image_multilayer_index(ima->rr, &sima->iuser);
else
BKE_image_multiview_index(ima, &sima->iuser);
}
ibuf = ED_space_image_acquire_buffer(sima, &lock);
/* draw the image or grid */

View File

@@ -30,14 +30,21 @@
#include <stddef.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#ifndef WIN32
# include <unistd.h>
#else
# include <io.h>
#endif
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_string_utf8.h"
#include "BLF_translation.h"
@@ -60,6 +67,7 @@
#include "BKE_report.h"
#include "BKE_screen.h"
#include "BKE_sound.h"
#include "BKE_scene.h"
#include "GPU_draw.h"
#include "GPU_buffers.h"
@@ -68,6 +76,7 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_moviecache.h"
#include "intern/openexr/openexr_multi.h"
#include "RE_pipeline.h"
@@ -936,6 +945,7 @@ static void image_filesel(bContext *C, wmOperator *op, const char *path)
typedef struct ImageOpenData {
PropertyPointerRNA pprop;
ImageUser *iuser;
ImageFormatData im_format;
} ImageOpenData;
typedef struct ImageFrame {
@@ -946,7 +956,6 @@ typedef struct ImageFrame {
static void image_open_init(bContext *C, wmOperator *op)
{
ImageOpenData *iod;
op->customdata = iod = MEM_callocN(sizeof(ImageOpenData), __func__);
iod->iuser = CTX_data_pointer_get_type(C, "image_user", &RNA_ImageUser).data;
UI_context_active_but_prop_get_templateID(C, &iod->pprop.ptr, &iod->pprop.prop);
@@ -1048,7 +1057,7 @@ static int image_open_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
ImageUser *iuser = NULL;
ImageOpenData *iod;
ImageOpenData *iod = op->customdata;
PointerRNA idptr;
Image *ima = NULL;
char path[FILE_MAX];
@@ -1085,6 +1094,21 @@ static int image_open_exec(bContext *C, wmOperator *op)
if (!op->customdata)
image_open_init(C, op);
/* handle multiview images */
if (RNA_boolean_get(op->ptr, "use_multiview")) {
ImageFormatData *imf = &iod->im_format;
ima->flag |= IMA_USE_VIEWS;
ima->views_format = imf->views_format;
*ima->stereo3d_format = imf->stereo3d_format;
}
else {
ima->flag &= ~IMA_USE_VIEWS;
ima->flag &= ~IMA_IS_STEREO;
ima->flag &= ~IMA_IS_MULTIVIEW;
BKE_image_free_views(ima);
}
/* only image path after save, never ibuf */
if (is_relative_path) {
if (!exists) {
@@ -1128,6 +1152,8 @@ static int image_open_exec(bContext *C, wmOperator *op)
iuser->framenr = 1;
iuser->offset = frame_ofs - 1;
iuser->fie_ima = 2;
iuser->scene = scene;
BKE_image_init_imageuser(ima, iuser);
}
/* XXX unpackImage frees image buffers */
@@ -1146,7 +1172,8 @@ static int image_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
SpaceImage *sima = CTX_wm_space_image(C); /* XXX other space types can call */
const char *path = U.textudir;
Image *ima = NULL;
Scene *scene = CTX_data_scene(C);
PropertyRNA *prop;
if (sima) {
ima = sima->image;
}
@@ -1185,11 +1212,44 @@ static int image_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(
image_open_init(C, op);
/* show multiview save options only if scene has multiviews */
prop = RNA_struct_find_property(op->ptr, "show_multiview");
RNA_property_boolean_set(op->ptr, prop, (scene->r.scemode & R_MULTIVIEW) != 0);
image_filesel(C, op, path);
return OPERATOR_RUNNING_MODAL;
}
static bool image_open_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
{
const char *prop_id = RNA_property_identifier(prop);
return !(STREQ(prop_id, "filepath") ||
STREQ(prop_id, "directory") ||
STREQ(prop_id, "filename")
);
}
static void image_open_draw(bContext *UNUSED(C), wmOperator *op)
{
uiLayout *layout = op->layout;
ImageOpenData *iod = op->customdata;
ImageFormatData *imf = &iod->im_format;
PointerRNA imf_ptr, ptr;
/* main draw call */
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
uiDefAutoButsRNA(layout, &ptr, image_open_draw_check_prop, '\0');
/* image template */
RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &imf_ptr);
/* multiview template */
if (RNA_boolean_get(op->ptr, "show_multiview"))
uiTemplateImageFormatViews(layout, &imf_ptr, op->ptr);
}
/* called by other space types too */
void IMAGE_OT_open(wmOperatorType *ot)
{
@@ -1202,6 +1262,7 @@ void IMAGE_OT_open(wmOperatorType *ot)
ot->exec = image_open_exec;
ot->invoke = image_open_invoke;
ot->cancel = image_open_cancel;
ot->ui = image_open_draw;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1233,10 +1294,10 @@ static int image_match_len_exec(bContext *C, wmOperator *UNUSED(op))
}
if (!ima || !iuser || !ima->anim)
if (!ima || !iuser || !BKE_image_has_anim(ima))
return OPERATOR_CANCELLED;
iuser->frames = IMB_anim_get_duration(ima->anim, IMB_TC_RECORD_RUN);
iuser->frames = IMB_anim_get_duration(((ImageAnim *) ima->anims.first)->anim, IMB_TC_RECORD_RUN);
BKE_image_user_frame_calc(iuser, scene->r.cfra, 0);
return OPERATOR_FINISHED;
@@ -1433,6 +1494,10 @@ static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima,
}
}
/* use the multiview image settings as the default */
simopts->im_format.stereo3d_format = *ima->stereo3d_format;
simopts->im_format.views_format = ima->views_format;
/* color management */
BKE_color_managed_display_settings_copy(&simopts->im_format.display_settings, &scene->display_settings);
BKE_color_managed_view_settings_copy(&simopts->im_format.view_settings, &scene->view_settings);
@@ -1468,30 +1533,131 @@ static void save_image_options_to_op(SaveImageOptions *simopts, wmOperator *op)
RNA_string_set(op->ptr, "filepath", simopts->filepath);
}
/* returns the pass index for the view_id */
static int get_multiview_pass_id(RenderResult *rr, ImageUser *iuser, const int view_id)
{
RenderLayer *rl;
RenderPass *rpass;
int passtype;
short rl_index = 0, rp_index;
if (rr == NULL || iuser == NULL)
return 0;
if (BLI_listbase_count_ex(&rr->views, 2) < 2)
return iuser->pass;
if (RE_HasFakeLayer(rr))
rl_index ++; /* fake compo/sequencer layer */
rl = BLI_findlink(&rr->layers, rl_index);
if (!rl) return iuser->pass;
rpass = BLI_findlink(&rl->passes, iuser->pass);
passtype = rpass->passtype;
rp_index = 0;
for (rpass = rl->passes.first; rpass; rpass = rpass->next, rp_index++) {
if (rpass->passtype == passtype &&
rpass->view_id == view_id)
{
return rp_index;
}
}
return iuser->pass;
}
static void save_image_post(wmOperator *op, ImBuf *ibuf, Image *ima, int ok, int save_copy, const char *relbase, int relative, int do_newpath, const char *filepath)
{
if (ok) {
if (!save_copy) {
if (do_newpath) {
BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name));
BLI_strncpy(ima->name, filepath, sizeof(ima->name));
}
ibuf->userflags &= ~IB_BITMAPDIRTY;
/* change type? */
if (ima->type == IMA_TYPE_R_RESULT) {
ima->type = IMA_TYPE_IMAGE;
/* workaround to ensure the render result buffer is no longer used
* by this image, otherwise can crash when a new render result is
* created. */
if (ibuf->rect && !(ibuf->mall & IB_rect))
imb_freerectImBuf(ibuf);
if (ibuf->rect_float && !(ibuf->mall & IB_rectfloat))
imb_freerectfloatImBuf(ibuf);
if (ibuf->zbuf && !(ibuf->mall & IB_zbuf))
IMB_freezbufImBuf(ibuf);
if (ibuf->zbuf_float && !(ibuf->mall & IB_zbuffloat))
IMB_freezbuffloatImBuf(ibuf);
}
if (ELEM(ima->source, IMA_SRC_GENERATED, IMA_SRC_VIEWER)) {
ima->source = IMA_SRC_FILE;
ima->type = IMA_TYPE_IMAGE;
}
/* only image path, never ibuf */
if (relative) {
BLI_path_rel(ima->name, relbase); /* only after saving */
}
IMB_colormanagment_colorspace_from_ibuf_ftype(&ima->colorspace_settings, ibuf);
}
}
else {
BKE_reportf(op->reports, RPT_ERROR, "Could not write image %s", filepath);
}
}
static void save_imbuf_post(ImBuf *ibuf, ImBuf *colormanaged_ibuf)
{
if (colormanaged_ibuf != ibuf) {
/* This guys might be modified by image buffer write functions,
* need to copy them back from color managed image buffer to an
* original one, so file type of image is being properly updated.
*/
ibuf->ftype = colormanaged_ibuf->ftype;
ibuf->planes = colormanaged_ibuf->planes;
IMB_freeImBuf(colormanaged_ibuf);
}
}
/**
* \return success.
* \note ``ima->name`` and ``ibuf->name`` should end up the same.
* \note for multiview the first ``ibuf`` is important to get the settings.
*/
static bool save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveImageOptions *simopts, bool do_newpath)
{
Image *ima = ED_space_image(sima);
void *lock;
ImBuf *ibuf = ED_space_image_acquire_buffer(sima, &lock);
Scene *scene;
RenderResult *rr = NULL;
bool ok = false;
WM_cursor_wait(1);
if (ibuf) {
ImBuf *colormanaged_ibuf;
ImBuf *colormanaged_ibuf = NULL;
const char *relbase = ID_BLEND_PATH(CTX_data_main(C), &ima->id);
const bool relative = (RNA_struct_find_property(op->ptr, "relative_path") && RNA_boolean_get(op->ptr, "relative_path"));
const bool save_copy = (RNA_struct_find_property(op->ptr, "copy") && RNA_boolean_get(op->ptr, "copy"));
const bool save_as_render = (RNA_struct_find_property(op->ptr, "save_as_render") && RNA_boolean_get(op->ptr, "save_as_render"));
ImageFormatData *imf = &simopts->im_format;
const bool is_multilayer = imf->imtype == R_IMF_IMTYPE_MULTILAYER;
bool is_mono;
/* old global to ensure a 2nd save goes to same dir */
BLI_strncpy(G.ima, simopts->filepath, sizeof(G.ima));
WM_cursor_wait(1);
if (ima->type == IMA_TYPE_R_RESULT) {
/* enforce user setting for RGB or RGBA, but skip BW */
if (simopts->im_format.planes == R_IMF_PLANES_RGBA) {
@@ -1512,83 +1678,197 @@ static bool save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
}
}
colormanaged_ibuf = IMB_colormanagement_imbuf_for_write(ibuf, save_as_render, true, &imf->view_settings, &imf->display_settings, imf);
/* we need renderresult for exr and rendered multiview */
scene = CTX_data_scene(C);
rr = BKE_image_acquire_renderresult(scene, ima);
is_mono = rr ? BLI_listbase_count_ex(&rr->views, 2) < 2 : (ima->flag & IMA_IS_MULTIVIEW) == 0;
if (simopts->im_format.imtype == R_IMF_IMTYPE_MULTILAYER) {
Scene *scene = CTX_data_scene(C);
RenderResult *rr = BKE_image_acquire_renderresult(scene, ima);
if (rr) {
ok = RE_WriteRenderResult(op->reports, rr, simopts->filepath, simopts->im_format.exr_codec);
/* error handling */
if (!rr) {
if (imf->imtype == R_IMF_IMTYPE_MULTILAYER) {
BKE_report(op->reports, RPT_ERROR, "Did not write, no Multilayer Image");
goto cleanup;
}
}
else {
if (imf->views_format == R_IMF_VIEWS_STEREO_3D) {
if ((ima->flag & IMA_IS_STEREO) == 0) {
BKE_reportf(op->reports, RPT_ERROR, "Did not write, the image doesn't have a \"%s\" and \"%s\" views",
STEREO_LEFT_NAME, STEREO_RIGHT_NAME);
goto cleanup;
}
/* it shouldn't ever happen*/
if ((BLI_findstring(&rr->views, STEREO_LEFT_NAME, offsetof(RenderView, name)) == NULL) ||
(BLI_findstring(&rr->views, STEREO_RIGHT_NAME, offsetof(RenderView, name)) == NULL))
{
BKE_reportf(op->reports, RPT_ERROR, "Did not write, the image doesn't have a \"%s\" and \"%s\" views",
STEREO_LEFT_NAME, STEREO_RIGHT_NAME);
goto cleanup;
}
}
}
/* fancy multiview OpenEXR */
if ((imf->imtype == R_IMF_IMTYPE_MULTILAYER) && (imf->views_format == R_IMF_VIEWS_MULTIVIEW)) {
ok = RE_WriteRenderResult(op->reports, rr, simopts->filepath, imf, true, NULL);
save_image_post(op, ibuf, ima, ok, true, relbase, relative, do_newpath, simopts->filepath);
ED_space_image_release_buffer(sima, ibuf, lock);
}
else if ((imf->imtype == R_IMF_IMTYPE_OPENEXR) && (imf->views_format == R_IMF_VIEWS_MULTIVIEW)) {
/* treat special Openexr case separetely (this is the singlelayer multiview OpenEXR */
BKE_imbuf_write_prepare(ibuf, imf);
ok = BKE_image_save_openexr_multiview(ima, ibuf, simopts->filepath, (IB_rect | IB_zbuf | IB_zbuffloat | IB_multiview));
ED_space_image_release_buffer(sima, ibuf, lock);
}
/* regular mono pipeline */
else if (is_mono) {
if (is_multilayer) {
ok = RE_WriteRenderResult(op->reports, rr, simopts->filepath, imf, false, NULL);
}
else {
BKE_report(op->reports, RPT_ERROR, "Did not write, no Multilayer Image");
colormanaged_ibuf = IMB_colormanagement_imbuf_for_write(ibuf, save_as_render, true, &imf->view_settings, &imf->display_settings, imf);
ok = BKE_imbuf_write_as(colormanaged_ibuf, simopts->filepath, imf, save_copy);
save_imbuf_post(ibuf, colormanaged_ibuf);
}
BKE_image_release_renderresult(scene, ima);
}
else {
ok = BKE_imbuf_write_as(colormanaged_ibuf, simopts->filepath, &simopts->im_format, save_copy);
save_image_post(op, ibuf, ima, ok, (is_multilayer ? true : save_copy), relbase, relative, do_newpath, simopts->filepath);
ED_space_image_release_buffer(sima, ibuf, lock);
}
/* individual multiview images */
else if (imf->views_format == R_IMF_VIEWS_INDIVIDUAL) {
size_t i;
unsigned char planes = ibuf->planes;
const size_t totviews = (rr ? BLI_listbase_count(&rr->views) : BLI_listbase_count(&ima->views));
if (ok) {
if (!save_copy) {
if (do_newpath) {
BLI_strncpy(ibuf->name, simopts->filepath, sizeof(ibuf->name));
BLI_strncpy(ima->name, simopts->filepath, sizeof(ima->name));
if (!is_multilayer) {
ED_space_image_release_buffer(sima, ibuf, lock);
}
for (i = 0; i < totviews; i++) {
char filepath[FILE_MAX];
bool ok_view = false;
const char *view = rr ? ((RenderView *) BLI_findlink(&rr->views, i))->name :
((ImageView *) BLI_findlink(&ima->views, i))->name;
if (is_multilayer) {
BKE_scene_multiview_view_filepath_get(&scene->r, simopts->filepath, view, filepath);
ok_view = RE_WriteRenderResult(op->reports, rr, filepath, imf, false, view);
save_image_post(op, ibuf, ima, ok_view, true, relbase, relative, do_newpath, filepath);
}
else {
/* copy iuser to get the correct ibuf for this view */
ImageUser iuser = sima->iuser;
iuser.view = i;
iuser.flag &= ~IMA_SHOW_STEREO;
ibuf->userflags &= ~IB_BITMAPDIRTY;
if (rr) {
iuser.pass = get_multiview_pass_id(rr, &sima->iuser, i);
BKE_image_multilayer_index(rr, &iuser);
}
else {
BKE_image_multiview_index(ima, &iuser);
}
/* change type? */
if (ima->type == IMA_TYPE_R_RESULT) {
ima->type = IMA_TYPE_IMAGE;
ibuf = BKE_image_acquire_ibuf(sima->image, &iuser, &lock);
ibuf->planes = planes;
/* workaround to ensure the render result buffer is no longer used
* by this image, otherwise can crash when a new render result is
* created. */
if (ibuf->rect && !(ibuf->mall & IB_rect))
imb_freerectImBuf(ibuf);
if (ibuf->rect_float && !(ibuf->mall & IB_rectfloat))
imb_freerectfloatImBuf(ibuf);
if (ibuf->zbuf && !(ibuf->mall & IB_zbuf))
IMB_freezbufImBuf(ibuf);
if (ibuf->zbuf_float && !(ibuf->mall & IB_zbuffloat))
IMB_freezbuffloatImBuf(ibuf);
}
if (ELEM(ima->source, IMA_SRC_GENERATED, IMA_SRC_VIEWER)) {
ima->source = IMA_SRC_FILE;
ima->type = IMA_TYPE_IMAGE;
BKE_scene_multiview_view_filepath_get(&scene->r, simopts->filepath, view, filepath);
colormanaged_ibuf = IMB_colormanagement_imbuf_for_write(ibuf, save_as_render, true, &imf->view_settings, &imf->display_settings, imf);
ok_view = BKE_imbuf_write_as(colormanaged_ibuf, filepath, &simopts->im_format, save_copy);
save_imbuf_post(ibuf, colormanaged_ibuf);
save_image_post(op, ibuf, ima, ok_view, true, relbase, relative, do_newpath, filepath);
BKE_image_release_ibuf(sima->image, ibuf, lock);
}
ok &= ok_view;
}
/* only image path, never ibuf */
if (relative) {
BLI_path_rel(ima->name, relbase); /* only after saving */
}
IMB_colormanagment_colorspace_from_ibuf_ftype(&ima->colorspace_settings, ibuf);
if (is_multilayer) {
ED_space_image_release_buffer(sima, ibuf, lock);
}
}
else {
BKE_reportf(op->reports, RPT_ERROR, "Could not write image %s", simopts->filepath);
}
/* stereo (multiview) images */
else if (simopts->im_format.views_format == R_IMF_VIEWS_STEREO_3D) {
if (imf->imtype == R_IMF_IMTYPE_MULTILAYER) {
ok = RE_WriteRenderResult(op->reports, rr, simopts->filepath, imf, false, NULL);
save_image_post(op, ibuf, ima, ok, true, relbase, relative, do_newpath, simopts->filepath);
ED_space_image_release_buffer(sima, ibuf, lock);
}
else {
ImBuf *ibuf_stereo[2] = {NULL};
unsigned char planes = ibuf->planes;
const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
int i;
/* we need to get the specific per-view buffers */
ED_space_image_release_buffer(sima, ibuf, lock);
for (i = 0; i < 2; i ++) {
ImageUser iuser = sima->iuser;
iuser.flag &= ~IMA_SHOW_STEREO;
if (rr) {
int id = BLI_findstringindex(&rr->views, names[i], offsetof(RenderView, name));
iuser.pass = get_multiview_pass_id(rr, &sima->iuser, id);
iuser.view = id;
BKE_image_multilayer_index(rr, &iuser);
}
else {
iuser.view = i;
BKE_image_multiview_index(ima, &iuser);
}
ibuf = BKE_image_acquire_ibuf(sima->image, &iuser, &lock);
if (ibuf == NULL) {
BKE_report(op->reports, RPT_ERROR, "Did not write, unexpected error when saving stereo image");
goto cleanup;
}
ibuf->planes = planes;
/* color manage the ImBuf leaving it ready for saving */
colormanaged_ibuf = IMB_colormanagement_imbuf_for_write(ibuf, save_as_render, true,
&imf->view_settings, &imf->display_settings, imf);
BKE_imbuf_write_prepare(colormanaged_ibuf, imf);
IMB_prepare_write_ImBuf(IMB_isfloat(colormanaged_ibuf), colormanaged_ibuf);
/* duplicate buffer to prevent locker issue when using render result */
ibuf_stereo[i] = IMB_dupImBuf(colormanaged_ibuf);
save_imbuf_post(ibuf, colormanaged_ibuf);
BKE_image_release_ibuf(sima->image, ibuf, lock);
}
ibuf = IMB_stereo3d_ImBuf(imf, ibuf_stereo[0], ibuf_stereo[1]);
/* save via traditional path */
ok = BKE_imbuf_write_as(ibuf, simopts->filepath, imf, save_copy);
IMB_freeImBuf(ibuf);
for (i = 0; i < 2; i ++) {
IMB_freeImBuf(ibuf_stereo[i]);
}
}
}
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, sima->image);
WM_cursor_wait(0);
if (colormanaged_ibuf != ibuf) {
/* This guys might be modified by image buffer write functions,
* need to copy them back from color managed image buffer to an
* original one, so file type of image is being properly updated.
*/
ibuf->ftype = colormanaged_ibuf->ftype;
ibuf->planes = colormanaged_ibuf->planes;
IMB_freeImBuf(colormanaged_ibuf);
}
}
else {
cleanup:
ED_space_image_release_buffer(sima, ibuf, lock);
}
ED_space_image_release_buffer(sima, ibuf, lock);
if (rr) {
BKE_image_release_renderresult(scene, ima);
}
WM_cursor_wait(0);
return ok;
}
@@ -1636,6 +1916,7 @@ static int image_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS
Image *ima = ED_space_image(sima);
Scene *scene = CTX_data_scene(C);
SaveImageOptions simopts;
PropertyRNA *prop;
const bool save_as_render = ((ima->source == IMA_SRC_VIEWER) || (ima->flag & IMA_VIEW_AS_RENDER));
if (RNA_struct_property_is_set(op->ptr, "filepath"))
@@ -1657,6 +1938,12 @@ static int image_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS
op->customdata = MEM_mallocN(sizeof(simopts.im_format), __func__);
memcpy(op->customdata, &simopts.im_format, sizeof(simopts.im_format));
/* show multiview save options only if image has multiviews */
prop = RNA_struct_find_property(op->ptr, "show_multiview");
RNA_property_boolean_set(op->ptr, prop, (ima->flag & IMA_IS_MULTIVIEW) != 0);
prop = RNA_struct_find_property(op->ptr, "use_multiview");
RNA_property_boolean_set(op->ptr, prop, (ima->flag & IMA_IS_MULTIVIEW) != 0);
image_filesel(C, op, simopts.filepath);
return OPERATOR_RUNNING_MODAL;
@@ -1683,15 +1970,20 @@ static void image_save_as_draw(bContext *UNUSED(C), wmOperator *op)
{
uiLayout *layout = op->layout;
ImageFormatData *imf = op->customdata;
PointerRNA ptr;
PointerRNA imf_ptr, ptr;
const bool is_multiview = RNA_boolean_get(op->ptr, "use_multiview");
/* image template */
RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &ptr);
uiTemplateImageSettings(layout, &ptr, false);
RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &imf_ptr);
uiTemplateImageSettings(layout, &imf_ptr, false);
/* main draw call */
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
uiDefAutoButsRNA(layout, &ptr, image_save_as_draw_check_prop, '\0');
/* multiview template */
if (is_multiview)
uiTemplateImageFormatViews(layout, &imf_ptr, NULL);
}
static int image_save_as_poll(bContext *C)
@@ -1714,8 +2006,6 @@ static int image_save_as_poll(bContext *C)
void IMAGE_OT_save_as(wmOperatorType *ot)
{
// PropertyRNA *prop;
/* identifiers */
ot->name = "Save As Image";
ot->idname = "IMAGE_OT_save_as";
@@ -1932,6 +2222,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
float color[4];
int width, height, floatbuf, gen_type, alpha;
int gen_context;
int stereo3d;
/* retrieve state */
sima = CTX_wm_space_image(C);
@@ -1952,11 +2243,12 @@ static int image_new_exec(bContext *C, wmOperator *op)
RNA_float_get_array(op->ptr, "color", color);
alpha = RNA_boolean_get(op->ptr, "alpha");
gen_context = RNA_enum_get(op->ptr, "gen_context");
stereo3d = RNA_boolean_get(op->ptr, "use_stereo_3d");
if (!alpha)
color[3] = 1.0f;
ima = BKE_image_add_generated(bmain, width, height, name, alpha ? 32 : 24, floatbuf, gen_type, color);
ima = BKE_image_add_generated(bmain, width, height, name, alpha ? 32 : 24, floatbuf, gen_type, color, stereo3d);
if (!ima)
return OPERATOR_CANCELLED;
@@ -2036,6 +2328,53 @@ static int image_new_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e
return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X, 5 * UI_UNIT_Y);
}
static void image_new_draw(bContext *UNUSED(C), wmOperator *op)
{
uiLayout *split, *col[2];
uiLayout *layout = op->layout;
PointerRNA ptr;
#if 0
Scene *scene = CTX_data_scene(C);
const bool is_multiview = (scene->r.scemode & R_MULTIVIEW) != 0;
#endif
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
/* copy of WM_operator_props_dialog_popup() layout */
split = uiLayoutSplit(layout, 0.5f, false);
col[0] = uiLayoutColumn(split, false);
col[1] = uiLayoutColumn(split, false);
uiItemL(col[0], IFACE_("Name"), ICON_NONE);
uiItemR(col[1], &ptr, "name", 0, "", ICON_NONE);
uiItemL(col[0], IFACE_("Width"), ICON_NONE);
uiItemR(col[1], &ptr, "width", 0, "", ICON_NONE);
uiItemL(col[0], IFACE_("Height"), ICON_NONE);
uiItemR(col[1], &ptr, "height", 0, "", ICON_NONE);
uiItemL(col[0], IFACE_("Color"), ICON_NONE);
uiItemR(col[1], &ptr, "color", 0, "", ICON_NONE);
uiItemL(col[0], "", ICON_NONE);
uiItemR(col[1], &ptr, "alpha", 0, NULL, ICON_NONE);
uiItemL(col[0], IFACE_("Generated Type"), ICON_NONE);
uiItemR(col[1], &ptr, "generated_type", 0, "", ICON_NONE);
uiItemL(col[0], "", ICON_NONE);
uiItemR(col[1], &ptr, "float", 0, NULL, ICON_NONE);
#if 0
if (is_multiview) {
uiItemL(col[0], "", ICON_NONE);
uiItemR(col[1], &ptr, "use_stereo_3d", 0, NULL, ICON_NONE);
}
#endif
}
void IMAGE_OT_new(wmOperatorType *ot)
{
PropertyRNA *prop;
@@ -2056,6 +2395,7 @@ void IMAGE_OT_new(wmOperatorType *ot)
/* api callbacks */
ot->exec = image_new_exec;
ot->invoke = image_new_invoke;
ot->ui = image_new_draw;
/* flags */
ot->flag = OPTYPE_UNDO;
@@ -2075,7 +2415,8 @@ void IMAGE_OT_new(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "float", 0, "32 bit Float", "Create image with 32 bit floating point bit depth");
prop = RNA_def_enum(ot->srna, "gen_context", gen_context_items, 0, "Gen Context", "Generation context");
RNA_def_property_flag(prop, PROP_HIDDEN);
prop = RNA_def_boolean(ot->srna, "use_stereo_3d", 0, "Stereo 3D", "Create an image with left and right views");
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
}
#undef IMA_DEF_NAME
@@ -2200,7 +2541,7 @@ static bool image_pack_test(bContext *C, wmOperator *op)
if (!ima)
return 0;
if (!as_png && ima->packedfile)
if (!as_png && BKE_image_has_packedfile(ima))
return 0;
if (ima->source == IMA_SRC_SEQUENCE || ima->source == IMA_SRC_MOVIE) {
@@ -2229,7 +2570,7 @@ static int image_pack_exec(bContext *C, wmOperator *op)
if (as_png)
BKE_image_memorypack(ima);
else
ima->packedfile = newPackedFile(op->reports, ima->name, ID_BLEND_PATH(bmain, &ima->id));
BKE_image_packfiles(op->reports, ima, ID_BLEND_PATH(bmain, &ima->id));
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
@@ -2301,7 +2642,7 @@ static int image_unpack_exec(bContext *C, wmOperator *op)
if (!ima) ima = CTX_data_edit_image(C);
}
if (!ima || !ima->packedfile)
if (!ima || !BKE_image_has_packedfile(ima))
return OPERATOR_CANCELLED;
if (ima->source == IMA_SRC_SEQUENCE || ima->source == IMA_SRC_MOVIE) {
@@ -2329,7 +2670,7 @@ static int image_unpack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
if (RNA_struct_property_is_set(op->ptr, "id"))
return image_unpack_exec(C, op);
if (!ima || !ima->packedfile)
if (!ima || !BKE_image_has_packedfile(ima))
return OPERATOR_CANCELLED;
if (ima->source == IMA_SRC_SEQUENCE || ima->source == IMA_SRC_MOVIE) {
@@ -2340,7 +2681,7 @@ static int image_unpack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
if (G.fileflags & G_AUTOPACK)
BKE_report(op->reports, RPT_WARNING, "AutoPack is enabled, so image will be packed again on file save");
unpack_menu(C, "IMAGE_OT_unpack", ima->id.name + 2, ima->name, "textures", ima->packedfile);
unpack_menu(C, "IMAGE_OT_unpack", ima->id.name + 2, ima->name, "textures", BKE_image_has_packedfile(ima) ? ((ImagePackedFile *)ima->packedfiles.first)->packedfile : NULL);
return OPERATOR_FINISHED;
}

View File

@@ -156,7 +156,8 @@ static SpaceLink *image_new(const bContext *UNUSED(C))
simage->iuser.ok = true;
simage->iuser.fie_ima = 2;
simage->iuser.frames = 100;
simage->iuser.flag = IMA_SHOW_STEREO;
scopes_new(&simage->scopes);
simage->sample_line_hist.height = 100;

View File

@@ -703,7 +703,9 @@ static void node_buts_image_user(uiLayout *layout, bContext *C, PointerRNA *ptr,
uiItemR(col, ptr, "use_auto_refresh", 0, NULL, ICON_NONE);
}
if (RNA_enum_get(imaptr, "type") == IMA_TYPE_MULTILAYER) {
if (RNA_enum_get(imaptr, "type") == IMA_TYPE_MULTILAYER &&
RNA_boolean_get(ptr, "has_layers"))
{
col = uiLayoutColumn(layout, false);
uiItemR(col, ptr, "layer", 0, NULL, ICON_NONE);
}
@@ -1214,6 +1216,24 @@ static void node_shader_set_butfunc(bNodeType *ntype)
/* ****************** BUTTON CALLBACKS FOR COMPOSITE NODES ***************** */
static void node_buts_image_views(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr,
PointerRNA *imaptr)
{
uiLayout *col;
if (!imaptr->data)
return;
col = uiLayoutColumn(layout, false);
if (RNA_boolean_get(ptr, "has_views")) {
if (RNA_enum_get(ptr, "view") == 0)
uiItemR(col, ptr, "view", 0, NULL, ICON_CAMERA_STEREO);
else
uiItemR(col, ptr, "view", 0, NULL, ICON_SCENE);
}
}
static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
bNode *node = ptr->data;
@@ -1227,6 +1247,8 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *
imaptr = RNA_pointer_get(ptr, "image");
node_buts_image_user(layout, C, ptr, &imaptr, &iuserptr);
node_buts_image_views(layout, C, ptr, &imaptr);
}
static void node_composit_buts_image_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
@@ -1717,8 +1739,8 @@ static void node_composit_buts_id_mask(uiLayout *layout, bContext *UNUSED(C), Po
static void node_composit_buts_file_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
PointerRNA imfptr = RNA_pointer_get(ptr, "format");
int multilayer = (RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_MULTILAYER);
const bool multilayer = RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_MULTILAYER;
if (multilayer)
uiItemL(layout, IFACE_("Path:"), ICON_NONE);
else
@@ -1727,15 +1749,22 @@ static void node_composit_buts_file_output(uiLayout *layout, bContext *UNUSED(C)
}
static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, PointerRNA *ptr)
{
Scene *scene = CTX_data_scene(C);
PointerRNA imfptr = RNA_pointer_get(ptr, "format");
PointerRNA active_input_ptr, op_ptr;
uiLayout *row, *col;
int active_index;
int multilayer = (RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_MULTILAYER);
const bool multilayer = RNA_enum_get(&imfptr, "file_format") == R_IMF_IMTYPE_MULTILAYER;
const bool is_multiview = (scene->r.scemode & R_MULTIVIEW) != 0;
node_composit_buts_file_output(layout, C, ptr);
uiTemplateImageSettings(layout, &imfptr, false);
/* disable stereo output for multilayer, too much work for something that no one will use */
/* if someone asks for that we can implement it */
if (is_multiview)
uiTemplateImageFormatViews(layout, &imfptr, NULL);
uiItemS(layout);
uiItemO(layout, IFACE_("Add Input"), ICON_ZOOMIN, "NODE_OT_output_file_add_socket");
@@ -1797,6 +1826,9 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi
col = uiLayoutColumn(layout, false);
uiLayoutSetActive(col, RNA_boolean_get(&active_input_ptr, "use_node_format") == false);
uiTemplateImageSettings(col, &imfptr, false);
if (is_multiview)
uiTemplateImageFormatViews(layout, &imfptr, NULL);
}
}
}
@@ -2090,6 +2122,18 @@ static void node_composit_buts_switch(uiLayout *layout, bContext *UNUSED(C), Poi
uiItemR(layout, ptr, "check", 0, NULL, ICON_NONE);
}
static void node_composit_buts_switch_view_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *UNUSED(ptr))
{
PointerRNA op_ptr;
wmOperatorType *ot = WM_operatortype_find("NODE_OT_switch_view_update", 1);
BLI_assert(ot != 0);
WM_operator_properties_create_ptr(&op_ptr, ot);
uiItemFullO_ptr(layout, ot, "Update Views", ICON_FILE_REFRESH, op_ptr.data, WM_OP_INVOKE_DEFAULT, 0);
}
static void node_composit_buts_boxmask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiLayout *row;
@@ -2587,6 +2631,9 @@ static void node_composit_set_butfunc(bNodeType *ntype)
case CMP_NODE_SWITCH:
ntype->draw_buttons = node_composit_buts_switch;
break;
case CMP_NODE_SWITCH_VIEW:
ntype->draw_buttons_ex = node_composit_buts_switch_view_ex;
break;
case CMP_NODE_MASK_BOX:
ntype->draw_buttons = node_composit_buts_boxmask;
ntype->draw_backdrop = node_composit_backdrop_boxmask;
@@ -2959,6 +3006,7 @@ static void node_file_output_socket_draw(bContext *C, uiLayout *layout, PointerR
imfptr = RNA_pointer_get(node_ptr, "format");
imtype = RNA_enum_get(&imfptr, "file_format");
if (imtype == R_IMF_IMTYPE_MULTILAYER) {
NodeImageMultiFileSocket *input = sock->storage;
RNA_pointer_create(&ntree->id, &RNA_NodeOutputFileSlotLayer, input, &inputptr);

View File

@@ -212,13 +212,13 @@ static void compo_progressjob(void *cjv, float progress)
*(cj->progress) = progress;
}
/* only this runs inside thread */
static void compo_startjob(void *cjv, short *stop, short *do_update, float *progress)
{
CompoJob *cj = cjv;
bNodeTree *ntree = cj->localtree;
Scene *scene = cj->scene;
SceneRenderView *srv;
if (scene->use_nodes == false)
return;
@@ -238,7 +238,11 @@ static void compo_startjob(void *cjv, short *stop, short *do_update, float *prog
// XXX BIF_store_spare();
/* 1 is do_previews */
ntreeCompositExecTree(cj->scene, ntree, &cj->scene->r, false, true, &scene->view_settings, &scene->display_settings);
for (srv = scene->r.views.first; srv; srv = srv->next) {
if (BKE_scene_multiview_is_render_view_active(&scene->r, srv) == false) continue;
ntreeCompositExecTree(cj->scene, ntree, &cj->scene->r, false, true, &scene->view_settings, &scene->display_settings, srv->name);
}
ntree->test_break = NULL;
ntree->stats_draw = NULL;
@@ -1660,6 +1664,54 @@ void NODE_OT_delete(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ****************** Switch View ******************* */
static int node_switch_view_poll(bContext *C)
{
SpaceNode *snode = CTX_wm_space_node(C);
if (snode && snode->edittree)
return true;
return false;
}
static int node_switch_view_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceNode *snode = CTX_wm_space_node(C);
bNode *node, *next;
for (node = snode->edittree->nodes.first; node; node = next) {
next = node->next;
if (node->flag & SELECT) {
/* call the update function from the Switch View node */
node->update = NODE_UPDATE_OPERATOR;
}
}
ntreeUpdateTree(CTX_data_main(C), snode->edittree);
snode_notify(C, snode);
snode_dag_update(C, snode);
return OPERATOR_FINISHED;
}
void NODE_OT_switch_view_update(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Update Views";
ot->description = "Update views of selected node";
ot->idname = "NODE_OT_switch_view_update";
/* api callbacks */
ot->exec = node_switch_view_exec;
ot->poll = node_switch_view_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ****************** Delete with reconnect ******************* */
static int node_delete_reconnect_exec(bContext *C, wmOperator *UNUSED(op))
{

View File

@@ -200,6 +200,8 @@ void NODE_OT_output_file_add_socket(struct wmOperatorType *ot);
void NODE_OT_output_file_remove_active_socket(struct wmOperatorType *ot);
void NODE_OT_output_file_move_active_socket(struct wmOperatorType *ot);
void NODE_OT_switch_view_update (struct wmOperatorType *ot);
/* Note: clipboard_cut is a simple macro of copy + delete */
void NODE_OT_clipboard_copy(struct wmOperatorType *ot);
void NODE_OT_clipboard_paste(struct wmOperatorType *ot);

View File

@@ -123,6 +123,8 @@ void node_operatortypes(void)
WM_operatortype_append(NODE_OT_viewer_border);
WM_operatortype_append(NODE_OT_clear_viewer_border);
WM_operatortype_append(NODE_OT_switch_view_update);
WM_operatortype_append(NODE_OT_tree_socket_add);
WM_operatortype_append(NODE_OT_tree_socket_remove);
WM_operatortype_append(NODE_OT_tree_socket_move);

View File

@@ -60,6 +60,7 @@
#include "ED_screen.h"
#include "ED_sequencer.h"
#include "UI_interface.h"
#include "BKE_sound.h"
@@ -70,6 +71,10 @@
/* own include */
#include "sequencer_intern.h"
typedef struct SequencerAddData {
ImageFormatData im_format;
} SequencerAddData;
/* Generic functions, reused by add strip operators */
/* avoid passing multiple args and be more verbose */
@@ -222,6 +227,19 @@ static void seq_load_operator_info(SeqLoadInfo *seq_load, wmOperator *op)
}
RNA_PROP_END;
}
if ((prop = RNA_struct_find_property(op->ptr, "use_multiview")) && RNA_property_boolean_get(op->ptr, prop)) {
if (op->customdata) {
SequencerAddData *sad = op->customdata;
ImageFormatData *imf = &sad->im_format;
seq_load->views_format = imf->views_format;
seq_load->flag |= SEQ_USE_VIEWS;
/* operator custom data is always released after the SeqLoadInfo, no need to handle the memory here */
seq_load->stereo3d_format = &imf->stereo3d_format;
}
}
}
/**
@@ -573,6 +591,9 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad
return OPERATOR_CANCELLED;
}
if (op->customdata)
MEM_freeN(op->customdata);
BKE_sequencer_sort(scene);
BKE_sequencer_update_muting(ed);
@@ -581,15 +602,40 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad
return OPERATOR_FINISHED;
}
/* add sequencer operators */
static void sequencer_add_init(bContext *UNUSED(C), wmOperator *op)
{
op->customdata = MEM_callocN(sizeof(SequencerAddData), __func__);
}
static void sequencer_add_cancel(bContext *UNUSED(C), wmOperator *op)
{
if (op->customdata)
MEM_freeN(op->customdata);
op->customdata = NULL;
}
static bool sequencer_add_draw_check_prop(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
{
const char *prop_id = RNA_property_identifier(prop);
return !(STREQ(prop_id, "filepath") ||
STREQ(prop_id, "directory") ||
STREQ(prop_id, "filename")
);
}
/* add movie operator */
static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op)
{
return sequencer_add_generic_strip_exec(C, op, BKE_sequencer_add_movie_strip);
}
static int sequencer_add_movie_strip_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
PropertyRNA *prop;
Scene *scene = CTX_data_scene(C);
/* This is for drag and drop */
if ((RNA_struct_property_is_set(op->ptr, "files") && RNA_collection_length(op->ptr, "files")) ||
RNA_struct_property_is_set(op->ptr, "filepath"))
@@ -599,13 +645,37 @@ static int sequencer_add_movie_strip_invoke(bContext *C, wmOperator *op, const w
}
sequencer_generic_invoke_xy__internal(C, op, 0, SEQ_TYPE_MOVIE);
sequencer_add_init(C, op);
/* show multiview save options only if scene has multiviews */
prop = RNA_struct_find_property(op->ptr, "show_multiview");
RNA_property_boolean_set(op->ptr, prop, (scene->r.scemode & R_MULTIVIEW) != 0);
WM_event_add_fileselect(C, op);
return OPERATOR_RUNNING_MODAL;
//return sequencer_add_movie_strip_exec(C, op);
}
static void sequencer_add_draw(bContext *UNUSED(C), wmOperator *op)
{
uiLayout *layout = op->layout;
SequencerAddData *sad = op->customdata;
ImageFormatData *imf = &sad->im_format;
PointerRNA imf_ptr, ptr;
/* main draw call */
RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr);
uiDefAutoButsRNA(layout, &ptr, sequencer_add_draw_check_prop, '\0');
/* image template */
RNA_pointer_create(NULL, &RNA_ImageFormatSettings, imf, &imf_ptr);
/* multiview template */
if (RNA_boolean_get(op->ptr, "show_multiview"))
uiTemplateImageFormatViews(layout, &imf_ptr, op->ptr);
}
void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot)
{
@@ -618,9 +688,11 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot)
/* api callbacks */
ot->invoke = sequencer_add_movie_strip_invoke;
ot->exec = sequencer_add_movie_strip_exec;
ot->cancel = sequencer_add_cancel;
ot->ui = sequencer_add_draw;
ot->poll = ED_operator_sequencer_active_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -735,6 +807,9 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
sequencer_add_apply_overlap(C, op, seq);
if (op->customdata)
MEM_freeN(op->customdata);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -742,6 +817,9 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
static int sequencer_add_image_strip_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
PropertyRNA *prop;
Scene *scene = CTX_data_scene(C);
/* drag drop has set the names */
if (RNA_struct_property_is_set(op->ptr, "files") && RNA_collection_length(op->ptr, "files")) {
sequencer_generic_invoke_xy__internal(C, op, SEQPROP_ENDFRAME | SEQPROP_NOPATHS, SEQ_TYPE_IMAGE);
@@ -750,6 +828,12 @@ static int sequencer_add_image_strip_invoke(bContext *C, wmOperator *op, const w
sequencer_generic_invoke_xy__internal(C, op, SEQPROP_ENDFRAME, SEQ_TYPE_IMAGE);
sequencer_add_init(C, op);
/* show multiview save options only if scene has multiviews */
prop = RNA_struct_find_property(op->ptr, "show_multiview");
RNA_property_boolean_set(op->ptr, prop, (scene->r.scemode & R_MULTIVIEW) != 0);
WM_event_add_fileselect(C, op);
return OPERATOR_RUNNING_MODAL;
}
@@ -766,6 +850,8 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot)
/* api callbacks */
ot->invoke = sequencer_add_image_strip_invoke;
ot->exec = sequencer_add_image_strip_exec;
ot->cancel = sequencer_add_cancel;
ot->ui = sequencer_add_draw;
ot->poll = ED_operator_sequencer_active_editable;

View File

@@ -50,6 +50,7 @@
#include "BKE_main.h"
#include "BKE_sequencer.h"
#include "BKE_sound.h"
#include "BKE_scene.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
@@ -860,7 +861,7 @@ void ED_sequencer_special_preview_clear(void)
sequencer_special_update_set(NULL);
}
ImBuf *sequencer_ibuf_get(struct Main *bmain, Scene *scene, SpaceSeq *sseq, int cfra, int frame_ofs)
ImBuf *sequencer_ibuf_get(struct Main *bmain, Scene *scene, SpaceSeq *sseq, int cfra, int frame_ofs, const char *viewname)
{
SeqRenderData context;
ImBuf *ibuf;
@@ -888,6 +889,7 @@ ImBuf *sequencer_ibuf_get(struct Main *bmain, Scene *scene, SpaceSeq *sseq, int
bmain->eval_ctx, bmain, scene,
rectx, recty, proxy_size,
&context);
context.view_id = BKE_scene_multiview_view_id_get(&scene->r, viewname);
/* sequencer could start rendering, in this case we need to be sure it wouldn't be canceled
* by Esc pressed somewhere in the past
@@ -994,6 +996,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
const bool is_imbuf = ED_space_sequencer_check_show_imbuf(sseq);
int format, type;
bool glsl_used = false;
const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
if (G.is_rendering == false && (scene->r.seq_flag & R_SEQ_GL_PREV) == 0) {
/* stop all running jobs, except screen one. currently previews frustrate Render
@@ -1023,8 +1026,9 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
return;
}
ibuf = sequencer_ibuf_get(bmain, scene, sseq, cfra, frame_ofs);
/* for now we only support Left/Right */
ibuf = sequencer_ibuf_get(bmain, scene, sseq, cfra, frame_ofs, names[sseq->multiview_eye]);
if (ibuf == NULL)
return;

View File

@@ -180,8 +180,6 @@ static void seq_proxy_build_job(const bContext *C)
Scene *scene = CTX_data_scene(C);
Editing *ed = BKE_sequencer_editing_get(scene, false);
ScrArea *sa = CTX_wm_area(C);
struct SeqIndexBuildContext *context;
LinkData *link;
Sequence *seq;
GSet *file_list;
@@ -209,9 +207,7 @@ static void seq_proxy_build_job(const bContext *C)
SEQP_BEGIN (ed, seq)
{
if ((seq->flag & SELECT)) {
context = BKE_sequencer_proxy_rebuild_context(pj->main, pj->scene, seq, file_list);
link = BLI_genericNodeN(context);
BLI_addtail(&pj->queue, link);
BKE_sequencer_proxy_rebuild_context(pj->main, pj->scene, seq, file_list, &pj->queue);
}
}
SEQ_END
@@ -3442,12 +3438,18 @@ static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op))
SEQP_BEGIN(ed, seq)
{
if ((seq->flag & SELECT)) {
struct SeqIndexBuildContext *context;
ListBase queue = {NULL, NULL};
LinkData *link;
short stop = 0, do_update;
float progress;
context = BKE_sequencer_proxy_rebuild_context(bmain, scene, seq, file_list);
BKE_sequencer_proxy_rebuild(context, &stop, &do_update, &progress);
BKE_sequencer_proxy_rebuild_finish(context, 0);
BKE_sequencer_proxy_rebuild_context(bmain, scene, seq, file_list, &queue);
for (link = queue.first; link; link = link->next) {
struct SeqIndexBuildContext *context = link->data;
BKE_sequencer_proxy_rebuild(context, &stop, &do_update, &progress);
BKE_sequencer_proxy_rebuild_finish(context, 0);
}
BKE_sequencer_free_imbuf(scene, &ed->seqbase, false);
}
}

View File

@@ -62,7 +62,7 @@ void sequencer_special_update_set(Sequence *seq);
/* UNUSED */
// void seq_reset_imageofs(struct SpaceSeq *sseq);
struct ImBuf *sequencer_ibuf_get(struct Main *bmain, struct Scene *scene, struct SpaceSeq *sseq, int cfra, int frame_ofs);
struct ImBuf *sequencer_ibuf_get(struct Main *bmain, struct Scene *scene, struct SpaceSeq *sseq, int cfra, int frame_ofs, const char *viewname);
/* sequencer_edit.c */
struct View2D;

View File

@@ -94,7 +94,7 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
Scene *scene = CTX_data_scene(C);
SpaceSeq *sseq = (SpaceSeq *) CTX_wm_space_data(C);
ARegion *ar = CTX_wm_region(C);
ImBuf *ibuf = sequencer_ibuf_get(bmain, scene, sseq, CFRA, 0);
ImBuf *ibuf = sequencer_ibuf_get(bmain, scene, sseq, CFRA, 0, NULL);
ImageSampleInfo *info = op->customdata;
float fx, fy;

Some files were not shown because too many files have changed in this diff Show More