Compare commits

..

336 Commits

Author SHA1 Message Date
e76ff4df41 Merge branch 'master' into tmp-widget-opti
# Conflicts:
#	source/blender/gpu/shaders/gpu_shader_2D_widget_base_vert.glsl
2020-05-25 11:48:31 +02:00
528f0b95c4 Merge remote-tracking branch 'origin/blender-v2.83-release' 2020-05-25 10:45:39 +02:00
41bb0548b0 Fix T76897: Lamp Power Not Updating from Driver
Lamps were not tagged with `ID_RECALC_SHADING` when they were updated
from drivers. As a result, Cycles considered the lamp as unchanged. This
is resolved by having a (seemingly non-functional) callback in a new
`LIGHT_UPDATE` depsgraph node.

This patch unconditionally adds the `LIGHT_UPDATE` node + the relation
from the lamp's PARAMETERS node.

Differential Revision: https://developer.blender.org/D7822

Reviewed by: brecht
2020-05-25 10:07:10 +02:00
9b9f84b317 Fix crash when converting BMesh to Mesh with shape keys
The `BM_mesh_bm_to_me()` function copies shape keys from the BMesh to
the Mesh. However, it tries to copy the same number of shape keys as are
defined on the target mesh. Since the target mesh does not necessarily
have the same number of shape keys as the BMesh, this would crash if the
target Mesh has more.

Found while performing some tests for {D7785}.

Differential Revision: https://developer.blender.org/D7818

Reviewed by: brecht
2020-05-25 09:43:01 +02:00
5a842b3412 Merge branch 'blender-v2.83-release' 2020-05-25 15:55:54 +10:00
c15bb3b55f Fix T77031: Blender as pymodule crashes when rendering
No longer enforce WITH_HEADLESS when building as a Python module
as it disables GPU access which is needed for rendering.
2020-05-25 15:53:43 +10:00
ffcb87813b Merge branch 'blender-v2.83-release' 2020-05-25 15:01:01 +10:00
dc429d5910 Merge branch 'blender-v2.83-release' 2020-05-25 15:00:58 +10:00
31f3e9082a Cleanup: make format 2020-05-25 14:55:48 +10:00
f274b8c102 CMake: disable WITH_USD with blender_lite configurations 2020-05-25 14:54:41 +10:00
0700521833 Py Docs: Update Sphinx and Theme Dependencies
`sphinx_rtd_theme==0.5.0rc1` probably should not be used for 2.83 but it 
would be nice to test
2020-05-24 19:23:28 -04:00
5db2d9c82b Deps: ffmpeg 4.2.3 + codecs update
This diff updates:
FFmpeg : 4.3.2
libogg : 1.3.4
flac   : 1.3.3
vpx    : 1.8.2
xvid   : 1.3.7
x264   : 33f9e1474613f59392be5ab6a7e7abf60fa63622

x264 seemingly has given up on even providing snapshots
and has been updated to the latest hash available at
this time.

faad has been removed since ffmpeg has not supported
it since 2010.
2020-05-24 15:18:39 -06:00
f13b687551 Merge branch 'blender-v2.83-release' 2020-05-24 21:14:23 +02:00
0d0df683d9 Fix(unreported): Crash on prefetching while transforming strip.
While investigating T76274, I found crash scenario when playhead is near end
frame and moving a strip. It is not as easy to reproduce, about 5% success
rate, and it will be even harder after rB4066c921fbe5. Exact cause wasn't
identified yet.

I wanted to disable prefetching during modal operator execution in VSE, but
currently I don't have any signalling method in place. Checking for G.moving
seems to resolve this problem, but it doesn't adress root cause of bug.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D7820
2020-05-24 21:03:31 +02:00
6b8555e01c VR: Fix big performance bottleneck for simple scenes
Blender's main loop puts the main thread to sleep for 5ms if no user input was
received from the OS. We never want that to happen while the VR session is
running, which runs on the main thread too.

For simpler scenes, where the viewport already draws fast, this may have quite
some impact. E.g. in my tests, the classroom scene went from ~55 to quite
stable 90 FPS in solid mode (total render time as measured and averaged by
Windows Mixed Reality utilities). With Eevee, it only went from 41 to 47 FPS.
In complex files, there's barely a difference. E.g. less than 1 FPS increase in
a Spring file (both Solid mode and Eevee).
2020-05-24 17:26:31 +02:00
8e4c74292a Fix T77000: Preferences window can not be opened from script operator
The operators to open the Preferences, Driver Editor, or Info Log window did
not work when executed from another operator or the Python console. Should work
for all of these now.

I considered using operator properties instead, so the position could be set by
a script, with some fallback (e.g. current window center). But decided that's
not really worth the boilerplate and decreased code readability. Can still be
done if there's a need for it.
2020-05-24 16:14:11 +02:00
f43bb98646 Merge branch 'blender-v2.83-release' 2020-05-24 10:22:28 +02:00
22462fed00 Fix T77003: GPencil Paint presets not initializated
In som ecases, the Paint was not ready when the brushes and palette were created. Now, first the paint is checked.
2020-05-24 10:22:03 +02:00
525fc36a80 Deps : XR_OpenXR_SDK 1.0.8 2020-05-23 15:58:15 -06:00
2ddd9813ef deps: SDL 2.0.12 2020-05-23 15:41:44 -06:00
157b9e78a4 Deps: OpenSubDiv 3.4.3 2020-05-23 15:21:28 -06:00
93f60a4da5 Deps: Freetype 2.10.2 2020-05-23 14:37:17 -06:00
f5cd06ed45 deps: OpenAL 1.20.1 2020-05-23 14:02:34 -06:00
1f34a34fa5 Merge branch 'blender-v2.83-release' 2020-05-23 10:43:41 -06:00
6f8d99322c Fix T76578: Show bone visibility driver in outliner
Allow setting drivers and keyframes for the bone visibility restriction
icon in the outliner. Before the button was a simple icon button, but it
is now connected to the RNA property to show the driven or keyframed
state.

Also when hiding a bone from the outliner it would be deselected, but
from the properties editor it would remain selected. This moves the
deselection to the RNA update function to ensure the bone is always
deselected.

Differential Revision: https://developer.blender.org/D7825
2020-05-23 10:36:54 -06:00
041e440649 Merge branch 'blender-v2.83-release' 2020-05-23 15:26:24 +02:00
b4613e0bca GPencil: Fix unreported Noise modifier does not work in axis aligned strokes
If the stroke is totally straight, the normal was not calculated properly.
2020-05-23 15:25:54 +02:00
08c1f5bf33 Cycles: Improve sampling of area lights
This patch uses the sampling method described in "A Low Distortion Map Between Triangle and Square" by Eric Heitz.
The benefit is avoiding sqrt in the calculation, which could be cheaper on some architectures, and the result is
more even sampling across the triangle surface.

Based on ideas from
https://pharr.org/matt/blog/2019/02/27/triangle-sampling-1.html
https://pharr.org/matt/blog/2019/03/13/triangle-sampling-1.5.html

Reviewed By: Brecht Van Lommel

Differential Revision: https://developer.blender.org/D6566
2020-05-23 14:21:49 +02:00
86fa8dc7f7 Merge branch 'blender-v2.83-release' 2020-05-22 22:59:02 +02:00
ece8ecb4dd Cleanup: remove unnecessary NULL test 2020-05-22 22:57:58 +02:00
Ankit
e8dd8c2829 Cleanup: silence deprecation warnings of Carbon Finder Favorites items
Differential Revision: https://developer.blender.org/D7655
2020-05-22 21:52:38 +02:00
f27e122d95 Fix T76925: Cycles OpenCL compile error with some drivers on Linux 2020-05-22 21:50:24 +02:00
e8209c36e6 Cleanup: Deduplicate code 2020-05-22 14:58:56 -03:00
45f17e10ec Fix redo with local orientation 2020-05-22 14:43:51 -03:00
a958725f81 Fix unused parameter ftext 2020-05-22 14:43:51 -03:00
3bc15c097c Fix T76940: Empty HUD (Redo Panel)
If the redo panel was made visible with the same size it had before
(e.g. stored in the file), the runtime region coordinates wouldn't get
set and ended up being all 0. E.g. the simplest way to cause this was
having a collapsed HUD, saving the file, re-opening it with the same
effective DPI and doing an operation so the closed HUD would appear
again.

Now the size is always recalculated if the visibility state of the HUD
changes.
2020-05-22 18:40:10 +02:00
43d33b3626 Merge branch 'blender-v2.83-release' 2020-05-22 17:48:10 +02:00
98689f51c0 Fix T74443: No render in VP9 lossless mode
We define Lossless as CRF 0 (which is usually the best quality and is
working fine with other codecs afaict), but since WebM only allows for
CRF values between 2-32 and actually has a dedicated "lossless" mode, I
suggest using that (it produces large files though, so double-checking
would be welcome).

https://trac.ffmpeg.org/wiki/Encode/VP9#LosslessVP9

Maniphest Tasks: T74443

Differential Revision: https://developer.blender.org/D7800
2020-05-22 17:41:27 +02:00
cbd4b8ebb0 Fix T76974: Shear Tool Misses Orientation 2020-05-22 12:39:57 -03:00
c75a665c44 Transform: refactoring - unify constraint and default orientation 2020-05-22 12:39:56 -03:00
06860ba29b Merge branch 'blender-v2.83-release' 2020-05-22 17:21:52 +02:00
a76e804309 Fix T76960: fluid baking operators not working with pinned object
Maniphest Tasks: T76960

Differential Revision: https://developer.blender.org/D7819
2020-05-22 17:16:31 +02:00
1633a65d41 RNA: Make enum properties compatible with raw access.
This will allow to use foreach_get/set on enums of RNA collection items,
which can save a lot of time in some cases (see incoming FBX updates).
2020-05-22 15:41:34 +02:00
Jeroen Bakker
0236863c6d Fix T73115: In Front Drawing Bone Envelope Distance
The in front drawing was not supported for transparent part of the   armature. This patch adds a second transparent pass for drawing in
front.

Reviewed By: Clément Foucault

Differential Revision: https://developer.blender.org/D7763
2020-05-22 15:09:48 +02:00
920b698746 Merge branch 'blender-v2.83-release' 2020-05-22 22:42:16 +10:00
8ddcc7fd51 Merge branch 'blender-v2.83-release' 2020-05-22 22:20:01 +10:00
69e331201e UV: remove "UV Local View" for UV editing
This feature was added when Blender used tex-face (per-face images),
but doesn't make as much sense since this was removed.

Removing this from UV edit-mode as this wasn't working in any
of the 2.8x releases, causing UV's to be visible but unselectable.

Resolves issue raised in T76958.
2020-05-22 22:18:32 +10:00
Jeroen Bakker
59aed2a255 Fix T73726: Workbench Closest Interpolation Artifacts
All textures in workbench are using linear interpolation. The fragment
shader modifies the uv coordinates to sample always in the center of a
texel. In rare conditions the GPU could sample an incorrect value due to
rounding errors making some rendering artifacts.

This patch skips the interpolation in the fragment shader to remove
these render artifacts.

Reviewed By: Clément Foucault

Differential Revision: https://developer.blender.org/D7816
2020-05-22 14:11:36 +02:00
f990b42504 Revert "UI: Remove duplicate Mark/Clear Seam entries from Edge menus"
Seams are widely used outside UV context so it's okay to duplicate entries.
Based on community feedback, thanks!

This reverts commit fc62a3366c.
2020-05-22 13:41:48 +02:00
f5c682045d Merge branch 'blender-v2.83-release' 2020-05-22 13:36:23 +02:00
4066c921fb Fix (unreported): prefetching wastes resources when end frame is reached
This bug is not really visible for user. When end frame is reached by
prefetching thread, it doesn't stop and keeps on getting images from
cache.

Add chech for this situation and simplify logic involved in suspending,
so it's easier to read.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D7757
2020-05-22 13:31:49 +02:00
c4edc6f3f7 Fix (unreported): Don't restart prefetching during rendering.
Prefetching is stopped in BKE_sequencer_cache_cleanup, but is restarted quickly.

Prefetching has negative effect on performance while rendering.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D7751
2020-05-22 13:05:08 +02:00
a1a333a1e9 Fix T76774: Crash on prefetching sequences from another scene.
When rendering another scene, caching in disabled by setting
local_context.skip_cache = true. Precondition checking for this flag was
missing in BKE_sequencer_cache_get and it wasn't first thing to check in
BKE_sequencer_cache_put.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D7750
2020-05-22 12:59:26 +02:00
fbbc0229b8 Cleanup: only use nullptr in USD exporter
This removes all use of `NULL` from the USD Exporter, also when calling
into C code.

No functional changes.
2020-05-22 10:12:13 +02:00
b87d81be96 Wayland: support key repeat 2020-05-22 18:09:17 +10:00
fe739f8c26 GHOST: fix GHOST_System::getMilliSeconds()
This wasn't returning milliseconds, causing problems with key repeat.
2020-05-22 18:08:13 +10:00
ce6fd6b6a2 Fix missing header building with wayland 2020-05-22 16:47:59 +10:00
Jeroen Bakker
42f8d52401 Fix T64277: Inverted Wheelmouse
When using CTRL wheel mouse the items were selected in a different order than when opening the menu and use the wheel mouse.

Reviewed By: Brecht van Lommel

Differential Revision: https://developer.blender.org/D7791
2020-05-22 07:32:44 +02:00
3aacd8a4ab Merge branch 'blender-v2.83-release' 2020-05-22 12:40:02 +10:00
1b994a37f4 Fix Python console cursor height 2020-05-22 12:36:39 +10:00
8f21f867e7 Fix T76949: Crash When Selecting Materials Tab.
Dummy typo in own recent libquery refactor, of course that one missed
change was on a line not covered by our tests or the production file
used for validation...
2020-05-21 23:20:29 +02:00
70c483e7db libquery: Cleanup: finish refactor by removing no more used code. 2020-05-21 19:37:57 +02:00
3cb6efd3ab Libquery refactor: Cleanup (remove no more used macros). 2020-05-21 19:36:05 +02:00
1f6ef73f98 Refactor: Move scene foreach_id to new IDTypeInfo structure. 2020-05-21 19:29:55 +02:00
c732edbaa4 Refactor: Move object foreach_id to new IDTypeInfo structure. 2020-05-21 19:09:48 +02:00
ce74df6248 Refactor: Move NOP idtypes foreach_id to new IDTypeInfo structure. 2020-05-21 18:35:11 +02:00
7e4654e4ce UI: Fix T76918: 3D Mouse Inconsistent / Inaccessible UI
This consolidates the UI code for NDOF input settings, making all
settings accessible from the preferences. This works around an issue
where the Space Navigator's "Menu" button doesn't trigger the settings
menu in Blender.

I also took the opportunity to redo the UI layout.

Differential Revision: https://developer.blender.org/D7806
2020-05-21 11:42:23 -04:00
df14b11526 GPencil: Cleanup macro 2020-05-21 16:25:35 +02:00
a39ca327bc Fix T76935: Current orientation not taken in account when using "Align to transform orientation" 2020-05-21 11:01:06 -03:00
de7d32bb7d Fix T76933: 'Align to Transform Orientation' crashes for Custom orientations 2020-05-21 11:01:06 -03:00
2fe615ab9f Merge branch 'blender-v2.83-release' 2020-05-21 23:07:18 +10:00
8a8c61190b Docs: note that the color-ramp uses image alpha
Avoid misunderstanding from T59110
2020-05-21 23:03:24 +10:00
0c9e73845c BLI: improve Vector test 2020-05-21 14:35:19 +02:00
03d8783db0 Merge branch 'blender-v2.83-release' 2020-05-21 19:34:41 +10:00
376b69cbff Fix T73568: Vertex selection fails in weight-paint mode
Lasso, circle, box select fails in weight paint mode with modifiers.
2020-05-21 19:32:15 +10:00
2efd00d4d2 Merge branch 'blender-v2.83-release' 2020-05-21 18:19:10 +10:00
d15efbdc56 Fix T76922: Meta-balls created twice the specified size 2020-05-21 18:18:00 +10:00
850fbe8547 Merge branch 'blender-v2.83-release' 2020-05-21 16:34:36 +10:00
c13bf40ab1 Merge branch 'blender-v2.83-release' 2020-05-21 16:34:20 +10:00
0ff663b6fc Merge branch 'blender-v2.83-release' 2020-05-21 16:33:28 +10:00
8d648e0972 Cleanup: spelling 2020-05-21 16:22:37 +10:00
fcfb87def9 Cleanup: excess blank lines and parenthesis 2020-05-21 16:17:44 +10:00
f66bfb5a86 Cleanup: quiet uninitialized warning
It's possible for the value to be uninitialized
in the case of loading newer preferences into an older Blender.
2020-05-21 15:57:46 +10:00
bbef6fe336 Merge branch 'blender-v2.83-release' 2020-05-21 12:59:55 +10:00
8ecfa6a828 Merge branch 'blender-v2.83-release' 2020-05-21 12:59:51 +10:00
b4a6418e2b Cleanup: add doxy sections for event queue handling
The main function to handle events didn't have it's own section.
2020-05-21 12:22:32 +10:00
522e6c0c06 Cleanup: add asserts for textview drawing
This would have prevented T74298.
2020-05-21 12:22:32 +10:00
8a0840b0ee Merge branch 'blender-v2.83-release'
# Conflicts:
#	source/blender/draw/engines/eevee/eevee_volumes.c
2020-05-20 22:56:09 +02:00
af3a55bb1b Overlay: Wireframe: Add visualization for Hairs in wireframe mode
This only works for particle systems for now.

Fix T61928 Wireframe mode hair not visible
2020-05-20 22:54:04 +02:00
71fa460145 UI: Remove Panel Grid Snapping While Dragging
The reason to have this isn't quite clear, but it looks like a vestige
of the 2.5 transition. Removing this makes dragging panels feel
much more responsive.

Thanks to Julian Eisel @Severin for the original change.

Differential Revision: https://developer.blender.org/D7803
2020-05-20 16:27:44 -04:00
6d7dc2265f UI: Rephrase Tooltip to Avoid 2nd Person 2020-05-20 15:53:45 -04:00
8bff3ec76b Transform: Don't negate the z axis of the View orientation
This was so because of the rotate transformation mode but it can make
other modes confusing and add unnecessary complexity.
2020-05-20 16:22:28 -03:00
600fd1c6f0 Fix T76919: Wrong orientation when changing translate to rotate
During the refactor of the transform operations, in an attempt to
maintain previous behavior, the default orientation of the translate
and resize operations became `Global` and the rotate operation became
`View`.

Now the default is always `View`, and on redo, the translate and rotate
operations are saved as `Global`.
2020-05-20 16:22:10 -03:00
29afadcb15 GPencil: Create new frame when Erase only if additive drawing is enabled
Differential Revision: https://developer.blender.org/D7804
2020-05-20 20:33:49 +02:00
b9aa2acecd Refactor: Move collection foreach_id to new IDTypeInfo structure. 2020-05-20 18:43:47 +02:00
e2b87aabb6 Cleanup collection handling in lib_query code.
Now we do not need anymore that extra function...
2020-05-20 18:43:47 +02:00
1c79484d53 Libquery: refactor: handle scene's master collection like any othe embedded ID. 2020-05-20 18:43:46 +02:00
3a284a37fd Refactor: Move simulation foreach_id to new IDTypeInfo structure. 2020-05-20 18:43:46 +02:00
ee44283393 Refactor: Move pointcloud and volume foreach_id to new IDTypeInfo structure. 2020-05-20 18:43:46 +02:00
2059b30ee2 Cleanup: Keep common IDTypeInfo code separated from ID type specific API.
Also remove useless IDTypeInfo callbacks.
2020-05-20 18:43:46 +02:00
4d613018ee Refactor: Move hair foreach_id to new IDTypeInfo structure. 2020-05-20 18:43:46 +02:00
e2d961809b Cleanup: Keep common IDTypeInfo code separated from ID type specific API.
Also remove useless IDTypeInfo callbacks.
2020-05-20 18:43:46 +02:00
140935ee7e Refactor: Move grease pencil foreach_id to new IDTypeInfo structure. 2020-05-20 18:43:46 +02:00
e4e31e4f14 Fix T76916: Cycles missing deform motion blur for shape key + subdiv modifier 2020-05-20 18:00:34 +02:00
93b5682444 Fix T76909 GPencil: Layers with mask(s) invisible when using "in front"
The gpSceneDepthTexture is using a dummy 1px texture which was generating
wrong values for uvs when sampling gpMaskTexture.

Use the max size of both since any of the 2 can use dummy texture.
2020-05-20 17:48:24 +02:00
e15ffc0c54 UI: Fix Wideline AA for timeline 2020-05-20 17:48:24 +02:00
796412dca0 UI: Allow registering File Browser as child of other child windows
E.g. when opening the File Browser from the Preferences window, it would
be the child of the main window the Preferences belong to. Now it can be
a child of the Preferences window itself.
The File Browser always stays on top of its parent window. Which avoids
some issues with OS window management, see T76418 and T72693.
Also removes a now unnecessary workaround to move the child window back
to the front after closing the file browser (opening the file browser
would move the main window and the file browser to the front).

Fixes T76418, T72693.
2020-05-20 17:10:25 +02:00
8fe448b44d Fix T75197: Eevee does not render instanced smoke
This check was introduced in rBc8005703f298, but does not
seem necessary anymore.

Reviewers: fclem, sebbas, brecht

Differential Revision: https://developer.blender.org/D7799
2020-05-20 16:55:43 +02:00
ccf43fe605 Cycles: Fix rendering instanced smoke domain.
The problem was that Cycles would store a pointer to an object in
`DEGObjectIterData->templ_dupli_object`. This pointer was then accessed
when the iterator was already freed.

Reviewers: brecht

Differential Revision: https://developer.blender.org/D7797
2020-05-20 16:53:28 +02:00
aa0e98d707 Merge branch 'blender-v2.83-release' 2020-05-20 16:52:03 +02:00
b44101950d Fix T73979: Wrong location of fluid mesh when domain origin is not in center
Reviewers: sebbas

Differential Revision: https://developer.blender.org/D7802
2020-05-20 16:52:03 +02:00
c1545c9a9d Fluid: Fix for non-moving liquid particles
Issue was introduced in 7bb3d9787e with new Mantaflow files from 61280e5af3.
2020-05-20 16:37:29 +02:00
717577d5fc BLI: Fix VectorSet copy constructor
Thanks to Howard for pointing that out.
2020-05-20 15:47:32 +02:00
e1050fb395 Merge branch 'blender-v2.83-release' 2020-05-20 15:31:54 +02:00
9897ef6a20 Fix T70948: Library Override: Parenting library override objects does not save offset from parent.
Parent inverse matrix needs to be overridable as well...
2020-05-20 15:31:02 +02:00
22c30219e7 Merge branch 'blender-v2.83-release' 2020-05-20 15:17:21 +02:00
d33c27d68b Fix T75457: Toggle brushes using same hotkey twice is broken
Caused by rB47da01a4db1d.

Above commit did not change the toolname it was setting when the brush
was actually toggled.

Maniphest Tasks: T75457

Differential Revision: https://developer.blender.org/D7792
2020-05-20 15:05:33 +02:00
3a5a158362 Merge branch 'blender-v2.83-release' 2020-05-20 22:16:42 +10:00
707a4c355f Merge branch 'blender-v2.83-release' 2020-05-20 22:16:34 +10:00
eb57377f12 Fix T76794: Number button cursor overrides eyedropper cursor
Pressing 'E' over a number button to pick a distance was keeping
left-right arrows instead of using the eye-dropper cursor.

Workaround this by clearing the active button before setting the cursor.
2020-05-20 22:07:55 +10:00
7d3bf5166d Fix color picker being used for non-color buttons such as rotation
Issue raised in T76794
2020-05-20 22:04:56 +10:00
578b0c00ca Merge branch 'blender-v2.83-release' 2020-05-20 10:43:02 +02:00
3360db83c4 Fix T76883: Zero users scenes after undo.
Some tags need to be preserved when we reuse existing ID entirely.
AFAICT, currently this is only the EXTRAUSER one.
2020-05-20 10:39:50 +02:00
db6e267bfc Fix T74298: Incorrect cursor position in Python console 2020-05-20 18:16:52 +10:00
ec86db82b0 Merge branch 'blender-v2.83-release' 2020-05-20 15:00:57 +10:00
5fe7605f3d Fix the current pixelsize impacting thumbnails 2020-05-20 14:58:57 +10:00
f69ecce14b Merge branch 'blender-v2.83-release' 2020-05-20 13:53:26 +10:00
a296dff2c8 Correct invalid limits in last commit 2020-05-20 13:48:25 +10:00
31137004ae UI: add text to icon-only menu items when displayed in search
Without this icon-only buttons in popovers don't have any text.
2020-05-20 12:43:02 +10:00
bfdfa35e6e Merge branch 'blender-v2.83-release' 2020-05-20 03:34:31 +02:00
aa02a05bc7 Fix T75977: Lower the merge limit in the bisect/mirror operation in symmetrize
This operation is using the code of the mirror modifier, so no default
is guaranteed to work in all cases. This value matches the defaults of
the mirror modifier.

Reviewed By: jbakker

Maniphest Tasks: T75977

Differential Revision: https://developer.blender.org/D7495
2020-05-20 03:24:51 +02:00
dfe8195dfe Cleanup: compiler warning 2020-05-20 01:15:08 +02:00
8f050b6825 Fix Cycles viewport render fully restarting after undo
With the optimized undo datablock pointers remain the same, so Cycles can now
update just the parts that changed.
2020-05-20 01:11:42 +02:00
499c0229f7 Fix T76858: non-thread safe sculpt memory allocation when using --debug-memory
By default the guarded memory allocator is not thread safe, that needs to be
initialized.
2020-05-20 00:33:49 +02:00
4f622c9a08 Fix Windows build after recent guardedalloc changes 2020-05-20 00:32:17 +02:00
e610964e89 Merge branch 'blender-v2.83-release' 2020-05-20 01:22:54 +02:00
183ba284f2 Cleanup: make guarded memory allocation always thread safe
Previously this would be enabled when threads were used, but threads are now
basically always in use so there is no point. Further, this is only needed for
guarded allocation with --debug-memory which is not performance critical.
2020-05-20 01:03:05 +02:00
120e9924c1 Cleanup: remove legacy mmap memory allocation for 32 bit
This helped to go beyond the 4GB limit, but is no longer relevant for 64 bit.
2020-05-20 00:57:41 +02:00
33fc42bd65 Merge branch 'blender-v2.83-release' 2020-05-20 00:46:15 +02:00
5ca8875f69 Fix T73148: Incorrect Repeat Last for transforms with Individual Origins and Normal orientation
`pvec` was confusing and was adding steps that are apparently unnecessary.
So the code has been redone so as not to use this pvec.
2020-05-19 18:54:57 -03:00
3bced3b306 Fix flag conflict in transform operators
This added some redundant properties
2020-05-19 18:54:57 -03:00
5267ce8e03 Merge branch 'blender-v2.83-release' 2020-05-19 23:42:32 +02:00
59cfb20fa1 Fix PBVH parallel range not initializing user data correctly in some cases
This was already changed for the TBB-based BLI_task_parallel_range in master.
This task local storage should always be initialized from the template, not
copied from another task which may be executing at the time the copy happens.

This may not fix any actual bug, we only use this user data for parallel reduce
and it's not clear that TBB ever calls the copy constructor for that case.

Ref T76858
2020-05-19 23:36:28 +02:00
8d63d7337c Fix unnecessary buffer reallocation in sculpt mode, causing an assert
Probably did not cause an actual, the assert is a performance warning.

Ref T76858
2020-05-19 23:36:12 +02:00
20c30534aa Fix T75383:Bevel weird behaviour when using bevel weights
Don't use the cube corner special case when the offsets are different
for the three edges involved. The generic VMesh for this situation isn't
perfect, but it's much better than a failed cube corner VMesh.

Tests pass.
2020-05-19 16:54:05 -04:00
42d77fbea1 UI: Make timeline vertical bars thickness work on OSX
Make use of Polyline shader.
2020-05-19 22:43:42 +02:00
8e0a57f9bd Merge branch 'blender-v2.83-release' 2020-05-19 16:40:53 -04:00
c554f4e14f Fix T75383:Bevel weird behaviour when using bevel weights
Don't use the cube corner special case when the offsets are different
for the three edges involved. The generic VMesh for this situation isn't
perfect, but it's much better than a failed cube corner VMesh.

Tests pass.
2020-05-19 16:40:40 -04:00
13125e0948 GPU: Attempt to fix Crash on startup with Intel HD Graphics 620/630
This only enables the workarounds that we know have effects on intels.
We could add the other workarounds if needed.

Related task T72098
2020-05-19 22:24:25 +02:00
a5a069c272 Fix T76080 Workbench: Background Glitches caused by Screen Cavity effect 2020-05-19 21:37:43 +02:00
0a19b8a5b4 OpenSubdiv: Remove old GPU code
This code was accidentally reintroduced in e73d7d27dc.
2020-05-19 21:35:47 +02:00
a3bdbb5e5b Merge branch 'blender-v2.83-release' 2020-05-19 16:32:43 -03:00
d6cc16831a Fix T73594: Scale Cage sometimes has incorrect center in edit mode
Differential Revision: https://developer.blender.org/D6803
2020-05-19 16:30:21 -03:00
5201bc9dd4 Fix T66916 UI: Wrong information in Status bar after cancelling a render
Fixed thanks to @manowii
2020-05-19 21:23:56 +02:00
e73d7d27dc Merge branch 'blender-v2.83-release' 2020-05-19 21:23:54 +02:00
7bb3d9787e Fix T76812: [Mantaflow] Inflow particles not continuous
Makes use of the new particle skipping option introduced in f25a882955cb.
2020-05-19 21:12:30 +02:00
61280e5af3 Fluid: Updated Mantaflow source files
Includes changes for particle skipping during advection.
2020-05-19 21:12:30 +02:00
fa270a37e8 Fix T76564 Curve: Missing orco cause mesh to not render 2020-05-19 21:01:21 +02:00
a4cbacacbf Fix T73847 Overlay: Camera orthographic scale moves background image 2020-05-19 21:01:21 +02:00
08b4faef01 Properly fix: T71040 / T58983 Ocean Modifier crashes at high resolutions
For a more detailed description of the issue see the commit
message for rB497cd3d7dd6e497be484eb78a8ddb23f53b20343

This change moves fftw to a shared library and reverts the bandaid
we did for 2.83.
2020-05-19 12:28:19 -06:00
a6c0874355 win/deps: generate sndfiles import library with ms lib tool
Unsure what it is that upsets it so much, but when linking
both sndfile and fftw dynamically, the linker gets confused
and thinks that fftw is importing sf_close from the blender
binary (which makes *NO* sense) leading to a start-up error.

Generating the import library from the .def file using the
ms lib tool creates an import library that works fine.
2020-05-19 12:22:36 -06:00
059f79bdd7 Clarify autokeyframe tootip
This applies to masks as well.

Spotted while looking into T76872.

Differential Revision: https://developer.blender.org/D7788
2020-05-19 18:43:30 +02:00
cfb7664d5b Fix: build error due to missing definitions
Reviewers: sergey, brecht

Differential Revision: https://developer.blender.org/D7787
2020-05-19 17:36:40 +02:00
dd62d95687 Merge branch 'blender-v2.83-release' 2020-05-19 17:10:44 +02:00
7fcf2e7d4a Fix T74577: world_to_camera_view broken for off-axis projection
The issue was that the projection would be inverted.
So if you shifted 0.1 along the y axis, world_to_camera_view would act
as if you had shited it -0.1 along the y axis.
2020-05-19 16:27:09 +02:00
813ff8913b UI: Small Changes to Graph Editor Active Vertex Panel
- X / Y value orders are all consistent, between handles and the keyframe.
  - Values are labeled consistently, with just "Frame" and "Value"
  - The more important type property that can affect the others comes first.
  - The "type" property provides nice visual separation between the
    handle properties.

Reviewed By: sybren, billreynish

Differential Revision: https://developer.blender.org/D7738
2020-05-19 10:27:07 -04:00
338abd6f68 Merge branch 'blender-v2.83-release' 2020-05-19 16:03:24 +02:00
0c20fce2f2 Fix T76697: [Mantaflow] mesh generation does not account for some particles
Adapted mesh generation to account for domains with disabled fractionstoo.
2020-05-19 16:02:38 +02:00
Josh Belanich
03fa66d274 Fix T72889: Cycles camera motion blur not usng more than 2 steps
Differential Revision: https://developer.blender.org/D7782
2020-05-19 15:40:56 +02:00
46c35dc283 Fix UV shadow drawing not respecting 'UV Opacity' setting
reapply changes from 30cbbccc60 / D7764 that were only meant for
master. Sorry for the noise!
2020-05-19 15:35:28 +02:00
a95afed6de Merge remote-tracking branch 'origin/blender-v2.83-release' 2020-05-19 15:24:45 +02:00
9ccc73ade8 Animation: Make dopesheet filter labels consistent
There are three different label styles for the three Dopesheet filter
labels:

- "Display Hidden", which uses "Display" rather than "Show" as the other
  two options.
- "Show Errors", which does not use the word "only" to indicate it will
  hide all the non-error channels.
- "Only Selected", so no "show" or "display" in the label at all.

This commit changes:
- Always use the word "Show", not "Display".
- Always use the word "Only" when enabling the filter hides everything
  else.

Reviewed By: billreynish

Differential Revision: https://developer.blender.org/D7742
2020-05-19 15:23:44 +02:00
Jeroen Bakker
9ac4e4a1c7 Fix T76375: UDIM Rectangular Tiled Image EEVEE freezes Blender
When packing the image the height of the tile was checked to the width
of the packing area. This resulted that the tile was ignored.

Reviewed By: Clément Foucault

Differential Revision: https://developer.blender.org/D7784
2020-05-19 15:20:40 +02:00
cc485191e4 Merge branch 'blender-v2.83-release' 2020-05-19 15:18:39 +02:00
a6646fb0d0 Fix T76881: Changing "Use Speed Vectors" deletes all existing cache
Reviewers: sebbas
2020-05-19 15:18:33 +02:00
8c4965f86d Fix build error after 30cbbccc60
That part only applies to master, sorry for the noise
2020-05-19 15:17:11 +02:00
14278cd932 Fix T76694: Fluid cache is deleted when changing Upres Factor
Reviewers: sebbas
2020-05-19 15:13:25 +02:00
eb1cb7cb81 Merge branch 'blender-v2.83-release' 2020-05-19 14:45:07 +02:00
30cbbccc60 Fix (unreported) UV shadow not drawing smooth
When showing UV edges after modifiers [draw_uvs_shadow], these were never
drawn anti-aliased [in contrast to the 'main' UVs].

Also: they did not respect the new 'UV Opacity' setting.

Differential Revision: https://developer.blender.org/D7764
2020-05-19 14:42:19 +02:00
22998abe92 Merge branch 'blender-v2.83-release' 2020-05-19 14:17:40 +02:00
675ba2073d Fix T75694: Compositor Backdrop boundbox missing updates
This adds notifiers for backimage_move & backimage_fit.

Maniphest Tasks: T75694

Differential Revision: https://developer.blender.org/D7778
2020-05-19 14:16:22 +02:00
325307d82b Merge branch 'blender-v2.83-release' 2020-05-19 13:59:39 +02:00
4fa1fc29bd Fluid: Cleanup unused variables 2020-05-19 12:33:17 +02:00
e5c5e25c68 GPencil: Make is_nofill_stroke property editable
This can be used by some add-ons.
2020-05-19 12:24:42 +02:00
82bda82ec4 Fix T76541: OpenGl Depth Picking not selecting frontmost object
The issue was that we used GL_ALWAYS for depth checking here which would
lead to the depth information from objects being messed up.

It would not represent which object was closest to the camera.

Reviewed By: Clément Foucault, Jeroen Bakker, Campbell Barton

Differential Revision: http://developer.blender.org/D7710
2020-05-19 12:22:28 +02:00
25dea3e65e Fix T76717: Set Rotation Mode Incorrectly Recalculates Bone Rotation In Pose Mode
The issue was that we didn't convert the current rotational values.
We simply just switched mode without doing any data conversions.
2020-05-19 12:22:18 +02:00
10528a5cd4 Fix Frame Dropping not dropping the correct amount of frames
Previously the playback mode "Frame Dropping" would not drop the correct
number of frames which would lead to slow playback.

For example, the playback target is 60fps.  However we can only muster
around 32 fps.

The delta frames from the last step is in this case ~1.98 or so.

With the previous code, we would floor this.  That would lead us to step
forward one frame each time, effectively playing back the animation at
half the speed as we will try to render every frame.

To fix this we simply save the remaining fraction from the previous
frame and use it to compute the current frame step.

Reviewed By: Sybren

Differential Revision: http://developer.blender.org/D7694
2020-05-19 12:22:07 +02:00
24e5c64ea2 Made pose push/relax to breakdown behave smooth on rotations
A follow up to T67212. I missed that the rotation interpolation had its
own code path.

The previous rotation push code was actually wrong (but smooth).

Now all of the actions behave correctly and is smoothly interpolated.
2020-05-19 12:21:53 +02:00
cddfa7a449 Fix T72729: Mask Modifier Loose Edges Not Shown
When using the mask modifier loose edges could be added to the mesh.
These edges weren't marked as loose edges and wasn't picked up by other
areas of blender.

This fix recalculates the loose edges so they have the correct flag
`ME_LOOSE_EDGE`.

Reviewed By: Sybren Stüvel

Differential Revision: https://developer.blender.org/D7766
2020-05-19 10:12:57 +02:00
b96ccb5126 Fix T76865: Vertex paint draws hidden but cannot be painted onto 2020-05-19 18:06:27 +10:00
f89b89fa7f CMake: Enable WITH_USD by default
Having USD disabled by default was an oversight, and could have been
corrected earlier. It's already enabled by default in the
`blender_release.cmake` and `blender_full.cmake`.
2020-05-19 09:39:51 +02:00
291136eece Fix T76689: Armature layers not indicating the existence of bones
From what I can see, there are two issues at play in {T76689} and its merged-in report {T76590}:

- In Blender ≤ 2.79 the bone layer dots were updated in the draw code. This ensured the info was up to date before drawing. This is no longer possible, as the drawing code uses evaluated objects, and those should not be written to. This has been addressed in rB709f126e8143 by calling the update function explicitly in various places in the code. The problem is that this wasn't added to all necessary spots.
- When in edit mode, changes are made to the edit bones but not to the 'actual' bones (this is synced when exiting edit mode). This causes undo to mess up the layer indicators.

I think both issues can be addressed by having the dependency graph update the used layer info as part of the armature evaluation. This will make the undo system work properly, and allows the removal of some `BKE_armature_refresh_layer_used()` from various places.

There is still the issue that there are two functions (`BKE_armature_refresh_layer_used()` and `ED_armature_edit_refresh_layer_used()`) that are both responsible for updating `bArmature::layer_used`. This is a trickier thing to solve, though, as the definition of the `EditBone` struct resides in the armature editor module. This means that blenkernel can't iterate over edit bones, but on the other hand the dependency graph shouldn't call any editor functions either. This is why I left the `ED_armature_edit_refresh_layer_used()` calls untouched.

The downside of recalculating `layer_used` from the dependency graph (at least in the way that I did it now) is that it is called every time a user moves a bone in pose mode. This frequency of updates is not necessary.

Differential Revision: https://developer.blender.org/D7709
2020-05-19 09:39:51 +02:00
888427cabb Fix T76780: Freestyle pass for one scene not accessible in compositor in other scenes
Current implementation would update the nodetree of the freestyle scene not the composite scene.

Reviewed By: Dalai Felinto

Differential Revision: https://developer.blender.org/D7770
2020-05-19 08:24:52 +02:00
fc06c248ed Fix T73169: Side by Side Stereo Rendering Glitches
Side by side and top down views were rendered using an unset matrix.
This fix will reset the matrix just before copying the views to the
screen.

Reviewed By: Clément Foucault, Dalai Felinto

Differential Revision: https://developer.blender.org/D7777
2020-05-19 08:22:05 +02:00
ac8b36535e Cleanup: Creator Args Spelling
Differential Revision: https://developer.blender.org/D7735
2020-05-19 00:54:37 -04:00
5fa58fb8a2 Fix T76821: Generalize Use Flow Tooltip 2020-05-19 00:53:59 -04:00
1151bcd53d Merge branch 'blender-v2.83-release' 2020-05-19 13:31:48 +10:00
f557198540 Merge branch 'blender-v2.83-release' 2020-05-19 13:31:44 +10:00
15bf81268c Fix switching to particle edit-mode from editmode
Similar to T76859
2020-05-19 13:27:08 +10:00
1afa97d547 Fix T76859: Cannot switch from editmode to texturepaint mode
Caused by 5159b8e1ea.
2020-05-19 13:18:10 +10:00
7bd07c9f5a Merge branch 'blender-v2.83-release' 2020-05-19 01:33:08 +02:00
ff7a30d928 Fix sculpt mask interpolation in subdivisions
The interpolation function of the datalayer was misssing so the sculpt
mask data was corrupted every time a subdivision surface modifier was
applied.

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D7640
2020-05-19 01:31:55 +02:00
79a48c5676 Merge branch 'blender-v2.83-release' 2020-05-19 01:08:23 +02:00
7c9c8cee7b Fix T76397: Missing value property on Clear Mask pie menu
Without this value defined it was reusing the same 1.0 value after using
fill mask, so it was not working.

Reviewed By: jbakker

Maniphest Tasks: T76397

Differential Revision: https://developer.blender.org/D7699
2020-05-19 01:07:38 +02:00
393050e8e5 Merge remote-tracking branch 'origin/blender-v2.83-release' 2020-05-18 16:37:57 -06:00
497cd3d7dd Fix: T71040 / T58983 Ocean Modifier crashes at high resolutions
This is not as much a fix as a work around, but given the real
involves replacing how we build fftw, it is not eligible for 2.83
which is in BCON3 already.

The root of the issue lies with (how we build) fftw3

The first issue is: fftw does not build with MSVC, there are other
dependencies that are not compatible with MSVC and for those we
build the libraries required with mingw64, same for fftw

The second issue is: for reasons unknown we really really really
liked all deps to link statically so wherever possible we did so.

Now during the building of the fftw it linked a few symbols from
libgcc (which we do not ship) like __chkstk_ms, for which we passed
some flags to stop generating calls to it. Problem solved! There
is no way this could possibly turn around and bite us in the rear.

fast forward to today mystery crashes that look like a race condition.

What is happening is, we tell the linker that each thread will require
a 2-megabyte stack, now if every thread immediately allocated 2 megs,
that be 'rough' on the memory usage. So, what happens is (for all apps
not just blender), 2 megs are reserved but not backed by any real memory
and the first page is allocated for use by the stack, now as the stack
grows, it will eventually grow out of that first page, and end up in
an area that has not been allocated yet, to deal with that the allocated
page is followed by a guard page, someone touches the guard page it's
time to grow the stack!

Meanwhile in FFTW is it's doing substantial allocation using alloca
(up to 64 kb) on the stack, jumping over the guard page, and ending
up in reserved but not yet committed memory, causing an access violation.

Now if you think, that doesn't sound right! something should have
protected us from that! You are correct! That thing was __chkstk_ms
which we disabled.

Given we do not want a dependency on libgcc while building with MSVC
the proper solution is to build fftw as a shared library which will
statically link any bits and pieces it needs, however that change
is a little bit too big to be doing in BCON3.

So as a work around, we change the size the stack grows from 8k to
68k which gives fftw a little bit more wiggle room to keep it out
of trouble most of the time.

Note this only sidesteps the issue, this may come up again if the
conditions are just right, and a proper solution will need to be
implemented for 2.90.
2020-05-18 16:35:53 -06:00
c4ee94328f Fix invalid bit shift when GPU shader attribute is not found 2020-05-18 21:22:02 +02:00
0bdb827bdf Fix NULL pointer access reported by ASAN (harmless in practice but still weak) 2020-05-18 21:20:10 +02:00
e0ae229acb Fix potential crash due to dyntopo GPU buffer invalid memory access
When the number of triangles in a node became zero, the wireframe batch was
not freed along with the triangles batch and could still reference a freed
vertex buffer.

Ref T76858
2020-05-18 21:01:41 +02:00
afbe71342b Fix T76813: Snap to Edge Center returning a different normal from snap to Edge
This difference was intentional, but using the edge direction as normal is more useful.
2020-05-18 15:19:13 -03:00
06c57d3e7a Refactor: Move workspace foreach_id to new IDTypeInfo structure. 2020-05-18 19:01:20 +02:00
8f10f9d5dc Refactor: Move WindowManager and Screen foreach_id to new IDTypeInfo structure.
That one was a bit more complicated, and is still only partial refactor
(ultimately we want to have a foreach_id callback in SpaceType itself I
think...).
2020-05-18 18:51:06 +02:00
ae97a7ac10 Refactor: Move action foreach_id to new IDTypeInfo structure. 2020-05-18 18:43:11 +02:00
38a8d3aff1 Merge branch 'blender-v2.83-release' 2020-05-18 17:56:57 +02:00
46a4a53824 Outliner: Fix (unreported) more data-changing operators missing undo. 2020-05-18 17:56:33 +02:00
35f9c3b9a4 Merge branch 'blender-v2.83-release' 2020-05-18 17:35:30 +02:00
20b94257dc Fix part of T76544: dyntopo sculpt undo stack memory leak 2020-05-18 17:25:09 +02:00
31fc01eecb OIpenSubdiv: Cleanup, move to a better sounding namespace
The code is not only part of C-API, but also implements Blender-specific
glue level implementation.
2020-05-18 17:25:07 +02:00
9bc7ea5496 Fix T76814: [Mantaflow] Surface Tension always works
Initialize the curvature grid and compute the laplacian only if the diffusion flag is set.
2020-05-18 17:19:51 +02:00
fa116a9bbe Fix T76795: Missing node tree update after remove-on-cancel
Reviewers: brecht

Differential Revision: https://developer.blender.org/D7775
2020-05-18 17:08:57 +02:00
2ad5131f77 OpenSubdiv: Cleanyp, remove old GPU code
All parts of drawing (shaders, GL mesh descriptor, material partitioner
and so on) needs to be redone for the draw manager and new OpenSubdiv
library.

Removing untested code which is doomed to be replaced to make localized
refactoring easier.
2020-05-18 17:06:48 +02:00
22f68f85a4 OpenSubdiv: Cleanup, remove unused topology orientation code
The code was trying to make winding consistent and manifold, same as
OpenSubdiv expects it to.

Unfortunately, the code was having some issues in corner cases so the
winding wasn't really correct.
Fortunately, the latter (compared to when this code was originally
written) supports orientation on OpenSubdiv side.

Removing code which is currently unused in Blender and which had
known issues. Is simple enough to bring the code from Git history
if the functionality is needed in the future.
2020-05-18 17:06:48 +02:00
54665233eb OpenSubdiv: Cleanup, Remove from legacy SubsurfCCG code
The CPU side implementation is done on a new dedicate base ground.
The GPU side must be redone anyway.
2020-05-18 17:06:48 +02:00
151fb62190 Merge branch 'blender-v2.83-release' 2020-05-18 17:04:43 +02:00
0d57ab611c Fix T76851: GPencil brush is reset after change mode
This was introduced by commit rBe58525706328

Now, the brush is not changed when change mode.

Thanks @Alaska for helping with this bug.
2020-05-18 17:04:17 +02:00
6eb00fb02e Fix T76730 DRW: Sorting of empty shading groups.
This is to fix an assert in EEVEE caused by a transparent shading group
that is create but not populated by any drawcall.
2020-05-18 16:59:04 +02:00
0bd7e202fb Curves: Disable Curve Normals by default
This patch just disable the curve Normals by default.

Reviewed By: #user_interface, billreynish, Severin

Differential Revision: https://developer.blender.org/D7755
2020-05-18 16:38:53 +02:00
cb8d8335b2 Fix T76828 Grease Pencil: Toggle Caps doesn't work
This was a logic error.
2020-05-18 16:01:07 +02:00
19413c4a82 Cleanup: GPencil: Fix float double promotion 2020-05-18 16:01:07 +02:00
48a5b1664a Merge branch 'blender-v2.83-release' 2020-05-18 15:54:30 +02:00
27cac4a102 Fix T62422: Baking ray distance do not work
The previous naming scheme for the "selected to active" baking options
lead to confusion and they were not describing what they actually did.

To remedy this, I've added a new settings that does what the older setting implied it did.

Reviewed By: Brecht, Dalai, Andy Davies

Differential Revision: http://developer.blender.org/D7733
2020-05-18 15:50:36 +02:00
121b2c0424 Fix T76799: Crash from undoing the copy-pasting of multiple data blocks.
Bug was actually in outliner code, paste operator would not generate any
undo step...

This was not correct ever, but with new undo code this has become a
critical issue, it cannot survive a situation where current main data
has been changed without a proper undo push.

This illustrates again how much of a catastrophic mess the 'tools'
callbacks of the outliner are currently, it has already caused us quiet
some pain in the past, and will keep doing so until this is fully
sanitized am afraid.

Would strongly suggest getting rid of thosw nasty mix of custom
callbacks requiring manual undo pushes, I do not see the added value of
this compared to regular menus calling regular operators. It only adds
confusion and extra code for nothing...
2020-05-18 15:47:03 +02:00
dcf67fdf7f UI: Widget: Make emboss offset dependent of line width 2020-05-18 15:27:30 +02:00
27b23148fa UI: Widgets: Reduce constants count in shader 2020-05-18 15:27:29 +02:00
6ede93bab3 Cleanup: Put GPU_state_init inside gpu_state.c
Also put glDisable(GL_DITHER) in it since we don't even use it (but is
enabled by default).

Also leave GL_MULTISAMPLE on by default since it has no impact on non-MSAA
framebuffers.
2020-05-18 15:27:29 +02:00
18dd289e1a Merge branch 'blender-v2.83-release' 2020-05-18 21:29:26 +10:00
80b340b034 Merge branch 'blender-v2.83-release' 2020-05-18 21:29:23 +10:00
b487ef6116 Fix T76593: Coordinate limit of 10,000 units
This is no longer needed for number button dragging to work properly.
2020-05-18 21:16:00 +10:00
b75ce05c3b Fix T75292: File-select events not handled while modal handler is active
Reviewers: Severin

Differential Revision: https://developer.blender.org/D7720
2020-05-18 11:59:53 +02:00
b1492b76ba Alembic: Fix bad allocation with invalid knots data
It is not impossible that the number of knots is stored wrong in the
file (for example, it will be 1 knot only).

This change fixes bad memory allocation and bad memory access in such
cases. It also fixes strict compiler warning which was mentioning that
the allocation size is wrong),

There isn't really the correct way of dealing with such situation, so
simply fall back to Blender's knots calculation.

Differential Revision: https://developer.blender.org/D7765
2020-05-18 11:50:34 +02:00
9796cb1661 Fix T76721: ASAN crash on animation rendering
Simple solution: remove the code which was causing bad threading
conflicts.

This code was a part of workaround for a specific state of linked
scene. It seems to be not needed anymore, since the pose is ensured
to be up to date by the following call stack:

- Dependency graph update,
- Copy-=on-write operation called on object.
- object_copy_data().
- BKE_pose_rebuild().

The workaround was a no-functional change for the dependency graph
anyway, because it was modifying original objects, not the ones
which are evaluated.
2020-05-18 11:48:24 +02:00
f3edff2d7d AVI: Fix read past array bounds
It is not enough to copy max of destination buffer size bytes, the
source might be smaller than the destination size.
2020-05-18 11:05:45 +02:00
005d04e145 Manta: Cleanup, strict compiler flag
For some reason was only visible with gcc-10 in release builds.

Kind of makes sense since there is no CMake code which removes strict
compiler flag, so deal with strict flags in the code itself.
2020-05-18 11:05:45 +02:00
a432cb2ad9 Merge branch 'blender-v2.83-release' 2020-05-18 18:58:21 +10:00
008e964940 Fix T76852: Breakdowner remembers limits last used 2020-05-18 18:49:40 +10:00
470ed9f074 Merge branch 'blender-v2.83-release' 2020-05-18 10:49:23 +02:00
04d15f1625 Fix T76573: Make links with Multires leading to crash 2020-05-18 10:48:45 +02:00
52d8b3a014 Fix T76849: Duplicate templates show in the New menu 2020-05-18 17:59:52 +10:00
a4b2734fe2 Fix T76801: Renaming bone in pose mode doesn't redraw the viewport names
The RNA name property of pose bones did not have any update logic defined.

Same issue also applied to the channel name in animation editors.

Duplicated the update logic from (edit-)bones now, other pose bone functions do
this too...
2020-05-18 09:51:20 +02:00
68ba154869 Merge branch 'blender-v2.83-release' 2020-05-18 17:14:28 +10:00
fd8d2ceafe Merge branch 'blender-v2.83-release' 2020-05-18 17:14:24 +10:00
815ffaa6c1 Merge branch 'blender-v2.83-release' 2020-05-18 17:14:17 +10:00
98e18c41b6 Cleanup: unused warning in last commit 2020-05-18 17:11:48 +10:00
2a3797b109 Cleanup: remove NULL checks from object mode switching take #2
Re-apply changes from 54ea356240,
with a poll function that uses the same active object as the operator,
matching other mode switching functions.
2020-05-18 17:07:23 +10:00
ff144edd8c Revert "Cleanup: remove redundant active object NULL check & poll"
This reverts commit 54ea356240 it
introduced crashes when trying to go to edit mode when the active
object was hidden.

Fix T76837
2020-05-18 08:32:07 +02:00
218579fa53 Merge branch 'blender-v2.83-release' 2020-05-18 16:30:34 +10:00
cfea716128 Fix error mixing incompatible enums when generating the proxy name 2020-05-18 16:12:17 +10:00
41825c7e0d Merge branch 'blender-v2.83-release' 2020-05-18 14:37:48 +10:00
9af72792a3 Cleanup: quiet enum conversion warning 2020-05-18 14:36:02 +10:00
5c5a638b57 Fix: Build error with MSVC
A parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax.

Removing the cast seems fine for both MSVC and GCC
2020-05-17 12:22:14 -06:00
dde7a762c3 Fluid: Bake cache for more frames by default 2020-05-17 17:09:29 +02:00
fe257cc384 Fix T74060: Smoke flow force field not working with Mantaflow Gas
cb252ca8d316 was also needed to fix the velocity loading from the cache.
2020-05-17 17:09:28 +02:00
a975cb9207 Fluid: Foundation for new OpenVDB file IO
This commit lays the foundation for support for OpenVDB caching with multiple grids per cache file.
2020-05-17 17:09:28 +02:00
0abe5936b7 Fluid: Cleanup namespace std 2020-05-17 17:09:28 +02:00
15dd6cb668 UI: Widget: Replace geometry by fragment shader drawing
This means all the antiailasing is done inside the fragment shader.

We use a Signed Distance Field to draw the 2D rounded boxes. This ensure
the best quality for AA.

This reduce the averge Batch for widget to 16 verts instead of ~600 and
reduce overshading a lot.

Theme Emboss alpha and tria alpha needs to be changed after this refactor.
2020-05-17 02:58:02 +02:00
eaf7d36d66 UI: Graph Editor: Draw Handles Lines With Smoothing
Enabling "Use High Quality Display" in the graph editor enables
AA for the curves, this enables it for bezier handles too.

Differential Revision: https://developer.blender.org/D7740
2020-05-15 15:12:58 -04:00
d9773edaa3 Cycles: code refactor to bake using regular render session and tiles
There should be no user visible change from this, except that tile size
now affects performance. The goal here is to simplify bake denoising in
D3099, letting it reuse more denoising tiles and pass code.

A lot of code is now shared with regular rendering, with the two main
differences being that we read some render result passes from the bake API
when starting to render a tile, and call the bake kernel instead of the
path trace kernel.

With this kind of design where Cycles asks for tiles from the bake API,
it should eventually be easier to reduce memory usage, show tiles as
they are baked, or bake multiple passes at once, though there's still
quite some work needed for that.

Reviewers: #cycles

Subscribers: monio, wmatyjewicz, lukasstockner97, michaelknubben

Differential Revision: https://developer.blender.org/D3108
2020-05-15 20:25:24 +02:00
3ff8ca60e9 Merge branch 'blender-v2.83-release' 2020-05-15 19:38:40 +02:00
e5ace51295 Fix T76734: Changing Envelope FModifier controlpoints missing update
Issue is that update functions defined in
`rna_def_fmodifier_envelope_ctrl` (namely `rna_FModifier_update`) are
actually never called.

This is because UI code for FCurve modifiers often does not use RNA
buttons but uses custom update functions (or non at all). For example,
rB9a88bd55903a did this for the generators, envelope control points did
not have this at all.

This is now changed to use RNA buttons for the envelope control points,
this could done for other non-RNA buttons as well to get rid of
'validate_fmodifier_cb()'.

Maniphest Tasks: T76734

Differential Revision: https://developer.blender.org/D7732
2020-05-15 19:29:33 +02:00
e1c2eba4de Merge branch 'blender-v2.83-release' 2020-05-15 19:26:02 +02:00
abcb23f5a3 Fix T76698: Movie clip stabilize display ignore footage colorspace
settings

Stabilized ImBuf just needs to use the same colorspace and alpha
settings as the original one.

Maniphest Tasks: T76698

Differential Revision: https://developer.blender.org/D7713
2020-05-15 19:08:58 +02:00
a8fc3c88ef Refactor: Move linestyle foreach_id to new IDTypeInfo structure. 2020-05-15 19:03:53 +02:00
7ff933089a Refactor: Move mask foreach_id to new IDTypeInfo structure. 2020-05-15 19:03:53 +02:00
c44d6fb987 Refactor: Move movieclip foreach_id to new IDTypeInfo structure. 2020-05-15 19:03:53 +02:00
0055aa994d Refactor: Move particle foreach_id to new IDTypeInfo structure. 2020-05-15 19:03:53 +02:00
a952f8dab0 Merge branch 'blender-v2.83-release' 2020-05-15 18:40:19 +02:00
001d70eb2b Fix T76277: Remove wrong cast in rna_NodeTree_update
This patch fixes T76277 by removing the incorrect cast from
`ptr->data` to `bNode`. The address of `ptr->owner_id` and
`ptr->data` both point to the node tree. Passing the node tree
incorrectly as a node into the `ED_node_tag_update_nodetree`
corrupts the data, because it attempts to set flags on the
node.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D7747
2020-05-15 18:29:42 +02:00
ecec6547c7 Merge branch 'blender-v2.83-release' 2020-05-15 18:02:10 +02:00
9632a06201 Fix embedded IDs not being enough/properly initialized.
Among other things, they were missing library pointer, session uuid
initialization, etc.

Fix T74546: Corrupted nodegroups crash blender when copy pasting or
appending them.

Fix (unreported) asserts when undoing some production scenes (from
coffee run e.g.).

Initialy caused by rB0aac74f18f2d.
2020-05-15 17:57:13 +02:00
b14243be77 blenlib: BLI_file_attributes() Correction
Adds an Correction to properly handle possibility of overflow of path name.

Differential Revision: https://developer.blender.org/D7739

Reviewed by Brecht Van Lommel
2020-05-15 08:11:57 -07:00
0f2c7f3864 Merge branch 'blender-v2.83-release' 2020-05-15 16:54:33 +02:00
0541906162 Cleanup: rename readfile utils dealing with embedded IDs to proper name. 2020-05-15 16:54:03 +02:00
363f18c8b5 Merge branch 'blender-v2.83-release' 2020-05-15 16:51:36 +02:00
1cad0a627e GPencil: Fix unreported missing Sculpt/Vertex/Weight paint brushes
This error was introduced wit the change in commit https://developer.blender.org/rB6a850f3cc840

As the brushes were not created, all modes except Edit were broken. 

Now, the brushes and palette are not created when load the file in versioning code, but when the mode is enabled.

Also, if the brush already exist, the parameters are not reset as it was done in the versioning code in order to keep user settings.

The same logic is used for the default palette.
2020-05-15 16:50:38 +02:00
d6e0b55b1c Merge branch 'blender-v2.83-release' 2020-05-15 16:32:50 +02:00
a269761ec1 Cleanup: clang format
Sorry for the noise, somehow missed that in rB0a32f6c8686c.
2020-05-15 16:31:18 +02:00
b67f649077 Merge branch 'blender-v2.83-release' 2020-05-15 16:02:12 +02:00
266caa1820 Fix T76755: texture paint on udims crash
Caused by rB5593efec01c2.

Use first texture if we dont have an ImageUser (instead of multiview
one). Same fix as in rB9ace7e243978 / T74925.

Maniphest Tasks: T76755

Differential Revision: https://developer.blender.org/D7743
2020-05-15 15:56:35 +02:00
1aace88d0c UI: Widget: Make emboss offset dependent of line width 2020-05-15 15:49:52 +02:00
291f9462fc UI: Widgets: Reduce constants count in shader 2020-05-15 15:21:02 +02:00
998e26704b Merge branch 'blender-v2.83-release' 2020-05-15 23:16:39 +10:00
fe0036c586 Fix T76563: Transforming an auto-aligned point won't set it aligned
When local origins are used or a single control point is selected,
change the handle types from auto to aligned.
2020-05-15 23:13:57 +10:00
0538d00cc2 Cleanup: Put GPU_state_init inside gpu_state.c
Also put glDisable(GL_DITHER) in it since we don't even use it (but is
enabled by default).

Also leave GL_MULTISAMPLE on by default since it has no impact on non-MSAA
framebuffers.
2020-05-15 15:02:46 +02:00
2b36cf3118 Libmv: Fix crash solving when having negative frames
Don't use linear array with frame as an index since it has the
following disadvantages:

- Requires every application to take care of frame remapping, which
  could be way more annoying than it sounds.

- Inefficient from memory point of view when solving part of a footage
  which is closer to the end of frame range.

Using map technically is slower from performance point of view, but
could not feel any difference as the actual computation is way more
complex than access of camera on individual frames.

Solves crash aspect of T72009
2020-05-15 14:59:25 +02:00
86580c437b Cleanup: int->BVHCacheType enum 2020-05-15 13:55:01 +02:00
03659c2cf9 Merge branch 'blender-v2.83-release' 2020-05-15 13:47:04 +02:00
a5d394fad2 Fix segfault when trying to free uninitialized loop normals
Forgot this corner case when I created the new normal flip code.
2020-05-15 13:39:35 +02:00
0a32f6c868 Fix T76710: objects get lost in linked/overridden collections
Right now:
- drag-drop in the Outliner prevents dropping inside linked collections
- drag-drop in the Outliner allows dropping inside overridden
collections (should not be the case)
- `Object Properties` > `Collections` panel allows to add to overridden
collection (should not be the case)
- `Object Properties` > `Collections` panel filters out non-local
collections (so adding to linked collections is forbidden)
- `bpy collection.objects.link()` allows to add to linked collections
(should not be the case)
- `bpy collection.objects.link()` allows to add to overridden
collections (should not be the case)

While this might be supported in the future for overriden collections,
these cases should not be allowed atm. since objects get lost on file
reload.

Note: for the case of the `Object Properties` > `Collections` panel,
this could be improved further to filter out overridden collections as
well.

Reviewers: mont29, brecht

Subscribers:
2020-05-15 13:32:15 +02:00
3a14c011f9 GPencil: Fix unreported crash using U key in Draw mode
The problem was the preview could be not available when press the key.
2020-05-15 13:05:58 +02:00
04517ee936 Merge remote-tracking branch 'origin/blender-v2.83-release' 2020-05-15 12:59:24 +02:00
0ae64a9945 Fix T76695: Not exporting normals properly in Alembic format
When auto-smooth enabled, but no custom normals layer present, the Alembic
exporter would incorrectly assume the mesh was shaded smooth. This is now
corrected, and normals are always written when auto-smooth is enabled.
2020-05-15 12:58:48 +02:00
5f95912afc BLI: add missing include for size_t 2020-05-15 12:48:45 +02:00
7049d2dc58 Fix T76778: Dopesheet "Show Errors" affects timeline
Since the timeline is a variation of the dopesheet, it also respects
some of the dopesheet settings.

The "Selected Only" setting is overridden from a scene property (since
rB4904eadc0f38) and the "Display Hidden" dopesheet setting seems to be
ignored.

This commit adds the remaining "Show Errors" setting to the menu,
allowing it to be updated from the timeline.
2020-05-15 11:54:17 +02:00
547f50b5e0 Libmv: Add map utility 2020-05-15 11:20:45 +02:00
6398892121 Libmv: Cleanup, spelling 2020-05-15 11:20:45 +02:00
f1cb11f0fa Merge branch 'blender-v2.83-release' 2020-05-15 10:53:32 +02:00
19d822c677 Fix T76740: Static Override - Library Override Crash
Missing proper tagging of 'backward' pointer from fcurve to its group in
RNA would lead to infinite loop...

Issue was triggered by override, but crash could be generated from other
places as well (like from py console), on any action actually...
2020-05-15 10:46:55 +02:00
e60560bda0 Fix T76738: Duplicate brushes cause assertion on undo
Changes for 2.90 versioning.
2020-05-15 17:53:03 +10:00
559a8886d6 Merge branch 'blender-v2.83-release' 2020-05-15 17:48:31 +10:00
20c25bffda Merge branch 'blender-v2.83-release' 2020-05-15 17:47:58 +10:00
656692913b Merge branch 'blender-v2.83-release' 2020-05-15 17:47:54 +10:00
3c0fd51cf4 Fix T76738: Duplicate brushes cause assertion on undo 2020-05-15 17:45:41 +10:00
6a850f3cc8 Fix duplicate ID's being created when appending/linking
This removes grease pencil brush creation/dat-block delete on load,
since this causes duplicate data-blocks.

Add assert to prevent this happening in the future
since the error is isn't obvious.
2020-05-15 17:42:01 +10:00
c361f911f9 Fix error versioning paint-slots pre-2.80 2020-05-15 16:51:33 +10:00
191c562f98 Merge branch 'blender-v2.83-release' 2020-05-15 12:52:31 +10:00
4ce1829289 Cleanup: don't check flags as booleans
Causes unexpected behavior when adding new flags.
2020-05-15 12:47:47 +10:00
c880e54a95 Cycles: Refactor microfacet BSDFs to remove separate anisotropy code
Since the sampling and evaluation functions handle both cases anyways,
there's not really a point for keeping the distinction in the kernel,
so we might as well cut down the number of CLOSURE_BSDF_MICROFACETs a bit.

Differential Revision: https://developer.blender.org/D7736
2020-05-15 00:52:57 +02:00
8d918fe0f2 Merge branch 'blender-v2.83-release' 2020-05-14 21:50:07 +02:00
f716bb3b71 GPencil: Add licence text at header 2020-05-14 21:49:44 +02:00
516e1b4031 Fix T76025: Flip/recalc steep custom normals produces wrong result
The issue was the custom loop normal data would be mangled when we
reversed the face loops.

The flip face code will now correctly flip the custom face normals so
they are not left in an undefined state.

Reviewed By: Bastien

Differential Revision: http://developer.blender.org/D7528
2020-05-14 21:17:33 +02:00
2efe77ca51 Fix missing hinting information in default font
Updates the font file to bring back hinting data, which got lost somehow
in dc3f073d1c.

Second and (hopefully) final fix for T75898.
2020-05-14 20:17:26 +02:00
Nikhil Shringarpurey
3ced9c1c72 Fix missing hinting information in monospace font
Updates the monospace font file to bring back hinting data, which got
lost somehow in dc3f073d1c.

Partial fix for T75898.
2020-05-14 20:17:07 +02:00
6716baa1f7 Fix T76476 EEVEE: Invalid Vector to Float conversion for nodegroups
The previous code only handled the RGBA socket case. For vectors, we simply
use the average of the 3 compoments. This is done using a temp Vector Math
node using the dot operation.
2020-05-14 19:57:51 +02:00
4ac748c099 Merge branch 'blender-v2.83-release' 2020-05-14 19:54:15 +02:00
5f31e5031c GPencil: Fix unreported problem filling textured strokes
The internal image used for filling was not correct when the texture was used in stroke and this makes impossible get a right filling.
2020-05-14 19:53:55 +02:00
cc3d3a453e Fix: Broken build with TBB disabled.
Lite builds without TBB and still needs the alternative codepath
2020-05-14 10:39:12 -06:00
Tautvydas Andrikys
33ce0cb5a1 Fix T63588: Cycles unnecessarily updates background importance sampling map 2020-05-14 17:56:50 +02:00
461fee5328 BLI: deduplicate address sanitizer code
Reviewers: brecht, campbellbarton

Differential Revision: https://developer.blender.org/D7731
2020-05-14 17:42:54 +02:00
5940485369 Fix T76168 Workbench: Shadows behind a culled backface are inverted 2020-05-14 17:41:05 +02:00
16d8a683be Fix T73984: unnecessary Cycles viewport updates with object texture coordinates
Remove old code that added extra updates for shaders that have a dependency on
objects. The dependency graph can now tell Cycles when a material is affected by
an object transform.
2020-05-14 17:39:37 +02:00
ea84c12a2b Merge remote-tracking branch 'origin/blender-v2.83-release' 2020-05-14 17:14:12 +02:00
72492eb2a2 Update RNA Manual References after camera fix
There was no link to the base camera* properties (e.g., lens).
2020-05-14 17:13:52 +02:00
dc4983dfdd Merge branch 'blender-v2.83-release' 2020-05-14 16:49:18 +02:00
78e3b7c28d Sculpt: Render Face Sets always as flat shading
This removes the smooth shading rendering from the face set overlay when
smooth shading is enabled.

Reviewed By: jbakker

Maniphest Tasks: T74906, T74622, T75331, T76530

Differential Revision: https://developer.blender.org/D7105
2020-05-14 16:47:50 +02:00
fa23e313f1 Merge branch 'blender-v2.83-release' 2020-05-14 16:32:38 +02:00
e585257063 GPencil: Changes in 2D template
Differential Revision: https://developer.blender.org/D7619
2020-05-14 16:31:51 +02:00
462 changed files with 8466 additions and 11369 deletions

View File

@@ -281,7 +281,7 @@ option(WITH_ALEMBIC "Enable Alembic Support" ON)
option(WITH_ALEMBIC_HDF5 "Enable Legacy Alembic Support (not officially supported)" OFF)
# Universal Scene Description support
option(WITH_USD "Enable Universal Scene Description (USD) Support" OFF)
option(WITH_USD "Enable Universal Scene Description (USD) Support" ON)
# 3D format support
# Disable opencollada when we don't have precompiled libs
@@ -628,12 +628,6 @@ if(WITH_PYTHON_MODULE AND WITH_PYTHON_INSTALL)
message(FATAL_ERROR "WITH_PYTHON_MODULE requires WITH_PYTHON_INSTALL to be OFF")
endif()
# may as well build python module without a UI
if(WITH_PYTHON_MODULE)
set(WITH_HEADLESS ON)
endif()
if(NOT WITH_PYTHON)
set(WITH_CYCLES OFF)
set(WITH_DRACO OFF)

View File

@@ -130,7 +130,6 @@ if(NOT WIN32 OR ENABLE_MINGW64)
include(cmake/vpx.cmake)
include(cmake/x264.cmake)
include(cmake/xvidcore.cmake)
include(cmake/faad.cmake)
include(cmake/ffmpeg.cmake)
include(cmake/fftw.cmake)
include(cmake/sndfile.cmake)

View File

@@ -1,40 +0,0 @@
# ***** BEGIN GPL LICENSE BLOCK *****
#
# 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.
#
# ***** END GPL LICENSE BLOCK *****
set(FAAD_EXTRA_ARGS)
if(WIN32)
set(FAAD_EXTRA_CONFIGURE "utils\\win32\\ac2ver.exe" "faad2" "configure.ac" > libfaad\\win32_ver.h)
else()
set(FAAD_EXTRA_CONFIGURE echo .)
endif()
ExternalProject_Add(external_faad
URL ${FAAD_URI}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH MD5=${FAAD_HASH}
PREFIX ${BUILD_DIR}/faad
CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/faad/src/external_faad/ && ${FAAD_EXTRA_CONFIGURE} && ${CONFIGURE_COMMAND} --disable-shared --enable-static --prefix=${LIBDIR}/faad
BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/faad/src/external_faad/ && make -j${MAKE_THREADS}
INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/faad/src/external_faad/ && make install
INSTALL_DIR ${LIBDIR}/faad
)
if(MSVC)
set_target_properties(external_faad PROPERTIES FOLDER Mingw)
endif()

View File

@@ -127,7 +127,6 @@ endif()
add_dependencies(
external_ffmpeg
external_zlib
external_faad
external_openjpeg
external_xvidcore
external_x264

View File

@@ -19,8 +19,12 @@
set(FFTW_EXTRA_ARGS)
if(WIN32)
set(FFTW3_ENV set CFLAGS=-fno-stack-check -fno-stack-protector -mno-stack-arg-probe -fno-lto &&)
set(FFTW3_PATCH_COMMAND ${PATCH_CMD} --verbose -p 0 -N -d ${BUILD_DIR}/fftw3/src/external_fftw3 < ${PATCH_DIR}/fftw3.diff)
set(FFTW_EXTRA_ARGS --disable-static --enable-shared)
set(FFTW_INSTALL install-strip)
else()
set(FFTW_EXTRA_ARGS --enable-static)
set(FFTW_INSTALL install)
endif()
ExternalProject_Add(external_fftw3
@@ -28,10 +32,10 @@ ExternalProject_Add(external_fftw3
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH MD5=${FFTW_HASH}
PREFIX ${BUILD_DIR}/fftw3
CONFIGURE_COMMAND ${CONFIGURE_ENV} && ${FFTW3_ENV} cd ${BUILD_DIR}/fftw3/src/external_fftw3/ && ${CONFIGURE_COMMAND} --enable-static --prefix=${mingw_LIBDIR}/fftw3
CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/fftw3/src/external_fftw3/ && ${CONFIGURE_COMMAND} ${FFTW_EXTRA_ARGS} --prefix=${mingw_LIBDIR}/fftw3
PATCH_COMMAND ${FFTW3_PATCH_COMMAND}
BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/fftw3/src/external_fftw3/ && make -j${MAKE_THREADS}
INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/fftw3/src/external_fftw3/ && make install
INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/fftw3/src/external_fftw3/ && make ${FFTW_INSTALL}
INSTALL_DIR ${LIBDIR}/fftw3
)
@@ -39,7 +43,8 @@ if(MSVC)
set_target_properties(external_fftw3 PROPERTIES FOLDER Mingw)
if(BUILD_MODE STREQUAL Release)
ExternalProject_Add_Step(external_fftw3 after_install
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/fftw3/lib/libfftw3.a ${HARVEST_TARGET}/fftw3/lib/libfftw.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/fftw3/lib/libfftw3.dll.a ${HARVEST_TARGET}/fftw3/lib/libfftw.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/fftw3/bin/libfftw3-3.dll ${HARVEST_TARGET}/fftw3/lib/libfftw3-3.dll
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/fftw3/include/fftw3.h ${HARVEST_TARGET}/fftw3/include/fftw3.h
DEPENDEES install
)

View File

@@ -44,10 +44,6 @@ if(BUILD_MODE STREQUAL Release)
# glew-> opengl
${CMAKE_COMMAND} -E copy ${LIBDIR}/glew/lib/libglew32.lib ${HARVEST_TARGET}/opengl/lib/glew.lib &&
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/glew/include/ ${HARVEST_TARGET}/opengl/include/ &&
# sndfile
${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/lib/libsndfile.dll.a ${HARVEST_TARGET}/sndfile/lib/libsndfile-1.lib &&
${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/bin/libsndfile-1.dll ${HARVEST_TARGET}/sndfile/lib/libsndfile-1.dll &&
${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/include/sndfile.h ${HARVEST_TARGET}/sndfile/include/sndfile.h &&
# tiff
${CMAKE_COMMAND} -E copy ${LIBDIR}/tiff/lib/tiff.lib ${HARVEST_TARGET}/tiff/lib/libtiff.lib &&
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/tiff/include/ ${HARVEST_TARGET}/tiff/include/ &&

View File

@@ -52,7 +52,6 @@ if(BUILD_MODE STREQUAL Release)
PREFIX ${BUILD_DIR}/openal
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openal ${DEFAULT_CMAKE_FLAGS} ${OPENAL_EXTRA_ARGS}
INSTALL_DIR ${LIBDIR}/openal
PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/openal/src/external_openal < ${PATCH_DIR}/openal.diff
)
if(WIN32)

View File

@@ -67,7 +67,7 @@ endif()
ExternalProject_Add(external_opensubdiv
URL ${OPENSUBDIV_URI}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH MD5=${OPENSUBDIV_Hash}
URL_HASH MD5=${OPENSUBDIV_HASH}
PREFIX ${BUILD_DIR}/opensubdiv
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/opensubdiv -Wno-dev ${DEFAULT_CMAKE_FLAGS} ${OPENSUBDIV_EXTRA_ARGS}
INSTALL_DIR ${LIBDIR}/opensubdiv

View File

@@ -60,3 +60,14 @@ if(UNIX)
external_flac
)
endif()
if(BUILD_MODE STREQUAL Release AND WIN32)
ExternalProject_Add_Step(external_sndfile after_install
COMMAND lib /def:${BUILD_DIR}/sndfile/src/external_sndfile/src/libsndfile-1.def /machine:x64 /out:${BUILD_DIR}/sndfile/src/external_sndfile/src/libsndfile-1.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/bin/libsndfile-1.dll ${HARVEST_TARGET}/sndfile/lib/libsndfile-1.dll
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/sndfile/src/external_sndfile/src/libsndfile-1.lib ${HARVEST_TARGET}/sndfile/lib/libsndfile-1.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/include/sndfile.h ${HARVEST_TARGET}/sndfile/include/sndfile.h
DEPENDEES install
)
endif()

View File

@@ -20,9 +20,9 @@ set(ZLIB_VERSION 1.2.11)
set(ZLIB_URI https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz)
set(ZLIB_HASH 1c9f62f0778697a09d36121ead88e08e)
set(OPENAL_VERSION 1.18.2)
set(OPENAL_VERSION 1.20.1)
set(OPENAL_URI http://openal-soft.org/openal-releases/openal-soft-${OPENAL_VERSION}.tar.bz2)
set(OPENAL_HASH d4eeb0889812e2fdeaa1843523d76190)
set(OPENAL_HASH 556695068ce8375b89986083d810fd35)
set(PNG_VERSION 1.6.35)
set(PNG_URI http://prdownloads.sourceforge.net/libpng/libpng-${PNG_VERSION}.tar.xz)
@@ -66,9 +66,9 @@ else()
set(OPENEXR_VERSION_POSTFIX)
endif()
set(FREETYPE_VERSION 2.10.1)
set(FREETYPE_VERSION 2.10.2)
set(FREETYPE_URI http://prdownloads.sourceforge.net/freetype/freetype-${FREETYPE_VERSION}.tar.gz)
set(FREETYPE_HASH c50a3c9e5e62bdc938a6e1598a782947)
set(FREETYPE_HASH b1cb620e4c875cd4d1bfa04945400945)
set(GLEW_VERSION 1.13.0)
set(GLEW_URI http://prdownloads.sourceforge.net/glew/glew/${GLEW_VERSION}/glew-${GLEW_VERSION}.tgz)
@@ -101,13 +101,13 @@ set(CUEW_GIT_UID 1744972026de9cf27c8a7dc39cf39cd83d5f922f)
set(CUEW_URI https://github.com/CudaWrangler/cuew/archive/${CUEW_GIT_UID}.zip)
set(CUEW_HASH 86760d62978ebfd96cd93f5aa1abaf4a)
set(OPENSUBDIV_VERSION v3_4_0_RC2)
set(OPENSUBDIV_Hash f6a10ba9efaa82fde86fe65aad346319)
set(OPENSUBDIV_VERSION v3_4_3)
set(OPENSUBDIV_URI https://github.com/PixarAnimationStudios/OpenSubdiv/archive/${OPENSUBDIV_VERSION}.tar.gz)
set(OPENSUBDIV_HASH 7bbfa275d021fb829e521df749160edb)
set(SDL_VERSION 2.0.8)
set(SDL_VERSION 2.0.12)
set(SDL_URI https://www.libsdl.org/release/SDL2-${SDL_VERSION}.tar.gz)
set(SDL_HASH 3800d705cef742c6a634f202c37f263f)
set(SDL_HASH 783b6f2df8ff02b19bb5ce492b99c8ff)
set(OPENCOLLADA_VERSION v1.6.68)
set(OPENCOLLADA_URI https://github.com/KhronosGroup/OpenCOLLADA/archive/${OPENCOLLADA_VERSION}.tar.gz)
@@ -168,9 +168,9 @@ set(LAME_VERSION 3.100)
set(LAME_URI http://downloads.sourceforge.net/project/lame/lame/3.100/lame-${LAME_VERSION}.tar.gz)
set(LAME_HASH 83e260acbe4389b54fe08e0bdbf7cddb)
set(OGG_VERSION 1.3.3)
set(OGG_VERSION 1.3.4)
set(OGG_URI http://downloads.xiph.org/releases/ogg/libogg-${OGG_VERSION}.tar.gz)
set(OGG_HASH c2e8a485110b97550f453226ec644ebac6cb29d1caef2902c007edab4308d985)
set(OGG_HASH fe5670640bd49e828d64d2879c31cb4dde9758681bb664f9bdbf159a01b0c76e)
set(VORBIS_VERSION 1.3.6)
set(VORBIS_URI http://downloads.xiph.org/releases/vorbis/libvorbis-${VORBIS_VERSION}.tar.gz)
@@ -180,24 +180,24 @@ set(THEORA_VERSION 1.1.1)
set(THEORA_URI http://downloads.xiph.org/releases/theora/libtheora-${THEORA_VERSION}.tar.bz2)
set(THEORA_HASH b6ae1ee2fa3d42ac489287d3ec34c5885730b1296f0801ae577a35193d3affbc)
set(FLAC_VERSION 1.3.2)
set(FLAC_VERSION 1.3.3)
set(FLAC_URI http://downloads.xiph.org/releases/flac/flac-${FLAC_VERSION}.tar.xz)
set(FLAC_HASH 91cfc3ed61dc40f47f050a109b08610667d73477af6ef36dcad31c31a4a8d53f)
set(FLAC_HASH 213e82bd716c9de6db2f98bcadbc4c24c7e2efe8c75939a1a84e28539c4e1748)
set(VPX_VERSION 1.7.0)
set(VPX_VERSION 1.8.2)
set(VPX_URI https://github.com/webmproject/libvpx/archive/v${VPX_VERSION}/libvpx-v${VPX_VERSION}.tar.gz)
set(VPX_HASH 1fec931eb5c94279ad219a5b6e0202358e94a93a90cfb1603578c326abfc1238)
set(VPX_HASH 8735d9fcd1a781ae6917f28f239a8aa358ce4864ba113ea18af4bb2dc8b474ac)
set(OPUS_VERSION 1.3.1)
set(OPUS_URI https://archive.mozilla.org/pub/opus/opus-${OPUS_VERSION}.tar.gz)
set(OPUS_HASH 65b58e1e25b2a114157014736a3d9dfeaad8d41be1c8179866f144a2fb44ff9d)
set(X264_URI http://download.videolan.org/pub/videolan/x264/snapshots/x264-snapshot-20180811-2245-stable.tar.bz2)
set(X264_HASH ae8a868a0e236a348b35d79f3ee80294b169d1195408b689f9851383661ed7aa)
set(X264_URI https://code.videolan.org/videolan/x264/-/archive/master/x264-33f9e1474613f59392be5ab6a7e7abf60fa63622.tar.gz)
set(X264_HASH 300dfb5b6c35722516f168868ce9419252a9e9eb77a05d82c9cede925b691bd6)
set(XVIDCORE_VERSION 1.3.5)
set(XVIDCORE_URI http://downloads.xvid.org/downloads/xvidcore-${XVIDCORE_VERSION}.tar.gz)
set(XVIDCORE_HASH 165ba6a2a447a8375f7b06db5a3c91810181f2898166e7c8137401d7fc894cf0)
set(XVIDCORE_VERSION 1.3.7)
set(XVIDCORE_URI https://downloads.xvid.com/downloads/xvidcore-${XVIDCORE_VERSION}.tar.gz)
set(XVIDCORE_HASH abbdcbd39555691dd1c9b4d08f0a031376a3b211652c0d8b3b8aa9be1303ce2d)
# This has to be in sync with the version in blenders /extern folder.
set(OPENJPEG_VERSION 2.3.0)
@@ -206,13 +206,9 @@ set(OPENJPEG_SHORT_VERSION 2.3)
set(OPENJPEG_URI https://github.com/uclouvain/openjpeg/archive/66297f07a43.zip)
set(OPENJPEG_HASH 8242b18d908c7c42174e4231a741cfa7ce7c26b6ed5c9644feb9df7b3054310b)
set(FAAD_VERSION 2-2.8.8)
set(FAAD_URI http://downloads.sourceforge.net/faac/faad${FAAD_VERSION}.tar.gz)
set(FAAD_HASH 28f6116efdbe9378269f8a6221767d1f)
set(FFMPEG_VERSION 4.0.2)
set(FFMPEG_VERSION 4.2.3)
set(FFMPEG_URI http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2)
set(FFMPEG_HASH 5576e8a22f80b6a336db39808f427cfb)
set(FFMPEG_HASH 695fad11f3baf27784e24cb0e977b65a)
set(FFTW_VERSION 3.3.8)
set(FFTW_URI http://www.fftw.org/fftw-${FFTW_VERSION}.tar.gz)
@@ -319,6 +315,6 @@ set(MESA_VERSION 18.3.1)
set(MESA_URI ftp://ftp.freedesktop.org/pub/mesa//mesa-${MESA_VERSION}.tar.xz)
set(MESA_HASH d60828056d77bfdbae0970f9b15fb1be)
set(XR_OPENXR_SDK_VERSION 1.0.6)
set(XR_OPENXR_SDK_VERSION 1.0.8)
set(XR_OPENXR_SDK_URI https://github.com/KhronosGroup/OpenXR-SDK/archive/release-${XR_OPENXR_SDK_VERSION}.tar.gz)
set(XR_OPENXR_SDK_HASH 21daea7c3bfec365298d779a0e19caa1)
set(XR_OPENXR_SDK_HASH c6de63d2e0f9029aa58dfa97cad8ce07)

View File

@@ -18,9 +18,6 @@
if(WIN32)
set(X264_EXTRA_ARGS --enable-win32thread --cross-prefix=${MINGW_HOST}- --host=${MINGW_HOST})
set(X264_PATCH_CMD ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/x264/src/external_x264 < ${PATCH_DIR}/x264.diff)
else()
set(X264_PATCH_CMD echo .)
endif()
@@ -29,7 +26,6 @@ ExternalProject_Add(external_x264
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH SHA256=${X264_HASH}
PREFIX ${BUILD_DIR}/x264
PATCH_COMMAND ${X264_PATCH_CMD}
CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/x264/src/external_x264/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/x264
--enable-static
--enable-pic

View File

@@ -1,13 +0,0 @@
diff -Naur external_openal_original/CMakeLists.txt external_openal/CMakeLists.txt
--- external_openal_original/CMakeLists.txt 2016-01-24 20:12:39 -0700
+++ external_openal/CMakeLists.txt 2018-06-02 12:16:52 -0600
@@ -885,7 +885,8 @@
OPTION(ALSOFT_REQUIRE_MMDEVAPI "Require MMDevApi backend" OFF)
IF(HAVE_WINDOWS_H)
# Check MMSystem backend
- CHECK_INCLUDE_FILES("windows.h;mmsystem.h" HAVE_MMSYSTEM_H -D_WIN32_WINNT=0x0502)
+ set(CMAKE_REQUIRED_FLAGS "-D_WIN32_WINNT=0x0502")
+ CHECK_INCLUDE_FILES("windows.h;mmsystem.h" HAVE_MMSYSTEM_H)
IF(HAVE_MMSYSTEM_H)
CHECK_SHARED_FUNCTION_EXISTS(waveOutOpen "windows.h;mmsystem.h" winmm "" HAVE_LIBWINMM)
IF(HAVE_LIBWINMM)

View File

@@ -1,22 +0,0 @@
--- x264-snapshot-20180811-2245-stable\configure 2018-08-11 14:45:05 -0600
+++ external_x264\configure 2018-08-11 23:51:35 -0600
@@ -396,7 +396,7 @@
# list of all preprocessor HAVE values we can define
CONFIG_HAVE="MALLOC_H ALTIVEC ALTIVEC_H MMX ARMV6 ARMV6T2 NEON BEOSTHREAD POSIXTHREAD WIN32THREAD THREAD LOG2F SWSCALE \
LAVF FFMS GPAC AVS GPL VECTOREXT INTERLACED CPU_COUNT OPENCL THP LSMASH X86_INLINE_ASM AS_FUNC INTEL_DISPATCHER \
- MSA MMAP WINRT VSX ARM_INLINE_ASM STRTOK_R BITDEPTH8 BITDEPTH10"
+ MSA MMAP WINRT VSX ARM_INLINE_ASM BITDEPTH8 BITDEPTH10"
# parse options
@@ -1071,10 +1071,6 @@
define HAVE_LOG2F
fi
-if cc_check 'string.h' '' 'strtok_r(0, 0, 0);' ; then
- define HAVE_STRTOK_R
-fi
-
if [ "$SYS" != "WINDOWS" ] && cpp_check "sys/mman.h unistd.h" "" "defined(MAP_PRIVATE)"; then
define HAVE_MMAP
fi

View File

@@ -52,6 +52,7 @@ set(WITH_OPENVDB OFF CACHE BOOL "" FORCE)
set(WITH_QUADRIFLOW OFF CACHE BOOL "" FORCE)
set(WITH_SDL OFF CACHE BOOL "" FORCE)
set(WITH_TBB OFF CACHE BOOL "" FORCE)
set(WITH_USD OFF CACHE BOOL "" FORCE)
if(UNIX AND NOT APPLE)
set(WITH_GHOST_XDND OFF CACHE BOOL "" FORCE)

View File

@@ -190,7 +190,7 @@ if(MSVC_VERSION GREATER 1914 AND NOT MSVC_CLANG)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /JMC")
endif()
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} /SUBSYSTEM:CONSOLE /STACK:2097152 ")
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} /SUBSYSTEM:CONSOLE /STACK:2097152")
set(PLATFORM_LINKFLAGS_RELEASE "/NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib")
set(PLATFORM_LINKFLAGS_DEBUG "${PLATFORM_LINKFLAGS_DEBUG} /IGNORE:4099 /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcmtd.lib")

View File

@@ -1,2 +1,2 @@
Sphinx==1.8.5
sphinx_rtd_theme==0.4.3
Sphinx==3.0.3
sphinx_rtd_theme==0.5.0rc1

View File

@@ -1,3 +1,3 @@
#define MANTA_GIT_VERSION "commit b4a2742bd743e2913fba94dd35846042e2650212"
#define MANTA_GIT_VERSION "commit b61bf9efa7a1d8ca98635076a7e9f2c4dacb2914"

View File

@@ -469,6 +469,7 @@ template<class S> class ParticleSystem : public ParticleBase {
const int integrationMode,
const bool deleteInObstacle = true,
const bool stopInObstacle = true,
const bool skipNew = false,
const ParticleDataImpl<int> *ptype = NULL,
const int exclude = 0);
static PyObject *_W_9(PyObject *_self, PyObject *_linargs, PyObject *_kwds)
@@ -486,13 +487,20 @@ template<class S> class ParticleSystem : public ParticleBase {
const int integrationMode = _args.get<int>("integrationMode", 2, &_lock);
const bool deleteInObstacle = _args.getOpt<bool>("deleteInObstacle", 3, true, &_lock);
const bool stopInObstacle = _args.getOpt<bool>("stopInObstacle", 4, true, &_lock);
const bool skipNew = _args.getOpt<bool>("skipNew", 5, false, &_lock);
const ParticleDataImpl<int> *ptype = _args.getPtrOpt<ParticleDataImpl<int>>(
"ptype", 5, NULL, &_lock);
const int exclude = _args.getOpt<int>("exclude", 6, 0, &_lock);
"ptype", 6, NULL, &_lock);
const int exclude = _args.getOpt<int>("exclude", 7, 0, &_lock);
pbo->_args.copy(_args);
_retval = getPyNone();
pbo->advectInGrid(
flags, vel, integrationMode, deleteInObstacle, stopInObstacle, ptype, exclude);
pbo->advectInGrid(flags,
vel,
integrationMode,
deleteInObstacle,
stopInObstacle,
skipNew,
ptype,
exclude);
pbo->_args.check();
}
pbFinalizePlugin(pbo->getParent(), "ParticleSystem::advectInGrid", !noTiming);
@@ -1863,6 +1871,7 @@ template<class S> struct _GridAdvectKernel : public KernelBase {
const Real dt,
const bool deleteInObstacle,
const bool stopInObstacle,
const bool skipNew,
const ParticleDataImpl<int> *ptype,
const int exclude,
std::vector<Vec3> &u)
@@ -1873,6 +1882,7 @@ template<class S> struct _GridAdvectKernel : public KernelBase {
dt(dt),
deleteInObstacle(deleteInObstacle),
stopInObstacle(stopInObstacle),
skipNew(skipNew),
ptype(ptype),
exclude(exclude),
u(u)
@@ -1885,11 +1895,13 @@ template<class S> struct _GridAdvectKernel : public KernelBase {
const Real dt,
const bool deleteInObstacle,
const bool stopInObstacle,
const bool skipNew,
const ParticleDataImpl<int> *ptype,
const int exclude,
std::vector<Vec3> &u) const
{
if ((p[idx].flag & ParticleBase::PDELETE) || (ptype && ((*ptype)[idx] & exclude))) {
if ((p[idx].flag & ParticleBase::PDELETE) || (ptype && ((*ptype)[idx] & exclude)) ||
(skipNew && (p[idx].flag & ParticleBase::PNEW))) {
u[idx] = 0.;
return;
}
@@ -1910,7 +1922,7 @@ template<class S> struct _GridAdvectKernel : public KernelBase {
void operator()(const tbb::blocked_range<IndexInt> &__r) const
{
for (IndexInt idx = __r.begin(); idx != (IndexInt)__r.end(); idx++)
op(idx, p, vel, flags, dt, deleteInObstacle, stopInObstacle, ptype, exclude, u);
op(idx, p, vel, flags, dt, deleteInObstacle, stopInObstacle, skipNew, ptype, exclude, u);
}
void run()
{
@@ -1922,6 +1934,7 @@ template<class S> struct _GridAdvectKernel : public KernelBase {
const Real dt;
const bool deleteInObstacle;
const bool stopInObstacle;
const bool skipNew;
const ParticleDataImpl<int> *ptype;
const int exclude;
std::vector<Vec3> &u;
@@ -1933,6 +1946,7 @@ template<class S> struct GridAdvectKernel : public KernelBase {
const Real dt,
const bool deleteInObstacle,
const bool stopInObstacle,
const bool skipNew,
const ParticleDataImpl<int> *ptype,
const int exclude)
: KernelBase(p.size()),
@@ -1943,6 +1957,7 @@ template<class S> struct GridAdvectKernel : public KernelBase {
dt,
deleteInObstacle,
stopInObstacle,
skipNew,
ptype,
exclude,
u),
@@ -1952,6 +1967,7 @@ template<class S> struct GridAdvectKernel : public KernelBase {
dt(dt),
deleteInObstacle(deleteInObstacle),
stopInObstacle(stopInObstacle),
skipNew(skipNew),
ptype(ptype),
exclude(exclude),
u((size))
@@ -2001,16 +2017,21 @@ template<class S> struct GridAdvectKernel : public KernelBase {
return stopInObstacle;
}
typedef bool type5;
inline const ParticleDataImpl<int> *getArg6()
inline const bool &getArg6()
{
return skipNew;
}
typedef bool type6;
inline const ParticleDataImpl<int> *getArg7()
{
return ptype;
}
typedef ParticleDataImpl<int> type6;
inline const int &getArg7()
typedef ParticleDataImpl<int> type7;
inline const int &getArg8()
{
return exclude;
}
typedef int type7;
typedef int type8;
void runMessage()
{
debMsg("Executing kernel GridAdvectKernel ", 3);
@@ -2025,6 +2046,7 @@ template<class S> struct GridAdvectKernel : public KernelBase {
const Real dt;
const bool deleteInObstacle;
const bool stopInObstacle;
const bool skipNew;
const ParticleDataImpl<int> *ptype;
const int exclude;
std::vector<Vec3> u;
@@ -2195,6 +2217,7 @@ void ParticleSystem<S>::advectInGrid(const FlagGrid &flags,
const int integrationMode,
const bool deleteInObstacle,
const bool stopInObstacle,
const bool skipNew,
const ParticleDataImpl<int> *ptype,
const int exclude)
{
@@ -2208,8 +2231,15 @@ void ParticleSystem<S>::advectInGrid(const FlagGrid &flags,
}
// update positions
GridAdvectKernel<S> kernel(
mData, vel, flags, getParent()->getDt(), deleteInObstacle, stopInObstacle, ptype, exclude);
GridAdvectKernel<S> kernel(mData,
vel,
flags,
getParent()->getDt(),
deleteInObstacle,
stopInObstacle,
skipNew,
ptype,
exclude);
integratePointSet(kernel, integrationMode);
if (!deleteInObstacle) {
@@ -2438,15 +2468,15 @@ template<class S> void ParticleSystem<S>::compress()
//! insert buffered positions as new particles, update additional particle data
template<class S> void ParticleSystem<S>::insertBufferedParticles()
{
// clear new flag everywhere
for (IndexInt i = 0; i < (IndexInt)mData.size(); ++i)
mData[i].flag &= ~PNEW;
if (mNewBufferPos.size() == 0)
return;
IndexInt newCnt = mData.size();
resizeAll(newCnt + mNewBufferPos.size());
// clear new flag everywhere
for (IndexInt i = 0; i < (IndexInt)mData.size(); ++i)
mData[i].flag &= ~PNEW;
for (IndexInt i = 0; i < (IndexInt)mNewBufferPos.size(); ++i) {
int flag = (mNewBufferFlag.size() > 0) ? mNewBufferFlag[i] : 0;
// note, other fields are not initialized here...

View File

@@ -82,8 +82,8 @@ class CyclesRender(bpy.types.RenderEngine):
def render(self, depsgraph):
engine.render(self, depsgraph)
def bake(self, depsgraph, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result):
engine.bake(self, depsgraph, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result)
def bake(self, depsgraph, obj, pass_type, pass_filter, width, height):
engine.bake(self, depsgraph, obj, pass_type, pass_filter, width, height)
# viewport render
def view_update(self, context, depsgraph):

View File

@@ -168,11 +168,11 @@ def render(engine, depsgraph):
_cycles.render(engine.session, depsgraph.as_pointer())
def bake(engine, depsgraph, obj, pass_type, pass_filter, object_id, pixel_array, num_pixels, depth, result):
def bake(engine, depsgraph, obj, pass_type, pass_filter, width, height):
import _cycles
session = getattr(engine, "session", None)
if session is not None:
_cycles.bake(engine.session, depsgraph.as_pointer(), obj.as_pointer(), pass_type, pass_filter, object_id, pixel_array.as_pointer(), num_pixels, depth, result.as_pointer())
_cycles.bake(engine.session, depsgraph.as_pointer(), obj.as_pointer(), pass_type, pass_filter, width, height)
def reset(engine, data, depsgraph):

View File

@@ -1907,10 +1907,15 @@ class CYCLES_RENDER_PT_bake_selected_to_active(CyclesButtonsPanel, Panel):
col.prop(cbk, "use_cage", text="Cage")
if cbk.use_cage:
col.prop(cbk, "cage_extrusion", text="Extrusion")
col.prop(cbk, "cage_object", text="Cage Object")
col.prop(cbk, "cage_object")
col = layout.column()
col.prop(cbk, "cage_extrusion")
col.active = cbk.cage_object is None
else:
col.prop(cbk, "cage_extrusion", text="Ray Distance")
col.prop(cbk, "cage_extrusion", text="Extrusion")
col = layout.column()
col.prop(cbk, "max_ray_distance")
class CYCLES_RENDER_PT_bake_output(CyclesButtonsPanel, Panel):

View File

@@ -460,9 +460,12 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render,
sync_objects(b_depsgraph, b_v3d, 0.0f);
}
/* always sample these times for camera motion */
motion_times.insert(-1.0f);
motion_times.insert(1.0f);
/* Insert motion times from camera. Motion times from other objects
* have already been added in a sync_objects call. */
uint camera_motion_steps = object_motion_steps(b_cam, b_cam);
for (size_t step = 0; step < camera_motion_steps; step++) {
motion_times.insert(scene->camera->motion_time(step));
}
/* note iteration over motion_times set happens in sorted order */
foreach (float relative_time, motion_times) {
@@ -487,10 +490,8 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render,
b_engine.frame_set(frame, subframe);
python_thread_state_save(python_thread_state);
/* sync camera, only supports two times at the moment */
if (relative_time == -1.0f || relative_time == 1.0f) {
sync_camera_motion(b_render, b_cam, width, height, relative_time);
}
/* Syncs camera motion if relative_time is one of the camera's motion times. */
sync_camera_motion(b_render, b_cam, width, height, relative_time);
/* sync object */
sync_objects(b_depsgraph, b_v3d, relative_time);

View File

@@ -298,22 +298,18 @@ static PyObject *render_func(PyObject * /*self*/, PyObject *args)
static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
{
PyObject *pysession, *pydepsgraph, *pyobject;
PyObject *pypixel_array, *pyresult;
const char *pass_type;
int num_pixels, depth, object_id, pass_filter;
int pass_filter, width, height;
if (!PyArg_ParseTuple(args,
"OOOsiiOiiO",
"OOOsiii",
&pysession,
&pydepsgraph,
&pyobject,
&pass_type,
&pass_filter,
&object_id,
&pypixel_array,
&num_pixels,
&depth,
&pyresult))
&width,
&height))
return NULL;
BlenderSession *session = (BlenderSession *)PyLong_AsVoidPtr(pysession);
@@ -326,23 +322,9 @@ static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
RNA_id_pointer_create((ID *)PyLong_AsVoidPtr(pyobject), &objectptr);
BL::Object b_object(objectptr);
void *b_result = PyLong_AsVoidPtr(pyresult);
PointerRNA bakepixelptr;
RNA_pointer_create(NULL, &RNA_BakePixel, PyLong_AsVoidPtr(pypixel_array), &bakepixelptr);
BL::BakePixel b_bake_pixel(bakepixelptr);
python_thread_state_save(&session->python_thread_state);
session->bake(b_depsgraph,
b_object,
pass_type,
pass_filter,
object_id,
b_bake_pixel,
(size_t)num_pixels,
depth,
(float *)b_result);
session->bake(b_depsgraph, b_object, pass_type, pass_filter, width, height);
python_thread_state_restore(&session->python_thread_state);

View File

@@ -247,9 +247,7 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg
void BlenderSession::free_session()
{
if (sync)
delete sync;
delete sync;
delete session;
}
@@ -317,6 +315,7 @@ static void end_render_result(BL::RenderEngine &b_engine,
void BlenderSession::do_write_update_render_tile(RenderTile &rtile,
bool do_update_only,
bool do_read_only,
bool highlight)
{
int x = rtile.x - session->tile_manager.params.full_x;
@@ -342,7 +341,23 @@ void BlenderSession::do_write_update_render_tile(RenderTile &rtile,
BL::RenderLayer b_rlay = *b_single_rlay;
if (do_update_only) {
if (do_read_only) {
/* copy each pass */
BL::RenderLayer::passes_iterator b_iter;
for (b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) {
BL::RenderPass b_pass(*b_iter);
/* find matching pass type */
PassType pass_type = BlenderSync::get_pass_type(b_pass);
int components = b_pass.channels();
rtile.buffers->set_pass_rect(pass_type, components, (float *)b_pass.rect());
}
end_render_result(b_engine, b_rr, false, false, false);
}
else if (do_update_only) {
/* Sample would be zero at initial tile update, which is only needed
* to tag tile form blender side as IN PROGRESS for proper highlight
* no buffers should be sent to blender yet. For denoise we also
@@ -362,9 +377,14 @@ void BlenderSession::do_write_update_render_tile(RenderTile &rtile,
}
}
void BlenderSession::read_render_tile(RenderTile &rtile)
{
do_write_update_render_tile(rtile, false, true, false);
}
void BlenderSession::write_render_tile(RenderTile &rtile)
{
do_write_update_render_tile(rtile, false, false);
do_write_update_render_tile(rtile, false, false, false);
}
void BlenderSession::update_render_tile(RenderTile &rtile, bool highlight)
@@ -374,9 +394,9 @@ void BlenderSession::update_render_tile(RenderTile &rtile, bool highlight)
* would need to be investigated a bit further, but for now shall be fine
*/
if (!b_engine.is_preview())
do_write_update_render_tile(rtile, true, highlight);
do_write_update_render_tile(rtile, true, false, highlight);
else
do_write_update_render_tile(rtile, false, false);
do_write_update_render_tile(rtile, false, false, false);
}
static void add_cryptomatte_layer(BL::RenderResult &b_rr, string name, string manifest)
@@ -593,25 +613,6 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
#endif
}
static void populate_bake_data(BakeData *data,
const int object_id,
BL::BakePixel &pixel_array,
const int num_pixels)
{
BL::BakePixel bp = pixel_array;
int i;
for (i = 0; i < num_pixels; i++) {
if (bp.object_id() == object_id) {
data->set(i, bp.primitive_id(), bp.uv(), bp.du_dx(), bp.du_dy(), bp.dv_dx(), bp.dv_dy());
}
else {
data->set_null(i);
}
bp = bp.next();
}
}
static int bake_pass_filter_get(const int pass_filter)
{
int flag = BAKE_FILTER_NONE;
@@ -642,43 +643,26 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
BL::Object &b_object,
const string &pass_type,
const int pass_filter,
const int object_id,
BL::BakePixel &pixel_array,
const size_t num_pixels,
const int /*depth*/,
float result[])
const int bake_width,
const int bake_height)
{
b_depsgraph = b_depsgraph_;
ShaderEvalType shader_type = get_shader_type(pass_type);
/* Set baking flag in advance, so kernel loading can check if we need
* any baking capabilities.
*/
scene->bake_manager->set_baking(true);
/* ensure kernels are loaded before we do any scene updates */
session->load_kernels();
if (shader_type == SHADER_EVAL_UV) {
/* force UV to be available */
Pass::add(PASS_UV, scene->film->passes);
}
int bake_pass_filter = bake_pass_filter_get(pass_filter);
bake_pass_filter = BakeManager::shader_type_to_pass_filter(shader_type, bake_pass_filter);
/* force use_light_pass to be true if we bake more than just colors */
if (bake_pass_filter & ~BAKE_FILTER_COLOR) {
Pass::add(PASS_LIGHT, scene->film->passes);
}
/* Initialize bake manager, before we load the baking kernels. */
scene->bake_manager->set(scene, b_object.name(), shader_type, bake_pass_filter);
/* create device and update scene */
scene->film->tag_update(scene);
scene->integrator->tag_update(scene);
/* Passes are identified by name, so in order to return the combined pass we need to set the
* name. */
Pass::add(PASS_COMBINED, scene->film->passes, "Combined");
session->read_bake_tile_cb = function_bind(&BlenderSession::read_render_tile, this, _1);
session->write_render_tile_cb = function_bind(&BlenderSession::write_render_tile, this, _1);
if (!session->progress.get_cancel()) {
/* update scene */
/* Sync scene. */
BL::Object b_camera_override(b_engine.camera_override());
sync->sync_camera(b_render, b_camera_override, width, height, "");
sync->sync_data(
@@ -686,75 +670,43 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
builtin_images_load();
}
BakeData *bake_data = NULL;
/* Object might have been disabled for rendering or excluded in some
* other way, in that case Blender will report a warning afterwards. */
bool object_found = false;
foreach (Object *ob, scene->objects) {
if (ob->name == b_object.name()) {
object_found = true;
break;
}
}
if (!session->progress.get_cancel()) {
/* get buffer parameters */
if (object_found && !session->progress.get_cancel()) {
/* Get session and buffer parameters. */
SessionParams session_params = BlenderSync::get_session_params(
b_engine, b_userpref, b_scene, background);
BufferParams buffer_params = BlenderSync::get_buffer_params(
b_scene, b_render, b_v3d, b_rv3d, scene->camera, width, height);
session_params.progressive_refine = false;
scene->bake_manager->set_shader_limit((size_t)b_engine.tile_x(), (size_t)b_engine.tile_y());
BufferParams buffer_params;
buffer_params.width = bake_width;
buffer_params.height = bake_height;
buffer_params.passes = scene->film->passes;
/* set number of samples */
/* Update session. */
session->tile_manager.set_samples(session_params.samples);
session->reset(buffer_params, session_params.samples);
session->update_scene();
/* find object index. todo: is arbitrary - copied from mesh_displace.cpp */
size_t object_index = OBJECT_NONE;
int tri_offset = 0;
for (size_t i = 0; i < scene->objects.size(); i++) {
const Object *object = scene->objects[i];
const Geometry *geom = object->geometry;
if (object->name == b_object.name() && geom->type == Geometry::MESH) {
const Mesh *mesh = static_cast<const Mesh *>(geom);
object_index = i;
tri_offset = mesh->prim_offset;
break;
}
}
/* Object might have been disabled for rendering or excluded in some
* other way, in that case Blender will report a warning afterwards. */
if (object_index != OBJECT_NONE) {
int object = object_index;
bake_data = scene->bake_manager->init(object, tri_offset, num_pixels);
populate_bake_data(bake_data, object_id, pixel_array, num_pixels);
}
/* set number of samples */
session->tile_manager.set_samples(session_params.samples);
session->reset(buffer_params, session_params.samples);
session->update_scene();
session->progress.set_update_callback(
function_bind(&BlenderSession::update_bake_progress, this));
}
/* Perform bake. Check cancel to avoid crash with incomplete scene data. */
if (!session->progress.get_cancel() && bake_data) {
scene->bake_manager->bake(scene->device,
&scene->dscene,
scene,
session->progress,
shader_type,
bake_pass_filter,
bake_data,
result);
if (object_found && !session->progress.get_cancel()) {
session->start();
session->wait();
}
/* free all memory used (host and device), so we wouldn't leave render
* engine with extra memory allocated
*/
session->device_free();
delete sync;
sync = NULL;
session->read_bake_tile_cb = function_null;
session->write_render_tile_cb = function_null;
}
void BlenderSession::do_write_update_render_result(BL::RenderLayer &b_rlay,

View File

@@ -66,14 +66,12 @@ class BlenderSession {
BL::Object &b_object,
const string &pass_type,
const int custom_flag,
const int object_id,
BL::BakePixel &pixel_array,
const size_t num_pixels,
const int depth,
float pixels[]);
const int bake_width,
const int bake_height);
void write_render_result(BL::RenderLayer &b_rlay, RenderTile &rtile);
void write_render_tile(RenderTile &rtile);
void read_render_tile(RenderTile &rtile);
/* update functions are used to update display buffer only after sample was rendered
* only needed for better visual feedback */
@@ -155,7 +153,10 @@ class BlenderSession {
void do_write_update_render_result(BL::RenderLayer &b_rlay,
RenderTile &rtile,
bool do_update_only);
void do_write_update_render_tile(RenderTile &rtile, bool do_update_only, bool highlight);
void do_write_update_render_tile(RenderTile &rtile,
bool do_update_only,
bool do_read_only,
bool highlight);
void builtin_images_load();

View File

@@ -384,16 +384,16 @@ static ShaderNode *add_node(Scene *scene,
switch (b_aniso_node.distribution()) {
case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN:
aniso->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID;
aniso->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ID;
break;
case BL::ShaderNodeBsdfAnisotropic::distribution_GGX:
aniso->distribution = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID;
aniso->distribution = CLOSURE_BSDF_MICROFACET_GGX_ID;
break;
case BL::ShaderNodeBsdfAnisotropic::distribution_MULTI_GGX:
aniso->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID;
aniso->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
break;
case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY:
aniso->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID;
aniso->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID;
break;
}
@@ -1231,12 +1231,11 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
Shader *shader;
/* test if we need to sync */
if (shader_map.add_or_update(&shader, b_mat) || shader->need_sync_object || update_all) {
if (shader_map.add_or_update(&shader, b_mat) || update_all) {
ShaderGraph *graph = new ShaderGraph();
shader->name = b_mat.name().c_str();
shader->pass_id = b_mat.pass_index();
shader->need_sync_object = false;
/* create nodes */
if (b_mat.use_nodes() && b_mat.node_tree()) {

View File

@@ -85,8 +85,6 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
/* Sync recalc flags from blender to cycles. Actual update is done separate,
* so we can do it later on if doing it immediate is not suitable. */
bool has_updated_objects = b_depsgraph.id_type_updated(BL::DriverTarget::id_type_OBJECT);
if (experimental) {
/* Mark all meshes as needing to be exported again if dicing changed. */
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
@@ -189,19 +187,6 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
if (viewport_parameters.modified(new_viewport_parameters)) {
world_recalc = true;
}
/* Updates shader with object dependency if objects changed. */
if (has_updated_objects) {
if (scene->default_background->has_object_dependency) {
world_recalc = true;
}
foreach (Shader *shader, scene->shaders) {
if (shader->has_object_dependency) {
shader->need_sync_object = true;
}
}
}
}
void BlenderSync::sync_data(BL::RenderSettings &b_render,
@@ -496,6 +481,9 @@ PassType BlenderSync::get_pass_type(BL::RenderPass &b_pass)
MAP_PASS("AO", PASS_AO);
MAP_PASS("Shadow", PASS_SHADOW);
MAP_PASS("BakePrimitive", PASS_BAKE_PRIMITIVE);
MAP_PASS("BakeDifferential", PASS_BAKE_DIFFERENTIAL);
#ifdef __KERNEL_DEBUG__
MAP_PASS("Debug BVH Traversed Nodes", PASS_BVH_TRAVERSED_NODES);
MAP_PASS("Debug BVH Traversed Instances", PASS_BVH_TRAVERSED_INSTANCES);

View File

@@ -34,15 +34,13 @@ CCL_NAMESPACE_BEGIN
/* TODO: verify this is not loading unnecessary attributes. */
class BlenderSmokeLoader : public ImageLoader {
public:
BlenderSmokeLoader(const BL::Object &b_ob, AttributeStandard attribute)
: b_ob(b_ob), attribute(attribute)
BlenderSmokeLoader(BL::Object &b_ob, AttributeStandard attribute)
: b_domain(object_fluid_gas_domain_find(b_ob)), b_mesh(b_ob.data()), attribute(attribute)
{
}
bool load_metadata(ImageMetaData &metadata) override
{
BL::FluidDomainSettings b_domain = object_fluid_gas_domain_find(b_ob);
if (!b_domain) {
return false;
}
@@ -79,7 +77,6 @@ class BlenderSmokeLoader : public ImageLoader {
/* Create a matrix to transform from object space to mesh texture space.
* This does not work with deformations but that can probably only be done
* well with a volume grid mapping of coordinates. */
BL::Mesh b_mesh(b_ob.data());
float3 loc, size;
mesh_texture_space(b_mesh, loc, size);
metadata.transform_3d = transform_translate(-loc) * transform_scale(size);
@@ -90,9 +87,6 @@ class BlenderSmokeLoader : public ImageLoader {
bool load_pixels(const ImageMetaData &, void *pixels, const size_t, const bool) override
{
/* smoke volume data */
BL::FluidDomainSettings b_domain = object_fluid_gas_domain_find(b_ob);
if (!b_domain) {
return false;
}
@@ -179,10 +173,11 @@ class BlenderSmokeLoader : public ImageLoader {
bool equals(const ImageLoader &other) const override
{
const BlenderSmokeLoader &other_loader = (const BlenderSmokeLoader &)other;
return b_ob == other_loader.b_ob && attribute == other_loader.attribute;
return b_domain == other_loader.b_domain && attribute == other_loader.attribute;
}
BL::Object b_ob;
BL::FluidDomainSettings b_domain;
BL::Mesh b_mesh;
AttributeStandard attribute;
};

View File

@@ -223,7 +223,7 @@ class CUDADevice : public Device {
CUdeviceptr d_wtile,
CUstream stream = 0);
void path_trace(DeviceTask &task, RenderTile &rtile, device_vector<WorkTile> &work_tiles);
void render(DeviceTask &task, RenderTile &rtile, device_vector<WorkTile> &work_tiles);
void film_convert(DeviceTask &task,
device_ptr buffer,

View File

@@ -586,20 +586,23 @@ void CUDADevice::reserve_local_memory(const DeviceRequestedFeatures &requested_f
cuMemGetInfo(&free_before, &total);
/* Get kernel function. */
CUfunction cuPathTrace;
CUfunction cuRender;
if (requested_features.use_integrator_branched) {
cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_branched_path_trace"));
if (requested_features.use_baking) {
cuda_assert(cuModuleGetFunction(&cuRender, cuModule, "kernel_cuda_bake"));
}
else if (requested_features.use_integrator_branched) {
cuda_assert(cuModuleGetFunction(&cuRender, cuModule, "kernel_cuda_branched_path_trace"));
}
else {
cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_path_trace"));
cuda_assert(cuModuleGetFunction(&cuRender, cuModule, "kernel_cuda_path_trace"));
}
cuda_assert(cuFuncSetCacheConfig(cuPathTrace, CU_FUNC_CACHE_PREFER_L1));
cuda_assert(cuFuncSetCacheConfig(cuRender, CU_FUNC_CACHE_PREFER_L1));
int min_blocks, num_threads_per_block;
cuda_assert(cuOccupancyMaxPotentialBlockSize(
&min_blocks, &num_threads_per_block, cuPathTrace, NULL, 0, 0));
cuda_assert(
cuOccupancyMaxPotentialBlockSize(&min_blocks, &num_threads_per_block, cuRender, NULL, 0, 0));
/* Launch kernel, using just 1 block appears sufficient to reserve
* memory for all multiprocessors. It would be good to do this in
@@ -609,7 +612,7 @@ void CUDADevice::reserve_local_memory(const DeviceRequestedFeatures &requested_f
void *args[] = {&d_work_tiles, &total_work_size};
cuda_assert(cuLaunchKernel(cuPathTrace, 1, 1, 1, num_threads_per_block, 1, 1, 0, 0, args, 0));
cuda_assert(cuLaunchKernel(cuRender, 1, 1, 1, num_threads_per_block, 1, 1, 0, 0, args, 0));
cuda_assert(cuCtxSynchronize());
@@ -1780,9 +1783,7 @@ void CUDADevice::adaptive_sampling_post(RenderTile &rtile,
0));
}
void CUDADevice::path_trace(DeviceTask &task,
RenderTile &rtile,
device_vector<WorkTile> &work_tiles)
void CUDADevice::render(DeviceTask &task, RenderTile &rtile, device_vector<WorkTile> &work_tiles)
{
scoped_timer timer(&rtile.buffers->render_time);
@@ -1790,21 +1791,24 @@ void CUDADevice::path_trace(DeviceTask &task,
return;
CUDAContextScope scope(this);
CUfunction cuPathTrace;
CUfunction cuRender;
/* Get kernel function. */
if (task.integrator_branched) {
cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_branched_path_trace"));
if (rtile.task == RenderTile::BAKE) {
cuda_assert(cuModuleGetFunction(&cuRender, cuModule, "kernel_cuda_bake"));
}
else if (task.integrator_branched) {
cuda_assert(cuModuleGetFunction(&cuRender, cuModule, "kernel_cuda_branched_path_trace"));
}
else {
cuda_assert(cuModuleGetFunction(&cuPathTrace, cuModule, "kernel_cuda_path_trace"));
cuda_assert(cuModuleGetFunction(&cuRender, cuModule, "kernel_cuda_path_trace"));
}
if (have_error()) {
return;
}
cuda_assert(cuFuncSetCacheConfig(cuPathTrace, CU_FUNC_CACHE_PREFER_L1));
cuda_assert(cuFuncSetCacheConfig(cuRender, CU_FUNC_CACHE_PREFER_L1));
/* Allocate work tile. */
work_tiles.alloc(1);
@@ -1822,8 +1826,8 @@ void CUDADevice::path_trace(DeviceTask &task,
* remain conservative for GPUs connected to a display to avoid driver
* timeouts and display freezing. */
int min_blocks, num_threads_per_block;
cuda_assert(cuOccupancyMaxPotentialBlockSize(
&min_blocks, &num_threads_per_block, cuPathTrace, NULL, 0, 0));
cuda_assert(
cuOccupancyMaxPotentialBlockSize(&min_blocks, &num_threads_per_block, cuRender, NULL, 0, 0));
if (!info.display_device) {
min_blocks *= 8;
}
@@ -1851,7 +1855,7 @@ void CUDADevice::path_trace(DeviceTask &task,
void *args[] = {&d_work_tiles, &total_work_size};
cuda_assert(
cuLaunchKernel(cuPathTrace, num_blocks, 1, 1, num_threads_per_block, 1, 1, 0, 0, args, 0));
cuLaunchKernel(cuRender, num_blocks, 1, 1, num_threads_per_block, 1, 1, 0, 0, args, 0));
/* Run the adaptive sampling kernels at selected samples aligned to step samples. */
uint filter_sample = sample + wtile->num_samples - 1;
@@ -1957,10 +1961,7 @@ void CUDADevice::shader(DeviceTask &task)
CUdeviceptr d_output = (CUdeviceptr)task.shader_output;
/* get kernel function */
if (task.shader_eval_type >= SHADER_EVAL_BAKE) {
cuda_assert(cuModuleGetFunction(&cuShader, cuModule, "kernel_cuda_bake"));
}
else if (task.shader_eval_type == SHADER_EVAL_DISPLACE) {
if (task.shader_eval_type == SHADER_EVAL_DISPLACE) {
cuda_assert(cuModuleGetFunction(&cuShader, cuModule, "kernel_cuda_displace"));
}
else {
@@ -2297,9 +2298,12 @@ void CUDADevice::thread_run(DeviceTask *task)
split_kernel->path_trace(task, tile, void_buffer, void_buffer);
}
else {
path_trace(*task, tile, work_tiles);
render(*task, tile, work_tiles);
}
}
else if (tile.task == RenderTile::BAKE) {
render(*task, tile, work_tiles);
}
else if (tile.task == RenderTile::DENOISE) {
tile.sample = tile.start_sample + tile.num_samples;

View File

@@ -188,6 +188,7 @@ class CPUDevice : public Device {
convert_to_byte_kernel;
KernelFunctions<void (*)(KernelGlobals *, uint4 *, float4 *, int, int, int, int, int)>
shader_kernel;
KernelFunctions<void (*)(KernelGlobals *, float *, int, int, int, int, int)> bake_kernel;
KernelFunctions<void (*)(
int, TileInfo *, int, int, float *, float *, float *, float *, float *, int *, int, int)>
@@ -270,6 +271,7 @@ class CPUDevice : public Device {
REGISTER_KERNEL(convert_to_half_float),
REGISTER_KERNEL(convert_to_byte),
REGISTER_KERNEL(shader),
REGISTER_KERNEL(bake),
REGISTER_KERNEL(filter_divide_shadow),
REGISTER_KERNEL(filter_get_feature),
REGISTER_KERNEL(filter_write_feature),
@@ -895,7 +897,7 @@ class CPUDevice : public Device {
}
}
void path_trace(DeviceTask &task, RenderTile &tile, KernelGlobals *kg)
void render(DeviceTask &task, RenderTile &tile, KernelGlobals *kg)
{
const bool use_coverage = kernel_data.film.cryptomatte_passes & CRYPT_ACCURATE;
@@ -919,12 +921,21 @@ class CPUDevice : public Device {
break;
}
for (int y = tile.y; y < tile.y + tile.h; y++) {
for (int x = tile.x; x < tile.x + tile.w; x++) {
if (use_coverage) {
coverage.init_pixel(x, y);
if (tile.task == RenderTile::PATH_TRACE) {
for (int y = tile.y; y < tile.y + tile.h; y++) {
for (int x = tile.x; x < tile.x + tile.w; x++) {
if (use_coverage) {
coverage.init_pixel(x, y);
}
path_trace_kernel()(kg, render_buffer, sample, x, y, tile.offset, tile.stride);
}
}
}
else {
for (int y = tile.y; y < tile.y + tile.h; y++) {
for (int x = tile.x; x < tile.x + tile.w; x++) {
bake_kernel()(kg, render_buffer, sample, x, y, tile.offset, tile.stride);
}
path_trace_kernel()(kg, render_buffer, sample, x, y, tile.offset, tile.stride);
}
}
tile.sample = sample + 1;
@@ -1019,9 +1030,12 @@ class CPUDevice : public Device {
split_kernel->path_trace(&task, tile, kgbuffer, void_buffer);
}
else {
path_trace(task, tile, kg);
render(task, tile, kg);
}
}
else if (tile.task == RenderTile::BAKE) {
render(task, tile, kg);
}
else if (tile.task == RenderTile::DENOISE) {
denoise(denoising, tile);
task.update_progress(&tile, tile.w * tile.h);

View File

@@ -451,6 +451,7 @@ class OpenCLDevice : public Device {
device_ptr rgba_half);
void shader(DeviceTask &task);
void update_adaptive(DeviceTask &task, RenderTile &tile, int sample);
void bake(DeviceTask &task, RenderTile &tile);
void denoise(RenderTile &tile, DenoisingTask &denoising);

View File

@@ -1367,6 +1367,9 @@ void OpenCLDevice::thread_run(DeviceTask *task)
*/
clFinish(cqCommandQueue);
}
else if (tile.task == RenderTile::BAKE) {
bake(*task, tile);
}
else if (tile.task == RenderTile::DENOISE) {
tile.sample = tile.start_sample + tile.num_samples;
denoise(tile, denoising);
@@ -1858,10 +1861,7 @@ void OpenCLDevice::shader(DeviceTask &task)
cl_int d_offset = task.offset;
OpenCLDevice::OpenCLProgram *program = &background_program;
if (task.shader_eval_type >= SHADER_EVAL_BAKE) {
program = &bake_program;
}
else if (task.shader_eval_type == SHADER_EVAL_DISPLACE) {
if (task.shader_eval_type == SHADER_EVAL_DISPLACE) {
program = &displace_program;
}
program->wait_for_availability();
@@ -1892,6 +1892,51 @@ void OpenCLDevice::shader(DeviceTask &task)
}
}
void OpenCLDevice::bake(DeviceTask &task, RenderTile &rtile)
{
scoped_timer timer(&rtile.buffers->render_time);
/* Cast arguments to cl types. */
cl_mem d_data = CL_MEM_PTR(const_mem_map["__data"]->device_pointer);
cl_mem d_buffer = CL_MEM_PTR(rtile.buffer);
cl_int d_x = rtile.x;
cl_int d_y = rtile.y;
cl_int d_w = rtile.w;
cl_int d_h = rtile.h;
cl_int d_offset = rtile.offset;
cl_int d_stride = rtile.stride;
bake_program.wait_for_availability();
cl_kernel kernel = bake_program();
cl_uint start_arg_index = kernel_set_args(kernel, 0, d_data, d_buffer);
set_kernel_arg_buffers(kernel, &start_arg_index);
start_arg_index += kernel_set_args(
kernel, start_arg_index, d_x, d_y, d_w, d_h, d_offset, d_stride);
int start_sample = rtile.start_sample;
int end_sample = rtile.start_sample + rtile.num_samples;
for (int sample = start_sample; sample < end_sample; sample++) {
if (task.get_cancel()) {
if (task.need_finish_queue == false)
break;
}
kernel_set_args(kernel, start_arg_index, sample);
enqueue_kernel(kernel, d_w, d_h);
rtile.sample = sample + 1;
task.update_progress(&rtile, rtile.w * rtile.h);
}
clFinish(cqCommandQueue);
}
string OpenCLDevice::kernel_build_options(const string *debug_src)
{
string build_options = "-cl-no-signed-zeros -cl-mad-enable ";

View File

@@ -229,8 +229,6 @@ ccl_device_inline int bsdf_sample(KernelGlobals *kg,
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
label = bsdf_microfacet_ggx_sample(kg,
sc,
@@ -281,7 +279,6 @@ ccl_device_inline int bsdf_sample(KernelGlobals *kg,
&sd->lcg_state);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
label = bsdf_microfacet_beckmann_sample(kg,
sc,
@@ -298,7 +295,6 @@ ccl_device_inline int bsdf_sample(KernelGlobals *kg,
pdf);
break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
label = bsdf_ashikhmin_shirley_sample(sc,
sd->Ng,
sd->I,
@@ -504,8 +500,6 @@ ccl_device_inline
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf);
break;
@@ -519,12 +513,10 @@ ccl_device_inline
sc, sd->I, omega_in, pdf, &sd->lcg_state);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
eval = bsdf_ashikhmin_shirley_eval_reflect(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
@@ -595,8 +587,6 @@ ccl_device_inline
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf);
break;
@@ -610,12 +600,10 @@ ccl_device_inline
sc, sd->I, omega_in, pdf, &sd->lcg_state);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
eval = bsdf_ashikhmin_shirley_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
@@ -679,18 +667,14 @@ ccl_device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness)
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
bsdf_microfacet_ggx_blur(sc, roughness);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
bsdf_microfacet_beckmann_blur(sc, roughness);
break;
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
bsdf_ashikhmin_shirley_blur(sc, roughness);
break;
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
@@ -719,18 +703,14 @@ ccl_device bool bsdf_merge(ShaderClosure *a, ShaderClosure *b)
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID:
return bsdf_microfacet_merge(a, b);
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
return bsdf_ashikhmin_velvet_merge(a, b);

View File

@@ -32,20 +32,11 @@ Other than that, the implementation directly follows the paper.
CCL_NAMESPACE_BEGIN
ccl_device int bsdf_ashikhmin_shirley_setup(MicrofacetBsdf *bsdf)
{
bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
bsdf->alpha_y = bsdf->alpha_x;
bsdf->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID;
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_ashikhmin_shirley_aniso_setup(MicrofacetBsdf *bsdf)
{
bsdf->alpha_x = clamp(bsdf->alpha_x, 1e-4f, 1.0f);
bsdf->alpha_y = clamp(bsdf->alpha_y, 1e-4f, 1.0f);
bsdf->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID;
bsdf->type = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID;
return SD_BSDF | SD_BSDF_HAS_EVAL;
}

View File

@@ -256,9 +256,7 @@ ccl_device_forceinline float3 reflection_color(const MicrofacetBsdf *bsdf, float
{
float3 F = make_float3(1.0f, 1.0f, 1.0f);
bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID ||
bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID ||
bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID);
bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID);
if (use_fresnel) {
float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior);
@@ -311,19 +309,27 @@ ccl_device int bsdf_microfacet_ggx_setup(MicrofacetBsdf *bsdf)
bsdf->extra = NULL;
bsdf->alpha_x = saturate(bsdf->alpha_x);
bsdf->alpha_y = bsdf->alpha_x;
bsdf->alpha_y = saturate(bsdf->alpha_y);
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_ID;
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
/* Required to maintain OSL interface. */
ccl_device int bsdf_microfacet_ggx_isotropic_setup(MicrofacetBsdf *bsdf)
{
bsdf->alpha_y = bsdf->alpha_x;
return bsdf_microfacet_ggx_setup(bsdf);
}
ccl_device int bsdf_microfacet_ggx_fresnel_setup(MicrofacetBsdf *bsdf, const ShaderData *sd)
{
bsdf->extra->cspec0 = saturate3(bsdf->extra->cspec0);
bsdf->alpha_x = saturate(bsdf->alpha_x);
bsdf->alpha_y = bsdf->alpha_x;
bsdf->alpha_y = saturate(bsdf->alpha_y);
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID;
@@ -361,32 +367,6 @@ ccl_device bool bsdf_microfacet_merge(const ShaderClosure *a, const ShaderClosur
(bsdf_a->extra->clearcoat == bsdf_b->extra->clearcoat)));
}
ccl_device int bsdf_microfacet_ggx_aniso_setup(MicrofacetBsdf *bsdf)
{
bsdf->extra = NULL;
bsdf->alpha_x = saturate(bsdf->alpha_x);
bsdf->alpha_y = saturate(bsdf->alpha_y);
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID;
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_microfacet_ggx_aniso_fresnel_setup(MicrofacetBsdf *bsdf, const ShaderData *sd)
{
bsdf->extra->cspec0 = saturate3(bsdf->extra->cspec0);
bsdf->alpha_x = saturate(bsdf->alpha_x);
bsdf->alpha_y = saturate(bsdf->alpha_y);
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID;
bsdf_microfacet_fresnel_color(sd, bsdf);
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_microfacet_ggx_refraction_setup(MicrofacetBsdf *bsdf)
{
bsdf->extra = NULL;
@@ -636,8 +616,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg,
*eval = make_float3(1e6f, 1e6f, 1e6f);
bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID ||
bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID ||
bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID);
bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID);
/* if fresnel is used, calculate the color with reflection_color(...) */
if (use_fresnel) {
@@ -811,19 +790,18 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals *kg,
ccl_device int bsdf_microfacet_beckmann_setup(MicrofacetBsdf *bsdf)
{
bsdf->alpha_x = saturate(bsdf->alpha_x);
bsdf->alpha_y = bsdf->alpha_x;
bsdf->alpha_y = saturate(bsdf->alpha_y);
bsdf->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ID;
return SD_BSDF | SD_BSDF_HAS_EVAL;
}
ccl_device int bsdf_microfacet_beckmann_aniso_setup(MicrofacetBsdf *bsdf)
/* Required to maintain OSL interface. */
ccl_device int bsdf_microfacet_beckmann_isotropic_setup(MicrofacetBsdf *bsdf)
{
bsdf->alpha_x = saturate(bsdf->alpha_x);
bsdf->alpha_y = saturate(bsdf->alpha_y);
bsdf->alpha_y = bsdf->alpha_x;
bsdf->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID;
return SD_BSDF | SD_BSDF_HAS_EVAL;
return bsdf_microfacet_beckmann_setup(bsdf);
}
ccl_device int bsdf_microfacet_beckmann_refraction_setup(MicrofacetBsdf *bsdf)

View File

@@ -384,32 +384,10 @@ ccl_device int bsdf_microfacet_multi_ggx_common_setup(MicrofacetBsdf *bsdf)
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
}
ccl_device int bsdf_microfacet_multi_ggx_aniso_setup(MicrofacetBsdf *bsdf)
{
if (is_zero(bsdf->T))
bsdf->T = make_float3(1.0f, 0.0f, 0.0f);
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
return bsdf_microfacet_multi_ggx_common_setup(bsdf);
}
ccl_device int bsdf_microfacet_multi_ggx_aniso_fresnel_setup(MicrofacetBsdf *bsdf,
const ShaderData *sd)
{
if (is_zero(bsdf->T))
bsdf->T = make_float3(1.0f, 0.0f, 0.0f);
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID;
bsdf_microfacet_fresnel_color(sd, bsdf);
return bsdf_microfacet_multi_ggx_common_setup(bsdf);
}
ccl_device int bsdf_microfacet_multi_ggx_setup(MicrofacetBsdf *bsdf)
{
bsdf->alpha_y = bsdf->alpha_x;
if (is_zero(bsdf->T))
bsdf->T = make_float3(1.0f, 0.0f, 0.0f);
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID;
@@ -418,7 +396,8 @@ ccl_device int bsdf_microfacet_multi_ggx_setup(MicrofacetBsdf *bsdf)
ccl_device int bsdf_microfacet_multi_ggx_fresnel_setup(MicrofacetBsdf *bsdf, const ShaderData *sd)
{
bsdf->alpha_y = bsdf->alpha_x;
if (is_zero(bsdf->T))
bsdf->T = make_float3(1.0f, 0.0f, 0.0f);
bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID;

View File

@@ -18,19 +18,33 @@ CCL_NAMESPACE_BEGIN
#ifdef __BAKING__
ccl_device_inline void compute_light_pass(
ccl_device_noinline void compute_light_pass(
KernelGlobals *kg, ShaderData *sd, PathRadiance *L, uint rng_hash, int pass_filter, int sample)
{
kernel_assert(kernel_data.film.use_light_pass);
PathRadiance L_sample;
PathState state;
Ray ray;
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
/* emission and indirect shader data memory used by various functions */
ShaderData emission_sd, indirect_sd;
/* Emission and indirect shader data memory used by various functions. */
ShaderDataTinyStorage emission_sd_storage;
ShaderData *emission_sd = AS_SHADER_DATA(&emission_sd_storage);
ShaderData indirect_sd;
/* Init radiance. */
path_radiance_init(kg, L);
/* Init path state. */
PathState state;
path_state_init(kg, emission_sd, &state, rng_hash, sample, NULL);
/* Evaluate surface shader. */
shader_eval_surface(kg, sd, &state, NULL, state.flag);
/* TODO, disable more closures we don't need besides transparent */
shader_bsdf_disable_transparency(kg, sd);
/* Init ray. */
Ray ray;
ray.P = sd->P + sd->Ng;
ray.D = -sd->Ng;
ray.t = FLT_MAX;
@@ -38,18 +52,6 @@ ccl_device_inline void compute_light_pass(
ray.time = 0.5f;
# endif
/* init radiance */
path_radiance_init(kg, &L_sample);
/* init path state */
path_state_init(kg, &emission_sd, &state, rng_hash, sample, NULL);
/* evaluate surface shader */
shader_eval_surface(kg, sd, &state, NULL, state.flag);
/* TODO, disable more closures we don't need besides transparent */
shader_bsdf_disable_transparency(kg, sd);
# ifdef __BRANCHED_PATH__
if (!kernel_data.integrator.branched) {
/* regular path tracer */
@@ -57,14 +59,13 @@ ccl_device_inline void compute_light_pass(
/* sample ambient occlusion */
if (pass_filter & BAKE_FILTER_AO) {
kernel_path_ao(
kg, sd, &emission_sd, &L_sample, &state, throughput, shader_bsdf_alpha(kg, sd));
kernel_path_ao(kg, sd, emission_sd, L, &state, throughput, shader_bsdf_alpha(kg, sd));
}
/* sample emission */
if ((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & SD_EMISSION)) {
float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
path_radiance_accum_emission(kg, &L_sample, &state, throughput, emission);
path_radiance_accum_emission(kg, L, &state, throughput, emission);
}
bool is_sss_sample = false;
@@ -77,12 +78,10 @@ ccl_device_inline void compute_light_pass(
SubsurfaceIndirectRays ss_indirect;
kernel_path_subsurface_init_indirect(&ss_indirect);
if (kernel_path_subsurface_scatter(
kg, sd, &emission_sd, &L_sample, &state, &ray, &throughput, &ss_indirect)) {
kg, sd, emission_sd, L, &state, &ray, &throughput, &ss_indirect)) {
while (ss_indirect.num_rays) {
kernel_path_subsurface_setup_indirect(
kg, &ss_indirect, &state, &ray, &L_sample, &throughput);
kernel_path_indirect(
kg, &indirect_sd, &emission_sd, &ray, throughput, &state, &L_sample);
kernel_path_subsurface_setup_indirect(kg, &ss_indirect, &state, &ray, L, &throughput);
kernel_path_indirect(kg, &indirect_sd, emission_sd, &ray, throughput, &state, L);
}
is_sss_sample = true;
}
@@ -91,18 +90,18 @@ ccl_device_inline void compute_light_pass(
/* sample light and BSDF */
if (!is_sss_sample && (pass_filter & (BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT))) {
kernel_path_surface_connect_light(kg, sd, &emission_sd, throughput, &state, &L_sample);
kernel_path_surface_connect_light(kg, sd, emission_sd, throughput, &state, L);
if (kernel_path_surface_bounce(kg, sd, &throughput, &state, &L_sample.state, &ray)) {
if (kernel_path_surface_bounce(kg, sd, &throughput, &state, &L->state, &ray)) {
# ifdef __LAMP_MIS__
state.ray_t = 0.0f;
# endif
/* compute indirect light */
kernel_path_indirect(kg, &indirect_sd, &emission_sd, &ray, throughput, &state, &L_sample);
kernel_path_indirect(kg, &indirect_sd, emission_sd, &ray, throughput, &state, L);
/* sum and reset indirect light pass variables for the next samples */
path_radiance_sum_indirect(&L_sample);
path_radiance_reset_indirect(&L_sample);
path_radiance_sum_indirect(L);
path_radiance_reset_indirect(L);
}
}
# ifdef __BRANCHED_PATH__
@@ -112,13 +111,13 @@ ccl_device_inline void compute_light_pass(
/* sample ambient occlusion */
if (pass_filter & BAKE_FILTER_AO) {
kernel_branched_path_ao(kg, sd, &emission_sd, &L_sample, &state, throughput);
kernel_branched_path_ao(kg, sd, emission_sd, L, &state, throughput);
}
/* sample emission */
if ((pass_filter & BAKE_FILTER_EMISSION) && (sd->flag & SD_EMISSION)) {
float3 emission = indirect_primitive_emission(kg, sd, 0.0f, state.flag, state.ray_pdf);
path_radiance_accum_emission(kg, &L_sample, &state, throughput, emission);
path_radiance_accum_emission(kg, L, &state, throughput, emission);
}
# ifdef __SUBSURFACE__
@@ -127,7 +126,7 @@ ccl_device_inline void compute_light_pass(
/* When mixing BSSRDF and BSDF closures we should skip BSDF lighting
* if scattering was successful. */
kernel_branched_path_subsurface_scatter(
kg, sd, &indirect_sd, &emission_sd, &L_sample, &state, &ray, throughput);
kg, sd, &indirect_sd, emission_sd, L, &state, &ray, throughput);
}
# endif
@@ -138,19 +137,16 @@ ccl_device_inline void compute_light_pass(
if (kernel_data.integrator.use_direct_light) {
int all = kernel_data.integrator.sample_all_lights_direct;
kernel_branched_path_surface_connect_light(
kg, sd, &emission_sd, &state, throughput, 1.0f, &L_sample, all);
kg, sd, emission_sd, &state, throughput, 1.0f, L, all);
}
# endif
/* indirect light */
kernel_branched_path_surface_indirect_light(
kg, sd, &indirect_sd, &emission_sd, throughput, 1.0f, &state, &L_sample);
kg, sd, &indirect_sd, emission_sd, throughput, 1.0f, &state, L);
}
}
# endif
/* accumulate into master L */
path_radiance_accum_sample(L, &L_sample);
}
/* this helps with AA but it's not the real solution as it does not AA the geometry
@@ -225,41 +221,28 @@ ccl_device float3 kernel_bake_evaluate_direct_indirect(KernelGlobals *kg,
return out;
}
ccl_device void kernel_bake_evaluate(KernelGlobals *kg,
ccl_global uint4 *input,
ccl_global float4 *output,
ShaderEvalType type,
int pass_filter,
int i,
int offset,
int sample)
ccl_device void kernel_bake_evaluate(
KernelGlobals *kg, ccl_global float *buffer, int sample, int x, int y, int offset, int stride)
{
ShaderData sd;
PathState state = {0};
uint4 in = input[i * 2];
uint4 diff = input[i * 2 + 1];
/* Setup render buffers. */
const int index = offset + x + y * stride;
const int pass_stride = kernel_data.film.pass_stride;
buffer += index * pass_stride;
float3 out = make_float3(0.0f, 0.0f, 0.0f);
int object = in.x;
int prim = in.y;
ccl_global float *primitive = buffer + kernel_data.film.pass_bake_primitive;
ccl_global float *differential = buffer + kernel_data.film.pass_bake_differential;
ccl_global float *output = buffer + kernel_data.film.pass_combined;
int prim = __float_as_uint(primitive[1]);
if (prim == -1)
return;
float u = __uint_as_float(in.z);
float v = __uint_as_float(in.w);
float dudx = __uint_as_float(diff.x);
float dudy = __uint_as_float(diff.y);
float dvdx = __uint_as_float(diff.z);
float dvdy = __uint_as_float(diff.w);
prim += kernel_data.bake.tri_offset;
/* Random number generator. */
uint rng_hash = hash_uint2(x, y) ^ kernel_data.integrator.seed;
int num_samples = kernel_data.integrator.aa_samples;
/* random number generator */
uint rng_hash = cmj_hash(offset + i, kernel_data.integrator.seed);
float filter_x, filter_y;
if (sample == 0) {
filter_x = filter_y = 0.5f;
@@ -268,23 +251,29 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg,
path_rng_2D(kg, rng_hash, sample, num_samples, PRNG_FILTER_U, &filter_x, &filter_y);
}
/* subpixel u/v offset */
/* Barycentric UV with subpixel offset. */
float u = primitive[2];
float v = primitive[3];
float dudx = differential[0];
float dudy = differential[1];
float dvdx = differential[2];
float dvdy = differential[3];
if (sample > 0) {
u = bake_clamp_mirror_repeat(u + dudx * (filter_x - 0.5f) + dudy * (filter_y - 0.5f), 1.0f);
v = bake_clamp_mirror_repeat(v + dvdx * (filter_x - 0.5f) + dvdy * (filter_y - 0.5f),
1.0f - u);
}
/* triangle */
/* Shader data setup. */
int object = kernel_data.bake.object_index;
int shader;
float3 P, Ng;
triangle_point_normal(kg, object, prim, u, v, &P, &Ng, &shader);
/* light passes */
PathRadiance L;
path_radiance_init(kg, &L);
ShaderData sd;
shader_setup_from_sample(
kg,
&sd,
@@ -302,7 +291,7 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg,
LAMP_NONE);
sd.I = sd.N;
/* update differentials */
/* Setup differentials. */
sd.dP.dx = sd.dPdu * dudx + sd.dPdv * dvdx;
sd.dP.dy = sd.dPdu * dudy + sd.dPdv * dvdy;
sd.du.dx = dudx;
@@ -310,17 +299,24 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg,
sd.dv.dx = dvdx;
sd.dv.dy = dvdy;
/* set RNG state for shaders that use sampling */
/* Set RNG state for shaders that use sampling. */
PathState state = {0};
state.rng_hash = rng_hash;
state.rng_offset = 0;
state.sample = sample;
state.num_samples = num_samples;
state.min_ray_pdf = FLT_MAX;
/* light passes if we need more than color */
if (pass_filter & ~BAKE_FILTER_COLOR)
/* Light passes if we need more than color. */
PathRadiance L;
int pass_filter = kernel_data.bake.pass_filter;
if (kernel_data.bake.pass_filter & ~BAKE_FILTER_COLOR)
compute_light_pass(kg, &sd, &L, rng_hash, pass_filter, sample);
float3 out = make_float3(0.0f, 0.0f, 0.0f);
ShaderEvalType type = (ShaderEvalType)kernel_data.bake.type;
switch (type) {
/* data passes */
case SHADER_EVAL_NORMAL:
@@ -441,10 +437,8 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg,
}
/* write output */
const float output_fac = 1.0f / num_samples;
const float4 scaled_result = make_float4(out.x, out.y, out.z, 1.0f) * output_fac;
output[i] = (sample == 0) ? scaled_result : output[i] + scaled_result;
const float4 result = make_float4(out.x, out.y, out.z, 1.0f);
kernel_write_pass_float4(output, result);
}
#endif /* __BAKING__ */

View File

@@ -28,13 +28,13 @@ ccl_device float4 film_get_pass_result(KernelGlobals *kg,
int display_pass_components = kernel_data.film.display_pass_components;
if (display_pass_components == 4) {
ccl_global float4 *in = (ccl_global float4 *)(buffer + display_pass_stride +
index * kernel_data.film.pass_stride);
float4 in = *(ccl_global float4 *)(buffer + display_pass_stride +
index * kernel_data.film.pass_stride);
float alpha = use_display_sample_scale ?
(kernel_data.film.use_display_pass_alpha ? in->w : 1.0f / sample_scale) :
(kernel_data.film.use_display_pass_alpha ? in.w : 1.0f / sample_scale) :
1.0f;
pass_result = make_float4(in->x, in->y, in->z, alpha);
pass_result = make_float4(in.x, in.y, in.z, alpha);
int display_divide_pass_stride = kernel_data.film.display_divide_pass_stride;
if (display_divide_pass_stride != -1) {

View File

@@ -1041,11 +1041,19 @@ ccl_device_forceinline void triangle_light_sample(KernelGlobals *kg,
}
}
else {
/* compute random point in triangle */
randu = sqrtf(randu);
/* compute random point in triangle. From Eric Heitz's "A Low-Distortion Map Between Triangle
* and Square" */
float u = randu;
float v = randv;
if (v > u) {
u *= 0.5f;
v -= u;
}
else {
v *= 0.5f;
u -= v;
}
const float u = 1.0f - randu;
const float v = randv * randu;
const float t = 1.0f - u - v;
ls->P = u * V[0] + v * V[1] + t * V[2];
/* compute incoming direction, distance and pdf */

View File

@@ -395,6 +395,10 @@ typedef enum PassType {
PASS_VOLUME_INDIRECT,
/* No Scatter color since it's tricky to define what it would even mean. */
PASS_CATEGORY_LIGHT_END = 63,
PASS_BAKE_PRIMITIVE,
PASS_BAKE_DIFFERENTIAL,
PASS_CATEGORY_BAKE_END = 95
} PassType;
#define PASS_ANY (~0)
@@ -1248,6 +1252,10 @@ typedef struct KernelFilm {
float4 xyz_to_b;
float4 rgb_to_y;
int pass_bake_primitive;
int pass_bake_differential;
int pad;
#ifdef __KERNEL_DEBUG__
int pass_bvh_traversed_nodes;
int pass_bvh_traversed_instances;
@@ -1427,6 +1435,14 @@ typedef struct KernelTables {
} KernelTables;
static_assert_align(KernelTables, 16);
typedef struct KernelBake {
int object_index;
int tri_offset;
int type;
int pass_filter;
} KernelBake;
static_assert_align(KernelBake, 16);
typedef struct KernelData {
KernelCamera cam;
KernelFilm film;
@@ -1435,6 +1451,7 @@ typedef struct KernelData {
KernelBVH bvh;
KernelCurves curve;
KernelTables tables;
KernelBake bake;
} KernelData;
static_assert_align(KernelData, 16);

View File

@@ -46,6 +46,9 @@ void KERNEL_FUNCTION_FULL_NAME(shader)(KernelGlobals *kg,
int offset,
int sample);
void KERNEL_FUNCTION_FULL_NAME(bake)(
KernelGlobals *kg, float *buffer, int sample, int x, int y, int offset, int stride);
/* Split kernels */
void KERNEL_FUNCTION_FULL_NAME(data_init)(KernelGlobals *kg,

View File

@@ -132,6 +132,18 @@ void KERNEL_FUNCTION_FULL_NAME(convert_to_half_float)(KernelGlobals *kg,
# endif /* KERNEL_STUB */
}
/* Bake */
void KERNEL_FUNCTION_FULL_NAME(bake)(
KernelGlobals *kg, float *buffer, int sample, int x, int y, int offset, int stride)
{
# ifdef KERNEL_STUB
STUB_ASSERT(KERNEL_ARCH, bake);
# else
kernel_bake_evaluate(kg, buffer, sample, x, y, offset, stride);
# endif /* KERNEL_STUB */
}
/* Shader Evaluate */
void KERNEL_FUNCTION_FULL_NAME(shader)(KernelGlobals *kg,
@@ -146,12 +158,7 @@ void KERNEL_FUNCTION_FULL_NAME(shader)(KernelGlobals *kg,
# ifdef KERNEL_STUB
STUB_ASSERT(KERNEL_ARCH, shader);
# else
if (type >= SHADER_EVAL_BAKE) {
# ifdef __BAKING__
kernel_bake_evaluate(kg, input, output, (ShaderEvalType)type, filter, i, offset, sample);
# endif
}
else if (type == SHADER_EVAL_DISPLACE) {
if (type == SHADER_EVAL_DISPLACE) {
kernel_displace_evaluate(kg, input, output, i);
}
else {

View File

@@ -214,13 +214,16 @@ kernel_cuda_background(uint4 *input,
#ifdef __BAKING__
extern "C" __global__ void
CUDA_LAUNCH_BOUNDS(CUDA_THREADS_BLOCK_WIDTH, CUDA_KERNEL_MAX_REGISTERS)
kernel_cuda_bake(uint4 *input, float4 *output, int type, int filter, int sx, int sw, int offset, int sample)
kernel_cuda_bake(WorkTile *tile, uint total_work_size)
{
int x = sx + blockDim.x*blockIdx.x + threadIdx.x;
int work_index = ccl_global_id(0);
if(work_index < total_work_size) {
uint x, y, sample;
get_work_pixel(tile, work_index, &x, &y, &sample);
if(x < sx + sw) {
KernelGlobals kg;
kernel_bake_evaluate(&kg, input, output, (ShaderEvalType)type, filter, x, offset, sample);
kernel_bake_evaluate(&kg, tile->buffer, sample, x, y, tile->offset, tile->stride);
}
}
#endif

View File

@@ -100,14 +100,14 @@ CLOSURE_FLOAT3_PARAM(DiffuseClosure, params.N),
BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet)
BSDF_CLOSURE_CLASS_BEGIN(AshikhminShirley,
ashikhmin_shirley_aniso,
ashikhmin_shirley,
MicrofacetBsdf,
LABEL_GLOSSY | LABEL_REFLECT)
CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.N),
CLOSURE_FLOAT3_PARAM(AshikhminShirleyClosure, params.T),
CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_x),
CLOSURE_FLOAT_PARAM(AshikhminShirleyClosure, params.alpha_y),
BSDF_CLOSURE_CLASS_END(AshikhminShirley, ashikhmin_shirley_aniso)
BSDF_CLOSURE_CLASS_END(AshikhminShirley, ashikhmin_shirley)
BSDF_CLOSURE_CLASS_BEGIN(DiffuseToon, diffuse_toon, ToonBsdf, LABEL_DIFFUSE)
CLOSURE_FLOAT3_PARAM(DiffuseToonClosure, params.N),
@@ -121,42 +121,42 @@ CLOSURE_FLOAT3_PARAM(DiffuseClosure, params.N),
CLOSURE_FLOAT_PARAM(GlossyToonClosure, params.smooth),
BSDF_CLOSURE_CLASS_END(GlossyToon, glossy_toon)
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXIsotropic,
microfacet_ggx_isotropic,
MicrofacetBsdf,
LABEL_GLOSSY | LABEL_REFLECT)
CLOSURE_FLOAT3_PARAM(MicrofacetGGXIsotropicClosure, params.N),
CLOSURE_FLOAT_PARAM(MicrofacetGGXIsotropicClosure, params.alpha_x),
BSDF_CLOSURE_CLASS_END(MicrofacetGGXIsotropic, microfacet_ggx_isotropic)
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX,
microfacet_ggx,
MicrofacetBsdf,
LABEL_GLOSSY | LABEL_REFLECT)
CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, params.N),
CLOSURE_FLOAT3_PARAM(MicrofacetGGXClosure, params.T),
CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, params.alpha_x),
CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, params.alpha_y),
BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx)
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXAniso,
microfacet_ggx_aniso,
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannIsotropic,
microfacet_beckmann_isotropic,
MicrofacetBsdf,
LABEL_GLOSSY | LABEL_REFLECT)
CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, params.N),
CLOSURE_FLOAT3_PARAM(MicrofacetGGXAnisoClosure, params.T),
CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, params.alpha_x),
CLOSURE_FLOAT_PARAM(MicrofacetGGXAnisoClosure, params.alpha_y),
BSDF_CLOSURE_CLASS_END(MicrofacetGGXAniso, microfacet_ggx_aniso)
CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannIsotropicClosure, params.N),
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannIsotropicClosure, params.alpha_x),
BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannIsotropic, microfacet_beckmann_isotropic)
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann,
microfacet_beckmann,
MicrofacetBsdf,
LABEL_GLOSSY | LABEL_REFLECT)
CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, params.N),
CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannClosure, params.T),
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, params.alpha_x),
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, params.alpha_y),
BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann)
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannAniso,
microfacet_beckmann_aniso,
MicrofacetBsdf,
LABEL_GLOSSY | LABEL_REFLECT)
CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, params.N),
CLOSURE_FLOAT3_PARAM(MicrofacetBeckmannAnisoClosure, params.T),
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, params.alpha_x),
CLOSURE_FLOAT_PARAM(MicrofacetBeckmannAnisoClosure, params.alpha_y),
BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannAniso, microfacet_beckmann_aniso)
BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction,
microfacet_ggx_refraction,
MicrofacetBsdf,
@@ -362,13 +362,13 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
id++,
closure_bsdf_transparent_params(),
closure_bsdf_transparent_prepare);
register_closure(
ss, "microfacet_ggx", id++, bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare);
register_closure(ss,
"microfacet_ggx_aniso",
"microfacet_ggx",
id++,
bsdf_microfacet_ggx_aniso_params(),
bsdf_microfacet_ggx_aniso_prepare);
bsdf_microfacet_ggx_isotropic_params(),
bsdf_microfacet_ggx_isotropic_prepare);
register_closure(
ss, "microfacet_ggx_aniso", id++, bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare);
register_closure(ss,
"microfacet_ggx_refraction",
id++,
@@ -417,13 +417,13 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
register_closure(ss,
"microfacet_beckmann",
id++,
bsdf_microfacet_beckmann_params(),
bsdf_microfacet_beckmann_prepare);
bsdf_microfacet_beckmann_isotropic_params(),
bsdf_microfacet_beckmann_isotropic_prepare);
register_closure(ss,
"microfacet_beckmann_aniso",
id++,
bsdf_microfacet_beckmann_aniso_params(),
bsdf_microfacet_beckmann_aniso_prepare);
bsdf_microfacet_beckmann_params(),
bsdf_microfacet_beckmann_prepare);
register_closure(ss,
"microfacet_beckmann_refraction",
id++,
@@ -432,8 +432,8 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
register_closure(ss,
"ashikhmin_shirley",
id++,
bsdf_ashikhmin_shirley_aniso_params(),
bsdf_ashikhmin_shirley_aniso_prepare);
bsdf_ashikhmin_shirley_params(),
bsdf_ashikhmin_shirley_prepare);
register_closure(
ss, "ashikhmin_velvet", id++, bsdf_ashikhmin_velvet_params(), bsdf_ashikhmin_velvet_prepare);
register_closure(
@@ -582,7 +582,7 @@ class MicrofacetGGXAnisoFresnelClosure : public MicrofacetFresnelClosure {
return;
}
sd->flag |= bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf, sd);
sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
}
};
@@ -676,7 +676,7 @@ class MicrofacetMultiGGXAnisoClosure : public MicrofacetMultiClosure {
}
bsdf->ior = 0.0f;
sd->flag |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf);
sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
}
};
@@ -801,7 +801,7 @@ class MicrofacetMultiGGXAnisoFresnelClosure : public MicrofacetMultiFresnelClosu
return;
}
sd->flag |= bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf, sd);
sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd);
}
};

View File

@@ -320,9 +320,9 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg,
/* setup bsdf */
if (distribution == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID ||
roughness <= 0.075f) /* use single-scatter GGX */
sd->flag |= bsdf_microfacet_ggx_aniso_fresnel_setup(bsdf, sd);
sd->flag |= bsdf_microfacet_ggx_fresnel_setup(bsdf, sd);
else /* use multi-scatter GGX */
sd->flag |= bsdf_microfacet_multi_ggx_aniso_fresnel_setup(bsdf, sd);
sd->flag |= bsdf_microfacet_multi_ggx_fresnel_setup(bsdf, sd);
}
}
# ifdef __CAUSTICS_TRICKS__
@@ -515,12 +515,34 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg,
float roughness = sqr(param1);
bsdf->N = N;
bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
bsdf->alpha_x = roughness;
bsdf->alpha_y = roughness;
bsdf->ior = 0.0f;
bsdf->extra = NULL;
if (data_node.y == SVM_STACK_INVALID) {
bsdf->T = make_float3(0.0f, 0.0f, 0.0f);
bsdf->alpha_x = roughness;
bsdf->alpha_y = roughness;
}
else {
bsdf->T = stack_load_float3(stack, data_node.y);
/* rotate tangent */
float rotation = stack_load_float(stack, data_node.z);
if (rotation != 0.0f)
bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F);
/* compute roughness */
float anisotropy = clamp(param2, -0.99f, 0.99f);
if (anisotropy < 0.0f) {
bsdf->alpha_x = roughness / (1.0f + anisotropy);
bsdf->alpha_y = roughness * (1.0f + anisotropy);
}
else {
bsdf->alpha_x = roughness * (1.0f - anisotropy);
bsdf->alpha_y = roughness / (1.0f - anisotropy);
}
}
/* setup bsdf */
if (type == CLOSURE_BSDF_REFLECTION_ID)
sd->flag |= bsdf_reflection_setup(bsdf);
@@ -529,10 +551,10 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg,
else if (type == CLOSURE_BSDF_MICROFACET_GGX_ID)
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
else if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) {
kernel_assert(stack_valid(data_node.z));
kernel_assert(stack_valid(data_node.w));
bsdf->extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
if (bsdf->extra) {
bsdf->extra->color = stack_load_float3(stack, data_node.z);
bsdf->extra->color = stack_load_float3(stack, data_node.w);
bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
bsdf->extra->clearcoat = 0.0f;
sd->flag |= bsdf_microfacet_multi_ggx_setup(bsdf);
@@ -675,64 +697,6 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg,
sd->flag |= bsdf_microfacet_multi_ggx_glass_setup(bsdf);
break;
}
case CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID:
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID:
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID: {
#ifdef __CAUSTICS_TRICKS__
if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
break;
#endif
float3 weight = sd->svm_closure_weight * mix_weight;
MicrofacetBsdf *bsdf = (MicrofacetBsdf *)bsdf_alloc(sd, sizeof(MicrofacetBsdf), weight);
if (bsdf) {
bsdf->N = N;
bsdf->extra = NULL;
bsdf->T = stack_load_float3(stack, data_node.y);
/* rotate tangent */
float rotation = stack_load_float(stack, data_node.z);
if (rotation != 0.0f)
bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F);
/* compute roughness */
float roughness = sqr(param1);
float anisotropy = clamp(param2, -0.99f, 0.99f);
if (anisotropy < 0.0f) {
bsdf->alpha_x = roughness / (1.0f + anisotropy);
bsdf->alpha_y = roughness * (1.0f + anisotropy);
}
else {
bsdf->alpha_x = roughness * (1.0f - anisotropy);
bsdf->alpha_y = roughness / (1.0f - anisotropy);
}
bsdf->ior = 0.0f;
if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID) {
sd->flag |= bsdf_microfacet_beckmann_aniso_setup(bsdf);
}
else if (type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID) {
sd->flag |= bsdf_microfacet_ggx_aniso_setup(bsdf);
}
else if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID) {
kernel_assert(stack_valid(data_node.w));
bsdf->extra = (MicrofacetExtra *)closure_alloc_extra(sd, sizeof(MicrofacetExtra));
if (bsdf->extra) {
bsdf->extra->color = stack_load_float3(stack, data_node.w);
bsdf->extra->cspec0 = make_float3(0.0f, 0.0f, 0.0f);
bsdf->extra->clearcoat = 0.0f;
sd->flag |= bsdf_microfacet_multi_ggx_aniso_setup(bsdf);
}
}
else
sd->flag |= bsdf_ashikhmin_shirley_aniso_setup(bsdf);
}
break;
}
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: {
float3 weight = sd->svm_closure_weight * mix_weight;
VelvetBsdf *bsdf = (VelvetBsdf *)bsdf_alloc(sd, sizeof(VelvetBsdf), weight);

View File

@@ -539,12 +539,6 @@ typedef enum ClosureType {
CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID,
CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID,
CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID,
CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID,
CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID,
CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID,
CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_FRESNEL_ID,
CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID,
CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID,
CLOSURE_BSDF_ASHIKHMIN_VELVET_ID,
CLOSURE_BSDF_PHONG_RAMP_ID,
CLOSURE_BSDF_GLOSSY_TOON_ID,
@@ -605,10 +599,9 @@ typedef enum ClosureType {
#define CLOSURE_IS_BSDF_TRANSPARENT(type) (type == CLOSURE_BSDF_TRANSPARENT_ID)
#define CLOSURE_IS_BSDF_MULTISCATTER(type) \
(type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID || \
type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID || \
type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID)
#define CLOSURE_IS_BSDF_MICROFACET(type) \
((type >= CLOSURE_BSDF_MICROFACET_GGX_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID) || \
((type >= CLOSURE_BSDF_MICROFACET_GGX_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID) || \
(type >= CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID && \
type <= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) || \
(type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID))
@@ -616,8 +609,7 @@ typedef enum ClosureType {
(type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID || \
type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID || \
type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID || \
type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID || \
type == CLOSURE_BSDF_MICROFACET_GGX_ANISO_FRESNEL_ID)
type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID)
#define CLOSURE_IS_BSDF_OR_BSSRDF(type) (type <= CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID)
#define CLOSURE_IS_BSSRDF(type) \
(type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID)

View File

@@ -15,6 +15,7 @@
*/
#include "render/bake.h"
#include "render/buffers.h"
#include "render/integrator.h"
#include "render/mesh.h"
#include "render/object.h"
@@ -24,235 +25,13 @@
CCL_NAMESPACE_BEGIN
BakeData::BakeData(const int object, const size_t tri_offset, const size_t num_pixels)
: m_object(object), m_tri_offset(tri_offset), m_num_pixels(num_pixels)
{
m_primitive.resize(num_pixels);
m_u.resize(num_pixels);
m_v.resize(num_pixels);
m_dudx.resize(num_pixels);
m_dudy.resize(num_pixels);
m_dvdx.resize(num_pixels);
m_dvdy.resize(num_pixels);
}
BakeData::~BakeData()
{
m_primitive.clear();
m_u.clear();
m_v.clear();
m_dudx.clear();
m_dudy.clear();
m_dvdx.clear();
m_dvdy.clear();
}
void BakeData::set(int i, int prim, float uv[2], float dudx, float dudy, float dvdx, float dvdy)
{
m_primitive[i] = (prim == -1 ? -1 : m_tri_offset + prim);
m_u[i] = uv[0];
m_v[i] = uv[1];
m_dudx[i] = dudx;
m_dudy[i] = dudy;
m_dvdx[i] = dvdx;
m_dvdy[i] = dvdy;
}
void BakeData::set_null(int i)
{
m_primitive[i] = -1;
}
int BakeData::object()
{
return m_object;
}
size_t BakeData::size()
{
return m_num_pixels;
}
bool BakeData::is_valid(int i)
{
return m_primitive[i] != -1;
}
uint4 BakeData::data(int i)
{
return make_uint4(m_object, m_primitive[i], __float_as_int(m_u[i]), __float_as_int(m_v[i]));
}
uint4 BakeData::differentials(int i)
{
return make_uint4(__float_as_int(m_dudx[i]),
__float_as_int(m_dudy[i]),
__float_as_int(m_dvdx[i]),
__float_as_int(m_dvdy[i]));
}
BakeManager::BakeManager()
{
m_bake_data = NULL;
m_is_baking = false;
need_update = true;
m_shader_limit = 512 * 512;
}
BakeManager::~BakeManager()
{
if (m_bake_data)
delete m_bake_data;
}
bool BakeManager::get_baking()
{
return m_is_baking;
}
void BakeManager::set_baking(const bool value)
{
m_is_baking = value;
}
BakeData *BakeManager::init(const int object, const size_t tri_offset, const size_t num_pixels)
{
m_bake_data = new BakeData(object, tri_offset, num_pixels);
return m_bake_data;
}
void BakeManager::set_shader_limit(const size_t x, const size_t y)
{
m_shader_limit = x * y;
m_shader_limit = (size_t)pow(2, std::ceil(log(m_shader_limit) / log(2)));
}
bool BakeManager::bake(Device *device,
DeviceScene *dscene,
Scene *scene,
Progress &progress,
ShaderEvalType shader_type,
const int pass_filter,
BakeData *bake_data,
float result[])
{
size_t num_pixels = bake_data->size();
int num_samples = aa_samples(scene, bake_data, shader_type);
/* calculate the total pixel samples for the progress bar */
total_pixel_samples = 0;
for (size_t shader_offset = 0; shader_offset < num_pixels; shader_offset += m_shader_limit) {
size_t shader_size = (size_t)fminf(num_pixels - shader_offset, m_shader_limit);
total_pixel_samples += shader_size * num_samples;
}
progress.reset_sample();
progress.set_total_pixel_samples(total_pixel_samples);
/* needs to be up to date for baking specific AA samples */
dscene->data.integrator.aa_samples = num_samples;
device->const_copy_to("__data", &dscene->data, sizeof(dscene->data));
for (size_t shader_offset = 0; shader_offset < num_pixels; shader_offset += m_shader_limit) {
size_t shader_size = (size_t)fminf(num_pixels - shader_offset, m_shader_limit);
/* setup input for device task */
device_vector<uint4> d_input(device, "bake_input", MEM_READ_ONLY);
uint4 *d_input_data = d_input.alloc(shader_size * 2);
size_t d_input_size = 0;
for (size_t i = shader_offset; i < (shader_offset + shader_size); i++) {
d_input_data[d_input_size++] = bake_data->data(i);
d_input_data[d_input_size++] = bake_data->differentials(i);
}
if (d_input_size == 0) {
m_is_baking = false;
return false;
}
/* run device task */
device_vector<float4> d_output(device, "bake_output", MEM_READ_WRITE);
d_output.alloc(shader_size);
d_output.zero_to_device();
d_input.copy_to_device();
DeviceTask task(DeviceTask::SHADER);
task.shader_input = d_input.device_pointer;
task.shader_output = d_output.device_pointer;
task.shader_eval_type = shader_type;
task.shader_filter = pass_filter;
task.shader_x = 0;
task.offset = shader_offset;
task.shader_w = d_output.size();
task.num_samples = num_samples;
task.get_cancel = function_bind(&Progress::get_cancel, &progress);
task.update_progress_sample = function_bind(&Progress::add_samples_update, &progress, _1, _2);
device->task_add(task);
device->task_wait();
if (progress.get_cancel()) {
d_input.free();
d_output.free();
m_is_baking = false;
return false;
}
d_output.copy_from_device(0, 1, d_output.size());
d_input.free();
/* read result */
int k = 0;
float4 *offset = d_output.data();
size_t depth = 4;
for (size_t i = shader_offset; i < (shader_offset + shader_size); i++) {
size_t index = i * depth;
float4 out = offset[k++];
if (bake_data->is_valid(i)) {
for (size_t j = 0; j < 4; j++) {
result[index + j] = out[j];
}
}
}
d_output.free();
}
m_is_baking = false;
return true;
}
void BakeManager::device_update(Device * /*device*/,
DeviceScene * /*dscene*/,
Scene * /*scene*/,
Progress &progress)
{
if (!need_update)
return;
if (progress.get_cancel())
return;
need_update = false;
}
void BakeManager::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
{
}
int BakeManager::aa_samples(Scene *scene, BakeData *bake_data, ShaderEvalType type)
static int aa_samples(Scene *scene, Object *object, ShaderEvalType type)
{
if (type == SHADER_EVAL_UV || type == SHADER_EVAL_ROUGHNESS) {
return 1;
}
else if (type == SHADER_EVAL_NORMAL) {
/* Only antialias normal if mesh has bump mapping. */
Object *object = scene->objects[bake_data->object()];
if (object->geometry) {
foreach (Shader *shader, object->geometry->used_shaders) {
if (shader->has_bump) {
@@ -269,7 +48,7 @@ int BakeManager::aa_samples(Scene *scene, BakeData *bake_data, ShaderEvalType ty
}
/* Keep it synced with kernel_bake.h logic */
int BakeManager::shader_type_to_pass_filter(ShaderEvalType type, const int pass_filter)
static int shader_type_to_pass_filter(ShaderEvalType type, int pass_filter)
{
const int component_flags = pass_filter &
(BAKE_FILTER_DIRECT | BAKE_FILTER_INDIRECT | BAKE_FILTER_COLOR);
@@ -292,4 +71,84 @@ int BakeManager::shader_type_to_pass_filter(ShaderEvalType type, const int pass_
}
}
BakeManager::BakeManager()
{
type = SHADER_EVAL_BAKE;
pass_filter = 0;
need_update = true;
}
BakeManager::~BakeManager()
{
}
bool BakeManager::get_baking()
{
return !object_name.empty();
}
void BakeManager::set(Scene *scene,
const std::string &object_name_,
ShaderEvalType type_,
int pass_filter_)
{
object_name = object_name_;
type = type_;
pass_filter = shader_type_to_pass_filter(type_, pass_filter_);
Pass::add(PASS_BAKE_PRIMITIVE, scene->film->passes);
Pass::add(PASS_BAKE_DIFFERENTIAL, scene->film->passes);
if (type == SHADER_EVAL_UV) {
/* force UV to be available */
Pass::add(PASS_UV, scene->film->passes);
}
/* force use_light_pass to be true if we bake more than just colors */
if (pass_filter & ~BAKE_FILTER_COLOR) {
Pass::add(PASS_LIGHT, scene->film->passes);
}
/* create device and update scene */
scene->film->tag_update(scene);
scene->integrator->tag_update(scene);
need_update = true;
}
void BakeManager::device_update(Device * /*device*/,
DeviceScene *dscene,
Scene *scene,
Progress & /* progress */)
{
if (!need_update)
return;
KernelIntegrator *kintegrator = &dscene->data.integrator;
KernelBake *kbake = &dscene->data.bake;
kbake->type = type;
kbake->pass_filter = pass_filter;
int object_index = 0;
foreach (Object *object, scene->objects) {
const Geometry *geom = object->geometry;
if (object->name == object_name && geom->type == Geometry::MESH) {
kbake->object_index = object_index;
kbake->tri_offset = geom->prim_offset;
kintegrator->aa_samples = aa_samples(scene, object, type);
break;
}
object_index++;
}
need_update = false;
}
void BakeManager::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
{
}
CCL_NAMESPACE_END

View File

@@ -25,67 +25,23 @@
CCL_NAMESPACE_BEGIN
class BakeData {
public:
BakeData(const int object, const size_t tri_offset, const size_t num_pixels);
~BakeData();
void set(int i, int prim, float uv[2], float dudx, float dudy, float dvdx, float dvdy);
void set_null(int i);
int object();
size_t size();
uint4 data(int i);
uint4 differentials(int i);
bool is_valid(int i);
private:
int m_object;
size_t m_tri_offset;
size_t m_num_pixels;
vector<int> m_primitive;
vector<float> m_u;
vector<float> m_v;
vector<float> m_dudx;
vector<float> m_dudy;
vector<float> m_dvdx;
vector<float> m_dvdy;
};
class BakeManager {
public:
BakeManager();
~BakeManager();
void set(Scene *scene, const std::string &object_name, ShaderEvalType type, int pass_filter);
bool get_baking();
void set_baking(const bool value);
BakeData *init(const int object, const size_t tri_offset, const size_t num_pixels);
void set_shader_limit(const size_t x, const size_t y);
bool bake(Device *device,
DeviceScene *dscene,
Scene *scene,
Progress &progress,
ShaderEvalType shader_type,
const int pass_filter,
BakeData *bake_data,
float result[]);
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
void device_free(Device *device, DeviceScene *dscene);
static int shader_type_to_pass_filter(ShaderEvalType type, const int pass_filter);
static int aa_samples(Scene *scene, BakeData *bake_data, ShaderEvalType type);
bool need_update;
size_t total_pixel_samples;
private:
BakeData *m_bake_data;
bool m_is_baking;
size_t m_shader_limit;
ShaderEvalType type;
int pass_filter;
std::string object_name;
};
CCL_NAMESPACE_END

View File

@@ -459,6 +459,40 @@ bool RenderBuffers::get_pass_rect(
return false;
}
bool RenderBuffers::set_pass_rect(PassType type, int components, float *pixels)
{
if (buffer.data() == NULL) {
return false;
}
int pass_offset = 0;
for (size_t j = 0; j < params.passes.size(); j++) {
Pass &pass = params.passes[j];
if (pass.type != type) {
pass_offset += pass.components;
continue;
}
float *out = buffer.data() + pass_offset;
int pass_stride = params.get_passes_size();
int size = params.width * params.height;
assert(pass.components == components);
for (int i = 0; i < size; i++, out += pass_stride, pixels += components) {
for (int j = 0; j < components; j++) {
out[j] = pixels[j];
}
}
return true;
}
return false;
}
/* Display Buffer */
DisplayBuffer::DisplayBuffer(Device *device, bool linear)

View File

@@ -92,6 +92,7 @@ class RenderBuffers {
const string &name, float exposure, int sample, int components, float *pixels);
bool get_denoising_pass_rect(
int offset, float exposure, int sample, int components, float *pixels);
bool set_pass_rect(PassType type, int components, float *pixels);
};
/* Display Buffer
@@ -130,7 +131,7 @@ class DisplayBuffer {
class RenderTile {
public:
typedef enum { PATH_TRACE = (1 << 0), DENOISE = (1 << 1) } Task;
typedef enum { PATH_TRACE = (1 << 0), BAKE = (1 << 1), DENOISE = (1 << 2) } Task;
Task task;
int x, y, w, h;

View File

@@ -196,6 +196,10 @@ void Pass::add(PassType type, vector<Pass> &passes, const char *name)
case PASS_AOV_VALUE:
pass.components = 1;
break;
case PASS_BAKE_PRIMITIVE:
case PASS_BAKE_DIFFERENTIAL:
pass.components = 4;
break;
default:
assert(false);
break;
@@ -386,11 +390,13 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
if (pass.type <= PASS_CATEGORY_MAIN_END) {
kfilm->pass_flag |= pass_flag;
}
else {
assert(pass.type <= PASS_CATEGORY_LIGHT_END);
else if (pass.type <= PASS_CATEGORY_LIGHT_END) {
kfilm->use_light_pass = 1;
kfilm->light_pass_flag |= pass_flag;
}
else {
assert(pass.type <= PASS_CATEGORY_BAKE_END);
}
switch (pass.type) {
case PASS_COMBINED:
@@ -471,6 +477,13 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
kfilm->pass_volume_direct = kfilm->pass_stride;
break;
case PASS_BAKE_PRIMITIVE:
kfilm->pass_bake_primitive = kfilm->pass_stride;
break;
case PASS_BAKE_DIFFERENTIAL:
kfilm->pass_bake_differential = kfilm->pass_stride;
break;
#ifdef WITH_CYCLES_DEBUG
case PASS_BVH_TRAVERSED_NODES:
kfilm->pass_bvh_traversed_nodes = kfilm->pass_stride;

View File

@@ -204,10 +204,6 @@ class ShaderNode : public Node {
{
return false;
}
virtual bool has_object_dependency()
{
return false;
}
virtual bool has_attribute_dependency()
{
return false;

View File

@@ -181,6 +181,7 @@ bool Light::has_contribution(Scene *scene)
LightManager::LightManager()
{
need_update = true;
need_update_background = true;
use_light_visibility = false;
}
@@ -901,7 +902,7 @@ void LightManager::device_update(Device *device,
VLOG(1) << "Total " << scene->lights.size() << " lights.";
device_free(device, dscene);
device_free(device, dscene, need_update_background);
use_light_visibility = false;
@@ -915,9 +916,11 @@ void LightManager::device_update(Device *device,
if (progress.get_cancel())
return;
device_update_background(device, dscene, scene, progress);
if (progress.get_cancel())
return;
if (need_update_background) {
device_update_background(device, dscene, scene, progress);
if (progress.get_cancel())
return;
}
device_update_ies(dscene);
if (progress.get_cancel())
@@ -929,14 +932,17 @@ void LightManager::device_update(Device *device,
}
need_update = false;
need_update_background = false;
}
void LightManager::device_free(Device *, DeviceScene *dscene)
void LightManager::device_free(Device *, DeviceScene *dscene, const bool free_background)
{
dscene->light_distribution.free();
dscene->lights.free();
dscene->light_background_marginal_cdf.free();
dscene->light_background_conditional_cdf.free();
if (free_background) {
dscene->light_background_marginal_cdf.free();
dscene->light_background_conditional_cdf.free();
}
dscene->ies_lights.free();
}
@@ -989,6 +995,7 @@ int LightManager::add_ies(const string &content)
ies_slots[slot]->hash = hash;
need_update = true;
need_update_background = true;
return slot;
}
@@ -1007,6 +1014,7 @@ void LightManager::remove_ies(int slot)
/* If the slot has no more users, update the device to remove it. */
need_update |= (ies_slots[slot]->users == 0);
need_update_background |= need_update;
}
void LightManager::device_update_ies(DeviceScene *dscene)

View File

@@ -88,6 +88,9 @@ class LightManager {
bool use_light_visibility;
bool need_update;
/* Need to update background (including multiple importance map) */
bool need_update_background;
LightManager();
~LightManager();
@@ -97,7 +100,7 @@ class LightManager {
void remove_ies(int slot);
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
void device_free(Device *device, DeviceScene *dscene);
void device_free(Device *device, DeviceScene *dscene, const bool free_background = true);
void tag_update(Scene *scene);

View File

@@ -2166,12 +2166,11 @@ NODE_DEFINE(AnisotropicBsdfNode)
SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
static NodeEnum distribution_enum;
distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID);
distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID);
distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID);
distribution_enum.insert("ashikhmin_shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID);
SOCKET_ENUM(
distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID);
distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ID);
distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_ID);
distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
distribution_enum.insert("ashikhmin_shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID);
SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_ID);
SOCKET_IN_VECTOR(tangent, "Tangent", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TANGENT);
@@ -2186,7 +2185,7 @@ NODE_DEFINE(AnisotropicBsdfNode)
AnisotropicBsdfNode::AnisotropicBsdfNode() : BsdfNode(node_type)
{
closure = CLOSURE_BSDF_MICROFACET_GGX_ANISO_ID;
closure = CLOSURE_BSDF_MICROFACET_GGX_ID;
}
void AnisotropicBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes)
@@ -2205,7 +2204,7 @@ void AnisotropicBsdfNode::compile(SVMCompiler &compiler)
{
closure = distribution;
if (closure == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ANISO_ID)
if (closure == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID)
BsdfNode::compile(
compiler, input("Roughness"), input("Anisotropy"), input("Rotation"), input("Color"));
else
@@ -2299,7 +2298,7 @@ void GlossyBsdfNode::compile(SVMCompiler &compiler)
if (closure == CLOSURE_BSDF_REFLECTION_ID)
BsdfNode::compile(compiler, NULL, NULL);
else if (closure == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID)
BsdfNode::compile(compiler, input("Roughness"), NULL, input("Color"));
BsdfNode::compile(compiler, input("Roughness"), NULL, NULL, input("Color"));
else
BsdfNode::compile(compiler, input("Roughness"), NULL);
}

View File

@@ -359,10 +359,6 @@ class PointDensityTextureNode : public ShaderNode {
{
return true;
}
bool has_object_dependency()
{
return true;
}
/* Parameters. */
ustring filename;
@@ -896,10 +892,6 @@ class TextureCoordinateNode : public ShaderNode {
{
return true;
}
bool has_object_dependency()
{
return use_transform;
}
float3 normal_osl;
bool from_dupli;

View File

@@ -764,10 +764,6 @@ void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath)
current_shader->has_volume_attribute_dependency = true;
}
if (node->has_object_dependency()) {
current_shader->has_object_dependency = true;
}
if (node->has_integrator_dependency()) {
current_shader->has_integrator_dependency = true;
}
@@ -1142,7 +1138,6 @@ void OSLCompiler::compile(OSLGlobals *og, Shader *shader)
shader->has_surface_spatial_varying = false;
shader->has_volume_spatial_varying = false;
shader->has_volume_attribute_dependency = false;
shader->has_object_dependency = false;
shader->has_integrator_dependency = false;
/* generate surface shader */

View File

@@ -410,7 +410,16 @@ bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_typ
rtile.num_samples = tile_manager.state.num_samples;
rtile.resolution = tile_manager.state.resolution_divider;
rtile.tile_index = tile->index;
rtile.task = tile->state == Tile::DENOISE ? RenderTile::DENOISE : RenderTile::PATH_TRACE;
if (tile->state == Tile::DENOISE) {
rtile.task = RenderTile::DENOISE;
}
else if (read_bake_tile_cb) {
rtile.task = RenderTile::BAKE;
}
else {
rtile.task = RenderTile::PATH_TRACE;
}
tile_lock.unlock();
@@ -451,11 +460,20 @@ bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_typ
rtile.buffers = tile->buffers;
rtile.sample = tile_manager.state.sample;
/* this will tag tile as IN PROGRESS in blender-side render pipeline,
* which is needed to highlight currently rendering tile before first
* sample was processed for it
*/
update_tile_sample(rtile);
if (read_bake_tile_cb) {
/* This will read any passes needed as input for baking. */
{
thread_scoped_lock tile_lock(tile_mutex);
read_bake_tile_cb(rtile);
}
rtile.buffers->buffer.copy_to_device();
}
else {
/* This will tag tile as IN PROGRESS in blender-side render pipeline,
* which is needed to highlight currently rendering tile before first
* sample was processed for it. */
update_tile_sample(rtile);
}
return true;
}
@@ -484,6 +502,7 @@ void Session::release_tile(RenderTile &rtile, const bool need_denoise)
bool delete_tile;
if (tile_manager.finish_tile(rtile.tile_index, need_denoise, delete_tile)) {
/* Finished tile pixels write. */
if (write_render_tile_cb && params.progressive_refine == false) {
write_render_tile_cb(rtile);
}
@@ -494,6 +513,7 @@ void Session::release_tile(RenderTile &rtile, const bool need_denoise)
}
}
else {
/* In progress tile pixels update. */
if (update_render_tile_cb && params.progressive_refine == false) {
update_render_tile_cb(rtile, false);
}

View File

@@ -148,6 +148,7 @@ class Session {
function<void(RenderTile &)> write_render_tile_cb;
function<void(RenderTile &, bool)> update_render_tile_cb;
function<void(RenderTile &)> read_bake_tile_cb;
explicit Session(const SessionParams &params);
~Session();

View File

@@ -206,7 +206,6 @@ Shader::Shader() : Node(node_type)
has_surface_spatial_varying = false;
has_volume_spatial_varying = false;
has_volume_attribute_dependency = false;
has_object_dependency = false;
has_integrator_dependency = false;
has_volume_connected = false;
prev_volume_step_rate = 0.0f;
@@ -218,7 +217,6 @@ Shader::Shader() : Node(node_type)
need_update = true;
need_update_geometry = true;
need_sync_object = false;
}
Shader::~Shader()
@@ -320,9 +318,11 @@ void Shader::tag_update(Scene *scene)
* has use_mis set to false. We are quite close to release now, so
* better to be safe.
*/
if (this == scene->background->get_shader(scene) &&
scene->light_manager->has_background_light(scene)) {
scene->light_manager->need_update = true;
if (this == scene->background->get_shader(scene)) {
scene->light_manager->need_update_background = true;
if (scene->light_manager->has_background_light(scene)) {
scene->light_manager->need_update = true;
}
}
/* quick detection of which kind of shaders we have to avoid loading

View File

@@ -98,7 +98,6 @@ class Shader : public Node {
/* synchronization */
bool need_update;
bool need_update_geometry;
bool need_sync_object;
/* If the shader has only volume components, the surface is assumed to
* be transparent.
@@ -121,7 +120,6 @@ class Shader : public Node {
bool has_surface_spatial_varying;
bool has_volume_spatial_varying;
bool has_volume_attribute_dependency;
bool has_object_dependency;
bool has_integrator_dependency;
/* displacement */

View File

@@ -448,10 +448,6 @@ void SVMCompiler::generate_node(ShaderNode *node, ShaderNodeSet &done)
current_shader->has_volume_attribute_dependency = true;
}
if (node->has_object_dependency()) {
current_shader->has_object_dependency = true;
}
if (node->has_integrator_dependency()) {
current_shader->has_integrator_dependency = true;
}
@@ -863,7 +859,6 @@ void SVMCompiler::compile(Shader *shader, array<int4> &svm_nodes, int index, Sum
shader->has_surface_spatial_varying = false;
shader->has_volume_spatial_varying = false;
shader->has_volume_attribute_dependency = false;
shader->has_object_dependency = false;
shader->has_integrator_dependency = false;
/* generate bump shader */

View File

@@ -23,8 +23,8 @@
#include "GHOST_System.h"
#include <chrono>
#include <stdio.h> /* just for printf */
#include <time.h>
#include "GHOST_DisplayManager.h"
#include "GHOST_EventManager.h"
@@ -58,12 +58,9 @@ GHOST_System::~GHOST_System()
GHOST_TUns64 GHOST_System::getMilliSeconds() const
{
GHOST_TUns64 millis = ::clock();
if (CLOCKS_PER_SEC != 1000) {
millis *= 1000;
millis /= CLOCKS_PER_SEC;
}
return millis;
return std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now().time_since_epoch())
.count();
}
GHOST_ITimerTask *GHOST_System::installTimer(GHOST_TUns64 delay,

View File

@@ -25,6 +25,7 @@
#include "GHOST_EventDragnDrop.h"
#include "GHOST_EventKey.h"
#include "GHOST_EventWheel.h"
#include "GHOST_TimerManager.h"
#include "GHOST_WindowManager.h"
#include "GHOST_ContextEGL.h"
@@ -34,7 +35,7 @@
#include <algorithm>
#include <atomic>
#include <exception>
#include <stdexcept>
#include <thread>
#include <unordered_map>
#include <unordered_set>
@@ -91,6 +92,13 @@ struct data_source_t {
char *buffer_out;
};
struct key_repeat_payload_t {
GHOST_SystemWayland *system;
GHOST_IWindow *window;
GHOST_TKey key;
GHOST_TEventKeyData key_data;
};
struct input_t {
GHOST_SystemWayland *system;
@@ -109,6 +117,17 @@ struct input_t {
struct xkb_context *xkb_context;
struct xkb_state *xkb_state;
struct {
/* Key repetition in character per second. */
int32_t rate;
/* Time (milliseconds) after which to start repeating keys. */
int32_t delay;
/* Timer for key repeats. */
GHOST_ITimerTask *timer = nullptr;
} key_repeat;
struct wl_surface *focus_pointer = nullptr;
struct wl_surface *focus_keyboard = nullptr;
struct wl_data_device *data_device = nullptr;
struct data_offer_t *data_offer_dnd; /* Drag & Drop. */
@@ -174,6 +193,11 @@ static void display_destroy(display_t *d)
}
}
if (input->keyboard) {
if (input->key_repeat.timer) {
delete static_cast<key_repeat_payload_t *>(input->key_repeat.timer->getUserData());
input->system->removeTimer(input->key_repeat.timer);
input->key_repeat.timer = nullptr;
}
wl_keyboard_destroy(input->keyboard);
}
if (input->xkb_state) {
@@ -420,22 +444,26 @@ static void relative_pointer_relative_motion(
input->x += wl_fixed_to_int(dx);
input->y += wl_fixed_to_int(dy);
input->system->pushEvent(
new GHOST_EventCursor(input->system->getMilliSeconds(),
GHOST_kEventCursorMove,
input->system->getWindowManager()->getActiveWindow(),
input->x,
input->y,
GHOST_TABLET_DATA_NONE));
GHOST_IWindow *win = static_cast<GHOST_WindowWayland *>(
wl_surface_get_user_data(input->focus_pointer));
input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(),
GHOST_kEventCursorMove,
win,
input->x,
input->y,
GHOST_TABLET_DATA_NONE));
}
static const zwp_relative_pointer_v1_listener relative_pointer_listener = {
relative_pointer_relative_motion};
relative_pointer_relative_motion,
};
static void dnd_events(const input_t *const input, const GHOST_TEventType event)
{
const GHOST_TUns64 time = input->system->getMilliSeconds();
GHOST_IWindow *const window = input->system->getWindowManager()->getActiveWindow();
GHOST_IWindow *const window = static_cast<GHOST_WindowWayland *>(
wl_surface_get_user_data(input->focus_pointer));
for (const std::string &type : mime_preference_order) {
input->system->pushEvent(new GHOST_EventDragnDrop(time,
event,
@@ -641,7 +669,7 @@ static void data_device_drop(void *data, struct wl_data_device * /*wl_data_devic
data_offer->types.begin(),
data_offer->types.end());
auto read_uris = [](GHOST_SystemWayland *const system,
auto read_uris = [](input_t *const input,
data_offer_t *data_offer,
const std::string mime_receive) {
const int x = data_offer->dnd.x;
@@ -655,6 +683,8 @@ static void data_device_drop(void *data, struct wl_data_device * /*wl_data_devic
delete data_offer;
data_offer = nullptr;
GHOST_SystemWayland *const system = input->system;
if (mime_receive == mime_text_uri) {
static constexpr const char *file_proto = "file://";
static constexpr const char *crlf = "\r\n";
@@ -683,10 +713,12 @@ static void data_device_drop(void *data, struct wl_data_device * /*wl_data_devic
malloc((uris[i].size() + 1) * sizeof(GHOST_TUns8)));
memcpy(flist->strings[i], uris[i].data(), uris[i].size() + 1);
}
GHOST_IWindow *win = static_cast<GHOST_WindowWayland *>(
wl_surface_get_user_data(input->focus_pointer));
system->pushEvent(new GHOST_EventDragnDrop(system->getMilliSeconds(),
GHOST_kEventDraggingDropDone,
GHOST_kDragnDropTypeFilenames,
system->getWindowManager()->getActiveWindow(),
win,
x,
y,
flist));
@@ -698,7 +730,7 @@ static void data_device_drop(void *data, struct wl_data_device * /*wl_data_devic
wl_display_roundtrip(system->display());
};
std::thread read_thread(read_uris, input->system, data_offer, mime_receive);
std::thread read_thread(read_uris, input, data_offer, mime_receive);
read_thread.detach();
}
@@ -778,17 +810,24 @@ static void pointer_enter(void *data,
input->pointer_serial = serial;
input->x = wl_fixed_to_int(surface_x);
input->y = wl_fixed_to_int(surface_y);
input->focus_pointer = surface;
static_cast<GHOST_WindowWayland *>(wl_surface_get_user_data(surface))->activate();
input->system->pushEvent(
new GHOST_EventCursor(input->system->getMilliSeconds(),
GHOST_kEventCursorMove,
static_cast<GHOST_WindowWayland *>(wl_surface_get_user_data(surface)),
input->x,
input->y,
GHOST_TABLET_DATA_NONE));
}
static void pointer_leave(void * /*data*/,
static void pointer_leave(void *data,
struct wl_pointer * /*wl_pointer*/,
uint32_t /*serial*/,
struct wl_surface *surface)
{
if (surface != nullptr) {
static_cast<GHOST_WindowWayland *>(wl_surface_get_user_data(surface))->deactivate();
static_cast<input_t *>(data)->focus_pointer = nullptr;
}
}
@@ -800,16 +839,22 @@ static void pointer_motion(void *data,
{
input_t *input = static_cast<input_t *>(data);
GHOST_IWindow *win = static_cast<GHOST_WindowWayland *>(
wl_surface_get_user_data(input->focus_pointer));
if (!win) {
return;
}
input->x = wl_fixed_to_int(surface_x);
input->y = wl_fixed_to_int(surface_y);
input->system->pushEvent(
new GHOST_EventCursor(input->system->getMilliSeconds(),
GHOST_kEventCursorMove,
input->system->getWindowManager()->getActiveWindow(),
wl_fixed_to_int(surface_x),
wl_fixed_to_int(surface_y),
GHOST_TABLET_DATA_NONE));
input->system->pushEvent(new GHOST_EventCursor(input->system->getMilliSeconds(),
GHOST_kEventCursorMove,
win,
wl_fixed_to_int(surface_x),
wl_fixed_to_int(surface_y),
GHOST_TABLET_DATA_NONE));
}
static void pointer_button(void *data,
@@ -843,14 +888,12 @@ static void pointer_button(void *data,
}
input_t *input = static_cast<input_t *>(data);
GHOST_IWindow *win = static_cast<GHOST_WindowWayland *>(
wl_surface_get_user_data(input->focus_pointer));
input->data_source->source_serial = serial;
input->buttons.set(ebutton, state == WL_POINTER_BUTTON_STATE_PRESSED);
input->system->pushEvent(
new GHOST_EventButton(input->system->getMilliSeconds(),
etype,
input->system->getWindowManager()->getActiveWindow(),
ebutton,
GHOST_TABLET_DATA_NONE));
input->system->pushEvent(new GHOST_EventButton(
input->system->getMilliSeconds(), etype, win, ebutton, GHOST_TABLET_DATA_NONE));
}
static void pointer_axis(void *data,
@@ -863,10 +906,10 @@ static void pointer_axis(void *data,
return;
}
input_t *input = static_cast<input_t *>(data);
GHOST_IWindow *win = static_cast<GHOST_WindowWayland *>(
wl_surface_get_user_data(input->focus_pointer));
input->system->pushEvent(
new GHOST_EventWheel(input->system->getMilliSeconds(),
input->system->getWindowManager()->getActiveWindow(),
std::signbit(value) ? +1 : -1));
new GHOST_EventWheel(input->system->getMilliSeconds(), win, std::signbit(value) ? +1 : -1));
}
static const struct wl_pointer_listener pointer_listener = {
@@ -913,13 +956,15 @@ static void keyboard_keymap(
* Notification that this seat's keyboard focus is on a certain
* surface.
*/
static void keyboard_enter(void * /*data*/,
static void keyboard_enter(void *data,
struct wl_keyboard * /*wl_keyboard*/,
uint32_t /*serial*/,
struct wl_surface * /*surface*/,
struct wl_surface *surface,
struct wl_array * /*keys*/)
{
/* pass */
if (surface != nullptr) {
static_cast<input_t *>(data)->focus_keyboard = surface;
}
}
/**
@@ -928,12 +973,14 @@ static void keyboard_enter(void * /*data*/,
* Notification that this seat's keyboard focus is no longer on a
* certain surface.
*/
static void keyboard_leave(void * /*data*/,
static void keyboard_leave(void *data,
struct wl_keyboard * /*wl_keyboard*/,
uint32_t /*serial*/,
struct wl_surface * /*surface*/)
struct wl_surface *surface)
{
/* pass */
if (surface != nullptr) {
static_cast<input_t *>(data)->focus_keyboard = nullptr;
}
}
/**
@@ -988,6 +1035,14 @@ static void keyboard_key(void *data,
}
const GHOST_TKey gkey = xkb_map_gkey(sym);
/* Delete previous timer. */
if (xkb_keymap_key_repeats(xkb_state_get_keymap(input->xkb_state), key + 8) &&
input->key_repeat.timer) {
delete static_cast<key_repeat_payload_t *>(input->key_repeat.timer->getUserData());
input->system->removeTimer(input->key_repeat.timer);
input->key_repeat.timer = nullptr;
}
GHOST_TEventKeyData key_data;
if (etype == GHOST_kEventKeyDown) {
@@ -999,13 +1054,38 @@ static void keyboard_key(void *data,
}
input->data_source->source_serial = serial;
input->system->pushEvent(new GHOST_EventKey(input->system->getMilliSeconds(),
etype,
input->system->getWindowManager()->getActiveWindow(),
gkey,
'\0',
key_data.utf8_buf,
false));
GHOST_IWindow *win = static_cast<GHOST_WindowWayland *>(
wl_surface_get_user_data(input->focus_keyboard));
input->system->pushEvent(new GHOST_EventKey(
input->system->getMilliSeconds(), etype, win, gkey, '\0', key_data.utf8_buf, false));
/* Start timer for repeating key, if applicable. */
if (input->key_repeat.rate > 0 &&
xkb_keymap_key_repeats(xkb_state_get_keymap(input->xkb_state), key + 8) &&
etype == GHOST_kEventKeyDown) {
key_repeat_payload_t *payload = new key_repeat_payload_t({
.system = input->system,
.window = win,
.key = gkey,
.key_data = key_data,
});
auto cb = [](GHOST_ITimerTask *task, GHOST_TUns64 /*time*/) {
struct key_repeat_payload_t *payload = static_cast<key_repeat_payload_t *>(
task->getUserData());
payload->system->pushEvent(new GHOST_EventKey(payload->system->getMilliSeconds(),
GHOST_kEventKeyDown,
payload->window,
payload->key,
'\0',
payload->key_data.utf8_buf,
true));
};
input->key_repeat.timer = input->system->installTimer(
input->key_repeat.delay, 1000 / input->key_repeat.rate, cb, payload);
}
}
static void keyboard_modifiers(void *data,
@@ -1025,12 +1105,24 @@ static void keyboard_modifiers(void *data,
group);
}
static void keyboard_repeat_info(void *data,
struct wl_keyboard * /*wl_keyboard*/,
int32_t rate,
int32_t delay)
{
input_t *input = static_cast<input_t *>(data);
input->key_repeat.rate = rate;
input->key_repeat.delay = delay;
}
static const struct wl_keyboard_listener keyboard_listener = {
keyboard_keymap,
keyboard_enter,
keyboard_leave,
keyboard_key,
keyboard_modifiers,
keyboard_repeat_info,
};
static void seat_capabilities(void *data, struct wl_seat *wl_seat, uint32_t capabilities)
@@ -1163,7 +1255,7 @@ static void global_add(void *data,
input->relative_pointer = nullptr;
input->locked_pointer = nullptr;
input->seat = static_cast<wl_seat *>(
wl_registry_bind(wl_registry, name, &wl_seat_interface, 2));
wl_registry_bind(wl_registry, name, &wl_seat_interface, 4));
display->inputs.push_back(input);
wl_seat_add_listener(input->seat, &seat_listener, input);
}
@@ -1260,10 +1352,18 @@ GHOST_SystemWayland::~GHOST_SystemWayland()
display_destroy(d);
}
bool GHOST_SystemWayland::processEvents(bool /*waitForEvent*/)
bool GHOST_SystemWayland::processEvents(bool waitForEvent)
{
wl_display_dispatch(d->display);
return true;
const bool fired = getTimerManager()->fireTimers(getMilliSeconds());
if (waitForEvent) {
wl_display_dispatch(d->display);
}
else {
wl_display_roundtrip(d->display);
}
return fired || (getEventManager()->getNumEvents() > 0);
}
int GHOST_SystemWayland::toggleConsole(int /*action*/)
@@ -1352,7 +1452,7 @@ GHOST_TUns8 GHOST_SystemWayland::getNumDisplays() const
GHOST_TSuccess GHOST_SystemWayland::getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const
{
if (getWindowManager()->getActiveWindow() != nullptr && !d->inputs.empty()) {
if (!d->inputs.empty() && (d->inputs[0]->focus_pointer != nullptr)) {
x = d->inputs[0]->x;
y = d->inputs[0]->y;
return GHOST_kSuccess;

View File

@@ -53,6 +53,14 @@ if(WIN32 AND NOT UNIX)
mmap_win.h
)
list(APPEND INC_SYS
${PTHREADS_INC}
)
list(APPEND LIB
${PTHREADS_LIBRARIES}
)
endif()
# Jemalloc 5.0.0+ needs extra configuration.

View File

@@ -145,14 +145,6 @@ extern void *(*MEM_mallocN_aligned)(size_t len,
const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
/**
* Same as callocN, clears memory and uses mmap (disk cached) if supported.
* Can be free'd with MEM_freeN as usual.
* */
extern void *(*MEM_mapallocN)(size_t len,
const char *str) /* ATTR_MALLOC */ ATTR_WARN_UNUSED_RESULT
ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
/** Print a list of the names and sizes of all allocated memory
* blocks. as a python dict for easy investigation */
extern void (*MEM_printmemlist_pydict)(void);
@@ -176,20 +168,11 @@ extern void (*MEM_set_error_callback)(void (*func)(const char *));
* @retval true for correct memory, false for corrupted memory. */
extern bool (*MEM_consistency_check)(void);
/** Set thread locking functions for safe memory allocation from multiple
* threads, pass NULL pointers to disable thread locking again. */
extern void (*MEM_set_lock_callback)(void (*lock)(void), void (*unlock)(void));
/** Attempt to enforce OSX (or other OS's) to have malloc and stack nonzero */
extern void (*MEM_set_memory_debug)(void);
/**
* Memory usage stats
* - MEM_get_memory_in_use is all memory
* - MEM_get_mapped_memory_in_use is a subset of all memory */
/** Memory usage stats. */
extern size_t (*MEM_get_memory_in_use)(void);
/** Get mapped memory usage. */
extern size_t (*MEM_get_mapped_memory_in_use)(void);
/** Get amount of memory blocks in use. */
extern unsigned int (*MEM_get_memory_blocks_in_use)(void);

View File

@@ -48,18 +48,14 @@ void *(*MEM_malloc_arrayN)(size_t len, size_t size, const char *str) = MEM_lockf
void *(*MEM_mallocN_aligned)(size_t len,
size_t alignment,
const char *str) = MEM_lockfree_mallocN_aligned;
void *(*MEM_mapallocN)(size_t len, const char *str) = MEM_lockfree_mapallocN;
void (*MEM_printmemlist_pydict)(void) = MEM_lockfree_printmemlist_pydict;
void (*MEM_printmemlist)(void) = MEM_lockfree_printmemlist;
void (*MEM_callbackmemlist)(void (*func)(void *)) = MEM_lockfree_callbackmemlist;
void (*MEM_printmemlist_stats)(void) = MEM_lockfree_printmemlist_stats;
void (*MEM_set_error_callback)(void (*func)(const char *)) = MEM_lockfree_set_error_callback;
bool (*MEM_consistency_check)(void) = MEM_lockfree_consistency_check;
void (*MEM_set_lock_callback)(void (*lock)(void),
void (*unlock)(void)) = MEM_lockfree_set_lock_callback;
void (*MEM_set_memory_debug)(void) = MEM_lockfree_set_memory_debug;
size_t (*MEM_get_memory_in_use)(void) = MEM_lockfree_get_memory_in_use;
size_t (*MEM_get_mapped_memory_in_use)(void) = MEM_lockfree_get_mapped_memory_in_use;
unsigned int (*MEM_get_memory_blocks_in_use)(void) = MEM_lockfree_get_memory_blocks_in_use;
void (*MEM_reset_peak_memory)(void) = MEM_lockfree_reset_peak_memory;
size_t (*MEM_get_peak_memory)(void) = MEM_lockfree_get_peak_memory;
@@ -111,17 +107,14 @@ void MEM_use_guarded_allocator(void)
MEM_mallocN = MEM_guarded_mallocN;
MEM_malloc_arrayN = MEM_guarded_malloc_arrayN;
MEM_mallocN_aligned = MEM_guarded_mallocN_aligned;
MEM_mapallocN = MEM_guarded_mapallocN;
MEM_printmemlist_pydict = MEM_guarded_printmemlist_pydict;
MEM_printmemlist = MEM_guarded_printmemlist;
MEM_callbackmemlist = MEM_guarded_callbackmemlist;
MEM_printmemlist_stats = MEM_guarded_printmemlist_stats;
MEM_set_error_callback = MEM_guarded_set_error_callback;
MEM_consistency_check = MEM_guarded_consistency_check;
MEM_set_lock_callback = MEM_guarded_set_lock_callback;
MEM_set_memory_debug = MEM_guarded_set_memory_debug;
MEM_get_memory_in_use = MEM_guarded_get_memory_in_use;
MEM_get_mapped_memory_in_use = MEM_guarded_get_mapped_memory_in_use;
MEM_get_memory_blocks_in_use = MEM_guarded_get_memory_blocks_in_use;
MEM_reset_peak_memory = MEM_guarded_reset_peak_memory;
MEM_get_peak_memory = MEM_guarded_get_peak_memory;

View File

@@ -28,6 +28,8 @@
#include <string.h> /* memcpy */
#include <sys/types.h>
#include <pthread.h>
#include "MEM_guardedalloc.h"
/* to ensure strict conversions */
@@ -50,17 +52,6 @@
//#define DEBUG_MEMCOUNTER
/* Only for debugging:
* defining DEBUG_THREADS will enable check whether memory manager
* is locked with a mutex when allocation is called from non-main
* thread.
*
* This helps troubleshooting memory issues caused by the fact
* guarded allocator is not thread-safe, however this check will
* fail to check allocations from openmp threads.
*/
//#define DEBUG_THREADS
/* Only for debugging:
* Defining DEBUG_BACKTRACE will store a backtrace from where
* memory block was allocated and print this trace for all
@@ -104,7 +95,7 @@ typedef struct MemHead {
const char *name;
const char *nextname;
int tag2;
short mmap; /* if true, memory was mmapped */
short pad1;
short alignment; /* if non-zero aligned alloc was used
* and alignment is stored here.
*/
@@ -124,24 +115,6 @@ typedef struct MemHead {
typedef MemHead MemHeadAligned;
/* for openmp threading asserts, saves time troubleshooting
* we may need to extend this if blender code starts using MEM_
* functions inside OpenMP correctly with omp_set_lock() */
#if 0 /* disable for now, only use to debug openmp code which doesn lock threads for malloc */
# if defined(_OPENMP) && defined(DEBUG)
# include <assert.h>
# include <omp.h>
# define DEBUG_OMP_MALLOC
# endif
#endif
#ifdef DEBUG_THREADS
# include <assert.h>
# include <pthread.h>
static pthread_t mainid;
#endif
#ifdef DEBUG_BACKTRACE
# if defined(__linux__) || defined(__APPLE__)
# include <execinfo.h>
@@ -187,13 +160,11 @@ static const char *check_memlist(MemHead *memh);
/* --------------------------------------------------------------------- */
static unsigned int totblock = 0;
static size_t mem_in_use = 0, mmap_in_use = 0, peak_mem = 0;
static size_t mem_in_use = 0, peak_mem = 0;
static volatile struct localListBase _membase;
static volatile struct localListBase *membase = &_membase;
static void (*error_callback)(const char *) = NULL;
static void (*thread_lock_callback)(void) = NULL;
static void (*thread_unlock_callback)(void) = NULL;
static bool malloc_debug_memset = false;
@@ -233,40 +204,16 @@ print_error(const char *str, ...)
fputs(buf, stderr);
}
static pthread_mutex_t thread_lock = PTHREAD_MUTEX_INITIALIZER;
static void mem_lock_thread(void)
{
#ifdef DEBUG_THREADS
static int initialized = 0;
if (initialized == 0) {
/* assume first allocation happens from main thread */
mainid = pthread_self();
initialized = 1;
}
if (!pthread_equal(pthread_self(), mainid) && thread_lock_callback == NULL) {
assert(!"Memory function is called from non-main thread without lock");
}
#endif
#ifdef DEBUG_OMP_MALLOC
assert(omp_in_parallel() == 0);
#endif
if (thread_lock_callback)
thread_lock_callback();
pthread_mutex_lock(&thread_lock);
}
static void mem_unlock_thread(void)
{
#ifdef DEBUG_THREADS
if (!pthread_equal(pthread_self(), mainid) && thread_lock_callback == NULL) {
assert(!"Thread lock was removed while allocation from thread is in progress");
}
#endif
if (thread_unlock_callback)
thread_unlock_callback();
pthread_mutex_unlock(&thread_lock);
}
bool MEM_guarded_consistency_check(void)
@@ -287,12 +234,6 @@ void MEM_guarded_set_error_callback(void (*func)(const char *))
error_callback = func;
}
void MEM_guarded_set_lock_callback(void (*lock)(void), void (*unlock)(void))
{
thread_lock_callback = lock;
thread_unlock_callback = unlock;
}
void MEM_guarded_set_memory_debug(void)
{
malloc_debug_memset = true;
@@ -320,10 +261,8 @@ void *MEM_guarded_dupallocN(const void *vmemh)
memh--;
#ifndef DEBUG_MEMDUPLINAME
if (UNLIKELY(memh->mmap))
newp = MEM_guarded_mapallocN(memh->len, "dupli_mapalloc");
else if (LIKELY(memh->alignment == 0))
newp = MEM_guarded_mapallocN(memh->len, "dupli_mapalloc");
if (LIKELY(memh->alignment == 0))
newp = MEM_guarded_mallocN(memh->len, "dupli_alloc");
else
newp = MEM_guarded_mallocN_aligned(memh->len, (size_t)memh->alignment, "dupli_alloc");
@@ -334,11 +273,7 @@ void *MEM_guarded_dupallocN(const void *vmemh)
MemHead *nmemh;
char *name = malloc(strlen(memh->name) + 24);
if (UNLIKELY(memh->mmap)) {
sprintf(name, "%s %s", "dupli_mapalloc", memh->name);
newp = MEM_guarded_mapallocN(memh->len, name);
}
else if (LIKELY(memh->alignment == 0)) {
if (LIKELY(memh->alignment == 0)) {
sprintf(name, "%s %s", "dupli_alloc", memh->name);
newp = MEM_guarded_mallocN(memh->len, name);
}
@@ -478,7 +413,7 @@ static void make_memhead_header(MemHead *memh, size_t len, const char *str)
memh->name = str;
memh->nextname = NULL;
memh->len = len;
memh->mmap = 0;
memh->pad1 = 0;
memh->alignment = 0;
memh->tag2 = MEMTAG2;
@@ -646,58 +581,6 @@ void *MEM_guarded_calloc_arrayN(size_t len, size_t size, const char *str)
return MEM_guarded_callocN(total_size, str);
}
/* note; mmap returns zero'd memory */
void *MEM_guarded_mapallocN(size_t len, const char *str)
{
MemHead *memh;
/* on 64 bit, simply use calloc instead, as mmap does not support
* allocating > 4 GB on Windows. the only reason mapalloc exists
* is to get around address space limitations in 32 bit OSes. */
if (sizeof(void *) >= 8)
return MEM_guarded_callocN(len, str);
len = SIZET_ALIGN_4(len);
#if defined(WIN32)
/* our windows mmap implementation is not thread safe */
mem_lock_thread();
#endif
memh = mmap(NULL,
len + sizeof(MemHead) + sizeof(MemTail),
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANON,
-1,
0);
#if defined(WIN32)
mem_unlock_thread();
#endif
if (memh != (MemHead *)-1) {
make_memhead_header(memh, len, str);
memh->mmap = 1;
atomic_add_and_fetch_z(&mmap_in_use, len);
mem_lock_thread();
peak_mem = mmap_in_use > peak_mem ? mmap_in_use : peak_mem;
mem_unlock_thread();
#ifdef DEBUG_MEMCOUNTER
if (_mallocn_count == DEBUG_MEMCOUNTER_ERROR_VAL)
memcount_raise(__func__);
memh->_count = _mallocn_count++;
#endif
return (++memh);
}
else {
print_error(
"Mapalloc returns null, fallback to regular malloc: "
"len=" SIZET_FORMAT " in %s, total %u\n",
SIZET_ARG(len),
str,
(unsigned int)mmap_in_use);
return MEM_guarded_callocN(len, str);
}
}
/* Memory statistics print */
typedef struct MemPrintBlock {
const char *name;
@@ -765,7 +648,7 @@ void MEM_guarded_printmemlist_stats(void)
pb++;
#ifdef USE_MALLOC_USABLE_SIZE
if (!membl->mmap && membl->alignment == 0) {
if (membl->alignment == 0) {
mem_in_use_slop += (sizeof(MemHead) + sizeof(MemTail) + malloc_usable_size((void *)membl)) -
membl->len;
}
@@ -1098,27 +981,13 @@ static void rem_memblock(MemHead *memh)
free((char *)memh->name);
#endif
if (memh->mmap) {
atomic_sub_and_fetch_z(&mmap_in_use, memh->len);
#if defined(WIN32)
/* our windows mmap implementation is not thread safe */
mem_lock_thread();
#endif
if (munmap(memh, memh->len + sizeof(MemHead) + sizeof(MemTail)))
printf("Couldn't unmap memory %s\n", memh->name);
#if defined(WIN32)
mem_unlock_thread();
#endif
if (UNLIKELY(malloc_debug_memset && memh->len))
memset(memh + 1, 255, memh->len);
if (LIKELY(memh->alignment == 0)) {
free(memh);
}
else {
if (UNLIKELY(malloc_debug_memset && memh->len))
memset(memh + 1, 255, memh->len);
if (LIKELY(memh->alignment == 0)) {
free(memh);
}
else {
aligned_free(MEMHEAD_REAL_PTR(memh));
}
aligned_free(MEMHEAD_REAL_PTR(memh));
}
}
@@ -1270,17 +1139,6 @@ size_t MEM_guarded_get_memory_in_use(void)
return _mem_in_use;
}
size_t MEM_guarded_get_mapped_memory_in_use(void)
{
size_t _mmap_in_use;
mem_lock_thread();
_mmap_in_use = mmap_in_use;
mem_unlock_thread();
return _mmap_in_use;
}
unsigned int MEM_guarded_get_memory_blocks_in_use(void)
{
unsigned int _totblock;

View File

@@ -24,13 +24,6 @@
#ifndef __MALLOCN_INTERN_H__
#define __MALLOCN_INTERN_H__
/* mmap exception */
#if defined(WIN32)
# include "mmap_win.h"
#else
# include <sys/mman.h>
#endif
#ifdef __GNUC__
# define UNUSED(x) UNUSED_##x __attribute__((__unused__))
#else
@@ -140,19 +133,14 @@ void *MEM_lockfree_mallocN_aligned(size_t len,
size_t alignment,
const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
void *MEM_lockfree_mapallocN(size_t len,
const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
void MEM_lockfree_printmemlist_pydict(void);
void MEM_lockfree_printmemlist(void);
void MEM_lockfree_callbackmemlist(void (*func)(void *));
void MEM_lockfree_printmemlist_stats(void);
void MEM_lockfree_set_error_callback(void (*func)(const char *));
bool MEM_lockfree_consistency_check(void);
void MEM_lockfree_set_lock_callback(void (*lock)(void), void (*unlock)(void));
void MEM_lockfree_set_memory_debug(void);
size_t MEM_lockfree_get_memory_in_use(void);
size_t MEM_lockfree_get_mapped_memory_in_use(void);
unsigned int MEM_lockfree_get_memory_blocks_in_use(void);
void MEM_lockfree_reset_peak_memory(void);
size_t MEM_lockfree_get_peak_memory(void) ATTR_WARN_UNUSED_RESULT;
@@ -188,19 +176,14 @@ void *MEM_guarded_mallocN_aligned(size_t len,
size_t alignment,
const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
void *MEM_guarded_mapallocN(size_t len,
const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
void MEM_guarded_printmemlist_pydict(void);
void MEM_guarded_printmemlist(void);
void MEM_guarded_callbackmemlist(void (*func)(void *));
void MEM_guarded_printmemlist_stats(void);
void MEM_guarded_set_error_callback(void (*func)(const char *));
bool MEM_guarded_consistency_check(void);
void MEM_guarded_set_lock_callback(void (*lock)(void), void (*unlock)(void));
void MEM_guarded_set_memory_debug(void);
size_t MEM_guarded_get_memory_in_use(void);
size_t MEM_guarded_get_mapped_memory_in_use(void);
unsigned int MEM_guarded_get_memory_blocks_in_use(void);
void MEM_guarded_reset_peak_memory(void);
size_t MEM_guarded_get_peak_memory(void) ATTR_WARN_UNUSED_RESULT;

View File

@@ -44,22 +44,18 @@ typedef struct MemHeadAligned {
} MemHeadAligned;
static unsigned int totblock = 0;
static size_t mem_in_use = 0, mmap_in_use = 0, peak_mem = 0;
static size_t mem_in_use = 0, peak_mem = 0;
static bool malloc_debug_memset = false;
static void (*error_callback)(const char *) = NULL;
static void (*thread_lock_callback)(void) = NULL;
static void (*thread_unlock_callback)(void) = NULL;
enum {
MEMHEAD_MMAP_FLAG = 1,
MEMHEAD_ALIGN_FLAG = 2,
MEMHEAD_ALIGN_FLAG = 1,
};
#define MEMHEAD_FROM_PTR(ptr) (((MemHead *)ptr) - 1)
#define PTR_FROM_MEMHEAD(memhead) (memhead + 1)
#define MEMHEAD_ALIGNED_FROM_PTR(ptr) (((MemHeadAligned *)ptr) - 1)
#define MEMHEAD_IS_MMAP(memhead) ((memhead)->len & (size_t)MEMHEAD_MMAP_FLAG)
#define MEMHEAD_IS_ALIGNED(memhead) ((memhead)->len & (size_t)MEMHEAD_ALIGN_FLAG)
/* Uncomment this to have proper peak counter. */
@@ -93,24 +89,10 @@ print_error(const char *str, ...)
}
}
#if defined(WIN32)
static void mem_lock_thread(void)
{
if (thread_lock_callback)
thread_lock_callback();
}
static void mem_unlock_thread(void)
{
if (thread_unlock_callback)
thread_unlock_callback();
}
#endif
size_t MEM_lockfree_allocN_len(const void *vmemh)
{
if (vmemh) {
return MEMHEAD_FROM_PTR(vmemh)->len & ~((size_t)(MEMHEAD_MMAP_FLAG | MEMHEAD_ALIGN_FLAG));
return MEMHEAD_FROM_PTR(vmemh)->len & ~((size_t)(MEMHEAD_ALIGN_FLAG));
}
else {
return 0;
@@ -133,29 +115,15 @@ void MEM_lockfree_freeN(void *vmemh)
atomic_sub_and_fetch_u(&totblock, 1);
atomic_sub_and_fetch_z(&mem_in_use, len);
if (MEMHEAD_IS_MMAP(memh)) {
atomic_sub_and_fetch_z(&mmap_in_use, len);
#if defined(WIN32)
/* our windows mmap implementation is not thread safe */
mem_lock_thread();
#endif
if (munmap(memh, len + sizeof(MemHead)))
printf("Couldn't unmap memory\n");
#if defined(WIN32)
mem_unlock_thread();
#endif
if (UNLIKELY(malloc_debug_memset && len)) {
memset(memh + 1, 255, len);
}
if (UNLIKELY(MEMHEAD_IS_ALIGNED(memh))) {
MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
aligned_free(MEMHEAD_REAL_PTR(memh_aligned));
}
else {
if (UNLIKELY(malloc_debug_memset && len)) {
memset(memh + 1, 255, len);
}
if (UNLIKELY(MEMHEAD_IS_ALIGNED(memh))) {
MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
aligned_free(MEMHEAD_REAL_PTR(memh_aligned));
}
else {
free(memh);
}
free(memh);
}
}
@@ -165,10 +133,7 @@ void *MEM_lockfree_dupallocN(const void *vmemh)
if (vmemh) {
MemHead *memh = MEMHEAD_FROM_PTR(vmemh);
const size_t prev_size = MEM_lockfree_allocN_len(vmemh);
if (UNLIKELY(MEMHEAD_IS_MMAP(memh))) {
newp = MEM_lockfree_mapallocN(prev_size, "dupli_mapalloc");
}
else if (UNLIKELY(MEMHEAD_IS_ALIGNED(memh))) {
if (UNLIKELY(MEMHEAD_IS_ALIGNED(memh))) {
MemHeadAligned *memh_aligned = MEMHEAD_ALIGNED_FROM_PTR(vmemh);
newp = MEM_lockfree_mallocN_aligned(
prev_size, (size_t)memh_aligned->alignment, "dupli_malloc");
@@ -397,47 +362,6 @@ void *MEM_lockfree_mallocN_aligned(size_t len, size_t alignment, const char *str
return NULL;
}
void *MEM_lockfree_mapallocN(size_t len, const char *str)
{
MemHead *memh;
/* on 64 bit, simply use calloc instead, as mmap does not support
* allocating > 4 GB on Windows. the only reason mapalloc exists
* is to get around address space limitations in 32 bit OSes. */
if (sizeof(void *) >= 8)
return MEM_lockfree_callocN(len, str);
len = SIZET_ALIGN_4(len);
#if defined(WIN32)
/* our windows mmap implementation is not thread safe */
mem_lock_thread();
#endif
memh = mmap(NULL, len + sizeof(MemHead), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
#if defined(WIN32)
mem_unlock_thread();
#endif
if (memh != (MemHead *)-1) {
memh->len = len | (size_t)MEMHEAD_MMAP_FLAG;
atomic_add_and_fetch_u(&totblock, 1);
atomic_add_and_fetch_z(&mem_in_use, len);
atomic_add_and_fetch_z(&mmap_in_use, len);
update_maximum(&peak_mem, mem_in_use);
update_maximum(&peak_mem, mmap_in_use);
return PTR_FROM_MEMHEAD(memh);
}
print_error(
"Mapalloc returns null, fallback to regular malloc: "
"len=" SIZET_FORMAT " in %s, total %u\n",
SIZET_ARG(len),
str,
(unsigned int)mmap_in_use);
return MEM_lockfree_callocN(len, str);
}
void MEM_lockfree_printmemlist_pydict(void)
{
}
@@ -476,12 +400,6 @@ bool MEM_lockfree_consistency_check(void)
return true;
}
void MEM_lockfree_set_lock_callback(void (*lock)(void), void (*unlock)(void))
{
thread_lock_callback = lock;
thread_unlock_callback = unlock;
}
void MEM_lockfree_set_memory_debug(void)
{
malloc_debug_memset = true;
@@ -492,11 +410,6 @@ size_t MEM_lockfree_get_memory_in_use(void)
return mem_in_use;
}
size_t MEM_lockfree_get_mapped_memory_in_use(void)
{
return mmap_in_use;
}
unsigned int MEM_lockfree_get_memory_blocks_in_use(void)
{
return totblock;

View File

@@ -150,6 +150,7 @@ if(WITH_LIBMV)
libmv/autotrack/tracks.h
libmv/base/aligned_malloc.h
libmv/base/id_generator.h
libmv/base/map.h
libmv/base/scoped_ptr.h
libmv/base/vector.h
libmv/base/vector_utils.h

View File

@@ -16,6 +16,7 @@ libmv/autotrack/tracks_test.cc
libmv/base/aligned_malloc.cc
libmv/base/aligned_malloc.h
libmv/base/id_generator.h
libmv/base/map.h
libmv/base/scoped_ptr.h
libmv/base/scoped_ptr_test.cc
libmv/base/vector.h

View File

@@ -23,6 +23,7 @@
#ifndef LIBMV_AUTOTRACK_RECONSTRUCTION_H_
#define LIBMV_AUTOTRACK_RECONSTRUCTION_H_
#include "libmv/base/map.h"
#include "libmv/base/vector.h"
#include "libmv/numeric/numeric.h"
#include "libmv/simple_pipeline/camera_intrinsics.h"
@@ -51,7 +52,7 @@ class Point {
};
// A reconstruction for a set of tracks. The indexing for clip, frame, and
// track should match that of a Tracs object, stored elsewhere.
// track should match that of a Tracks object, stored elsewhere.
class Reconstruction {
public:
// All methods copy their input reference or take ownership of the pointer.
@@ -75,7 +76,7 @@ class Reconstruction {
vector<CameraIntrinsics*> camera_intrinsics_;
// Indexed by Marker::clip then by Marker::frame.
vector<vector<CameraPose> > camera_poses_;
vector<map<int, CameraPose>> camera_poses_;
// Indexed by Marker::track.
vector<Point> points_;

View File

@@ -0,0 +1,34 @@
// Copyright (c) 2020 libmv authors.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
#ifndef LIBMV_BASE_MAP_H
#define LIBMV_BASE_MAP_H
#include <map>
#include <utility>
namespace libmv {
using std::map;
using std::make_pair;
} // namespace libmv
#endif // LIBMV_BASE_MAP_H

View File

@@ -24,6 +24,7 @@
#include "ceres/ceres.h"
#include "ceres/rotation.h"
#include "libmv/base/map.h"
#include "libmv/base/vector.h"
#include "libmv/logging/logging.h"
#include "libmv/multiview/fundamental.h"
@@ -407,47 +408,39 @@ void UnpackIntrinsicsFromArray(const double intrinsics_block[OFFSET_MAX],
// Get a vector of camera's rotations denoted by angle axis
// conjuncted with translations into single block
//
// Element with index i matches to a rotation+translation for
// Element with key i matches to a rotation+translation for
// camera at image i.
vector<Vec6> PackCamerasRotationAndTranslation(
const Tracks &tracks,
map<int, Vec6> PackCamerasRotationAndTranslation(
const EuclideanReconstruction &reconstruction) {
vector<Vec6> all_cameras_R_t;
int max_image = tracks.MaxImage();
map<int, Vec6> all_cameras_R_t;
all_cameras_R_t.resize(max_image + 1);
for (int i = 0; i <= max_image; i++) {
const EuclideanCamera *camera = reconstruction.CameraForImage(i);
if (!camera) {
continue;
}
ceres::RotationMatrixToAngleAxis(&camera->R(0, 0),
&all_cameras_R_t[i](0));
all_cameras_R_t[i].tail<3>() = camera->t;
vector<EuclideanCamera> all_cameras = reconstruction.AllCameras();
for (const EuclideanCamera& camera : all_cameras) {
Vec6 camera_R_t;
ceres::RotationMatrixToAngleAxis(&camera.R(0, 0), &camera_R_t(0));
camera_R_t.tail<3>() = camera.t;
all_cameras_R_t.insert(make_pair(camera.image, camera_R_t));
}
return all_cameras_R_t;
}
// Convert cameras rotations fro mangle axis back to rotation matrix.
void UnpackCamerasRotationAndTranslation(
const Tracks &tracks,
const vector<Vec6> &all_cameras_R_t,
const map<int, Vec6> &all_cameras_R_t,
EuclideanReconstruction *reconstruction) {
int max_image = tracks.MaxImage();
for (int i = 0; i <= max_image; i++) {
EuclideanCamera *camera = reconstruction->CameraForImage(i);
for (map<int, Vec6>::value_type image_and_camera_R_T : all_cameras_R_t) {
const int image = image_and_camera_R_T.first;
const Vec6& camera_R_t = image_and_camera_R_T.second;
EuclideanCamera *camera = reconstruction->CameraForImage(image);
if (!camera) {
continue;
}
ceres::AngleAxisToRotationMatrix(&all_cameras_R_t[i](0),
&camera->R(0, 0));
camera->t = all_cameras_R_t[i].tail<3>();
ceres::AngleAxisToRotationMatrix(&camera_R_t(0), &camera->R(0, 0));
camera->t = camera_R_t.tail<3>();
}
}
@@ -476,7 +469,7 @@ void CRSMatrixToEigenMatrix(const ceres::CRSMatrix &crs_matrix,
void EuclideanBundlerPerformEvaluation(const Tracks &tracks,
EuclideanReconstruction *reconstruction,
vector<Vec6> *all_cameras_R_t,
map<int, Vec6> *all_cameras_R_t,
ceres::Problem *problem,
BundleEvaluation *evaluation) {
int max_track = tracks.MaxTrack();
@@ -603,7 +596,7 @@ void AddResidualBlockToProblem(const CameraIntrinsics *invariant_intrinsics,
// are to be totally still here.
void EuclideanBundlePointsOnly(const CameraIntrinsics *invariant_intrinsics,
const vector<Marker> &markers,
vector<Vec6> &all_cameras_R_t,
map<int, Vec6> &all_cameras_R_t,
double intrinsics_block[OFFSET_MAX],
EuclideanReconstruction *reconstruction) {
ceres::Problem::Options problem_options;
@@ -699,8 +692,8 @@ void EuclideanBundleCommonIntrinsics(
//
// Block for minimization has got the following structure:
// <3 elements for angle-axis> <3 elements for translation>
vector<Vec6> all_cameras_R_t =
PackCamerasRotationAndTranslation(tracks, *reconstruction);
map<int, Vec6> all_cameras_R_t =
PackCamerasRotationAndTranslation(*reconstruction);
// Parameterization used to restrict camera motion for modal solvers.
ceres::SubsetParameterization *constant_translation_parameterization = NULL;
@@ -827,9 +820,7 @@ void EuclideanBundleCommonIntrinsics(
LG << "Final report:\n" << summary.FullReport();
// Copy rotations and translations back.
UnpackCamerasRotationAndTranslation(tracks,
all_cameras_R_t,
reconstruction);
UnpackCamerasRotationAndTranslation(all_cameras_R_t, reconstruction);
// Copy intrinsics back.
if (bundle_intrinsics != BUNDLE_NO_INTRINSICS)

View File

@@ -27,14 +27,14 @@ namespace libmv {
EuclideanReconstruction::EuclideanReconstruction() {}
EuclideanReconstruction::EuclideanReconstruction(
const EuclideanReconstruction &other) {
cameras_ = other.cameras_;
image_to_cameras_map_ = other.image_to_cameras_map_;
points_ = other.points_;
}
EuclideanReconstruction &EuclideanReconstruction::operator=(
const EuclideanReconstruction &other) {
if (&other != this) {
cameras_ = other.cameras_;
image_to_cameras_map_ = other.image_to_cameras_map_;
points_ = other.points_;
}
return *this;
@@ -44,12 +44,13 @@ void EuclideanReconstruction::InsertCamera(int image,
const Mat3 &R,
const Vec3 &t) {
LG << "InsertCamera " << image << ":\nR:\n"<< R << "\nt:\n" << t;
if (image >= cameras_.size()) {
cameras_.resize(image + 1);
}
cameras_[image].image = image;
cameras_[image].R = R;
cameras_[image].t = t;
EuclideanCamera camera;
camera.image = image;
camera.R = R;
camera.t = t;
image_to_cameras_map_.insert(make_pair(image, camera));
}
void EuclideanReconstruction::InsertPoint(int track, const Vec3 &X) {
@@ -69,22 +70,18 @@ EuclideanCamera *EuclideanReconstruction::CameraForImage(int image) {
const EuclideanCamera *EuclideanReconstruction::CameraForImage(
int image) const {
if (image < 0 || image >= cameras_.size()) {
ImageToCameraMap::const_iterator it = image_to_cameras_map_.find(image);
if (it == image_to_cameras_map_.end()) {
return NULL;
}
const EuclideanCamera *camera = &cameras_[image];
if (camera->image == -1) {
return NULL;
}
return camera;
return &it->second;
}
vector<EuclideanCamera> EuclideanReconstruction::AllCameras() const {
vector<EuclideanCamera> cameras;
for (int i = 0; i < cameras_.size(); ++i) {
if (cameras_[i].image != -1) {
cameras.push_back(cameras_[i]);
}
for (const ImageToCameraMap::value_type& image_and_camera :
image_to_cameras_map_) {
cameras.push_back(image_and_camera.second);
}
return cameras;
}
@@ -115,14 +112,14 @@ vector<EuclideanPoint> EuclideanReconstruction::AllPoints() const {
return points;
}
void ProjectiveReconstruction::InsertCamera(int image,
const Mat34 &P) {
void ProjectiveReconstruction::InsertCamera(int image, const Mat34 &P) {
LG << "InsertCamera " << image << ":\nP:\n"<< P;
if (image >= cameras_.size()) {
cameras_.resize(image + 1);
}
cameras_[image].image = image;
cameras_[image].P = P;
ProjectiveCamera camera;
camera.image = image;
camera.P = P;
image_to_cameras_map_.insert(make_pair(image, camera));
}
void ProjectiveReconstruction::InsertPoint(int track, const Vec4 &X) {
@@ -142,22 +139,18 @@ ProjectiveCamera *ProjectiveReconstruction::CameraForImage(int image) {
const ProjectiveCamera *ProjectiveReconstruction::CameraForImage(
int image) const {
if (image < 0 || image >= cameras_.size()) {
return NULL;
ImageToCameraMap::const_iterator it = image_to_cameras_map_.find(image);
if (it == image_to_cameras_map_.end()) {
return NULL;
}
const ProjectiveCamera *camera = &cameras_[image];
if (camera->image == -1) {
return NULL;
}
return camera;
return &it->second;
}
vector<ProjectiveCamera> ProjectiveReconstruction::AllCameras() const {
vector<ProjectiveCamera> cameras;
for (int i = 0; i < cameras_.size(); ++i) {
if (cameras_[i].image != -1) {
cameras.push_back(cameras_[i]);
}
for (const ImageToCameraMap::value_type& image_and_camera :
image_to_cameras_map_) {
cameras.push_back(image_and_camera.second);
}
return cameras;
}

View File

@@ -22,6 +22,7 @@
#define LIBMV_SIMPLE_PIPELINE_RECONSTRUCTION_H_
#include "libmv/base/vector.h"
#include "libmv/base/map.h"
#include "libmv/numeric/numeric.h"
namespace libmv {
@@ -120,7 +121,11 @@ class EuclideanReconstruction {
vector<EuclideanPoint> AllPoints() const;
private:
vector<EuclideanCamera> cameras_;
// Indexed by frame number.
typedef map<int, EuclideanCamera> ImageToCameraMap;
ImageToCameraMap image_to_cameras_map_;
// Insxed by track.
vector<EuclideanPoint> points_;
};
@@ -208,7 +213,11 @@ class ProjectiveReconstruction {
vector<ProjectivePoint> AllPoints() const;
private:
vector<ProjectiveCamera> cameras_;
// Indexed by frame number.
typedef map<int, ProjectiveCamera> ImageToCameraMap;
ImageToCameraMap image_to_cameras_map_;
// Indexed by track.
vector<ProjectivePoint> points_;
};

File diff suppressed because it is too large Load Diff

View File

@@ -60,6 +60,19 @@ struct MANTA {
int flags;
} Triangle;
// Cache helper typedefs
typedef struct GridItem {
void **pointer; /* Array of pointers for this grid.*/
int type;
int *res;
string name;
} GridItem;
typedef struct FileItem {
string filename;
vector<GridItem> grids;
} FileItem;
// Manta step, handling everything
void step(struct FluidModifierData *mmd, int startFrame);
@@ -72,6 +85,7 @@ struct MANTA {
void initLiquid(FluidModifierData *mmd = NULL);
void initLiquidMesh(FluidModifierData *mmd = NULL);
void initObstacle(FluidModifierData *mmd = NULL);
void initCurvature(FluidModifierData *mmd = NULL);
void initGuiding(FluidModifierData *mmd = NULL);
void initFractions(FluidModifierData *mmd = NULL);
void initInVelocity(FluidModifierData *mmd = NULL);
@@ -761,6 +775,7 @@ struct MANTA {
bool mUsingOutflow;
bool mUsingNoise;
bool mUsingMesh;
bool mUsingDiffusion;
bool mUsingMVel;
bool mUsingLiquid;
bool mUsingSmoke;
@@ -888,12 +903,12 @@ struct MANTA {
bool updateMeshFromObj(string filename);
bool updateMeshFromUni(string filename);
bool updateParticlesFromUni(string filename, bool isSecondarySys, bool isVelData);
bool updateGridFromUni(string filename, float *grid, bool isNoise);
bool updateGridFromVDB(string filename, float *grid, bool isNoise);
bool updateGridFromRaw(string filename, float *grid, bool isNoise);
bool updateGridsFromUni(string filename, vector<GridItem> grids);
bool updateGridsFromVDB(string filename, vector<GridItem> grids);
bool updateGridsFromRaw(string filename, vector<GridItem> grids);
bool updateMeshFromFile(string filename);
bool updateParticlesFromFile(string filename, bool isSecondarySys, bool isVelData);
bool updateGridFromFile(string filename, float *grid, bool isNoise);
bool updateGridsFromFile(string filename, vector<GridItem> grids);
string getDirectory(struct FluidModifierData *mmd, string subdirectory);
string getFile(struct FluidModifierData *mmd,
string subdirectory,

View File

@@ -259,7 +259,7 @@ const std::string fluid_alloc =
"\n\
mantaMsg('Fluid alloc data')\n\
flags_s$ID$ = s$ID$.create(FlagGrid)\n\
vel_s$ID$ = s$ID$.create(MACGrid)\n\
vel_s$ID$ = s$ID$.create(MACGrid, name='$NAME_VELOCITY$')\n\
velTmp_s$ID$ = s$ID$.create(MACGrid)\n\
x_vel_s$ID$ = s$ID$.create(RealGrid)\n\
y_vel_s$ID$ = s$ID$.create(RealGrid)\n\

View File

@@ -80,11 +80,11 @@ mantaMsg('Liquid alloc')\n\
phiParts_s$ID$ = s$ID$.create(LevelsetGrid)\n\
phi_s$ID$ = s$ID$.create(LevelsetGrid)\n\
phiTmp_s$ID$ = s$ID$.create(LevelsetGrid)\n\
curvature_s$ID$ = s$ID$.create(RealGrid)\n\
velOld_s$ID$ = s$ID$.create(MACGrid)\n\
velParts_s$ID$ = s$ID$.create(MACGrid)\n\
mapWeights_s$ID$ = s$ID$.create(MACGrid)\n\
fractions_s$ID$ = None # allocated dynamically\n\
curvature_s$ID$ = None\n\
\n\
pp_s$ID$ = s$ID$.create(BasicParticleSystem)\n\
pVel_pp$ID$ = pp_s$ID$.create(PdataVec3)\n\
@@ -124,6 +124,11 @@ liquid_mesh_dict_s$ID$ = dict(lMesh=mesh_sm$ID$)\n\
if using_speedvectors_s$ID$:\n\
liquid_meshvel_dict_s$ID$ = dict(lVelMesh=mVel_mesh$ID$)\n";
const std::string liquid_alloc_curvature =
"\n\
mantaMsg('Liquid alloc curvature')\n\
curvature_s$ID$ = s$ID$.create(RealGrid)\n";
const std::string liquid_alloc_particles =
"\n\
ppSnd_sp$ID$ = sp$ID$.create(BasicParticleSystem)\n\
@@ -227,7 +232,7 @@ def liquid_step_$ID$():\n\
mantaMsg('Liquid step')\n\
\n\
mantaMsg('Advecting particles')\n\
pp_s$ID$.advectInGrid(flags=flags_s$ID$, vel=vel_s$ID$, integrationMode=IntRK4, deleteInObstacle=deleteInObstacle_s$ID$, stopInObstacle=False)\n\
pp_s$ID$.advectInGrid(flags=flags_s$ID$, vel=vel_s$ID$, integrationMode=IntRK4, deleteInObstacle=deleteInObstacle_s$ID$, stopInObstacle=False, skipNew=True)\n\
\n\
mantaMsg('Pushing particles out of obstacles')\n\
pushOutofObs(parts=pp_s$ID$, flags=flags_s$ID$, phiObs=phiObs_s$ID$)\n\
@@ -284,12 +289,13 @@ def liquid_step_$ID$():\n\
alphaV = viscosity_s$ID$ * s$ID$.timestep * float(res_s$ID$*res_s$ID$)\n\
setWallBcs(flags=flags_s$ID$, vel=vel_s$ID$, obvel=None if using_fractions_s$ID$ else obvel_s$ID$, phiObs=phiObs_s$ID$, fractions=fractions_s$ID$)\n\
cgSolveDiffusion(flags_s$ID$, vel_s$ID$, alphaV)\n\
\n\
mantaMsg('Curvature')\n\
getLaplacian(laplacian=curvature_s$ID$, grid=phi_s$ID$)\n\
curvature_s$ID$.clamp(-1.0, 1.0)\n\
\n\
setWallBcs(flags=flags_s$ID$, vel=vel_s$ID$, obvel=None if using_fractions_s$ID$ else obvel_s$ID$, phiObs=phiObs_s$ID$, fractions=fractions_s$ID$)\n\
\n\
mantaMsg('Calculating curvature')\n\
getLaplacian(laplacian=curvature_s$ID$, grid=phi_s$ID$)\n\
\n\
if using_guiding_s$ID$:\n\
mantaMsg('Guiding and pressure')\n\
PD_fluid_guiding(vel=vel_s$ID$, velT=velT_s$ID$, flags=flags_s$ID$, phi=phi_s$ID$, curv=curvature_s$ID$, surfTens=surfaceTension_s$ID$, fractions=fractions_s$ID$, weight=weightGuide_s$ID$, blurRadius=beta_sg$ID$, pressure=pressure_s$ID$, tau=tau_sg$ID$, sigma=sigma_sg$ID$, theta=theta_sg$ID$, zeroPressureFixing=not doOpen_s$ID$)\n\
@@ -343,7 +349,10 @@ def liquid_step_mesh_$ID$():\n\
interpolateMACGrid(target=vel_sm$ID$, source=vel_s$ID$)\n\
mVel_mesh$ID$.setSource(vel_sm$ID$, isMAC=True)\n\
\n\
phi_sm$ID$.setBound(0.5,int(((upres_sm$ID$)*2)-2) )\n\
# Set 0.5 boundary at walls + account for extra wall thickness in fractions mode + account for grid scaling:\n\
# E.g. at upres=1 we expect 1 cell border (or 2 with fractions), at upres=2 we expect 2 cell border (or 4 with fractions), etc.\n\
# Use -1 since setBound() starts counting at 0 (and additional -1 for fractions to account for solid/fluid interface cells)\n\
phi_sm$ID$.setBound(value=0.5, boundaryWidth=(upres_sm$ID$*2)-2 if using_fractions_s$ID$ else upres_sm$ID$-1)\n\
phi_sm$ID$.createMesh(mesh_sm$ID$)\n";
const std::string liquid_step_particles =

View File

@@ -81,10 +81,10 @@ using_fire_s$ID$ = True\n";
const std::string smoke_alloc =
"\n\
mantaMsg('Smoke alloc')\n\
shadow_s$ID$ = s$ID$.create(RealGrid)\n\
shadow_s$ID$ = s$ID$.create(RealGrid, name='$NAME_SHADOW$')\n\
emission_s$ID$ = s$ID$.create(RealGrid)\n\
emissionIn_s$ID$ = s$ID$.create(RealGrid)\n\
density_s$ID$ = s$ID$.create(RealGrid)\n\
density_s$ID$ = s$ID$.create(RealGrid, name='$NAME_DENSITY$')\n\
densityIn_s$ID$ = s$ID$.create(RealGrid)\n\
heat_s$ID$ = None # allocated dynamically\n\
heatIn_s$ID$ = None\n\
@@ -108,7 +108,7 @@ const std::string smoke_alloc_noise =
"\n\
mantaMsg('Smoke alloc noise')\n\
vel_sn$ID$ = sn$ID$.create(MACGrid)\n\
density_sn$ID$ = sn$ID$.create(RealGrid)\n\
density_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_DENSITYNOISE$')\n\
phiIn_sn$ID$ = sn$ID$.create(LevelsetGrid)\n\
phiOut_sn$ID$ = sn$ID$.create(LevelsetGrid)\n\
phiObs_sn$ID$ = sn$ID$.create(LevelsetGrid)\n\
@@ -157,9 +157,9 @@ if 'color_g_s$ID$' in globals(): del color_g_s$ID$\n\
if 'color_b_s$ID$' in globals(): del color_b_s$ID$\n\
\n\
mantaMsg('Allocating colors')\n\
color_r_s$ID$ = s$ID$.create(RealGrid)\n\
color_g_s$ID$ = s$ID$.create(RealGrid)\n\
color_b_s$ID$ = s$ID$.create(RealGrid)\n\
color_r_s$ID$ = s$ID$.create(RealGrid, name='$NAME_COLORR$')\n\
color_g_s$ID$ = s$ID$.create(RealGrid, name='$NAME_COLORG$')\n\
color_b_s$ID$ = s$ID$.create(RealGrid, name='$NAME_COLORB$')\n\
color_r_in_s$ID$ = s$ID$.create(RealGrid)\n\
color_g_in_s$ID$ = s$ID$.create(RealGrid)\n\
color_b_in_s$ID$ = s$ID$.create(RealGrid)\n\
@@ -178,9 +178,9 @@ if 'color_g_sn$ID$' in globals(): del color_g_sn$ID$\n\
if 'color_b_sn$ID$' in globals(): del color_b_sn$ID$\n\
\n\
mantaMsg('Allocating colors noise')\n\
color_r_sn$ID$ = sn$ID$.create(RealGrid)\n\
color_g_sn$ID$ = sn$ID$.create(RealGrid)\n\
color_b_sn$ID$ = sn$ID$.create(RealGrid)\n\
color_r_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_COLORRNOISE$')\n\
color_g_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_COLORGNOISE$')\n\
color_b_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_COLORBNOISE$')\n\
\n\
# Add objects to dict to load them later on\n\
if 'smoke_noise_dict_final_s$ID$' in globals():\n\
@@ -213,7 +213,7 @@ if 'heat_s$ID$' in globals(): del heat_s$ID$\n\
if 'heatIn_s$ID$' in globals(): del heatIn_s$ID$\n\
\n\
mantaMsg('Allocating heat')\n\
heat_s$ID$ = s$ID$.create(RealGrid)\n\
heat_s$ID$ = s$ID$.create(RealGrid, name='$NAME_HEAT$')\n\
heatIn_s$ID$ = s$ID$.create(RealGrid)\n\
\n\
# Add objects to dict to load them later on\n\
@@ -232,9 +232,9 @@ if 'fuelIn_s$ID$' in globals(): del fuelIn_s$ID$\n\
if 'reactIn_s$ID$' in globals(): del reactIn_s$ID$\n\
\n\
mantaMsg('Allocating fire')\n\
flame_s$ID$ = s$ID$.create(RealGrid)\n\
fuel_s$ID$ = s$ID$.create(RealGrid)\n\
react_s$ID$ = s$ID$.create(RealGrid)\n\
flame_s$ID$ = s$ID$.create(RealGrid, name='$NAME_FLAME$')\n\
fuel_s$ID$ = s$ID$.create(RealGrid, name='$NAME_FUEL$')\n\
react_s$ID$ = s$ID$.create(RealGrid, name='$NAME_REACT$')\n\
fuelIn_s$ID$ = s$ID$.create(RealGrid)\n\
reactIn_s$ID$ = s$ID$.create(RealGrid)\n\
\n\
@@ -252,9 +252,9 @@ if 'fuel_sn$ID$' in globals(): del fuel_sn$ID$\n\
if 'react_sn$ID$' in globals(): del react_sn$ID$\n\
\n\
mantaMsg('Allocating fire noise')\n\
flame_sn$ID$ = sn$ID$.create(RealGrid)\n\
fuel_sn$ID$ = sn$ID$.create(RealGrid)\n\
react_sn$ID$ = sn$ID$.create(RealGrid)\n\
flame_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_FLAMENOISE$')\n\
fuel_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_FUELNOISE$')\n\
react_sn$ID$ = sn$ID$.create(RealGrid, name='$NAME_REACTNOISE$')\n\
\n\
# Add objects to dict to load them later on\n\
if 'smoke_noise_dict_final_s$ID$' in globals():\n\

View File

@@ -31,7 +31,6 @@ set(SRC
opensubdiv_capi_type.h
opensubdiv_converter_capi.h
opensubdiv_evaluator_capi.h
opensubdiv_gl_mesh_capi.h
opensubdiv_topology_refiner_capi.h
)
@@ -54,30 +53,20 @@ if(WITH_OPENSUBDIV)
internal/opensubdiv.cc
internal/opensubdiv_converter_factory.cc
internal/opensubdiv_converter_internal.cc
internal/opensubdiv_converter_orient.cc
internal/opensubdiv_device_context_cuda.cc
internal/opensubdiv_device_context_opencl.cc
internal/opensubdiv_evaluator.cc
internal/opensubdiv_evaluator_internal.cc
internal/opensubdiv_gl_mesh.cc
internal/opensubdiv_gl_mesh_draw.cc
internal/opensubdiv_gl_mesh_fvar.cc
internal/opensubdiv_gl_mesh_internal.cc
internal/opensubdiv_topology_refiner.cc
internal/opensubdiv_topology_refiner_internal.cc
internal/opensubdiv_util.cc
internal/opensubdiv_converter_factory.h
internal/opensubdiv_converter_internal.h
internal/opensubdiv_converter_orient.h
internal/opensubdiv_converter_orient_impl.h
internal/opensubdiv_device_context_cuda.h
internal/opensubdiv_device_context_opencl.h
internal/opensubdiv_edge_map.h
internal/opensubdiv_evaluator_internal.h
internal/opensubdiv_gl_mesh_draw.h
internal/opensubdiv_gl_mesh_fvar.h
internal/opensubdiv_gl_mesh_internal.h
internal/opensubdiv_internal.h
internal/opensubdiv_topology_refiner_internal.h
internal/opensubdiv_util.h
@@ -101,11 +90,7 @@ if(WITH_OPENSUBDIV)
OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK)
OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_COMPUTE)
data_to_c_simple(shader/gpu_shader_opensubdiv_vertex.glsl SRC)
data_to_c_simple(shader/gpu_shader_opensubdiv_geometry.glsl SRC)
data_to_c_simple(shader/gpu_shader_opensubdiv_fragment.glsl SRC)
add_definitions(-DGLEW_STATIC)
add_definitions(${GL_DEFINITIONS})
add_definitions(-DOSD_USES_GLEW)
if(WIN32)
@@ -131,7 +116,6 @@ else()
list(APPEND SRC
stub/opensubdiv_stub.cc
stub/opensubdiv_evaluator_stub.cc
stub/opensubdiv_gl_mesh_stub.cc
stub/opensubdiv_topology_refiner_stub.cc
)
endif()

View File

@@ -24,7 +24,6 @@
#include "opensubdiv_device_context_cuda.h"
#include "opensubdiv_device_context_opencl.h"
#include "opensubdiv_gl_mesh_capi.h"
void openSubdiv_init(void)
{
@@ -34,7 +33,6 @@ void openSubdiv_init(void)
void openSubdiv_cleanup(void)
{
openSubdiv_deinitGLMeshDrawingResources();
}
int openSubdiv_getAvailableEvaluators(void)
@@ -86,7 +84,7 @@ int openSubdiv_getVersionHex(void)
}
int major = 0, minor = 0, patch = 0;
vector<string> tokens;
opensubdiv_capi::stringSplit(&tokens, version, "_", true);
blender::opensubdiv::stringSplit(&tokens, version, "_", true);
if (tokens.size() == 3) {
major = atoi(tokens[0].c_str());
minor = atoi(tokens[1].c_str());

View File

@@ -28,14 +28,13 @@
#include <opensubdiv/far/topologyRefinerFactory.h>
#include "internal/opensubdiv_converter_internal.h"
#include "internal/opensubdiv_converter_orient.h"
#include "internal/opensubdiv_internal.h"
#include "internal/opensubdiv_util.h"
#include "opensubdiv_converter_capi.h"
using opensubdiv_capi::min;
using opensubdiv_capi::stack;
using opensubdiv_capi::vector;
using blender::opensubdiv::min;
using blender::opensubdiv::stack;
using blender::opensubdiv::vector;
struct TopologyRefinerData {
const OpenSubdiv_Converter *converter;
@@ -246,7 +245,8 @@ inline void TopologyRefinerFactory<TopologyRefinerData>::reportInvalidTopology(
} /* namespace OPENSUBDIV_VERSION */
} /* namespace OpenSubdiv */
namespace opensubdiv_capi {
namespace blender {
namespace opensubdiv {
namespace {
@@ -292,4 +292,5 @@ OpenSubdiv::Far::TopologyRefiner *createOSDTopologyRefinerFromConverter(
return TopologyRefinerFactory<TopologyRefinerData>::Create(cb_data, topology_options);
}
} // namespace opensubdiv_capi
} // namespace opensubdiv
} // namespace blender

View File

@@ -27,11 +27,13 @@
struct OpenSubdiv_Converter;
namespace opensubdiv_capi {
namespace blender {
namespace opensubdiv {
OpenSubdiv::Far::TopologyRefiner *createOSDTopologyRefinerFromConverter(
struct OpenSubdiv_Converter *converter);
} // namespace opensubdiv_capi
} // namespace opensubdiv
} // namespace blender
#endif // OPENSUBDIV_CONVERTER_FACTORY_H_

View File

@@ -25,7 +25,8 @@
#include <cassert>
#include <opensubdiv/sdc/crease.h>
namespace opensubdiv_capi {
namespace blender {
namespace opensubdiv {
OpenSubdiv::Sdc::SchemeType getSchemeTypeFromCAPI(OpenSubdiv_SchemeType type)
{
@@ -85,4 +86,5 @@ OpenSubdiv_FVarLinearInterpolation getCAPIFVarLinearInterpolationFromOSD(
return OSD_FVAR_LINEAR_INTERPOLATION_NONE;
}
} // namespace opensubdiv_capi
} // namespace opensubdiv
} // namespace blender

View File

@@ -30,7 +30,8 @@
struct OpenSubdiv_Converter;
namespace opensubdiv_capi {
namespace blender {
namespace opensubdiv {
// Convert scheme type from C-API enum to an OpenSubdiv native enum.
OpenSubdiv::Sdc::SchemeType getSchemeTypeFromCAPI(OpenSubdiv_SchemeType type);
@@ -44,6 +45,7 @@ OpenSubdiv::Sdc::Options::FVarLinearInterpolation getFVarLinearInterpolationFrom
OpenSubdiv_FVarLinearInterpolation getCAPIFVarLinearInterpolationFromOSD(
OpenSubdiv::Sdc::Options::FVarLinearInterpolation linear_interpolation);
} // namespace opensubdiv_capi
} // namespace opensubdiv
} // namespace blender
#endif // OPENSUBDIV_CONVERTER_INTERNAL_H_

View File

@@ -1,67 +0,0 @@
// Copyright 2018 Blender Foundation. All rights reserved.
//
// 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.
//
// Author: Sergey Sharybin
#include "internal/opensubdiv_converter_orient.h"
#include "internal/opensubdiv_internal.h"
namespace opensubdiv_capi {
void checkOrientedVertexConnectivity(const int num_vertex_edges,
const int num_vertex_faces,
const int *vertex_edges,
const int *vertex_faces,
const int *dst_vertex_edges,
const int *dst_vertex_faces)
{
#ifndef NDEBUG
for (int i = 0; i < num_vertex_faces; ++i) {
bool found = false;
for (int j = 0; j < num_vertex_faces; ++j) {
if (vertex_faces[i] == dst_vertex_faces[j]) {
found = true;
break;
}
}
if (!found) {
assert(!"vert-faces connectivity ruined");
}
}
for (int i = 0; i < num_vertex_edges; ++i) {
bool found = false;
for (int j = 0; j < num_vertex_edges; ++j) {
if (vertex_edges[i] == dst_vertex_edges[j]) {
found = true;
break;
}
}
if (!found) {
assert(!"vert-edges connectivity ruined");
}
}
#else
(void)num_vertex_edges;
(void)num_vertex_faces;
(void)vertex_edges;
(void)vertex_faces;
(void)dst_vertex_edges;
(void)dst_vertex_faces;
#endif
}
} // namespace opensubdiv_capi

View File

@@ -1,49 +0,0 @@
// Copyright 2018 Blender Foundation. All rights reserved.
//
// 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.
//
// Author: Sergey Sharybin
#ifndef OPENSUBDIV_CONVERTER_ORIENT_H_
# define OPENSUBDIV_CONVERTER_ORIENT_H_
# include <opensubdiv/far/types.h>
// Set of utility functions which are needed to bring topology to an orientation
// (or, winding, if you wish) which OpenSubdiv expects.
namespace opensubdiv_capi {
inline void reverseFaceVertices(int *face_vertices, const int num_vertices);
// TODO(sergey): Document which value corresponds to which winding.
inline int getLoopWinding(int vert0_of_face, int vert1_of_face);
inline void reverseFaceLoops(OpenSubdiv::Far::IndexArray *face_vertices,
OpenSubdiv::Far::IndexArray *face_edges);
// Used for debugging, checks whether orientation happened correct.
void checkOrientedVertexConnectivity(const int num_vertex_edges,
const int num_vertex_faces,
const int *vertex_edges,
const int *vertex_faces,
const int *dst_vertex_edges,
const int *dst_vertex_faces);
} // namespace opensubdiv_capi
#endif // OPENSUBDIV_CONVERTER_ORIENT_H_
#include "internal/opensubdiv_converter_orient_impl.h"

View File

@@ -1,69 +0,0 @@
// Copyright 2018 Blender Foundation. All rights reserved.
//
// 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.
//
// Author: Sergey Sharybin
#ifndef OPENSUBDIV_CONVERTER_ORIENT_IMPL_H_
#define OPENSUBDIV_CONVERTER_ORIENT_IMPL_H_
#include "internal/opensubdiv_converter_orient.h"
#include <cmath>
#include "internal/opensubdiv_util.h"
namespace opensubdiv_capi {
inline void reverseFaceVertices(int *face_vertices, const int num_vertices)
{
int last_vert = face_vertices[num_vertices - 1];
for (int i = num_vertices - 1; i > 0; --i) {
face_vertices[i] = face_vertices[i - 1];
}
face_vertices[0] = last_vert;
}
inline int getLoopWinding(int vert0_of_face, int vert1_of_face)
{
int delta_face = vert1_of_face - vert0_of_face;
if (abs(delta_face) != 1) {
if (delta_face > 0) {
delta_face = -1;
}
else {
delta_face = 1;
}
}
return delta_face;
}
inline void reverseFaceLoops(OpenSubdiv::Far::IndexArray *face_vertices,
OpenSubdiv::Far::IndexArray *face_edges)
{
const int num_face_vertices = face_vertices->size();
for (int i = 0; i < num_face_vertices / 2; ++i) {
const int j = num_face_vertices - i - 1;
if (i != j) {
swap((*face_vertices)[i], (*face_vertices)[j]);
swap((*face_edges)[i], (*face_edges)[j]);
}
}
reverseFaceVertices(&(*face_vertices)[0], num_face_vertices);
}
} // namespace opensubdiv_capi
#endif // OPENSUBDIV_CONVERTER_ORIENT_IMPL_H_

View File

@@ -21,7 +21,8 @@
#include "internal/opensubdiv_util.h"
namespace opensubdiv_capi {
namespace blender {
namespace opensubdiv {
// Helper class to ease dealing with edge indexing.
// Simply takes care of ensuring order of vertices is strictly defined.
@@ -144,12 +145,13 @@ template<typename T> typename EdgeTagMap<T>::value_type &EdgeTagMap<T>::operator
return edge_tags_[key];
}
} // namespace opensubdiv_capi
} // namespace opensubdiv
} // namespace blender
namespace std {
template<> struct hash<opensubdiv_capi::EdgeKey> {
std::size_t operator()(const opensubdiv_capi::EdgeKey &key) const
template<> struct hash<blender::opensubdiv::EdgeKey> {
std::size_t operator()(const blender::opensubdiv::EdgeKey &key) const
{
return key.hash();
}

View File

@@ -53,7 +53,8 @@ using OpenSubdiv::Osd::CpuPatchTable;
using OpenSubdiv::Osd::CpuVertexBuffer;
using OpenSubdiv::Osd::PatchCoord;
namespace opensubdiv_capi {
namespace blender {
namespace opensubdiv {
namespace {
@@ -731,7 +732,8 @@ void CpuEvalOutputAPI::evaluatePatchesLimit(const OpenSubdiv_PatchCoord *patch_c
}
}
} // namespace opensubdiv_capi
} // namespace opensubdiv
} // namespace blender
OpenSubdiv_EvaluatorInternal::OpenSubdiv_EvaluatorInternal()
: eval_output(NULL), patch_map(NULL), patch_table(NULL)
@@ -748,7 +750,7 @@ OpenSubdiv_EvaluatorInternal::~OpenSubdiv_EvaluatorInternal()
OpenSubdiv_EvaluatorInternal *openSubdiv_createEvaluatorInternal(
OpenSubdiv_TopologyRefiner *topology_refiner)
{
using opensubdiv_capi::vector;
using blender::opensubdiv::vector;
TopologyRefiner *refiner = topology_refiner->internal->osd_topology_refiner;
if (refiner == NULL) {
// Happens on bad topology.
@@ -851,13 +853,13 @@ OpenSubdiv_EvaluatorInternal *openSubdiv_createEvaluatorInternal(
}
// Create OpenSubdiv's CPU side evaluator.
// TODO(sergey): Make it possible to use different evaluators.
opensubdiv_capi::CpuEvalOutput *eval_output = new opensubdiv_capi::CpuEvalOutput(
blender::opensubdiv::CpuEvalOutput *eval_output = new blender::opensubdiv::CpuEvalOutput(
vertex_stencils, varying_stencils, all_face_varying_stencils, 2, patch_table);
OpenSubdiv::Far::PatchMap *patch_map = new PatchMap(*patch_table);
// Wrap everything we need into an object which we control from our side.
OpenSubdiv_EvaluatorInternal *evaluator_descr;
evaluator_descr = OBJECT_GUARDED_NEW(OpenSubdiv_EvaluatorInternal);
evaluator_descr->eval_output = new opensubdiv_capi::CpuEvalOutputAPI(eval_output, patch_map);
evaluator_descr->eval_output = new blender::opensubdiv::CpuEvalOutputAPI(eval_output, patch_map);
evaluator_descr->patch_map = patch_map;
evaluator_descr->patch_table = patch_table;
// TOOD(sergey): Look into whether we've got duplicated stencils arrays.

View File

@@ -29,7 +29,8 @@
struct OpenSubdiv_PatchCoord;
struct OpenSubdiv_TopologyRefiner;
namespace opensubdiv_capi {
namespace blender {
namespace opensubdiv {
// Anonymous forward declaration of actual evaluator implementation.
class CpuEvalOutput;
@@ -132,14 +133,15 @@ class CpuEvalOutputAPI {
OpenSubdiv::Far::PatchMap *patch_map_;
};
} // namespace opensubdiv_capi
} // namespace opensubdiv
} // namespace blender
struct OpenSubdiv_EvaluatorInternal {
public:
OpenSubdiv_EvaluatorInternal();
~OpenSubdiv_EvaluatorInternal();
opensubdiv_capi::CpuEvalOutputAPI *eval_output;
blender::opensubdiv::CpuEvalOutputAPI *eval_output;
const OpenSubdiv::Far::PatchMap *patch_map;
const OpenSubdiv::Far::PatchTable *patch_table;
};

View File

@@ -1,260 +0,0 @@
// Copyright 2013 Blender Foundation. All rights reserved.
//
// 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.
#include "opensubdiv_gl_mesh_capi.h"
#ifdef _MSC_VER
# include <iso646.h>
#endif
#include <opensubdiv/far/stencilTable.h>
#include <opensubdiv/osd/glMesh.h>
#include <opensubdiv/osd/glPatchTable.h>
using OpenSubdiv::Far::StencilTable;
using OpenSubdiv::Osd::GLMeshInterface;
using OpenSubdiv::Osd::GLPatchTable;
using OpenSubdiv::Osd::Mesh;
using OpenSubdiv::Osd::MeshBitset;
// CPU backend.
#include <opensubdiv/osd/cpuEvaluator.h>
#include <opensubdiv/osd/cpuGLVertexBuffer.h>
using OpenSubdiv::Osd::CpuEvaluator;
using OpenSubdiv::Osd::CpuGLVertexBuffer;
typedef Mesh<CpuGLVertexBuffer, StencilTable, CpuEvaluator, GLPatchTable> OsdCpuMesh;
// OpenMP backend.
#ifdef OPENSUBDIV_HAS_OPENMP
# include <opensubdiv/osd/ompEvaluator.h>
using OpenSubdiv::Osd::OmpEvaluator;
typedef Mesh<CpuGLVertexBuffer, StencilTable, OmpEvaluator, GLPatchTable> OsdOmpMesh;
#endif
// OpenCL backend.
#ifdef OPENSUBDIV_HAS_OPENCL
# include "opensubdiv_device_context_opencl.h"
# include <opensubdiv/osd/clEvaluator.h>
# include <opensubdiv/osd/clGLVertexBuffer.h>
using OpenSubdiv::Osd::CLEvaluator;
using OpenSubdiv::Osd::CLGLVertexBuffer;
using OpenSubdiv::Osd::CLStencilTable;
/* TODO(sergey): Use CLDeviceContext similar to OSD examples? */
typedef Mesh<CLGLVertexBuffer, CLStencilTable, CLEvaluator, GLPatchTable, CLDeviceContext>
OsdCLMesh;
static CLDeviceContext g_cl_device_context;
#endif
// CUDA backend.
#ifdef OPENSUBDIV_HAS_CUDA
# include "opensubdiv_device_context_cuda.h"
# include <opensubdiv/osd/cudaEvaluator.h>
# include <opensubdiv/osd/cudaGLVertexBuffer.h>
using OpenSubdiv::Osd::CudaEvaluator;
using OpenSubdiv::Osd::CudaGLVertexBuffer;
using OpenSubdiv::Osd::CudaStencilTable;
typedef Mesh<CudaGLVertexBuffer, CudaStencilTable, CudaEvaluator, GLPatchTable> OsdCudaMesh;
static CudaDeviceContext g_cuda_device_context;
#endif
// Transform feedback backend.
#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK
# include <opensubdiv/osd/glVertexBuffer.h>
# include <opensubdiv/osd/glXFBEvaluator.h>
using OpenSubdiv::Osd::GLStencilTableTBO;
using OpenSubdiv::Osd::GLVertexBuffer;
using OpenSubdiv::Osd::GLXFBEvaluator;
typedef Mesh<GLVertexBuffer, GLStencilTableTBO, GLXFBEvaluator, GLPatchTable>
OsdGLSLTransformFeedbackMesh;
#endif
// GLSL compute backend.
#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE
# include <opensubdiv/osd/glComputeEvaluator.h>
# include <opensubdiv/osd/glVertexBuffer.h>
using OpenSubdiv::Osd::GLComputeEvaluator;
using OpenSubdiv::Osd::GLStencilTableSSBO;
using OpenSubdiv::Osd::GLVertexBuffer;
typedef Mesh<GLVertexBuffer, GLStencilTableSSBO, GLComputeEvaluator, GLPatchTable>
OsdGLSLComputeMesh;
#endif
#include "MEM_guardedalloc.h"
#include "internal/opensubdiv_gl_mesh_draw.h"
#include "internal/opensubdiv_gl_mesh_fvar.h"
#include "internal/opensubdiv_gl_mesh_internal.h"
#include "internal/opensubdiv_topology_refiner_internal.h"
#include "internal/opensubdiv_util.h"
#include "opensubdiv_topology_refiner_capi.h"
using opensubdiv_capi::vector;
namespace {
GLMeshInterface *createGLMeshInterface(OpenSubdiv::Far::TopologyRefiner *topology_refiner,
const MeshBitset &bits,
const int num_vertex_elements,
const int num_varying_elements,
const int level,
eOpenSubdivEvaluator evaluator_type)
{
GLMeshInterface *mesh = NULL;
switch (evaluator_type) {
#define CHECK_EVALUATOR_TYPE(type, class) \
case OPENSUBDIV_EVALUATOR_##type: \
mesh = new class(topology_refiner, num_vertex_elements, num_varying_elements, level, bits); \
break;
#define CHECK_EVALUATOR_TYPE_STUB(type) \
case OPENSUBDIV_EVALUATOR_##type: \
mesh = NULL; \
break;
CHECK_EVALUATOR_TYPE(CPU, OsdCpuMesh)
#ifdef OPENSUBDIV_HAS_OPENMP
CHECK_EVALUATOR_TYPE(OPENMP, OsdOmpMesh)
#else
CHECK_EVALUATOR_TYPE_STUB(OPENMP)
#endif
#ifdef OPENSUBDIV_HAS_OPENCL
CHECK_EVALUATOR_TYPE(OPENCL, OsdCLMesh)
#else
CHECK_EVALUATOR_TYPE_STUB(OPENCL)
#endif
#ifdef OPENSUBDIV_HAS_CUDA
CHECK_EVALUATOR_TYPE(CUDA, OsdCudaMesh)
#else
CHECK_EVALUATOR_TYPE_STUB(CUDA)
#endif
#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK
CHECK_EVALUATOR_TYPE(GLSL_TRANSFORM_FEEDBACK, OsdGLSLTransformFeedbackMesh)
#else
CHECK_EVALUATOR_TYPE_STUB(GLSL_TRANSFORM_FEEDBACK)
#endif
#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE
CHECK_EVALUATOR_TYPE(GLSL_COMPUTE, OsdGLSLComputeMesh)
#else
CHECK_EVALUATOR_TYPE_STUB(GLSL_COMPUTE)
#endif
#undef CHECK_EVALUATOR_TYPE
#undef CHECK_EVALUATOR_TYPE_STUB
}
return mesh;
}
////////////////////////////////////////////////////////////////////////////////
// GLMesh structure "methods".
opensubdiv_capi::GLMeshFVarData *createFVarData(OpenSubdiv::Far::TopologyRefiner *topology_refiner,
GLMeshInterface *mesh,
const float *fvar_src_buffer)
{
using opensubdiv_capi::GLMeshFVarData;
GLMeshFVarData *fvar_data = new GLMeshFVarData();
fvar_data->create(topology_refiner, mesh->GetFarPatchTable(), 2, fvar_src_buffer);
return fvar_data;
}
unsigned int getPatchIndexBuffer(OpenSubdiv_GLMesh *gl_mesh)
{
return gl_mesh->internal->mesh_interface->GetPatchTable()->GetPatchIndexBuffer();
}
void bindVertexBuffer(OpenSubdiv_GLMesh *gl_mesh)
{
gl_mesh->internal->mesh_interface->BindVertexBuffer();
}
void setCoarsePositions(OpenSubdiv_GLMesh *gl_mesh,
const float *positions,
const int start_vertex,
const int num_vertices)
{
gl_mesh->internal->mesh_interface->UpdateVertexBuffer(positions, start_vertex, num_vertices);
}
void refine(OpenSubdiv_GLMesh *gl_mesh)
{
gl_mesh->internal->mesh_interface->Refine();
}
void synchronize(struct OpenSubdiv_GLMesh *gl_mesh)
{
gl_mesh->internal->mesh_interface->Synchronize();
}
void assignFunctionPointers(OpenSubdiv_GLMesh *gl_mesh)
{
gl_mesh->getPatchIndexBuffer = getPatchIndexBuffer;
gl_mesh->bindVertexBuffer = bindVertexBuffer;
gl_mesh->setCoarsePositions = setCoarsePositions;
gl_mesh->refine = refine;
gl_mesh->synchronize = synchronize;
gl_mesh->prepareDraw = opensubdiv_capi::GLMeshDisplayPrepare;
gl_mesh->drawPatches = opensubdiv_capi::GLMeshDisplayDrawPatches;
}
} // namespace
struct OpenSubdiv_GLMesh *openSubdiv_createOsdGLMeshFromTopologyRefiner(
OpenSubdiv_TopologyRefiner *topology_refiner, eOpenSubdivEvaluator evaluator_type)
{
using OpenSubdiv::Far::TopologyRefiner;
TopologyRefiner *osd_topology_refiner = topology_refiner->internal->osd_topology_refiner;
// TODO(sergey): Query this from refiner.
const bool is_adaptive = false;
MeshBitset bits;
bits.set(OpenSubdiv::Osd::MeshAdaptive, is_adaptive);
bits.set(OpenSubdiv::Osd::MeshUseSingleCreasePatch, 0);
bits.set(OpenSubdiv::Osd::MeshInterleaveVarying, 1);
bits.set(OpenSubdiv::Osd::MeshFVarData, 1);
bits.set(OpenSubdiv::Osd::MeshEndCapBSplineBasis, 1);
const int num_vertex_elements = 3;
const int num_varying_elements = 3;
GLMeshInterface *mesh = createGLMeshInterface(osd_topology_refiner,
bits,
num_vertex_elements,
num_varying_elements,
osd_topology_refiner->GetMaxLevel(),
evaluator_type);
if (mesh == NULL) {
return NULL;
}
OpenSubdiv_GLMesh *gl_mesh = OBJECT_GUARDED_NEW(OpenSubdiv_GLMesh);
assignFunctionPointers(gl_mesh);
gl_mesh->internal = new OpenSubdiv_GLMeshInternal();
gl_mesh->internal->evaluator_type = evaluator_type;
gl_mesh->internal->mesh_interface = mesh;
// Face-varying support.
// TODO(sergey): This part needs to be re-done.
if (osd_topology_refiner->GetNumFVarChannels() > 0) {
// TODO(sergey): This is a temporary stub to get things compiled. Need
// to store base level UVs somewhere else.
vector<float> uvs;
vector<float> fvar_data_buffer;
opensubdiv_capi::interpolateFVarData(*osd_topology_refiner, uvs, &fvar_data_buffer);
gl_mesh->internal->fvar_data = createFVarData(
osd_topology_refiner, mesh, &fvar_data_buffer[0]);
}
else {
gl_mesh->internal->fvar_data = NULL;
}
return gl_mesh;
}
void openSubdiv_deleteOsdGLMesh(OpenSubdiv_GLMesh *gl_mesh)
{
delete gl_mesh->internal;
OBJECT_GUARDED_DELETE(gl_mesh, OpenSubdiv_GLMesh);
}

View File

@@ -1,577 +0,0 @@
// Copyright 2013 Blender Foundation. All rights reserved.
//
// 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.
//
// Author: Sergey Sharybin
#include "internal/opensubdiv_gl_mesh_draw.h"
#ifdef _MSC_VER
# include <iso646.h>
#endif
#include <GL/glew.h>
#include <cmath>
#include <cstdio>
#include <opensubdiv/osd/glMesh.h>
#ifdef OPENSUBDIV_HAS_CUDA
# include <opensubdiv/osd/cudaGLVertexBuffer.h>
#endif // OPENSUBDIV_HAS_CUDA
#include <opensubdiv/osd/cpuEvaluator.h>
#include <opensubdiv/osd/cpuGLVertexBuffer.h>
#include "internal/opensubdiv_gl_mesh_fvar.h"
#include "internal/opensubdiv_gl_mesh_internal.h"
#include "internal/opensubdiv_util.h"
#include "opensubdiv_capi.h"
#include "opensubdiv_gl_mesh_capi.h"
using OpenSubdiv::Osd::GLMeshInterface;
extern "C" char datatoc_gpu_shader_opensubdiv_vertex_glsl[];
extern "C" char datatoc_gpu_shader_opensubdiv_geometry_glsl[];
extern "C" char datatoc_gpu_shader_opensubdiv_fragment_glsl[];
// TODO(sergey): Those are a bit of bad level calls :S
extern "C" {
void copy_m3_m3(float m1[3][3], float m2[3][3]);
void copy_m3_m4(float m1[3][3], float m2[4][4]);
void adjoint_m3_m3(float m1[3][3], float m[3][3]);
float determinant_m3_array(float m[3][3]);
bool invert_m3_m3(float m1[3][3], float m2[3][3]);
bool invert_m3(float m[3][3]);
void transpose_m3(float mat[3][3]);
}
#define MAX_LIGHTS 8
#define SUPPORT_COLOR_MATERIAL
typedef struct Light {
float position[4];
float ambient[4];
float diffuse[4];
float specular[4];
float spot_direction[4];
#ifdef SUPPORT_COLOR_MATERIAL
float constant_attenuation;
float linear_attenuation;
float quadratic_attenuation;
float spot_cutoff;
float spot_exponent;
float spot_cos_cutoff;
float pad, pad2;
#endif
} Light;
typedef struct Lighting {
Light lights[MAX_LIGHTS];
int num_enabled;
} Lighting;
typedef struct Transform {
float projection_matrix[16];
float model_view_matrix[16];
float normal_matrix[9];
} Transform;
static bool g_use_osd_glsl = false;
static int g_active_uv_index = 0;
static GLuint g_flat_fill_solid_program = 0;
static GLuint g_flat_fill_texture2d_program = 0;
static GLuint g_smooth_fill_solid_program = 0;
static GLuint g_smooth_fill_texture2d_program = 0;
static GLuint g_flat_fill_solid_shadeless_program = 0;
static GLuint g_flat_fill_texture2d_shadeless_program = 0;
static GLuint g_smooth_fill_solid_shadeless_program = 0;
static GLuint g_smooth_fill_texture2d_shadeless_program = 0;
static GLuint g_wireframe_program = 0;
static GLuint g_lighting_ub = 0;
static Lighting g_lighting_data;
static Transform g_transform;
namespace {
GLuint compileShader(GLenum shaderType,
const char *version,
const char *define,
const char *source)
{
const char *sources[] = {
version,
define,
#ifdef SUPPORT_COLOR_MATERIAL
"#define SUPPORT_COLOR_MATERIAL\n",
#else
"",
#endif
source,
};
GLuint shader = glCreateShader(shaderType);
glShaderSource(shader, 4, sources, NULL);
glCompileShader(shader);
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE) {
GLchar emsg[1024];
glGetShaderInfoLog(shader, sizeof(emsg), 0, emsg);
fprintf(stderr, "Error compiling GLSL: %s\n", emsg);
fprintf(stderr, "Version: %s\n", version);
fprintf(stderr, "Defines: %s\n", define);
fprintf(stderr, "Source: %s\n", source);
return 0;
}
return shader;
}
GLuint linkProgram(const char *version, const char *define)
{
GLuint vertexShader = compileShader(
GL_VERTEX_SHADER, version, define, datatoc_gpu_shader_opensubdiv_vertex_glsl);
if (vertexShader == 0) {
return 0;
}
GLuint geometryShader = compileShader(
GL_GEOMETRY_SHADER, version, define, datatoc_gpu_shader_opensubdiv_geometry_glsl);
if (geometryShader == 0) {
return 0;
}
GLuint fragmentShader = compileShader(
GL_FRAGMENT_SHADER, version, define, datatoc_gpu_shader_opensubdiv_fragment_glsl);
if (fragmentShader == 0) {
return 0;
}
GLuint program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, geometryShader);
glAttachShader(program, fragmentShader);
glBindAttribLocation(program, 0, "position");
glBindAttribLocation(program, 1, "normal");
glLinkProgram(program);
glDeleteShader(vertexShader);
glDeleteShader(geometryShader);
glDeleteShader(fragmentShader);
GLint status;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (status == GL_FALSE) {
GLchar emsg[1024];
glGetProgramInfoLog(program, sizeof(emsg), 0, emsg);
fprintf(stderr, "Error linking GLSL program : %s\n", emsg);
fprintf(stderr, "Defines: %s\n", define);
glDeleteProgram(program);
return 0;
}
glUniformBlockBinding(program, glGetUniformBlockIndex(program, "Lighting"), 0);
if (GLEW_VERSION_4_1) {
glProgramUniform1i(program, glGetUniformLocation(program, "texture_buffer"), 0);
glProgramUniform1i(program, glGetUniformLocation(program, "FVarDataOffsetBuffer"), 30);
glProgramUniform1i(program, glGetUniformLocation(program, "FVarDataBuffer"), 31);
}
else {
glUseProgram(program);
glUniform1i(glGetUniformLocation(program, "texture_buffer"), 0);
glUniform1i(glGetUniformLocation(program, "FVarDataOffsetBuffer"), 30);
glUniform1i(glGetUniformLocation(program, "FVarDataBuffer"), 31);
glUseProgram(0);
}
return program;
}
void bindProgram(OpenSubdiv_GLMesh *gl_mesh, int program)
{
glUseProgram(program);
// Matrices
glUniformMatrix4fv(
glGetUniformLocation(program, "modelViewMatrix"), 1, false, g_transform.model_view_matrix);
glUniformMatrix4fv(
glGetUniformLocation(program, "projectionMatrix"), 1, false, g_transform.projection_matrix);
glUniformMatrix3fv(
glGetUniformLocation(program, "normalMatrix"), 1, false, g_transform.normal_matrix);
// Lighting.
glBindBuffer(GL_UNIFORM_BUFFER, g_lighting_ub);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(g_lighting_data), &g_lighting_data);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, g_lighting_ub);
// Color.
{
// TODO(sergey): Stop using glGetMaterial.
float color[4];
glGetMaterialfv(GL_FRONT, GL_DIFFUSE, color);
glUniform4fv(glGetUniformLocation(program, "diffuse"), 1, color);
glGetMaterialfv(GL_FRONT, GL_SPECULAR, color);
glUniform4fv(glGetUniformLocation(program, "specular"), 1, color);
glGetMaterialfv(GL_FRONT, GL_SHININESS, color);
glUniform1f(glGetUniformLocation(program, "shininess"), color[0]);
}
// Face-vertex data.
opensubdiv_capi::GLMeshFVarData *fvar_data = gl_mesh->internal->fvar_data;
if (fvar_data != NULL) {
if (fvar_data->texture_buffer) {
glActiveTexture(GL_TEXTURE31);
glBindTexture(GL_TEXTURE_BUFFER, fvar_data->texture_buffer);
glActiveTexture(GL_TEXTURE0);
}
if (fvar_data->offset_buffer) {
glActiveTexture(GL_TEXTURE30);
glBindTexture(GL_TEXTURE_BUFFER, fvar_data->offset_buffer);
glActiveTexture(GL_TEXTURE0);
}
glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), fvar_data->fvar_width);
if (fvar_data->channel_offsets.size() > 0 && g_active_uv_index >= 0) {
glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"),
fvar_data->channel_offsets[g_active_uv_index]);
}
else {
glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0);
}
}
else {
glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), 0);
glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0);
}
}
} // namespace
bool openSubdiv_initGLMeshDrawingResources(void)
{
static bool need_init = true;
static bool init_success = false;
if (!need_init) {
return init_success;
}
// TODO(sergey): Update OSD drawing to OpenGL 3.3 core,
// then remove following line.
return false;
const char *version = "";
if (GLEW_VERSION_3_2) {
version = "#version 150 compatibility\n";
}
else if (GLEW_VERSION_3_1) {
version =
"#version 140\n"
"#extension GL_ARB_compatibility: enable\n";
}
else {
version = "#version 130\n";
// Minimum supported for OpenSubdiv.
}
g_flat_fill_solid_program = linkProgram(version,
"#define USE_COLOR_MATERIAL\n"
"#define USE_LIGHTING\n"
"#define FLAT_SHADING\n");
g_flat_fill_texture2d_program = linkProgram(version,
"#define USE_COLOR_MATERIAL\n"
"#define USE_LIGHTING\n"
"#define USE_TEXTURE_2D\n"
"#define FLAT_SHADING\n");
g_smooth_fill_solid_program = linkProgram(version,
"#define USE_COLOR_MATERIAL\n"
"#define USE_LIGHTING\n"
"#define SMOOTH_SHADING\n");
g_smooth_fill_texture2d_program = linkProgram(version,
"#define USE_COLOR_MATERIAL\n"
"#define USE_LIGHTING\n"
"#define USE_TEXTURE_2D\n"
"#define SMOOTH_SHADING\n");
g_flat_fill_solid_shadeless_program = linkProgram(version,
"#define USE_COLOR_MATERIAL\n"
"#define FLAT_SHADING\n");
g_flat_fill_texture2d_shadeless_program = linkProgram(version,
"#define USE_COLOR_MATERIAL\n"
"#define USE_TEXTURE_2D\n"
"#define FLAT_SHADING\n");
g_smooth_fill_solid_shadeless_program = linkProgram(version,
"#define USE_COLOR_MATERIAL\n"
"#define SMOOTH_SHADING\n");
g_smooth_fill_texture2d_shadeless_program = linkProgram(version,
"#define USE_COLOR_MATERIAL\n"
"#define USE_TEXTURE_2D\n"
"#define SMOOTH_SHADING\n");
g_wireframe_program = linkProgram(version, "#define WIREFRAME\n");
glGenBuffers(1, &g_lighting_ub);
glBindBuffer(GL_UNIFORM_BUFFER, g_lighting_ub);
glBufferData(GL_UNIFORM_BUFFER, sizeof(g_lighting_data), NULL, GL_STATIC_DRAW);
need_init = false;
init_success = g_flat_fill_solid_program != 0 && g_flat_fill_texture2d_program != 0 &&
g_smooth_fill_solid_program != 0 && g_smooth_fill_texture2d_program != 0 &&
g_wireframe_program;
return init_success;
}
void openSubdiv_deinitGLMeshDrawingResources(void)
{
if (g_lighting_ub != 0) {
glDeleteBuffers(1, &g_lighting_ub);
}
#define SAFE_DELETE_PROGRAM(program) \
do { \
if (program) { \
glDeleteProgram(program); \
} \
} while (false)
SAFE_DELETE_PROGRAM(g_flat_fill_solid_program);
SAFE_DELETE_PROGRAM(g_flat_fill_texture2d_program);
SAFE_DELETE_PROGRAM(g_smooth_fill_solid_program);
SAFE_DELETE_PROGRAM(g_smooth_fill_texture2d_program);
SAFE_DELETE_PROGRAM(g_flat_fill_solid_shadeless_program);
SAFE_DELETE_PROGRAM(g_flat_fill_texture2d_shadeless_program);
SAFE_DELETE_PROGRAM(g_smooth_fill_solid_shadeless_program);
SAFE_DELETE_PROGRAM(g_smooth_fill_texture2d_shadeless_program);
SAFE_DELETE_PROGRAM(g_wireframe_program);
#undef SAFE_DELETE_PROGRAM
}
namespace opensubdiv_capi {
namespace {
GLuint prepare_patchDraw(OpenSubdiv_GLMesh *gl_mesh, bool fill_quads)
{
GLint program = 0;
if (!g_use_osd_glsl) {
glGetIntegerv(GL_CURRENT_PROGRAM, &program);
if (program) {
GLint model;
glGetIntegerv(GL_SHADE_MODEL, &model);
GLint location = glGetUniformLocation(program, "osd_flat_shading");
if (location != -1) {
glUniform1i(location, model == GL_FLAT);
}
// Face-vertex data.
opensubdiv_capi::GLMeshFVarData *fvar_data = gl_mesh->internal->fvar_data;
if (fvar_data != NULL) {
if (fvar_data->texture_buffer) {
glActiveTexture(GL_TEXTURE31);
glBindTexture(GL_TEXTURE_BUFFER, fvar_data->texture_buffer);
glActiveTexture(GL_TEXTURE0);
}
if (fvar_data->offset_buffer) {
glActiveTexture(GL_TEXTURE30);
glBindTexture(GL_TEXTURE_BUFFER, fvar_data->offset_buffer);
glActiveTexture(GL_TEXTURE0);
}
GLint location = glGetUniformLocation(program, "osd_fvar_count");
if (location != -1) {
glUniform1i(location, fvar_data->fvar_width);
}
location = glGetUniformLocation(program, "osd_active_uv_offset");
if (location != -1) {
if (fvar_data->channel_offsets.size() > 0 && g_active_uv_index >= 0) {
glUniform1i(location, fvar_data->channel_offsets[g_active_uv_index]);
}
else {
glUniform1i(location, 0);
}
}
}
else {
glUniform1i(glGetUniformLocation(program, "osd_fvar_count"), 0);
glUniform1i(glGetUniformLocation(program, "osd_active_uv_offset"), 0);
}
}
return program;
}
if (fill_quads) {
int model;
GLboolean use_texture_2d;
glGetIntegerv(GL_SHADE_MODEL, &model);
glGetBooleanv(GL_TEXTURE_2D, &use_texture_2d);
if (model == GL_FLAT) {
if (use_texture_2d) {
program = g_flat_fill_texture2d_program;
}
else {
program = g_flat_fill_solid_program;
}
}
else {
if (use_texture_2d) {
program = g_smooth_fill_texture2d_program;
}
else {
program = g_smooth_fill_solid_program;
}
}
}
else {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
program = g_wireframe_program;
}
bindProgram(gl_mesh, program);
return program;
}
void perform_drawElements(GLuint program, int patch_index, int num_elements, int start_element)
{
if (program) {
glUniform1i(glGetUniformLocation(program, "PrimitiveIdBase"), patch_index);
}
glDrawElements(GL_LINES_ADJACENCY,
num_elements,
GL_UNSIGNED_INT,
reinterpret_cast<void *>(start_element * sizeof(unsigned int)));
}
void finishPatchDraw(bool fill_quads)
{
// TODO(sergey): Some of the stuff could be done once after the whole
// mesh is displayed.
/// Restore state.
if (!fill_quads) {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
glBindVertexArray(0);
if (g_use_osd_glsl) {
// TODO(sergey): Store previously used program and roll back to it?
glUseProgram(0);
}
}
void drawPartitionPatchesRange(GLMeshInterface *mesh,
GLuint program,
int start_patch,
int num_patches)
{
int traversed_patches = 0, num_remained_patches = num_patches;
const OpenSubdiv::Osd::PatchArrayVector &patches = mesh->GetPatchTable()->GetPatchArrays();
for (int i = 0; i < patches.size(); ++i) {
const OpenSubdiv::Osd::PatchArray &patch = patches[i];
OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor();
OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType();
if (patchType == OpenSubdiv::Far::PatchDescriptor::QUADS) {
const int num_block_patches = patch.GetNumPatches();
if (start_patch >= traversed_patches &&
start_patch < traversed_patches + num_block_patches) {
const int num_control_verts = desc.GetNumControlVertices();
const int start_draw_patch = start_patch - traversed_patches;
const int num_draw_patches = min(num_remained_patches,
num_block_patches - start_draw_patch);
perform_drawElements(program,
i + start_draw_patch,
num_draw_patches * num_control_verts,
patch.GetIndexBase() + start_draw_patch * num_control_verts);
num_remained_patches -= num_draw_patches;
}
if (num_remained_patches == 0) {
break;
}
traversed_patches += num_block_patches;
}
}
}
static void drawAllPatches(GLMeshInterface *mesh, GLuint program)
{
const OpenSubdiv::Osd::PatchArrayVector &patches = mesh->GetPatchTable()->GetPatchArrays();
for (int i = 0; i < patches.size(); ++i) {
const OpenSubdiv::Osd::PatchArray &patch = patches[i];
OpenSubdiv::Far::PatchDescriptor desc = patch.GetDescriptor();
OpenSubdiv::Far::PatchDescriptor::Type patchType = desc.GetType();
if (patchType == OpenSubdiv::Far::PatchDescriptor::QUADS) {
perform_drawElements(
program, i, patch.GetNumPatches() * desc.GetNumControlVertices(), patch.GetIndexBase());
}
}
}
} // namespace
void GLMeshDisplayPrepare(struct OpenSubdiv_GLMesh * /*gl_mesh*/,
const bool use_osd_glsl,
const int active_uv_index)
{
g_active_uv_index = active_uv_index;
g_use_osd_glsl = (use_osd_glsl != 0);
// Update transformation matrices.
glGetFloatv(GL_PROJECTION_MATRIX, g_transform.projection_matrix);
glGetFloatv(GL_MODELVIEW_MATRIX, g_transform.model_view_matrix);
copy_m3_m4((float(*)[3])g_transform.normal_matrix, (float(*)[4])g_transform.model_view_matrix);
invert_m3((float(*)[3])g_transform.normal_matrix);
transpose_m3((float(*)[3])g_transform.normal_matrix);
// Update OpenGL lights positions, colors etc.
g_lighting_data.num_enabled = 0;
for (int i = 0; i < MAX_LIGHTS; ++i) {
GLboolean enabled;
glGetBooleanv(GL_LIGHT0 + i, &enabled);
if (enabled) {
g_lighting_data.num_enabled++;
}
// TODO(sergey): Stop using glGetLight.
glGetLightfv(GL_LIGHT0 + i, GL_POSITION, g_lighting_data.lights[i].position);
glGetLightfv(GL_LIGHT0 + i, GL_AMBIENT, g_lighting_data.lights[i].ambient);
glGetLightfv(GL_LIGHT0 + i, GL_DIFFUSE, g_lighting_data.lights[i].diffuse);
glGetLightfv(GL_LIGHT0 + i, GL_SPECULAR, g_lighting_data.lights[i].specular);
glGetLightfv(GL_LIGHT0 + i, GL_SPOT_DIRECTION, g_lighting_data.lights[i].spot_direction);
#ifdef SUPPORT_COLOR_MATERIAL
glGetLightfv(
GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, &g_lighting_data.lights[i].constant_attenuation);
glGetLightfv(
GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, &g_lighting_data.lights[i].linear_attenuation);
glGetLightfv(
GL_LIGHT0 + i, GL_QUADRATIC_ATTENUATION, &g_lighting_data.lights[i].quadratic_attenuation);
glGetLightfv(GL_LIGHT0 + i, GL_SPOT_CUTOFF, &g_lighting_data.lights[i].spot_cutoff);
glGetLightfv(GL_LIGHT0 + i, GL_SPOT_EXPONENT, &g_lighting_data.lights[i].spot_exponent);
g_lighting_data.lights[i].spot_cos_cutoff = cos(g_lighting_data.lights[i].spot_cutoff);
#endif
}
}
void GLMeshDisplayDrawPatches(OpenSubdiv_GLMesh *gl_mesh,
const bool fill_quads,
const int start_patch,
const int num_patches)
{
GLMeshInterface *mesh = gl_mesh->internal->mesh_interface;
// Make sure all global invariants are initialized.
if (!openSubdiv_initGLMeshDrawingResources()) {
return;
}
/// Setup GLSL/OpenGL to draw patches in current context.
GLuint program = prepare_patchDraw(gl_mesh, fill_quads != 0);
if (start_patch != -1) {
drawPartitionPatchesRange(mesh, program, start_patch, num_patches);
}
else {
drawAllPatches(mesh, program);
}
// Finish patch drawing by restoring all changes to the OpenGL context.
finishPatchDraw(fill_quads != 0);
}
} // namespace opensubdiv_capi

View File

@@ -1,39 +0,0 @@
// Copyright 2013 Blender Foundation. All rights reserved.
//
// 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.
//
// Author: Sergey Sharybin
#ifndef OPENSUBDIV_GL_MESH_DRAW_H_
#define OPENSUBDIV_GL_MESH_DRAW_H_
#include <stdint.h> // for bool
struct OpenSubdiv_GLMesh;
namespace opensubdiv_capi {
void GLMeshDisplayPrepare(struct OpenSubdiv_GLMesh *gl_mesh,
const bool use_osd_glsl,
const int active_uv_index);
void GLMeshDisplayDrawPatches(OpenSubdiv_GLMesh *gl_mesh,
const bool fill_quads,
const int start_patch,
const int num_patches);
} // namespace opensubdiv_capi
#endif // OPENSUBDIV_GL_MESH_DRAW_H_

View File

@@ -1,171 +0,0 @@
// Copyright 2013 Blender Foundation. All rights reserved.
//
// 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.
//
// Author: Sergey Sharybin
#include "internal/opensubdiv_gl_mesh_fvar.h"
#include <GL/glew.h>
#include <opensubdiv/far/primvarRefiner.h>
#include "internal/opensubdiv_util.h"
namespace opensubdiv_capi {
////////////////////////////////////////////////////////////////////////////////
// GLMeshFVarData
GLMeshFVarData::GLMeshFVarData() : texture_buffer(0), offset_buffer(0)
{
}
GLMeshFVarData::~GLMeshFVarData()
{
release();
}
void GLMeshFVarData::release()
{
if (texture_buffer) {
glDeleteTextures(1, &texture_buffer);
}
if (offset_buffer) {
glDeleteTextures(1, &offset_buffer);
}
texture_buffer = 0;
offset_buffer = 0;
fvar_width = 0;
channel_offsets.clear();
}
void GLMeshFVarData::create(const OpenSubdiv::Far::TopologyRefiner *topology_refiner,
const OpenSubdiv::Far::PatchTable *patch_table,
int fvar_width,
const float *fvar_src_data)
{
release();
this->fvar_width = fvar_width;
/// Expand fvar data to per-patch array.
const int max_level = topology_refiner->GetMaxLevel();
const int num_channels = patch_table->GetNumFVarChannels();
vector<float> data;
int fvar_data_offset = 0;
channel_offsets.resize(num_channels);
for (int channel = 0; channel < num_channels; ++channel) {
OpenSubdiv::Far::ConstIndexArray indices = patch_table->GetFVarValues(channel);
channel_offsets[channel] = data.size();
data.reserve(data.size() + indices.size() * fvar_width);
for (int fvert = 0; fvert < indices.size(); ++fvert) {
int index = indices[fvert] * fvar_width;
for (int i = 0; i < fvar_width; ++i) {
data.push_back(fvar_src_data[fvar_data_offset + index++]);
}
}
if (topology_refiner->IsUniform()) {
const int num_values_max = topology_refiner->GetLevel(max_level).GetNumFVarValues(channel);
fvar_data_offset += num_values_max * fvar_width;
}
else {
const int num_values_total = topology_refiner->GetNumFVarValuesTotal(channel);
fvar_data_offset += num_values_total * fvar_width;
}
}
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), &data[0], GL_STATIC_DRAW);
glGenTextures(1, &texture_buffer);
glBindTexture(GL_TEXTURE_BUFFER, texture_buffer);
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, buffer);
glDeleteBuffers(1, &buffer);
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(
GL_ARRAY_BUFFER, channel_offsets.size() * sizeof(int), &channel_offsets[0], GL_STATIC_DRAW);
glGenTextures(1, &offset_buffer);
glBindTexture(GL_TEXTURE_BUFFER, offset_buffer);
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32I, buffer);
glBindTexture(GL_TEXTURE_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
////////////////////////////////////////////////////////////////////////////////
// Helper functions.
struct FVarVertex {
float u, v;
void Clear()
{
u = v = 0.0f;
}
void AddWithWeight(FVarVertex const &src, float weight)
{
u += weight * src.u;
v += weight * src.v;
}
};
void interpolateFVarData(const OpenSubdiv::Far::TopologyRefiner &refiner,
const vector<float> &uvs,
vector<float> *fvar_data)
{
const int fvar_width = 2;
const int max_level = refiner.GetMaxLevel();
size_t fvar_data_offset = 0, values_offset = 0;
for (int channel = 0; channel < refiner.GetNumFVarChannels(); ++channel) {
const int num_values = refiner.GetLevel(0).GetNumFVarValues(channel) * 2;
const int num_values_max = refiner.GetLevel(max_level).GetNumFVarValues(channel);
const int num_values_total = refiner.GetNumFVarValuesTotal(channel);
if (num_values_total <= 0) {
continue;
}
OpenSubdiv::Far::PrimvarRefiner primvar_refiner(refiner);
if (refiner.IsUniform()) {
// For uniform we only keep the highest level of refinement.
fvar_data->resize(fvar_data->size() + num_values_max * fvar_width);
vector<FVarVertex> buffer(num_values_total - num_values_max);
FVarVertex *src = &buffer[0];
memcpy(src, &uvs[values_offset], num_values * sizeof(float));
// Defer the last level to treat separately with its alternate
// destination.
for (int level = 1; level < max_level; ++level) {
FVarVertex *dst = src + refiner.GetLevel(level - 1).GetNumFVarValues(channel);
primvar_refiner.InterpolateFaceVarying(level, src, dst, channel);
src = dst;
}
FVarVertex *dst = reinterpret_cast<FVarVertex *>(&(*fvar_data)[fvar_data_offset]);
primvar_refiner.InterpolateFaceVarying(max_level, src, dst, channel);
fvar_data_offset += num_values_max * fvar_width;
}
else {
// For adaptive we keep all levels.
fvar_data->resize(fvar_data->size() + num_values_total * fvar_width);
FVarVertex *src = reinterpret_cast<FVarVertex *>(&(*fvar_data)[fvar_data_offset]);
memcpy(src, &uvs[values_offset], num_values * sizeof(float));
for (int level = 1; level <= max_level; ++level) {
FVarVertex *dst = src + refiner.GetLevel(level - 1).GetNumFVarValues(channel);
primvar_refiner.InterpolateFaceVarying(level, src, dst, channel);
src = dst;
}
fvar_data_offset += num_values_total * fvar_width;
}
values_offset += num_values;
}
}
} // namespace opensubdiv_capi

View File

@@ -1,57 +0,0 @@
// Copyright 2013 Blender Foundation. All rights reserved.
//
// 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.
//
// Author: Sergey Sharybin
#ifndef OPENSUBDIV_GL_MESH_FVAR_H_
#define OPENSUBDIV_GL_MESH_FVAR_H_
// NOTE: This is a [sane(er)] port of previous ground work for getting UVs to
// work. Still needs a lot of work to make it easy, correct and have proper
// data ownership.
#include <opensubdiv/far/patchTable.h>
#include <opensubdiv/far/topologyRefiner.h>
#include "internal/opensubdiv_util.h"
namespace opensubdiv_capi {
// The buffer which holds GPU resources for face-varying elements.
class GLMeshFVarData {
public:
GLMeshFVarData();
~GLMeshFVarData();
void release();
void create(const OpenSubdiv::Far::TopologyRefiner *refiner,
const OpenSubdiv::Far::PatchTable *patch_table,
int fvar_width,
const float *fvar_src_data);
unsigned int texture_buffer;
unsigned int offset_buffer;
vector<int> channel_offsets;
int fvar_width;
};
void interpolateFVarData(const OpenSubdiv::Far::TopologyRefiner &refiner,
const vector<float> &uvs,
vector<float> *fvar_data);
} // namespace opensubdiv_capi
#endif // OPENSUBDIV_GL_MESH_FVAR_H_

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